mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-28 00:04:05 +02:00
Merge branch 'master' of git.icinga.org:icingaweb2-module-director
This commit is contained in:
commit
8054fd37f1
@ -11,19 +11,13 @@ class Director_DatalistentryController extends ActionController
|
||||
|
||||
public function editAction()
|
||||
{
|
||||
$this->indexAction();
|
||||
$this->indexAction(true);
|
||||
}
|
||||
|
||||
public function indexAction($edit = false)
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ($request->getParam('edit')) {
|
||||
$edit = true;
|
||||
} else {
|
||||
$edit = false;
|
||||
}
|
||||
|
||||
$listId = $this->params->get('list_id');
|
||||
$this->view->lastId = $listId;
|
||||
|
||||
@ -46,6 +40,7 @@ class Director_DatalistentryController extends ActionController
|
||||
}
|
||||
|
||||
$form = $this->view->form = $this->loadForm('directorDatalistentry')
|
||||
->setListId($listId)
|
||||
->setSuccessUrl('director/datalistentry' . '?list_id=' . $listId)
|
||||
->setDb($this->db());
|
||||
|
||||
|
7
application/controllers/HosttemplatesController.php
Normal file
7
application/controllers/HosttemplatesController.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Icinga\Module\Director\Web\Controller\ObjectsController;
|
||||
|
||||
class Director_HosttemplatesController extends ObjectsController
|
||||
{
|
||||
}
|
62
application/controllers/SchemaController.php
Normal file
62
application/controllers/SchemaController.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
|
||||
class Director_SchemaController extends ActionController
|
||||
{
|
||||
protected $schema;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->schemas = array(
|
||||
'mysql' => $this->translate('MySQL schema'),
|
||||
'pgsql' => $this->translate('PostgreSQL schema'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function tabs()
|
||||
{
|
||||
$tabs = $this->getTabs();
|
||||
foreach ($this->schemas as $type => $title) {
|
||||
$tabs->add($type, array(
|
||||
'url' => 'director/schema/' . $type,
|
||||
'label' => $title,
|
||||
));
|
||||
}
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
public function mysqlAction()
|
||||
{
|
||||
$this->serveSchema('mysql');
|
||||
}
|
||||
|
||||
public function pgsqlAction()
|
||||
{
|
||||
$this->serveSchema('pgsql');
|
||||
}
|
||||
|
||||
protected function serveSchema($type)
|
||||
{
|
||||
$schema = file_get_contents(
|
||||
sprintf(
|
||||
'%s/schema/%s.sql',
|
||||
$this->Module()->getBasedir(),
|
||||
$type
|
||||
)
|
||||
);
|
||||
|
||||
if ($this->params->get('format') === 'sql') {
|
||||
header('Content-type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename=' . $type . '.sql');
|
||||
echo $schema;
|
||||
exit;
|
||||
// TODO: Shutdown
|
||||
} else {
|
||||
$this->tabs()->activate($type);
|
||||
$this->view->title = $this->schemas[$type];
|
||||
$this->view->schema = $schema;
|
||||
$this->render('schema');
|
||||
}
|
||||
}
|
||||
}
|
7
application/controllers/ServicetemplatesController.php
Normal file
7
application/controllers/ServicetemplatesController.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Icinga\Module\Director\Web\Controller\ObjectsController;
|
||||
|
||||
class Director_ServicetemplatesController extends ObjectsController
|
||||
{
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
|
||||
@ -8,42 +7,12 @@ class Director_SettingsController extends ActionController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->tabs = $this->Module()->getConfigTabs()->activate('config');
|
||||
$this->view->tabs = $this->Module()
|
||||
->getConfigTabs()
|
||||
->activate('config');
|
||||
|
||||
$resource = $this->Config()->get('db', 'resource');
|
||||
|
||||
$form = new ConfigForm();
|
||||
|
||||
$form->setIniConfig($this->Config('config'));
|
||||
$form->addElement('select', 'resource', array(
|
||||
'required' => true,
|
||||
'label' => $this->translate('DB Resource'),
|
||||
'multiOptions' => array(null => $this->translate('- please choose -')) + $this->getResources(),
|
||||
'value' => $resource
|
||||
));
|
||||
$form->setSubmitLabel($this->translate('Save'));
|
||||
|
||||
$form->setOnSuccess(function($form) {
|
||||
/** @var $form ConfigForm */
|
||||
$this->Config('config')->setSection('db', array(
|
||||
'resource' => $form->getValue('resource')
|
||||
));
|
||||
$form->save();
|
||||
});
|
||||
|
||||
$form->handleRequest();
|
||||
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
public function getResources()
|
||||
{
|
||||
$resources = array();
|
||||
foreach (ResourceFactory::getResourceConfigs() as $name => $resource) {
|
||||
if ($resource->type === 'db') {
|
||||
$resources['ido'][$name] = $name;
|
||||
}
|
||||
}
|
||||
return $resources;
|
||||
$this->view->form = $this->loadForm('config')
|
||||
->setModuleConfig($this->Config())
|
||||
->handleRequest();
|
||||
}
|
||||
}
|
||||
|
152
application/forms/ConfigForm.php
Normal file
152
application/forms/ConfigForm.php
Normal file
@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Forms;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Module\Director\Web\Form\QuickForm;
|
||||
|
||||
class ConfigForm extends QuickForm
|
||||
{
|
||||
protected $config;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$resources = $this->enumResources();
|
||||
|
||||
$this->addElement('select', 'resource', array(
|
||||
'required' => true,
|
||||
'label' => $this->translate('DB Resource'),
|
||||
'multiOptions' => $this->optionalEnum($resources),
|
||||
'class' => 'autosubmit',
|
||||
'value' => $this->config()->get('db', 'resource')
|
||||
));
|
||||
|
||||
if (empty($resources)) {
|
||||
$this->getElement('resource')->addError(
|
||||
$this->translate('This has to be a MySQL or PostgreSQL database')
|
||||
);
|
||||
|
||||
$hint = $this->translate('Please click %s to create new DB resources');
|
||||
$link = $this->getView()->qlink(
|
||||
$this->translate('here'),
|
||||
'config/resource',
|
||||
null,
|
||||
array('data-base-target' => '_main')
|
||||
);
|
||||
$this->addHtmlHint(sprintf($hint, $link));
|
||||
}
|
||||
|
||||
$this->setSubmitLabel($this->translate('Store configuration'));
|
||||
}
|
||||
|
||||
protected function onSetup()
|
||||
{
|
||||
if ($this->hasBeenSubmitted()) {
|
||||
// Do not hinder the form from being stored
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->hasBeenSent() && $this->isValidPartial($this->getRequest()->getPost())) {
|
||||
$resourceName = $this->getValue('resource');
|
||||
} else {
|
||||
$resourceName = $this->config()->get('db', 'resource');
|
||||
}
|
||||
|
||||
if ($resourceName) {
|
||||
$resource = ResourceFactory::create($resourceName);
|
||||
$db = $resource->getDbAdapter();
|
||||
|
||||
try {
|
||||
$query = $db->select()->from('director_dbversion', 'COUNT(*)');
|
||||
$db->fetchOne($query);
|
||||
|
||||
if (! $this->hasBeenSent()) {
|
||||
$hint = $this->translate(
|
||||
'Configuration looks good, you should be ready to %s'
|
||||
. ' Icinga Director'
|
||||
);
|
||||
$link = $this->getView()->qlink(
|
||||
$this->translate('start using'),
|
||||
'director/welcome',
|
||||
null,
|
||||
array('data-base-target' => '_main')
|
||||
);
|
||||
$this->addHtmlHint(sprintf($hint, $link));
|
||||
$this->moveSubmitToBottom();
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->getElement('resource')
|
||||
->addError('Could not fetch: ' . $e->getMessage())
|
||||
->removeDecorator('description');
|
||||
|
||||
$hint = $this->translate(
|
||||
'Please make sure that your database grants enough permissions'
|
||||
. ' and that you deployed the correct %s.'
|
||||
);
|
||||
$link = $this->getView()->qlink(
|
||||
$this->translate('database schema'),
|
||||
'director/schema/' . $resource->getDbType(),
|
||||
null,
|
||||
array('data-base-target' => '_next')
|
||||
);
|
||||
$this->addHtmlHint(sprintf($hint, $link));
|
||||
$this->moveSubmitToBottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setModuleConfig(Config $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
$config = $this->config();
|
||||
$value = $this->getValue('resource');
|
||||
|
||||
$config->setSection('db', array('resource' => $value));
|
||||
|
||||
try {
|
||||
$config->saveIni();
|
||||
$this->redirectOnSuccess($this->translate('Configuration has been stored'));
|
||||
} catch (Exception $e) {
|
||||
$this->getElement('resource')->addError(
|
||||
sprintf(
|
||||
$this->translate('Unable to store the configuration to "%s"'),
|
||||
$config->getConfigFile()
|
||||
)
|
||||
)->removeDecorator('description');
|
||||
$this->addHtmlHint(
|
||||
'<pre>' . $config . '</pre>'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function config()
|
||||
{
|
||||
if ($this->config === null) {
|
||||
$this->config = Config::module('director');
|
||||
}
|
||||
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
protected function enumResources()
|
||||
{
|
||||
$resources = array();
|
||||
$allowed = array('mysql', 'pgsql');
|
||||
|
||||
foreach (ResourceFactory::getResourceConfigs() as $name => $resource) {
|
||||
if ($resource->type === 'db' && in_array($resource->db, $allowed)) {
|
||||
$resources[$name] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $resources;
|
||||
}
|
||||
}
|
26
application/forms/CustomvarForm.php
Normal file
26
application/forms/CustomvarForm.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Forms;
|
||||
|
||||
use Icinga\Module\Director\Web\Form\QuickForm;
|
||||
|
||||
class CustomvarForm extends QuickForm
|
||||
{
|
||||
protected $submitLabel = false;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$this->removeCsrfToken();
|
||||
$this->removeElement(self::ID);
|
||||
$this->addElement('text', 'varname', array(
|
||||
'label' => $this->translate('Variable name'),
|
||||
'required' => true,
|
||||
));
|
||||
|
||||
$this->addElement('text', 'varvalue', array(
|
||||
'label' => $this->translate('Value'),
|
||||
));
|
||||
|
||||
// $this->addHidden('format', 'string'); // expression, json?
|
||||
}
|
||||
}
|
@ -7,22 +7,30 @@ use Icinga\Web\Hook;
|
||||
|
||||
class DirectorDatafieldForm extends DirectorObjectForm
|
||||
{
|
||||
protected $objectName = 'Data field';
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$this->addHtmlHint(
|
||||
$this->translate('Data fields allow you to customize input controls your custom variables.')
|
||||
);
|
||||
|
||||
$this->addElement('text', 'varname', array(
|
||||
'required' => true,
|
||||
'label' => $this->translate('Field name'),
|
||||
'description' => $this->translate('The unique name of the field')
|
||||
'description' => $this->translate('The unique name of the field'),
|
||||
'required' => true,
|
||||
));
|
||||
|
||||
$this->addElement('text', 'caption', array(
|
||||
'label' => $this->translate('Caption'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('The caption which should be displayed')
|
||||
));
|
||||
|
||||
$this->addElement('textarea', 'description', array(
|
||||
'label' => $this->translate('Description'),
|
||||
'description' => $this->translate('A description about the field')
|
||||
'description' => $this->translate('A description about the field'),
|
||||
'rows' => '3',
|
||||
));
|
||||
|
||||
$this->addElement('select', 'datatype', array(
|
||||
@ -30,15 +38,23 @@ class DirectorDatafieldForm extends DirectorObjectForm
|
||||
'description' => $this->translate('Field type'),
|
||||
'required' => true,
|
||||
'multiOptions' => $this->enumDataTypes(),
|
||||
'class' => 'autosubmit'
|
||||
'class' => 'autosubmit',
|
||||
));
|
||||
|
||||
if ($class = $this->object()->datatype) {
|
||||
$this->addSettings($class);
|
||||
} elseif ($class = $this->getSentValue('datatype')) {
|
||||
|
||||
if ($class = $this->getSentValue('datatype')) {
|
||||
if ($class && array_key_exists($class, $this->enumDataTypes())) {
|
||||
$this->addSettings($class);
|
||||
}
|
||||
} elseif ($class = $this->object()->datatype) {
|
||||
$this->addSettings($class);
|
||||
}
|
||||
|
||||
$this->addSettings();
|
||||
foreach ($this->object()->getSettings() as $key => $val) {
|
||||
if ($el = $this->getElement($key)) {
|
||||
$el->setValue($val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,8 +69,31 @@ class DirectorDatafieldForm extends DirectorObjectForm
|
||||
}
|
||||
}
|
||||
|
||||
protected function clearOutdatedSettings()
|
||||
{
|
||||
$names = array();
|
||||
$object = $this->object();
|
||||
$global = array('varname', 'description', 'caption', 'datatype');
|
||||
|
||||
foreach ($this->getElements() as $el) {
|
||||
if ($el->getIgnore()) continue;
|
||||
$name = $el->getName();
|
||||
if (in_array($name, $global)) continue;
|
||||
$names[$name] = $name;
|
||||
}
|
||||
|
||||
|
||||
foreach ($object->getSettings() as $setting => $value) {
|
||||
if (! array_key_exists($setting, $names)) {
|
||||
unset($object->$setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
$this->clearOutdatedSettings();
|
||||
|
||||
if ($class = $this->getValue('datatype')) {
|
||||
if (array_key_exists($class, $this->enumDataTypes())) {
|
||||
$this->addHidden('format', $class::getFormat());
|
||||
@ -64,21 +103,6 @@ class DirectorDatafieldForm extends DirectorObjectForm
|
||||
parent::onSuccess();
|
||||
}
|
||||
|
||||
public function loadObject($id)
|
||||
{
|
||||
parent::loadObject($id);
|
||||
|
||||
$this->addSettings();
|
||||
foreach ($this->object()->getSettings() as $key => $val) {
|
||||
if ($el = $this->getElement($key)) {
|
||||
$el->setValue($val);
|
||||
}
|
||||
}
|
||||
$this->moveSubmitToBottom();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function enumDataTypes()
|
||||
{
|
||||
$hooks = Hook::all('Director\\DataType');
|
||||
|
@ -3,22 +3,21 @@
|
||||
namespace Icinga\Module\Director\Forms;
|
||||
|
||||
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
|
||||
use Icinga\Authentication\Manager as Auth;
|
||||
use Icinga\Authentication\Auth;
|
||||
|
||||
class DirectorDatalistForm extends DirectorObjectForm
|
||||
{
|
||||
public function setup()
|
||||
{
|
||||
$this->addElement('text', 'list_name', array(
|
||||
'label' => $this->translate('List name')
|
||||
'label' => $this->translate('List name'),
|
||||
'required' => true,
|
||||
));
|
||||
|
||||
$this->addElement('hidden', 'owner');
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
$this->addHidden('owner', self::username());
|
||||
$this->object()->owner = self::username();
|
||||
parent::onSuccess();
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@ use Icinga\Module\Director\Web\Form\DirectorObjectForm;
|
||||
|
||||
class DirectorDatalistEntryForm extends DirectorObjectForm
|
||||
{
|
||||
protected $listId;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$this->addElement('text', 'entry_name', array(
|
||||
@ -18,9 +20,17 @@ class DirectorDatalistEntryForm extends DirectorObjectForm
|
||||
'label' => 'Type',
|
||||
'multiOptions' => array('string' => $this->translate('String'))
|
||||
));
|
||||
}
|
||||
|
||||
$this->addElement('hidden', 'list_id', array(
|
||||
'value' => $this->getRequest()->getParam('list_id'),
|
||||
));
|
||||
public function onSuccess()
|
||||
{
|
||||
$this->object()->list_id = $this->listId;
|
||||
parent::onSuccess();
|
||||
}
|
||||
|
||||
public function setListId($id)
|
||||
{
|
||||
$this->listId = $id;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ class IcingaCommandArgumentForm extends DirectorObjectForm
|
||||
{
|
||||
public function setup()
|
||||
{
|
||||
|
||||
$this->addElement('select', 'command_id', array(
|
||||
'label' => $this->translate('Check command'),
|
||||
'description' => $this->translate('Check command definition')
|
||||
'description' => $this->translate('Check command definition'),
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumCommands())
|
||||
));
|
||||
|
||||
$this->addElement('text', 'argument_name', array(
|
||||
@ -26,7 +26,6 @@ class IcingaCommandArgumentForm extends DirectorObjectForm
|
||||
));
|
||||
|
||||
$this->addHidden('value_format', 'string'); // expression, json?
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,7 +8,8 @@ class IcingaEndpointForm extends DirectorObjectForm
|
||||
{
|
||||
public function setup()
|
||||
{
|
||||
$isTemplate = isset($_POST['object_type']) && $_POST['object_type'] === 'template';
|
||||
$isTemplate = $this->getSentValue('object_type') === 'template';
|
||||
|
||||
$this->addElement('select', 'object_type', array(
|
||||
'label' => $this->translate('Object type'),
|
||||
'description' => $this->translate('Whether this should be a template'),
|
||||
@ -48,15 +49,7 @@ class IcingaEndpointForm extends DirectorObjectForm
|
||||
'description' => $this->translate('The log duration time.')
|
||||
));
|
||||
|
||||
$this->addElement('select', 'zone_id', array(
|
||||
'label' => $this->translate('Cluster Zone'),
|
||||
'description' => $this->translate('Check this host in this specific Icinga cluster zone'),
|
||||
'required' => true
|
||||
));
|
||||
|
||||
$this->addElement('text', 'imports', array(
|
||||
'label' => $this->translate('Imports'),
|
||||
'description' => $this->translate('The inherited endpoint template names')
|
||||
));
|
||||
$this->addZoneElement()
|
||||
->addImportsElement();
|
||||
}
|
||||
}
|
||||
|
@ -11,19 +11,19 @@ class IcingaHostFieldForm extends DirectorObjectForm
|
||||
$this->addElement('select', 'host_id', array(
|
||||
'label' => 'Host Tpl',
|
||||
'description' => 'Host Template',
|
||||
'multiOptions' => $this->optionalEnum($this->getDb()->enumHostTemplates())
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumHostTemplates())
|
||||
));
|
||||
|
||||
$this->addElement('select', 'datafield_id', array(
|
||||
'label' => 'Field',
|
||||
'description' => 'Field to assign',
|
||||
'multiOptions' => $this->optionalEnum($this->getDb()->enumDatafields())
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumDatafields())
|
||||
));
|
||||
|
||||
$this->optionalBoolean(
|
||||
'is_required',
|
||||
$this->translate('Required'),
|
||||
$this->translate('Whether this filed is required or not.')
|
||||
$this->translate('Whether this field should be required or not')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -9,31 +9,11 @@ class IcingaHostForm extends DirectorObjectForm
|
||||
{
|
||||
public function setup()
|
||||
{
|
||||
$isTemplate = isset($_POST['object_type']) && $_POST['object_type'] === 'template';
|
||||
$this->addElement('select', 'object_type', array(
|
||||
'label' => $this->translate('Object type'),
|
||||
'description' => $this->translate('Whether this should be a template'),
|
||||
'multiOptions' => array(
|
||||
null => '- please choose -',
|
||||
'object' => 'Host object',
|
||||
'template' => 'Host template',
|
||||
),
|
||||
'class' => 'autosubmit'
|
||||
));
|
||||
|
||||
if ($isTemplate) {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Host template name'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Name for the Icinga host template you are going to create')
|
||||
));
|
||||
} else {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Hostname'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Hostname for the Icinga host you are going to create')
|
||||
'description' => $this->translate('Icinga object name for this host')
|
||||
));
|
||||
}
|
||||
|
||||
$this->addElement('text', 'address', array(
|
||||
'label' => $this->translate('Host address'),
|
||||
@ -45,95 +25,31 @@ class IcingaHostForm extends DirectorObjectForm
|
||||
'description' => $this->translate('Usually your hosts main IPv6 address')
|
||||
));
|
||||
|
||||
$this->addElement('select', 'check_command_id', array(
|
||||
'label' => $this->translate('Check command'),
|
||||
'description' => $this->translate('Check command definition')
|
||||
));
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_notifications',
|
||||
$this->translate('Send notifications'),
|
||||
$this->translate('Whether to send notifications for this host')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_active_checks',
|
||||
$this->translate('Execute active checks'),
|
||||
$this->translate('Whether to actively check this host')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_passive_checks',
|
||||
$this->translate('Accept passive checks'),
|
||||
$this->translate('Whether to accept passive check results for this host')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_event_handler',
|
||||
$this->translate('Enable event handler'),
|
||||
$this->translate('Whether to enable event handlers this host')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_perfdata',
|
||||
$this->translate('Process performance data'),
|
||||
$this->translate('Whether to process performance data provided by this host')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'volatile',
|
||||
$this->translate('Volatile'),
|
||||
$this->translate('Whether this check is volatile.')
|
||||
);
|
||||
$this->addImportsElement();
|
||||
|
||||
/*
|
||||
$this->addElement('text', 'groups', array(
|
||||
'label' => $this->translate('Hostgroups'),
|
||||
'description' => $this->translate('One or more comma separated hostgroup names')
|
||||
));
|
||||
*/
|
||||
|
||||
$this->addElement('text', 'imports', array(
|
||||
'label' => $this->translate('Imports'),
|
||||
'description' => $this->translate('The inherited host template names')
|
||||
if ($this->isTemplate()) {
|
||||
$this->addElement('text', 'address', array(
|
||||
'label' => $this->translate('Host address'),
|
||||
'description' => $this->translate('Host address. Usually an IPv4 address, but may be any kind of address your check plugin is able to deal with')
|
||||
));
|
||||
|
||||
$this->addElement('select', 'zone_id', array(
|
||||
'label' => $this->translate('Cluster Zone'),
|
||||
'description' => $this->translate('Check this host in this specific Icinga cluster zone')
|
||||
$this->addElement('text', 'address6', array(
|
||||
'label' => $this->translate('IPv6 address'),
|
||||
'description' => $this->translate('Usually your hosts main IPv6 address')
|
||||
));
|
||||
|
||||
$this->addCheckExecutionElements();
|
||||
} else {
|
||||
$this->getElement('imports')->setRequired();
|
||||
}
|
||||
|
||||
public function loadObject($id)
|
||||
{
|
||||
parent::loadObject($id);
|
||||
|
||||
$this->addFields();
|
||||
|
||||
$this->moveSubmitToBottom();
|
||||
}
|
||||
|
||||
public function addFields()
|
||||
{
|
||||
$fields = $this->getObject()->getFields($this);
|
||||
$vars = $this->getObject()->vars();
|
||||
|
||||
foreach ($fields as $field) {
|
||||
$datatype = new $field->datatype;
|
||||
$datafield = DirectorDatafield::load($field->datafield_id, $this->getDb());
|
||||
$datatype->setSettings($datafield->getSettings());
|
||||
$varname = $datafield->varname;
|
||||
$el = $datatype->getFormElement('var_' . $varname, $this);
|
||||
$el->setLabel($field->caption);
|
||||
$el->setDescription($field->description);
|
||||
if (isset($vars->$varname)) {
|
||||
$el->setValue($vars->{$varname}->getValue());
|
||||
}
|
||||
|
||||
if ($field->is_required === 'y')
|
||||
{
|
||||
$el->setRequired(true);
|
||||
}
|
||||
|
||||
$this->addElement($el);
|
||||
}
|
||||
$this->addZoneElement();
|
||||
}
|
||||
}
|
||||
|
@ -8,39 +8,15 @@ class IcingaHostGroupForm extends DirectorObjectForm
|
||||
{
|
||||
public function setup()
|
||||
{
|
||||
$isTemplate = isset($_POST['object_type']) && $_POST['object_type'] === 'template';
|
||||
$this->addElement('select', 'object_type', array(
|
||||
'label' => $this->translate('Object type'),
|
||||
'description' => $this->translate('Whether this should be a template'),
|
||||
'multiOptions' => array(
|
||||
null => '- please choose -',
|
||||
'object' => 'Hostgroup object',
|
||||
'template' => 'Hostgroup template',
|
||||
)
|
||||
));
|
||||
|
||||
if ($isTemplate) {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Hostgroup template name'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Hostgroup for the Icinga hostgroup template you are going to create')
|
||||
));
|
||||
} else {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Hostgroup'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Hostgroup for the Icinga hostgroup you are going to create')
|
||||
'description' => $this->translate('Icinga object name for this hostgroup')
|
||||
));
|
||||
}
|
||||
|
||||
$this->addElement('text', 'display_name', array(
|
||||
'label' => $this->translate('Display Name'),
|
||||
'description' => $this->translate('The name which should displayed.')
|
||||
));
|
||||
|
||||
$this->addElement('text', 'imports', array(
|
||||
'label' => $this->translate('Imports'),
|
||||
'description' => $this->translate('The inherited hostgroup template names')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ class IcingaHostVarForm extends DirectorObjectForm
|
||||
$this->addElement('select', 'host_id', array(
|
||||
'label' => $this->translate('Host'),
|
||||
'description' => $this->translate('The name of the host'),
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumHosts()),
|
||||
'required' => true
|
||||
));
|
||||
|
||||
|
@ -9,21 +9,20 @@ class IcingaServiceFieldForm extends DirectorObjectForm
|
||||
public function setup()
|
||||
{
|
||||
$this->addElement('select', 'service_id', array(
|
||||
'label' => 'Service Tpl',
|
||||
'description' => 'Service Template',
|
||||
'multiOptions' => $this->optionalEnum($this->getDb()->enumServiceTemplates())
|
||||
'label' => 'Service template',
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumServiceTemplates())
|
||||
));
|
||||
|
||||
$this->addElement('select', 'datafield_id', array(
|
||||
'label' => 'Field',
|
||||
'description' => 'Field to assign',
|
||||
'multiOptions' => $this->optionalEnum($this->getDb()->enumDatafields())
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumDatafields())
|
||||
));
|
||||
|
||||
$this->optionalBoolean(
|
||||
'is_required',
|
||||
$this->translate('Required'),
|
||||
$this->translate('Whether this filed is required or not.')
|
||||
$this->translate('Whether this field should be required or not')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -8,86 +8,23 @@ class IcingaServiceForm extends DirectorObjectForm
|
||||
{
|
||||
public function setup()
|
||||
{
|
||||
$isTemplate = isset($_POST['object_type']) && $_POST['object_type'] === 'template';
|
||||
$this->addElement('select', 'object_type', array(
|
||||
'label' => $this->translate('Object type'),
|
||||
'description' => $this->translate('Whether this should be a template'),
|
||||
'multiOptions' => array(
|
||||
null => '- please choose -',
|
||||
'object' => 'Service object',
|
||||
'template' => 'Service template',
|
||||
),
|
||||
'class' => 'autosubmit'
|
||||
));
|
||||
|
||||
if ($isTemplate) {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Service template name'),
|
||||
'label' => $this->translate('Name'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Name for the Icinga service template you are going to create')
|
||||
));
|
||||
} else {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Servicename'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Servicename for the Icinga service you are going to create')
|
||||
));
|
||||
}
|
||||
|
||||
$this->addElement('select', 'check_command_id', array(
|
||||
'label' => $this->translate('Check command'),
|
||||
'description' => $this->translate('Check command definition')
|
||||
));
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_notifications',
|
||||
$this->translate('Send notifications'),
|
||||
$this->translate('Whether to send notifications for this service')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_active_checks',
|
||||
$this->translate('Execute active checks'),
|
||||
$this->translate('Whether to actively check this service')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_passive_checks',
|
||||
$this->translate('Accept passive checks'),
|
||||
$this->translate('Whether to accept passive check results for this service')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_event_handler',
|
||||
$this->translate('Enable event handler'),
|
||||
$this->translate('Whether to enable event handlers this service')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_perfdata',
|
||||
$this->translate('Process performance data'),
|
||||
$this->translate('Whether to process performance data provided by this service')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'volatile',
|
||||
$this->translate('Volatile'),
|
||||
$this->translate('Whether this check is volatile.')
|
||||
);
|
||||
|
||||
$this->addElement('select', 'zone_id', array(
|
||||
'label' => $this->translate('Cluster Zone'),
|
||||
'description' => $this->translate('Check this host in this specific Icinga cluster zone')
|
||||
'description' => $this->translate('Name for the Icinga object you are going to create')
|
||||
));
|
||||
|
||||
/*
|
||||
$this->addElement('text', 'groups', array(
|
||||
'label' => $this->translate('Servicegroups'),
|
||||
'description' => $this->translate('One or more comma separated servicegroup names')
|
||||
));
|
||||
*/
|
||||
|
||||
$this->addElement('text', 'imports', array(
|
||||
'label' => $this->translate('Imports'),
|
||||
'description' => $this->translate('The inherited service template names')
|
||||
));
|
||||
$this->addImportsElement();
|
||||
|
||||
if ($this->isTemplate()) {
|
||||
$this->addCheckExecutionElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,39 +8,15 @@ class IcingaServiceGroupForm extends DirectorObjectForm
|
||||
{
|
||||
public function setup()
|
||||
{
|
||||
$isTemplate = isset($_POST['object_type']) && $_POST['object_type'] === 'template';
|
||||
$this->addElement('select', 'object_type', array(
|
||||
'label' => $this->translate('Object type'),
|
||||
'description' => $this->translate('Whether this should be a template'),
|
||||
'multiOptions' => array(
|
||||
null => '- please choose -',
|
||||
'object' => 'Servicegroup object',
|
||||
'template' => 'Servicegroup template',
|
||||
)
|
||||
));
|
||||
|
||||
if ($isTemplate) {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Servicegroup template name'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Servicegroup for the Icinga servicegroup template you are going to create')
|
||||
));
|
||||
} else {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Servicegroup'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Servicegroup for the Icinga servicegroup you are going to create')
|
||||
'description' => $this->translate('Icinga object name for this servicegroup')
|
||||
));
|
||||
}
|
||||
|
||||
$this->addElement('text', 'display_name', array(
|
||||
'label' => $this->translate('Display Name'),
|
||||
'description' => $this->translate('The name which should displayed.')
|
||||
));
|
||||
|
||||
$this->addElement('text', 'imports', array(
|
||||
'label' => $this->translate('Imports'),
|
||||
'description' => $this->translate('The inherited servicegroup template names')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ class IcingaServiceVarForm extends DirectorObjectForm
|
||||
$this->addElement('select', 'service_id', array(
|
||||
'label' => $this->translate('Service'),
|
||||
'description' => $this->translate('The name of the service'),
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumServices()),
|
||||
'required' => true
|
||||
));
|
||||
|
||||
|
@ -43,15 +43,7 @@ class IcingaTimePeriodForm extends DirectorObjectForm
|
||||
'description' => $this->translate('the update method'),
|
||||
));
|
||||
|
||||
$this->addElement('select', 'zone_id', array(
|
||||
'label' => $this->translate('Cluster Zone'),
|
||||
'description' => $this->translate('Check this host in this specific Icinga cluster zone'),
|
||||
'required' => true
|
||||
));
|
||||
|
||||
$this->addElement('text', 'imports', array(
|
||||
'label' => $this->translate('Imports'),
|
||||
'description' => $this->translate('The inherited timperiods template names')
|
||||
));
|
||||
$this->addZoneElement();
|
||||
$this->addImportsElement();
|
||||
}
|
||||
}
|
||||
|
@ -49,20 +49,11 @@ class IcingaUserForm extends DirectorObjectForm
|
||||
$this->translate('Whether to send notifications for this user')
|
||||
);
|
||||
|
||||
|
||||
$this->addElement('select', 'zone_id', array(
|
||||
'label' => $this->translate('Cluster Zone'),
|
||||
'description' => $this->translate('Check this user in this specific Icinga cluster zone')
|
||||
));
|
||||
|
||||
$this->addElement('text', 'groups', array(
|
||||
'label' => $this->translate('Usergroups'),
|
||||
'description' => $this->translate('One or more comma separated usergroup names')
|
||||
));
|
||||
|
||||
$this->addElement('text', 'imports', array(
|
||||
'label' => $this->translate('Imports'),
|
||||
'description' => $this->translate('The inherited user template names')
|
||||
));
|
||||
$this->addImportsElement();
|
||||
}
|
||||
}
|
||||
|
@ -8,44 +8,15 @@ class IcingaUserGroupForm extends DirectorObjectForm
|
||||
{
|
||||
public function setup()
|
||||
{
|
||||
$isTemplate = isset($_POST['object_type']) && $_POST['object_type'] === 'template';
|
||||
$this->addElement('select', 'object_type', array(
|
||||
'label' => $this->translate('Object type'),
|
||||
'description' => $this->translate('Whether this should be a template'),
|
||||
'multiOptions' => array(
|
||||
null => '- please choose -',
|
||||
'object' => 'Usergroup object',
|
||||
'template' => 'Usergroup template',
|
||||
)
|
||||
));
|
||||
|
||||
if ($isTemplate) {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Usergroup template name'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Usergroup for the Icinga usergroup template you are going to create')
|
||||
));
|
||||
} else {
|
||||
$this->addElement('text', 'object_name', array(
|
||||
'label' => $this->translate('Usergroup'),
|
||||
'required' => true,
|
||||
'description' => $this->translate('Usergroup for the Icinga usergroup you are going to create')
|
||||
'description' => $this->translate('Icinga object name for this usergroup')
|
||||
));
|
||||
}
|
||||
|
||||
$this->addElement('text', 'display_name', array(
|
||||
'label' => $this->translate('Display Name'),
|
||||
'description' => $this->translate('The name which should displayed.')
|
||||
));
|
||||
|
||||
$this->addElement('select', 'zone_id', array(
|
||||
'label' => $this->translate('Cluster Zone'),
|
||||
'description' => $this->translate('Check this usergroup in this specific Icinga cluster zone')
|
||||
));
|
||||
|
||||
$this->addElement('text', 'imports', array(
|
||||
'label' => $this->translate('Imports'),
|
||||
'description' => $this->translate('The inherited usergroup template names')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ class IcingaZoneForm extends DirectorObjectForm
|
||||
|
||||
$this->addElement('select', 'parent_zone_id', array(
|
||||
'label' => $this->translate('Parent Zone'),
|
||||
'description' => $this->translate('Chose an (optional) parent zone')
|
||||
'description' => $this->translate('Chose an (optional) parent zone'),
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumZones())
|
||||
));
|
||||
|
||||
$this->addElement('text', 'imports', array(
|
||||
|
@ -15,6 +15,8 @@ class DatafieldTable extends QuickTable
|
||||
return array(
|
||||
'id' => 'f.id',
|
||||
'varname' => 'f.varname',
|
||||
'caption' => 'f.caption',
|
||||
'description' => 'f.description',
|
||||
'datatype' => 'f.datatype',
|
||||
);
|
||||
}
|
||||
@ -28,8 +30,8 @@ class DatafieldTable extends QuickTable
|
||||
{
|
||||
$view = $this->view();
|
||||
return array(
|
||||
'caption' => $view->translate('Label'),
|
||||
'varname' => $view->translate('Field name'),
|
||||
'datatype' => $view->translate('Data type'),
|
||||
);
|
||||
}
|
||||
|
||||
@ -40,7 +42,7 @@ class DatafieldTable extends QuickTable
|
||||
$query = $db->select()->from(
|
||||
array('f' => 'director_datafield'),
|
||||
array()
|
||||
)->order('varname ASC');
|
||||
)->order('caption ASC');
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
13
application/tables/IcingaHostTemplateTable.php
Normal file
13
application/tables/IcingaHostTemplateTable.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Tables;
|
||||
|
||||
use Icinga\Module\Director\Tables\IcingaHostTable;
|
||||
|
||||
class IcingaHostTemplateTable extends IcingaHostTable
|
||||
{
|
||||
public function getBaseQuery()
|
||||
{
|
||||
return $this->getUnfilteredQuery()->where('h.object_type = ?', 'template');
|
||||
}
|
||||
}
|
@ -33,7 +33,7 @@ class IcingaServiceTable extends QuickTable
|
||||
);
|
||||
}
|
||||
|
||||
public function getBaseQuery()
|
||||
public function getUnfilteredQuery()
|
||||
{
|
||||
$db = $this->connection()->getConnection();
|
||||
$query = $db->select()->from(
|
||||
@ -47,4 +47,9 @@ class IcingaServiceTable extends QuickTable
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getBaseQuery()
|
||||
{
|
||||
return $this->getUnfilteredQuery()->where('s.object_type = ?', 'object');
|
||||
}
|
||||
}
|
||||
|
13
application/tables/IcingaServiceTemplateTable.php
Normal file
13
application/tables/IcingaServiceTemplateTable.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Tables;
|
||||
|
||||
use Icinga\Module\Director\Tables\IcingaServiceTable;
|
||||
|
||||
class IcingaServiceTemplateTable extends IcingaServiceTable
|
||||
{
|
||||
public function getBaseQuery()
|
||||
{
|
||||
return $this->getUnfilteredQuery()->where('s.object_type = ?', 'template');
|
||||
}
|
||||
}
|
65
application/views/scripts/hosttemplates/tree.phtml
Normal file
65
application/views/scripts/hosttemplates/tree.phtml
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
use Icinga\Web\Url;
|
||||
|
||||
function dumpTree($tree, $self, $level = 0)
|
||||
{
|
||||
$hasChildren = ! empty($tree->children);
|
||||
if ($level === 0) {
|
||||
$class = 'root';
|
||||
} else {
|
||||
$class = 'host';
|
||||
}
|
||||
|
||||
if ($hasChildren) {
|
||||
$collapsed = '';
|
||||
} else {
|
||||
$collapsed = ' class="collapsed"';
|
||||
}
|
||||
|
||||
$html = '<li' . $collapsed . '>';
|
||||
if ($hasChildren) {
|
||||
ksort($tree->children);
|
||||
$html .= '<span class="handle"> </span>';
|
||||
}
|
||||
|
||||
if ($level === 0) {
|
||||
$html .= '<a name="Templates" class="root">' . $self->escape($tree->name) . '</a>';
|
||||
} else {
|
||||
$html .= $self->qlink(
|
||||
$tree->name,
|
||||
'director/host',
|
||||
array('name' => $tree->name),
|
||||
array('class' => $class)
|
||||
);
|
||||
}
|
||||
|
||||
if ($hasChildren) {
|
||||
$html .= '<ul>';
|
||||
foreach ($tree->children as $child) {
|
||||
$html .= dumpTree($child, $self, $level + 1);
|
||||
}
|
||||
$html .= '</ul>';
|
||||
}
|
||||
$html .= "</li>\n";
|
||||
return $html;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
<h1><?= $this->translate('Host template tree') ?></h1>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<ul class="tree" data-base-target="_next">
|
||||
|
||||
<?= dumpTree(
|
||||
(object) array(
|
||||
'name' => 'Templates',
|
||||
'children' => $this->tree
|
||||
),
|
||||
$this
|
||||
) ?>
|
||||
</ul>
|
||||
</div>
|
10
application/views/scripts/schema/schema.phtml
Normal file
10
application/views/scripts/schema/schema.phtml
Normal file
@ -0,0 +1,10 @@
|
||||
<div class="controls">
|
||||
<?= $tabs ?>
|
||||
<h1><?= $this->escape($title) ?></h1>
|
||||
<a href="<?= $this->url()->with('format', 'sql') ?>" target="_blank"><?= $this->icon('download') ?>Download</a>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<pre><?= $this->escape($schema) ?></pre>
|
||||
</div>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<?= $this->tabs ?>
|
||||
</div>
|
||||
|
||||
<div class="content" data-base-target="_next">
|
||||
<?= $form; ?>
|
||||
<div class="content">
|
||||
<?= $form ?>
|
||||
</div>
|
||||
|
@ -15,6 +15,8 @@ foreach ($new as $key => $value) {
|
||||
|
||||
if ($value === null) continue;
|
||||
|
||||
if (is_array($value)) $value = implode(', ', $value);
|
||||
|
||||
echo ' <tr><th>' . $this->escape($key) . '</th><td>';
|
||||
echo $this->escape($value);
|
||||
echo "</td></tr>\n";
|
||||
|
@ -17,12 +17,19 @@ foreach ($old as $key => $value) {
|
||||
$modified = array_key_exists($key, $new);
|
||||
|
||||
if ($value === null && ! $modified) continue;
|
||||
|
||||
if (is_array($value)) $value = implode(', ', $value);
|
||||
if (is_object($value)) $value = json_encode($value);
|
||||
|
||||
echo ' <tr><th>' . $this->escape($key) . '</th><td>';
|
||||
if ($modified) {
|
||||
$newval = $new->$key;
|
||||
if (is_array($newval)) $newval = implode(', ', $newval);
|
||||
if (is_object($newval)) $newval = json_encode($newval);
|
||||
printf(
|
||||
'<span class="old">%s</span> <span class="new">%s</span>',
|
||||
$this->escape($value),
|
||||
$this->escape($new->$key)
|
||||
$this->escape($newval)
|
||||
);
|
||||
} else {
|
||||
echo $this->escape($value);
|
||||
|
@ -7,5 +7,25 @@
|
||||
<?php if ($this->errorMessage): ?>
|
||||
<p class="error"><?= $this->errorMessage ?></p>
|
||||
<?php endif ?>
|
||||
Nothing to see here yet. We will point you to the most common tasks later on.
|
||||
<?php
|
||||
$actions = array(
|
||||
array('cloud', $this->translate('Monitoring Nodes'), 'director/commands'),
|
||||
array('host', $this->translate('Host objecs'), 'director/hosts'),
|
||||
array('services', $this->translate('Monitored Services'), 'director/services'),
|
||||
array('users', $this->translate('Users / Contacts'), 'director/users'),
|
||||
array('chat', $this->translate('Alarms and notifications'), 'director/notificatios'),
|
||||
array('database', $this->translate('Sync / Import'), 'director/list/importsource'),
|
||||
array('wrench', $this->translate('Configuration'), 'director/list/generatedconfig'),
|
||||
);
|
||||
?>
|
||||
<ul class="main-actions">
|
||||
<?php foreach ($actions as $a): ?>
|
||||
<li>
|
||||
<a href="<?= $this->url($a[2]) ?>">
|
||||
<?= $this->icon($a[0]) ?>
|
||||
<?= $this->escape($a[1]) ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -1,7 +1,20 @@
|
||||
<?php
|
||||
|
||||
// Sample permission:
|
||||
$this->providePermission('director/templates', 'Allow to modify templates');
|
||||
$this->providePermission('director/hosts/read', $this->translate('Allow to configure hosts'));
|
||||
$this->providePermission('director/hosts/write', $this->translate('Allow to configure hosts'));
|
||||
$this->providePermission('director/templates/read', $this->translate('Allow to see template details'));
|
||||
$this->providePermission('director/templates/write', $this->translate('Allow to configure templates'));
|
||||
|
||||
$this->provideRestriction(
|
||||
'director/hosttemplates/filter',
|
||||
$this->translate('Allow to use only host templates matching this filter')
|
||||
);
|
||||
|
||||
$this->provideRestriction(
|
||||
'director/dbresources/use',
|
||||
$this->translate('Allow to use only these db resources (comma separated list)')
|
||||
);
|
||||
|
||||
|
||||
$this->provideConfigTab('config', array(
|
||||
'title' => 'Configuration',
|
||||
@ -12,9 +25,10 @@ $section = $this->menuSection(
|
||||
$this->translate('Icinga Director')
|
||||
)->setIcon('cubes');
|
||||
|
||||
$section->add($this->translate('Overview'))->setUrl('director/welcome')->setPriority(20);
|
||||
$section->add($this->translate('Global'))->setUrl('director/commands');
|
||||
$section->add($this->translate('Hosts'))->setUrl('director/hosts');
|
||||
$section->add($this->translate('Fields'))->setUrl('director/field/host');
|
||||
$section->add($this->translate('Fields'))->setUrl('director/field/host')->setPriority(903);
|
||||
$section->add($this->translate('Services'))->setUrl('director/services');
|
||||
$section->add($this->translate('Users'))->setUrl('director/users');
|
||||
$section->add($this->translate('Import / Sync'))
|
||||
|
@ -45,12 +45,17 @@ abstract class CustomVariable implements IcingaConfigRenderer
|
||||
}
|
||||
|
||||
// TODO: implement delete()
|
||||
|
||||
public function hasBeenDeleted()
|
||||
{
|
||||
return $this->deleted;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->deleted = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// TODO: abstract
|
||||
public function getDbValue()
|
||||
{
|
||||
|
@ -89,7 +89,12 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
|
||||
|
||||
protected function refreshIndex()
|
||||
{
|
||||
$this->idx = array_keys($this->vars);
|
||||
$this->idx = array();
|
||||
foreach ($this->vars as $name => $var) {
|
||||
if (! $var->hasBeenDeleted()) {
|
||||
$this->idx[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function loadForStoredObject(IcingaObject $object)
|
||||
@ -169,10 +174,18 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
|
||||
public function setUnmodified()
|
||||
{
|
||||
$this->modified = false;
|
||||
$this->storedVars = $this->vars;
|
||||
$this->storedVars = array();
|
||||
foreach ($this->vars as $key => $var) {
|
||||
$this->storedVars[$key] = clone($var);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOriginalVars()
|
||||
{
|
||||
return $this->storedVars;
|
||||
}
|
||||
|
||||
public function toConfigString()
|
||||
{
|
||||
$out = '';
|
||||
@ -223,10 +236,11 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
|
||||
public function __unset($key)
|
||||
{
|
||||
if (! array_key_exists($key, $this->vars)) {
|
||||
throw new Exception('Trying to unset invalid key');
|
||||
return;
|
||||
}
|
||||
|
||||
unset($this->vars[$key]);
|
||||
$this->vars[$key]->delete();
|
||||
$this->modified = true;
|
||||
|
||||
$this->refreshIndex();
|
||||
}
|
||||
|
@ -2,9 +2,11 @@
|
||||
|
||||
namespace Icinga\Module\Director\DataType;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Data\Db\DbConnection;
|
||||
use Icinga\Module\Director\Web\Form\QuickForm;
|
||||
use Icinga\Module\Director\Web\Hook\DataTypeHook;
|
||||
use Icinga\Data\Db\DbConnection;
|
||||
use Icinga\Module\Director\Util;
|
||||
|
||||
class DataTypeSqlQuery extends DataTypeHook
|
||||
{
|
||||
@ -16,11 +18,22 @@ class DataTypeSqlQuery extends DataTypeHook
|
||||
|
||||
public function getFormElement($name, QuickForm $form)
|
||||
{
|
||||
try {
|
||||
$data = $this->fetchData();
|
||||
$error = false;
|
||||
} catch (Exception $e) {
|
||||
$data = array();
|
||||
$error = sprintf($form->translate('Unable to fetch data: %s'), $e->getMessage());
|
||||
}
|
||||
|
||||
$element = $form->createElement('select', $name, array(
|
||||
'multiOptions' => array(null => '- please choose -') +
|
||||
$this->fetchData(),
|
||||
'multiOptions' => $form->optionalEnum($data),
|
||||
));
|
||||
|
||||
if ($error) {
|
||||
$element->addError($error);
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
@ -36,17 +49,13 @@ class DataTypeSqlQuery extends DataTypeHook
|
||||
|
||||
public static function addSettingsFormFields(QuickForm $form)
|
||||
{
|
||||
$db = $form->getDb();
|
||||
|
||||
$form->addElement('text', 'resource', array(
|
||||
'label' => 'Resource name',
|
||||
'required' => true,
|
||||
));
|
||||
Util::addDbResourceFormElement($form, 'resource');
|
||||
|
||||
$form->addElement('textarea', 'query', array(
|
||||
'label' => 'DB Query',
|
||||
'description' => 'This query should return exactly two columns, value and label',
|
||||
'required' => true,
|
||||
'rows' => 10,
|
||||
));
|
||||
|
||||
return $form;
|
||||
|
@ -85,50 +85,51 @@ class Db extends DbConnection
|
||||
return $db->fetchOne($query);
|
||||
}
|
||||
|
||||
public function fetchHostTemplateTree()
|
||||
public function fetchTemplateTree($type)
|
||||
{
|
||||
$db = $this->db();
|
||||
$query = $db->select()->from(
|
||||
array('ph' => 'icinga_host'),
|
||||
array('p' => 'icinga_' . $type),
|
||||
array(
|
||||
'host' => 'h.object_name',
|
||||
'parent' => 'ph.object_name'
|
||||
'name' => 'o.object_name',
|
||||
'parent' => 'p.object_name'
|
||||
)
|
||||
)->join(
|
||||
array('hi' => 'icinga_host_inheritance'),
|
||||
'ph.id = hi.parent_host_id',
|
||||
array('i' => 'icinga_' . $type . '_inheritance'),
|
||||
'p.id = i.parent_' . $type . '_id',
|
||||
array()
|
||||
)->join(
|
||||
array('h' => 'icinga_host'),
|
||||
'h.id = hi.host_id',
|
||||
array('o' => 'icinga_' . $type),
|
||||
'o.id = i.' . $type . '_id',
|
||||
array()
|
||||
)->where("h.object_type = 'template'")
|
||||
->order('ph.object_name')
|
||||
->order('h.object_name');
|
||||
)->where("o.object_type = 'template'")
|
||||
->order('p.object_name')
|
||||
->order('o.object_name');
|
||||
|
||||
$relations = $db->fetchAll($query);
|
||||
$children = array();
|
||||
$hosts = array();
|
||||
$objects = array();
|
||||
foreach ($relations as $rel) {
|
||||
foreach (array('host', 'parent') as $col) {
|
||||
if (! array_key_exists($rel->$col, $hosts)) {
|
||||
$hosts[$rel->$col] = (object) array(
|
||||
foreach (array('name', 'parent') as $col) {
|
||||
if (! array_key_exists($rel->$col, $objects)) {
|
||||
$objects[$rel->$col] = (object) array(
|
||||
'name' => $rel->$col,
|
||||
'children' => array()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($relations as $rel) {
|
||||
$hosts[$rel->parent]->children[$rel->host] = $hosts[$rel->host];
|
||||
$children[$rel->host] = $rel->parent;
|
||||
$objects[$rel->parent]->children[$rel->name] = $objects[$rel->name];
|
||||
$children[$rel->name] = $rel->parent;
|
||||
}
|
||||
|
||||
foreach ($children as $name => $host) {
|
||||
unset($hosts[$name]);
|
||||
foreach ($children as $name => $object) {
|
||||
unset($objects[$name]);
|
||||
}
|
||||
|
||||
return $hosts;
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function fetchLatestImportedRows($source, $columns = null)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Icinga\Module\Director\Import;
|
||||
|
||||
use Icinga\Module\Director\Util;
|
||||
use Icinga\Module\Director\Web\Form\QuickForm;
|
||||
use Icinga\Module\Director\Web\Hook\ImportSourceHook;
|
||||
use Icinga\Data\Db\DbConnection;
|
||||
@ -23,13 +24,11 @@ class ImportSourceSql extends ImportSourceHook
|
||||
|
||||
public static function addSettingsFormFields(QuickForm $form)
|
||||
{
|
||||
$form->addElement('text', 'resource', array(
|
||||
'label' => 'Resource name',
|
||||
'required' => true,
|
||||
));
|
||||
Util::addDbResourceFormElement($form, 'resource');
|
||||
$form->addElement('textarea', 'query', array(
|
||||
'label' => 'DB Query',
|
||||
'required' => true,
|
||||
'rows' => 15,
|
||||
));
|
||||
return $form;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ namespace Icinga\Module\Director\Objects;
|
||||
use Icinga\Module\Director\Data\Db\DbObject;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Util;
|
||||
use Icinga\Authentication\Manager as Auth;
|
||||
use Icinga\Authentication\Auth;
|
||||
|
||||
class DirectorActivityLog extends DbObject
|
||||
{
|
||||
@ -39,6 +39,59 @@ class DirectorActivityLog extends DbObject
|
||||
}
|
||||
}
|
||||
|
||||
protected static function prepareNewObjectProperties(DbObject $object)
|
||||
{
|
||||
$props = $object->getProperties();
|
||||
if ($object->supportsCustomVars()) {
|
||||
// $props->vars = $object->vars()->toJson();
|
||||
}
|
||||
if ($object->supportsGroups()) {
|
||||
$props['groups'] = $object->groups()->listGroupNames();
|
||||
}
|
||||
if ($object->supportsCustomVars()) {
|
||||
$props['vars'] = $object->getVars();
|
||||
}
|
||||
|
||||
return json_encode($props);
|
||||
}
|
||||
|
||||
protected static function prepareModifiedProperties(DbObject $object)
|
||||
{
|
||||
$props = $object->getModifiedProperties();
|
||||
if ($object->supportsCustomVars()) {
|
||||
$mod = array();
|
||||
foreach ($object->vars() as $name => $var) {
|
||||
if ($var->hasBeenModified()) {
|
||||
$mod[$name] = $var->getValue();
|
||||
}
|
||||
}
|
||||
if (! empty($mod)) {
|
||||
$props['vars'] = (object) $mod;
|
||||
}
|
||||
}
|
||||
if ($object->supportsGroups()) {
|
||||
// $props['groups'] = $object->groups()->listGroupNames();
|
||||
}
|
||||
|
||||
return json_encode($props);
|
||||
}
|
||||
|
||||
protected static function prepareOriginalProperties(DbObject $object)
|
||||
{
|
||||
$props = $object->getModifiedProperties();
|
||||
if ($object->supportsCustomVars()) {
|
||||
$props['vars'] = (object) array();
|
||||
foreach ($object->vars()->getOriginalVars() as $name => $var) {
|
||||
$props['vars']->$name = $var->getValue();
|
||||
}
|
||||
}
|
||||
if ($object->supportsGroups()) {
|
||||
// $props['groups'] = $object->groups()->listGroupNames();
|
||||
}
|
||||
|
||||
return json_encode($props);
|
||||
}
|
||||
|
||||
public static function logCreation(DbObject $object, Db $db)
|
||||
{
|
||||
$data = array(
|
||||
@ -46,7 +99,7 @@ class DirectorActivityLog extends DbObject
|
||||
'action_name' => 'create',
|
||||
'author' => self::username(),
|
||||
'object_type' => $object->getTableName(),
|
||||
'new_properties' => json_encode($object->getProperties()),
|
||||
'new_properties' => self::prepareNewObjectProperties($object),
|
||||
'change_time' => date('Y-m-d H:i:s'), // TODO -> postgres!
|
||||
'parent_checksum' => $db->getLastActivityChecksum()
|
||||
);
|
||||
@ -63,8 +116,8 @@ class DirectorActivityLog extends DbObject
|
||||
'action_name' => 'modify',
|
||||
'author' => self::username(),
|
||||
'object_type' => $object->getTableName(),
|
||||
'old_properties' => json_encode($object->getOriginalProperties()),
|
||||
'new_properties' => json_encode($object->getModifiedProperties()),
|
||||
'old_properties' => self::prepareOriginalProperties($object),
|
||||
'new_properties' => self::prepareModifiedProperties($object),
|
||||
'change_time' => date('Y-m-d H:i:s'), // TODO -> postgres!
|
||||
'parent_checksum' => $db->getLastActivityChecksum()
|
||||
);
|
||||
|
@ -23,7 +23,6 @@ class DirectorDatafield extends DbObject
|
||||
|
||||
protected $settings = array();
|
||||
|
||||
|
||||
public function set($key, $value)
|
||||
{
|
||||
if ($this->hasProperty($key)) {
|
||||
@ -33,6 +32,7 @@ class DirectorDatafield extends DbObject
|
||||
if (! array_key_exists($key, $this->settings) || $value !== $this->settings[$key]) {
|
||||
$this->hasBeenModified = true;
|
||||
}
|
||||
|
||||
$this->settings[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
@ -50,6 +50,20 @@ class DirectorDatafield extends DbObject
|
||||
return parent::get($key);
|
||||
}
|
||||
|
||||
public function __unset($key)
|
||||
{
|
||||
if ($this->hasProperty($key)) {
|
||||
return parent::__set($key, $value);
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $this->settings)) {
|
||||
unset($this->settings[$key]);
|
||||
$this->hasBeenModified = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSettings()
|
||||
{
|
||||
return $this->settings;
|
||||
@ -100,7 +114,7 @@ class DirectorDatafield extends DbObject
|
||||
}
|
||||
|
||||
foreach ($del as $key) {
|
||||
$db->update(
|
||||
$db->delete(
|
||||
'director_datafield_setting',
|
||||
$db->quoteInto($where, $key)
|
||||
);
|
||||
|
@ -43,6 +43,8 @@ class IcingaHost extends IcingaObject
|
||||
|
||||
protected $supportsImports = true;
|
||||
|
||||
protected $supportsFields = true;
|
||||
|
||||
protected function renderCheck_command_id()
|
||||
{
|
||||
return $this->renderCommandProperty($this->check_command_id);
|
||||
@ -82,22 +84,4 @@ class IcingaHost extends IcingaObject
|
||||
{
|
||||
return $this->renderBooleanProperty('volatile');
|
||||
}
|
||||
|
||||
public function getFields(DirectorObjectForm $form)
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->select()
|
||||
->from(
|
||||
array('df' => 'director_datafield')
|
||||
)
|
||||
->join(
|
||||
array('hf' => 'icinga_host_field'),
|
||||
'df.id = hf.datafield_id'
|
||||
)
|
||||
->where('hf.host_id = ?', (int) $this->id)
|
||||
->order('df.caption ASC');
|
||||
|
||||
return $db->fetchAll($query);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
||||
|
||||
protected $supportsImports = false;
|
||||
|
||||
protected $supportsFields = false;
|
||||
|
||||
private $type;
|
||||
|
||||
private $vars;
|
||||
@ -55,6 +57,11 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
||||
return $this->supportsImports;
|
||||
}
|
||||
|
||||
public function supportsFields()
|
||||
{
|
||||
return $this->supportsFields;
|
||||
}
|
||||
|
||||
public function hasBeenModified()
|
||||
{
|
||||
if ($this->supportsCustomVars() && $this->vars !== null && $this->vars()->hasBeenModified()) {
|
||||
@ -132,37 +139,143 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
||||
return $this->importedObjects;
|
||||
}
|
||||
|
||||
public function clearImportedObjects()
|
||||
{
|
||||
$this->importedObjects = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getResolvedProperties()
|
||||
{
|
||||
$res = $this->resolveProperties();
|
||||
return $res['_MERGED_'];
|
||||
return $this->getResolved('Properties');
|
||||
}
|
||||
|
||||
public function getInheritedProperties()
|
||||
{
|
||||
return $this->getInherited('Properties');
|
||||
}
|
||||
|
||||
public function getOriginsProperties()
|
||||
{
|
||||
return $this->getOrigins('Properties');
|
||||
}
|
||||
|
||||
public function resolveProperties()
|
||||
{
|
||||
$props = array();
|
||||
$props['_MERGED_'] = (object) array();
|
||||
return $this->resolve('Properties');
|
||||
}
|
||||
|
||||
public function getResolvedFields()
|
||||
{
|
||||
return $this->getResolved('Fields');
|
||||
}
|
||||
|
||||
public function getInheritedFields()
|
||||
{
|
||||
return $this->getInherited('Fields');
|
||||
}
|
||||
|
||||
public function getOriginsFields()
|
||||
{
|
||||
return $this->getOrigins('Fields');
|
||||
}
|
||||
|
||||
public function resolveFields()
|
||||
{
|
||||
return $this->resolve('Fields');
|
||||
}
|
||||
|
||||
public function getResolvedVars()
|
||||
{
|
||||
return $this->getResolved('Vars');
|
||||
}
|
||||
|
||||
public function getInheritedVars()
|
||||
{
|
||||
return $this->getInherited('Vars');
|
||||
}
|
||||
|
||||
public function resolveVars()
|
||||
{
|
||||
return $this->resolve('Vars');
|
||||
}
|
||||
|
||||
public function getOriginsVars()
|
||||
{
|
||||
return $this->getOrigins('Vars');
|
||||
}
|
||||
|
||||
public function getVars()
|
||||
{
|
||||
$vars = (object) array();
|
||||
foreach ($this->vars() as $key => $var) {
|
||||
$vars->$key = $var->getValue();
|
||||
}
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
protected function getResolved($what)
|
||||
{
|
||||
$func = 'resolve' . $what;
|
||||
$res = $this->$func();
|
||||
return $res['_MERGED_'];
|
||||
}
|
||||
|
||||
protected function getInherited($what)
|
||||
{
|
||||
$func = 'resolve' . $what;
|
||||
$res = $this->$func();
|
||||
return $res['_INHERITED_'];
|
||||
}
|
||||
|
||||
protected function getOrigins($what)
|
||||
{
|
||||
$func = 'resolve' . $what;
|
||||
$res = $this->$func();
|
||||
return $res['_ORIGINS_'];
|
||||
}
|
||||
|
||||
protected function resolve($what)
|
||||
{
|
||||
$vals = array();
|
||||
$vals['_MERGED_'] = (object) array();
|
||||
$vals['_INHERITED_'] = (object) array();
|
||||
$vals['_ORIGINS_'] = (object) array();
|
||||
$objects = $this->importedObjects();
|
||||
|
||||
$objects[$this->object_name] = $this;
|
||||
$blacklist = array('id', 'object_type', 'object_name');
|
||||
$get = 'get' . $what;
|
||||
$getInherited = 'getInherited' . $what;
|
||||
$getOrigins = 'getOrigins' . $what;
|
||||
|
||||
foreach ($objects as $name => $object) {
|
||||
$props[$name] = (object) array();
|
||||
if ($name === $this->object_name) {
|
||||
$pprops = $object->getProperties();
|
||||
} else {
|
||||
$pprops = $object->getResolvedProperties();
|
||||
}
|
||||
foreach ($pprops as $key => $value) {
|
||||
if (in_array($key, $blacklist)) continue;
|
||||
if ($value !== null) {
|
||||
$props[$name]->$key = $value;
|
||||
$props['_MERGED_']->$key = $value;
|
||||
$origins = $object->$getOrigins();
|
||||
|
||||
foreach ($object->$getInherited() as $key => $value) {
|
||||
// $vals[$name]->$key = $value;
|
||||
$vals['_MERGED_']->$key = $value;
|
||||
$vals['_INHERITED_']->$key = $value;
|
||||
$vals['_ORIGINS_']->$key = $origins->$key;
|
||||
}
|
||||
|
||||
foreach ($object->$get() as $key => $value) {
|
||||
if ($value === null) continue;
|
||||
$vals['_MERGED_']->$key = $value;
|
||||
$vals['_INHERITED_']->$key = $value;
|
||||
$vals['_ORIGINS_']->$key = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $props;
|
||||
$blacklist = array('id', 'object_type', 'object_name');
|
||||
foreach ($this->$get() as $key => $value) {
|
||||
if ($value === null) continue;
|
||||
if (in_array($key, $blacklist)) continue;
|
||||
|
||||
// $vals[$this->object_name]->$key = $value;
|
||||
$vals['_MERGED_']->$key = $value;
|
||||
}
|
||||
|
||||
return $vals;
|
||||
}
|
||||
|
||||
protected function assertCustomVarsSupport()
|
||||
@ -243,6 +356,39 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
||||
return $this->getShortTableName() . '_id';
|
||||
}
|
||||
|
||||
public function getFields()
|
||||
{
|
||||
$fields = (object) array();
|
||||
|
||||
if (! $this->supportsFields()) {
|
||||
return $fields;
|
||||
}
|
||||
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->select()->from(
|
||||
array('df' => 'director_datafield'),
|
||||
array(
|
||||
'datafield_id' => 'f.datafield_id',
|
||||
'is_required' => 'f.is_required',
|
||||
'varname' => 'df.varname'
|
||||
)
|
||||
)->join(
|
||||
array('f' => $this->getTableName() . '_field'),
|
||||
'df.id = f.datafield_id',
|
||||
array()
|
||||
)->where('f.' . $this->getShortTableName() . '_id = ?', (int) $this->id)
|
||||
->order('df.caption ASC');
|
||||
|
||||
$res = $db->fetchAll($query);
|
||||
|
||||
foreach ($res as $r) {
|
||||
$fields->{$r->varname} = $r;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
public function isTemplate()
|
||||
{
|
||||
return $this->hasProperty('object_type')
|
||||
|
@ -158,19 +158,9 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
|
||||
if ($import instanceof $class) {
|
||||
$this->imports[$import->object_name] = $import;
|
||||
} elseif (is_string($import)) {
|
||||
$query = $this->object->getDb()->select()->from(
|
||||
$this->object->getTableName()
|
||||
)->where('object_name = ?', $import);
|
||||
$imports = $class::loadAll($connection, $query, 'object_name');
|
||||
$import = $class::load($import, $connection);
|
||||
$this->imports[$import->object_name] = $import;
|
||||
}
|
||||
if (! array_key_exists($import, $imports)) {
|
||||
throw new ProgrammingError(
|
||||
'The import "%s" doesn\'t exists.',
|
||||
$import
|
||||
);
|
||||
}
|
||||
|
||||
$this->imports[$import] = $imports[$import];
|
||||
|
||||
$this->modified = true;
|
||||
$this->refreshIndex();
|
||||
|
@ -38,6 +38,8 @@ class IcingaService extends IcingaObject
|
||||
|
||||
protected $supportsCustomVars = true;
|
||||
|
||||
protected $supportsFields = true;
|
||||
|
||||
protected $supportsImports = true;
|
||||
|
||||
protected function renderCheck_command_id()
|
||||
|
@ -2,13 +2,21 @@
|
||||
|
||||
namespace Icinga\Module\Director;
|
||||
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Module\Director\Web\Form\QuickForm;
|
||||
use Icinga\Web\Url;
|
||||
use Zend_Db_Expr;
|
||||
|
||||
class Util
|
||||
{
|
||||
protected static $auth;
|
||||
|
||||
protected static $allowedDbResources;
|
||||
|
||||
public static function pgBinEscape($binary)
|
||||
{
|
||||
return new \Zend_Db_Expr("'\\x" . bin2hex($binary) . "'");
|
||||
return new Zend_Db_Expr("'\\x" . bin2hex($binary) . "'");
|
||||
}
|
||||
|
||||
public static function hex2binary($bin)
|
||||
@ -20,4 +28,84 @@ class Util
|
||||
{
|
||||
return current(unpack('H*', $hex));
|
||||
}
|
||||
|
||||
public static function auth()
|
||||
{
|
||||
if (self::$auth === null) {
|
||||
self::$auth = Auth::getInstance();
|
||||
}
|
||||
return self::$auth;
|
||||
}
|
||||
|
||||
public static function hasPermission($name)
|
||||
{
|
||||
return self::auth()->hasPermission($name);
|
||||
}
|
||||
|
||||
public static function getRestrictions($name)
|
||||
{
|
||||
return self::auth()->getRestrictions($name);
|
||||
}
|
||||
|
||||
public static function dbResourceIsAllowed($name)
|
||||
{
|
||||
if (self::$allowedDbResources === null) {
|
||||
$restrictions = self::getRestrictions('director/dbresources/use');
|
||||
$list = array();
|
||||
foreach ($restrictions as $restriction) {
|
||||
foreach (preg_split('/\s*,\s*/', $restriction, -1, PREG_SPLIT_NO_EMPTY) as $key) {
|
||||
$list[$key] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
self::$allowedDbResources = $list;
|
||||
} else {
|
||||
$list = self::$allowedDbResources;
|
||||
}
|
||||
|
||||
if (empty($list) || array_key_exists($name, $list)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function enumDbResources()
|
||||
{
|
||||
$resources = array();
|
||||
foreach (ResourceFactory::getResourceConfigs() as $name => $resource) {
|
||||
if ($resource->type === 'db' && self::dbResourceIsAllowed($name)) {
|
||||
$resources[$name] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $resources;
|
||||
}
|
||||
|
||||
public static function addDbResourceFormElement(QuickForm $form, $name)
|
||||
{
|
||||
$list = Util::enumDbResources();
|
||||
|
||||
$form->addElement('select', $name, array(
|
||||
'label' => 'Resource name',
|
||||
'multiOptions' => $form->optionalEnum($list),
|
||||
'required' => true,
|
||||
));
|
||||
|
||||
if (true && empty($list)) {
|
||||
if (self::hasPermission('config/application/resources')) {
|
||||
$hint = $form->translate('Please click %s to create new DB resources');
|
||||
$link = sprintf(
|
||||
'<a href="' . Url::fromPath('config/resource') . '" data-base-target="_main">%s</a>',
|
||||
$form->translate('here')
|
||||
);
|
||||
$form->addHtmlHint(sprintf($hint, $link));
|
||||
$msg = $form->translate('No db resource available');
|
||||
} else {
|
||||
$msg = $form->translate('Please ask an administrator to grant you access to DB resources');
|
||||
}
|
||||
|
||||
$form->getElement($name)->addError($msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,18 +16,18 @@ abstract class ObjectController extends ActionController
|
||||
if ($name = $this->params->get('name')) {
|
||||
$params['name'] = $name;
|
||||
|
||||
$this->getTabs()->add($type, array(
|
||||
'url' => sprintf('director/%s', $ltype),
|
||||
'urlParams' => $params,
|
||||
'label' => $this->translate(ucfirst($ltype)),
|
||||
))->add('modify', array(
|
||||
$this->getTabs()->add('modify', array(
|
||||
'url' => sprintf('director/%s/edit', $ltype),
|
||||
'urlParams' => $params,
|
||||
'label' => $this->translate('Modify')
|
||||
'label' => $this->translate(ucfirst($ltype))
|
||||
))->add('delete', array(
|
||||
'url' => sprintf('director/%s/delete', $ltype),
|
||||
'urlParams' => $params,
|
||||
'label' => $this->translate('Delete')
|
||||
))->add('render', array(
|
||||
'url' => sprintf('director/%s/render', $ltype),
|
||||
'urlParams' => $params,
|
||||
'label' => $this->translate('Preview'),
|
||||
))->add('history', array(
|
||||
'url' => sprintf('director/%s/history', $ltype),
|
||||
'urlParams' => $params,
|
||||
@ -35,16 +35,21 @@ abstract class ObjectController extends ActionController
|
||||
));
|
||||
} else {
|
||||
$this->getTabs()->add('add', array(
|
||||
'url' => sprintf('director/%s', $type),
|
||||
'url' => sprintf('director/%s/add', $type),
|
||||
'label' => sprintf($this->translate('Add %s'), ucfirst($type)),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
return $this->editAction();
|
||||
}
|
||||
|
||||
public function renderAction()
|
||||
{
|
||||
$type = $this->getType();
|
||||
$this->getTabs()->activate($type);
|
||||
$this->getTabs()->activate('render');
|
||||
$this->view->object = $this->object();
|
||||
$this->render('object/show', null, true);
|
||||
}
|
||||
@ -80,17 +85,22 @@ abstract class ObjectController extends ActionController
|
||||
'icinga' . ucfirst($type)
|
||||
)->setDb($this->db());
|
||||
$form->loadObject($this->params->get('name'));
|
||||
$object = $form->getObject();
|
||||
|
||||
$url = Url::fromPath(
|
||||
sprintf('director/%s', $ltype),
|
||||
array('name' => $form->getObject()->object_name)
|
||||
array('name' => $object->object_name)
|
||||
);
|
||||
$form->setSuccessUrl($url);
|
||||
|
||||
$this->view->title = sprintf(
|
||||
$this->translate('Modify Icinga %s'),
|
||||
ucfirst($ltype)
|
||||
);
|
||||
if ($object->isTemplate()) {
|
||||
$title = $this->translate('Modify Icinga %s template');
|
||||
$form->setObjectType('template'); // WHY??
|
||||
} else {
|
||||
$title = $this->translate('Modify Icinga %s');
|
||||
}
|
||||
|
||||
$this->view->title = sprintf($title, ucfirst($ltype));
|
||||
$this->view->form->handleRequest();
|
||||
$this->render('object/form', null, true);
|
||||
}
|
||||
@ -102,15 +112,19 @@ abstract class ObjectController extends ActionController
|
||||
$ltype = strtolower($type);
|
||||
|
||||
$url = sprintf('director/%ss', $ltype);
|
||||
$this->view->form = $this->loadForm('icinga' . ucfirst($type))
|
||||
$form = $this->view->form = $this->loadForm('icinga' . ucfirst($type))
|
||||
->setDb($this->db())
|
||||
->setSuccessUrl($url);
|
||||
|
||||
$this->view->title = sprintf(
|
||||
$this->translate('Add new Icinga %s'),
|
||||
ucfirst($ltype)
|
||||
);
|
||||
$this->view->form->handleRequest();
|
||||
if ($this->params->get('type') === 'template') {
|
||||
$form->setObjectType('template');
|
||||
$title = $this->translate('Add new Icinga %s template');
|
||||
} else {
|
||||
$title = $this->translate('Add new Icinga %s');
|
||||
}
|
||||
|
||||
$this->view->title = sprintf($title, ucfirst($ltype));
|
||||
$form->handleRequest();
|
||||
$this->render('object/form', null, true);
|
||||
}
|
||||
|
||||
|
@ -16,14 +16,12 @@ abstract class ObjectsController extends ActionController
|
||||
|
||||
public function init()
|
||||
{
|
||||
$tabs = $this->getTabs();
|
||||
$type = $this->getType();
|
||||
$ltype = strtolower($type);
|
||||
|
||||
$object = $this->dummyObject();
|
||||
|
||||
if (in_array(ucfirst($type), $this->globalTypes)) {
|
||||
$ltype = strtolower($type);
|
||||
|
||||
$tabs = $this->getTabs();
|
||||
foreach ($this->globalTypes as $tabType) {
|
||||
$ltabType = strtolower($tabType);
|
||||
$tabs->add($ltabType, array(
|
||||
@ -33,67 +31,98 @@ abstract class ObjectsController extends ActionController
|
||||
}
|
||||
$tabs->activate($ltype);
|
||||
|
||||
} elseif ($object->isGroup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$singleType = substr($type, 0, -5);
|
||||
$tabs = $this->getTabs()->add('objects', array(
|
||||
'url' => sprintf('director/%ss', $singleType),
|
||||
'label' => $this->translate(ucfirst($singleType) . 's'),
|
||||
));
|
||||
|
||||
$tabs->add('objectgroups', array(
|
||||
'url' => sprintf('director/%ss', strtolower($type)),
|
||||
'label' => $this->translate(ucfirst(strtolower($type)) . 's')
|
||||
));
|
||||
|
||||
} else {
|
||||
$object = $this->dummyObject();
|
||||
if ($object->isGroup()) {
|
||||
$type = substr($type, 0, -5);
|
||||
}
|
||||
|
||||
$tabs = $this->getTabs()->add('objects', array(
|
||||
'url' => sprintf('director/%ss', strtolower($type)),
|
||||
'label' => $this->translate(ucfirst($type) . 's'),
|
||||
));
|
||||
if ($object->supportsGroups()) {
|
||||
$tabs = $this->getTabs()->add('objecttemplates', array(
|
||||
'url' => sprintf('director/%stemplates', strtolower($type)),
|
||||
'label' => $this->translate('Templates'),
|
||||
));
|
||||
if ($object->supportsGroups() || $object->isGroup()) {
|
||||
$tabs->add('objectgroups', array(
|
||||
'url' => sprintf('director/%sgroups', $type),
|
||||
'label' => $this->translate(ucfirst($type) . 'groups')
|
||||
'label' => $this->translate('Groups')
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
$tabs->add('tree', array(
|
||||
'url' => sprintf('director/%stemplates/tree', $type),
|
||||
'label' => $this->translate('Tree'),
|
||||
));
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$type = $this->getType();
|
||||
$ltype = strtolower($type);
|
||||
|
||||
$dummy = $this->dummyObject();
|
||||
|
||||
if (! in_array($type, $this->globalTypes)) {
|
||||
if ($this->dummyObject()->isGroup()) {
|
||||
if ($dummy->isGroup()) {
|
||||
$this->getTabs()->activate('objectgroups');
|
||||
$table = 'icinga' . ucfirst($type);
|
||||
} elseif ($dummy->isTemplate()) {
|
||||
$this->getTabs()->activate('objecttemplates');
|
||||
$table = 'icinga' . ucfirst($type);
|
||||
$this->loadTable($table);
|
||||
$table = 'icinga' . ucfirst($type) . 'Template';
|
||||
} else {
|
||||
$this->getTabs()->activate('objects');
|
||||
$table = 'icinga' . ucfirst($type);
|
||||
}
|
||||
} else {
|
||||
$table = 'icinga' . ucfirst($type);
|
||||
}
|
||||
|
||||
if ($dummy->isTemplate()) {
|
||||
$addParams = array('type' => 'template');
|
||||
$addTitle = $this->translate('Add %s template');
|
||||
} else {
|
||||
$addParams = array();
|
||||
$addTitle = $this->translate('Add %s');
|
||||
}
|
||||
|
||||
$this->view->addLink = $this->view->qlink(
|
||||
$this->translate('Add ' . ucfirst($ltype)),
|
||||
'director/' . $ltype . '/add'
|
||||
sprintf($addTitle, $this->translate(ucfirst($ltype))),
|
||||
'director/' . $ltype .'/add',
|
||||
$addParams
|
||||
);
|
||||
$this->view->title = $this->translate('Icinga ' . ucfirst($ltype));
|
||||
|
||||
$table = $this->loadTable('icinga' . ucfirst($type))->setConnection($this->db());
|
||||
$table = $this->loadTable($table)->setConnection($this->db());
|
||||
$this->setupFilterControl($table->getFilterEditor($this->getRequest()));
|
||||
$this->view->table = $this->applyPaginationLimits($table);
|
||||
|
||||
$this->render('objects/table', null, true);
|
||||
}
|
||||
|
||||
public function treeAction()
|
||||
{
|
||||
$this->getTabs()->activate('tree');
|
||||
$this->view->tree = $this->db()->fetchTemplateTree(strtolower($this->getType()));
|
||||
}
|
||||
|
||||
protected function dummyObject()
|
||||
{
|
||||
if ($this->dummy === null) {
|
||||
$class = $this->getObjectClassname();
|
||||
$this->dummy = $class::create(array());
|
||||
if ($this->dummy->hasProperty('object_type')) {
|
||||
if (false === strpos($this->getRequest()->getControllerName(), 'template')) {
|
||||
$this->dummy->object_type = 'object';
|
||||
} else {
|
||||
$this->dummy->object_type = 'template';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->dummy;
|
||||
@ -105,7 +134,11 @@ abstract class ObjectsController extends ActionController
|
||||
return preg_replace(
|
||||
array('/group$/', '/period$/', '/argument$/'),
|
||||
array('Group', 'Period', 'Argument'),
|
||||
str_replace(
|
||||
'template',
|
||||
'',
|
||||
substr($this->getRequest()->getControllerName(), 0, -1)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
namespace Icinga\Module\Director\Web\Form;
|
||||
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
use Icinga\Module\Director\Objects\DirectorDatafield;
|
||||
use Zend_Form_Element_Select as Zf_Select;
|
||||
|
||||
abstract class DirectorObjectForm extends QuickForm
|
||||
{
|
||||
@ -10,10 +12,12 @@ abstract class DirectorObjectForm extends QuickForm
|
||||
|
||||
protected $object;
|
||||
|
||||
private $objectName;
|
||||
protected $objectName;
|
||||
|
||||
private $className;
|
||||
|
||||
private $objectType = 'object';
|
||||
|
||||
protected function object($values = array())
|
||||
{
|
||||
if ($this->object === null) {
|
||||
@ -37,22 +41,62 @@ abstract class DirectorObjectForm extends QuickForm
|
||||
return;
|
||||
}
|
||||
|
||||
if ($object->supportsCustomVars()) {
|
||||
$this->addElement('note', '_newvar_hint', array('label' => 'New custom variable'));
|
||||
$this->addElement('text', '_newvar_name', array(
|
||||
'label' => 'Name'
|
||||
));
|
||||
$this->addElement('text', '_newvar_value', array(
|
||||
'label' => 'Value'
|
||||
));
|
||||
$this->addElement('select', '_newvar_format', array(
|
||||
'label' => 'Type',
|
||||
'multiOptions' => array('string' => $this->translate('String'))
|
||||
));
|
||||
}
|
||||
|
||||
if (false && $object->supportsRanges()) {
|
||||
/* TODO implement when new logic is there
|
||||
protected function isTemplate()
|
||||
{
|
||||
return $this->objectType === 'template';
|
||||
}
|
||||
|
||||
protected function handleImports($object, & $values)
|
||||
{
|
||||
if (! $object->supportsImports()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (array_key_exists('imports', $values)) {
|
||||
$value = $values['imports'];
|
||||
unset($values['imports']);
|
||||
$object->clearImportedObjects();
|
||||
$object->imports()->set($value);
|
||||
}
|
||||
|
||||
$el = $this->getElement('imports');
|
||||
if ($el) {
|
||||
$el->setMultiOptions($this->enumAllowedTemplates());
|
||||
$el->setValue($object->imports()->listImportNames());
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleRanges($object, & $values)
|
||||
{
|
||||
if (! $object->supportsRanges()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$key = 'ranges';
|
||||
$object = $this->object();
|
||||
|
||||
/* Sample:
|
||||
|
||||
array(
|
||||
'monday' => 'eins',
|
||||
'tuesday' => '00:00-24:00',
|
||||
'sunday' => 'zwei',
|
||||
);
|
||||
|
||||
*/
|
||||
if (array_key_exists($key, $values)) {
|
||||
$object->ranges()->set($values[$key]);
|
||||
unset($values[$key]);
|
||||
}
|
||||
|
||||
foreach ($object->ranges()->getRanges() as $key => $value) {
|
||||
$this->addRange($key, $value);
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO implement when new logic is there
|
||||
$this->addElement('note', '_newrange_hint', array('label' => 'New range'));
|
||||
$this->addElement('text', '_newrange_name', array(
|
||||
'label' => 'Name'
|
||||
@ -62,24 +106,59 @@ abstract class DirectorObjectForm extends QuickForm
|
||||
));
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleIcingaObject(& $values)
|
||||
protected function handleGroups($object, & $values)
|
||||
{
|
||||
$object = $this->object();
|
||||
$handled = array();
|
||||
if (! $object->supportsGroups()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($object->supportsGroups()) {
|
||||
if (array_key_exists('groups', $values)) {
|
||||
$object->groups()->set(
|
||||
preg_split('/\s*,\s*/', $values['groups'], -1, PREG_SPLIT_NO_EMPTY)
|
||||
);
|
||||
$handled['groups'] = true;
|
||||
$value = $values['groups'];
|
||||
unset($values['groups']);
|
||||
|
||||
// TODO: Drop this once we have arrays everwhere
|
||||
if (is_string($value)) {
|
||||
$value = preg_split('/\s*,\s*/', $value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
}
|
||||
|
||||
$object->groups()->set($value);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->object->supportsCustomVars()) {
|
||||
protected function handleProperties($object, & $values)
|
||||
{
|
||||
if ($this->hasBeenSent()) {
|
||||
$object->setProperties($values);
|
||||
}
|
||||
|
||||
$props = $object->getProperties();
|
||||
if (! $object instanceof IcingaObject) {
|
||||
$this->setDefaults($props);
|
||||
return $this;
|
||||
}
|
||||
|
||||
$inherited = $object->getInheritedProperties();
|
||||
$origins = $object->getOriginsProperties();
|
||||
|
||||
foreach ($props as $k => $v) {
|
||||
if (property_exists($inherited, $k)) {
|
||||
$this->setElementValue($k, $v, $inherited->$k, $origins->$k);
|
||||
} else {
|
||||
$this->setElementValue($k, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleCustomVars($object, & $values)
|
||||
{
|
||||
if (! $object->supportsCustomVars()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->hasBeenSent()) {
|
||||
$vars = array();
|
||||
$handled = array();
|
||||
$newvar = array(
|
||||
'type' => 'string',
|
||||
'name' => null,
|
||||
@ -99,60 +178,158 @@ abstract class DirectorObjectForm extends QuickForm
|
||||
}
|
||||
|
||||
foreach ($vars as $k => $v) {
|
||||
$this->object->vars()->$k = $v;
|
||||
if ($v === '' || $v === null) {
|
||||
unset($object->vars()->$k);
|
||||
} else {
|
||||
$object->vars()->$k = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if ($newvar['name'] && $newvar['value']) {
|
||||
$this->object->vars()->{$newvar['name']} = $newvar['value'];
|
||||
$object->vars()->{$newvar['name']} = $newvar['value'];
|
||||
}
|
||||
|
||||
foreach ($handled as $key) {
|
||||
unset($values[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($object->supportsImports()) {
|
||||
if (array_key_exists('imports', $values)) {
|
||||
$object->imports()->set(
|
||||
preg_split('/\s*,\s*/', $values['imports'], -1, PREG_SPLIT_NO_EMPTY)
|
||||
);
|
||||
$handled['imports'] = true;
|
||||
}
|
||||
$vars = $object->getVars();
|
||||
|
||||
$fields = $object->getResolvedFields();
|
||||
$inherits = $object->getInheritedVars();
|
||||
$origins = $object->getOriginsVars();
|
||||
|
||||
foreach ($fields as $field) {
|
||||
$varname = $field->varname;
|
||||
|
||||
// Get value from the related varname if set:
|
||||
if (property_exists($vars, $varname)) {
|
||||
$value = $vars->$varname;
|
||||
} else {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
if ($object->supportsRanges()) {
|
||||
$object->ranges()->set(array(
|
||||
'monday' => 'eins',
|
||||
'tuesday' => '00:00-24:00',
|
||||
'sunday' => 'zwei',
|
||||
if (property_exists($inherits, $varname)) {
|
||||
$inheritedValue = $inherits->$varname;
|
||||
$inheritFrom = $origins->$varname;
|
||||
if ($inheritFrom === $object->object_name) {
|
||||
$inherited = false;
|
||||
} else {
|
||||
$inherited = true;
|
||||
}
|
||||
} else {
|
||||
$inheritedValue = null;
|
||||
$inheritFrom = false;
|
||||
$inherited = false;
|
||||
}
|
||||
|
||||
$this->addField($field, $value, $inheritedValue, $inheritFrom);
|
||||
}
|
||||
|
||||
// Additional vars
|
||||
foreach ($vars as $key => $value) {
|
||||
// Did we already create a field for this var? Then skip it:
|
||||
if (array_key_exists($key, $fields)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Show inheritance information in case we inherited this var:
|
||||
if (isset($inherited->$key)) {
|
||||
$this->addCustomVar($key, $value, $inherited->$key, $origins->$key);
|
||||
} else {
|
||||
$this->addCustomVar($key, $value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($object->isTemplate()) {
|
||||
$this->addHtml('<h3>Add a custom variable</h3>');
|
||||
$this->addElement('text', '_newvar_name', array(
|
||||
'label' => 'Name'
|
||||
));
|
||||
$this->addElement('text', '_newvar_value', array(
|
||||
'label' => 'Value'
|
||||
));
|
||||
$this->addElement('select', '_newvar_format', array(
|
||||
'label' => 'Type',
|
||||
'multiOptions' => array('string' => $this->translate('String'))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($handled as $key => $value) {
|
||||
unset($values[$key]);
|
||||
public function setObjectType($type)
|
||||
{
|
||||
$this->objectType = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function addField($field, $value = null, $inherited = null, $inheritedFrom = null)
|
||||
{
|
||||
$datafield = DirectorDatafield::load($field->datafield_id, $this->getDb());
|
||||
$datatype = new $datafield->datatype;
|
||||
$datatype->setSettings($datafield->getSettings());
|
||||
|
||||
$name = 'var_' . $datafield->varname;
|
||||
$el = $datatype->getFormElement($name, $this);
|
||||
|
||||
$el->setLabel($datafield->caption);
|
||||
$el->setDescription($datafield->description);
|
||||
|
||||
if ($field->is_required === 'y' && ! $this->isTemplate()) {
|
||||
$el->setRequired(true);
|
||||
}
|
||||
|
||||
$this->addElement($el);
|
||||
$this->setElementValue($name, $value, $inherited, $inheritedFrom);
|
||||
|
||||
return $el;
|
||||
}
|
||||
|
||||
protected function setElementValue($name, $value = null, $inherited = null, $inheritedFrom = null)
|
||||
{
|
||||
$el = $this->getElement($name);
|
||||
if (! $el) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value !== null) {
|
||||
$el->setValue($value);
|
||||
}
|
||||
|
||||
if ($inherited === null || empty($inherited)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($el instanceof Zf_Select) {
|
||||
$multi = $el->getMultiOptions();
|
||||
if (array_key_exists($inherited, $multi)) {
|
||||
$multi[null] = $multi[$inherited] . sprintf(' (%s)', $inheritedFrom);
|
||||
} else {
|
||||
$multi[null] = $this->translate('- inherited -');
|
||||
}
|
||||
$el->setMultiOptions($multi);
|
||||
} else {
|
||||
$el->setAttrib('placeholder', $inherited . sprintf(' (%s)', $inheritedFrom));
|
||||
}
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
$object = $this->object;
|
||||
$values = $this->getValues();
|
||||
if ($object instanceof IcingaObject) {
|
||||
$this->handleIcingaObject($values);
|
||||
}
|
||||
$object->setProperties($values);
|
||||
$object = $this->object();
|
||||
if ($object->hasBeenModified()) {
|
||||
|
||||
$msg = sprintf(
|
||||
$object->hasBeenLoadedFromDb()
|
||||
? 'The Icinga %s has successfully been stored'
|
||||
: 'A new Icinga %s has successfully been created',
|
||||
? $this->translate('The %s has successfully been stored')
|
||||
: $this->translate('A new %s has successfully been created'),
|
||||
$this->translate($this->getObjectName())
|
||||
);
|
||||
|
||||
$object->store($this->db);
|
||||
$this->redirectOnSuccess($msg);
|
||||
} else {
|
||||
$msg = $this->translate('No action taken, object has not been modified');
|
||||
}
|
||||
|
||||
protected function optionalEnum($enum)
|
||||
{
|
||||
return array(
|
||||
null => $this->translate('- please choose -')
|
||||
) + $enum;
|
||||
$this->redirectOnSuccess($msg);
|
||||
}
|
||||
|
||||
protected function optionalBoolean($key, $label, $description)
|
||||
@ -202,65 +379,55 @@ abstract class DirectorObjectForm extends QuickForm
|
||||
return $this->objectName;
|
||||
}
|
||||
|
||||
protected function onRequest()
|
||||
{
|
||||
$object = $this->object();
|
||||
$values = array();
|
||||
|
||||
if ($this->hasBeenSent()) {
|
||||
$post = $this->getRequest()->getPost();
|
||||
foreach ($post as $key => $value) {
|
||||
$el = $this->getElement($key);
|
||||
if ($el && ! $el->getIgnore()) {
|
||||
$values[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($object instanceof IcingaObject) {
|
||||
if (! $object->hasBeenLoadedFromDb()) {
|
||||
$object->object_type = $this->objectType;
|
||||
}
|
||||
$this->handleImports($object, $values);
|
||||
$this->handleCustomVars($object, $values);
|
||||
$this->handleGroups($object, $values);
|
||||
$this->handleRanges($object, $values);
|
||||
}
|
||||
|
||||
$this->handleProperties($object, $values);
|
||||
|
||||
$this->moveSubmitToBottom();
|
||||
}
|
||||
|
||||
public function loadObject($id)
|
||||
{
|
||||
$this->prepareElements();
|
||||
$class = $this->getObjectClassname();
|
||||
$this->object = $class::load($id, $this->db);
|
||||
|
||||
// TODO: hmmmm...
|
||||
if (! is_array($id)) {
|
||||
$this->addHidden('id');
|
||||
}
|
||||
$this->setDefaults($this->object->getProperties());
|
||||
if (! $this->object instanceof IcingaObject) {
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($submit = $this->getElement('submit')) {
|
||||
$this->removeElement('submit');
|
||||
}
|
||||
|
||||
if ($this->object->supportsGroups()) {
|
||||
$this->getElement('groups')->setValue(
|
||||
implode(', ', $this->object->groups()->listGroupNames())
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->object->supportsImports()) {
|
||||
$this->getElement('imports')->setValue(
|
||||
implode(', ', $this->object->imports()->listImportNames())
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->object->supportsCustomVars()) {
|
||||
foreach ($this->object->vars() as $key => $value) {
|
||||
$this->addCustomVar($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->object->supportsRanges()) {
|
||||
/* TODO implement when new logic for customvars is there
|
||||
foreach ($this->object->ranges()->getRanges() as $key => $value) {
|
||||
$this->addRange($key, $value);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if ($submit) {
|
||||
$this->addElement($submit);
|
||||
}
|
||||
|
||||
if (! $this->hasBeenSubmitted()) {
|
||||
$this->beforeValidation($this->object->getProperties());
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function addCustomVar($key, $range)
|
||||
protected function addCustomVar($key, $value, $inherited = null, $inheritedFrom = null)
|
||||
{
|
||||
$this->addElement('text', 'var_' . $key, array(
|
||||
'label' => 'vars.' . $key,
|
||||
'value' => $range->getValue()
|
||||
));
|
||||
$label = 'vars.' . $key;
|
||||
$key = 'var_' . $key;
|
||||
$this->addElement('text', $key, array('label' => $label));
|
||||
$this->setElementValue($key, $value, $inherited, $inheritedFrom);
|
||||
}
|
||||
|
||||
protected function addRange($key, $range)
|
||||
@ -282,55 +449,102 @@ abstract class DirectorObjectForm extends QuickForm
|
||||
if ($this->object !== null) {
|
||||
$this->object->setConnection($db);
|
||||
}
|
||||
if ($this->hasElement('parent_zone_id')) {
|
||||
$this->getElement('parent_zone_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumZones()));
|
||||
}
|
||||
if ($this->hasElement('host_id')) {
|
||||
$this->getElement('host_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumHosts()));
|
||||
}
|
||||
if ($this->hasElement('hostgroup_id')) {
|
||||
$this->getElement('hostgroup_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumHostgroups()));
|
||||
}
|
||||
if ($this->hasElement('service_id')) {
|
||||
$this->getElement('service_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumServices()));
|
||||
}
|
||||
if ($this->hasElement('servicegroup_id')) {
|
||||
$this->getElement('servicegroup_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumServicegroups()));
|
||||
}
|
||||
if ($this->hasElement('user_id')) {
|
||||
$this->getElement('user_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumUsers()));
|
||||
}
|
||||
if ($this->hasElement('usergroup_id')) {
|
||||
$this->getElement('usergroup_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumUsergroups()));
|
||||
}
|
||||
if ($this->hasElement('zone_id')) {
|
||||
$this->getElement('zone_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumZones()));
|
||||
}
|
||||
if ($this->hasElement('check_command_id')) {
|
||||
$this->getElement('check_command_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumCheckCommands()));
|
||||
}
|
||||
if ($this->hasElement('command_id')) {
|
||||
$this->getElement('command_id')
|
||||
->setMultiOptions($this->optionalEnum($db->enumCommands()));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function addZoneElement()
|
||||
{
|
||||
$this->addElement('select', 'zone_id', array(
|
||||
'label' => $this->translate('Cluster Zone'),
|
||||
'description' => $this->translate('Icinga cluster zone'),
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumZones())
|
||||
));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function addImportsElement()
|
||||
{
|
||||
$this->addElement('multiselect', 'imports', array(
|
||||
'label' => $this->translate('Imports'),
|
||||
'description' => $this->translate('Importable templates'),
|
||||
'multiOptions' => $this->enumAllowedTemplates(),
|
||||
'class' => 'autosubmit'
|
||||
));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function addCheckExecutionElements()
|
||||
{
|
||||
$this->addHtml('<h3>Check execution</h3>');
|
||||
|
||||
$this->addElement('select', 'check_command_id', array(
|
||||
'label' => $this->translate('Check command'),
|
||||
'description' => $this->translate('Check command definition'),
|
||||
'multiOptions' => $this->optionalEnum($this->db->enumCheckCommands())
|
||||
));
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_active_checks',
|
||||
$this->translate('Execute active checks'),
|
||||
$this->translate('Whether to actively check this object')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_passive_checks',
|
||||
$this->translate('Accept passive checks'),
|
||||
$this->translate('Whether to accept passive check results for this object')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_notifications',
|
||||
$this->translate('Send notifications'),
|
||||
$this->translate('Whether to send notifications for this object')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_event_handler',
|
||||
$this->translate('Enable event handler'),
|
||||
$this->translate('Whether to enable event handlers this object')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'enable_perfdata',
|
||||
$this->translate('Process performance data'),
|
||||
$this->translate('Whether to process performance data provided by this object')
|
||||
);
|
||||
|
||||
$this->optionalBoolean(
|
||||
'volatile',
|
||||
$this->translate('Volatile'),
|
||||
$this->translate('Whether this check is volatile.')
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function enumAllowedTemplates()
|
||||
{
|
||||
$object = $this->object();
|
||||
$tpl = $this->db->enumIcingaTemplates($object->getShortTableName());
|
||||
$tpl = array_combine($tpl, $tpl);
|
||||
$id = $object->object_name;
|
||||
|
||||
if (array_key_exists($id, $tpl)) {
|
||||
unset($tpl[$id]);
|
||||
}
|
||||
return $tpl;
|
||||
}
|
||||
|
||||
private function dummyForTranslation()
|
||||
{
|
||||
$this->translate('Host');
|
||||
$this->translate('Service');
|
||||
$this->translate('Zone');
|
||||
$this->translate('Command');
|
||||
$this->translate('User');
|
||||
// ... TBC
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace Icinga\Module\Director\Web\Form;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Modules\Module;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Request;
|
||||
use Icinga\Web\Url;
|
||||
@ -60,24 +61,39 @@ abstract class QuickForm extends Zend_Form
|
||||
*/
|
||||
protected $icingaModule;
|
||||
|
||||
protected $icingaModuleName;
|
||||
|
||||
protected $hintCount = 0;
|
||||
|
||||
public function __construct($options = null)
|
||||
{
|
||||
if ($options !== null && array_key_exists('icingaModule', $options)) {
|
||||
$this->icingaModule = $options['icingaModule'];
|
||||
unset($options['icingaModule']);
|
||||
}
|
||||
parent::__construct($options);
|
||||
parent::__construct($this->handleOptions($options));
|
||||
$this->setMethod('post');
|
||||
$this->setAction(Url::fromRequest());
|
||||
$this->createIdElement();
|
||||
$this->regenerateCsrfToken();
|
||||
}
|
||||
|
||||
protected function handleOptions($options = null)
|
||||
{
|
||||
if ($options === null) {
|
||||
return $options;
|
||||
}
|
||||
|
||||
if (array_key_exists('icingaModule', $options)) {
|
||||
$this->icingaModule = $options['icingaModule'];
|
||||
$this->icingaModuleName = $this->icingaModule->getName();
|
||||
unset($options['icingaModule']);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
protected function addSubmitButtonIfSet()
|
||||
{
|
||||
if (false !== ($label = $this->getSubmitLabel())) {
|
||||
$this->addElement('submit', $label);
|
||||
$this->getElement($label)->setLabel($label);
|
||||
$this->getElement($label)->setLabel($label)->removeDecorator('Label');
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,6 +156,7 @@ abstract class QuickForm extends Zend_Form
|
||||
$element = $this->getElement(self::CSRF);
|
||||
}
|
||||
$element->setValue(CsrfToken::generate())->setIgnore(true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -159,6 +176,30 @@ abstract class QuickForm extends Zend_Form
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addHtmlHint($html, $options = array())
|
||||
{
|
||||
return $this->addHtml('<div class="hint">' . $html . '</div>', $options);
|
||||
}
|
||||
|
||||
public function addHtml($html, $options = array())
|
||||
{
|
||||
$name = '_HINT' . ++$this->hintCount;
|
||||
$this->addElement('note', $name, $options);
|
||||
$this->getElement($name)
|
||||
->setValue($html)
|
||||
->setIgnore(true)
|
||||
->removeDecorator('Label');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function optionalEnum($enum)
|
||||
{
|
||||
return array(
|
||||
null => $this->translate('- please choose -')
|
||||
) + $enum;
|
||||
}
|
||||
|
||||
public function setSuccessUrl($url)
|
||||
{
|
||||
$this->successUrl = $url;
|
||||
@ -217,8 +258,8 @@ abstract class QuickForm extends Zend_Form
|
||||
{
|
||||
if (! $this->didSetup) {
|
||||
$this->setup();
|
||||
$this->onSetup();
|
||||
$this->addSubmitButtonIfSet();
|
||||
$this->onSetup();
|
||||
$this->didSetup = true;
|
||||
}
|
||||
|
||||
@ -228,11 +269,9 @@ abstract class QuickForm extends Zend_Form
|
||||
public function handleRequest(Request $request = null)
|
||||
{
|
||||
if ($request !== null) {
|
||||
$this->request = $request;
|
||||
$this->setRequest($request);
|
||||
}
|
||||
|
||||
$this->prepareElements();
|
||||
|
||||
if ($this->hasBeenSent()) {
|
||||
$post = $this->getRequest()->getPost();
|
||||
if ($this->hasBeenSubmitted()) {
|
||||
@ -254,8 +293,11 @@ abstract class QuickForm extends Zend_Form
|
||||
|
||||
public function translate($string)
|
||||
{
|
||||
// TODO: A module should use it's own domain
|
||||
if ($this->icingaModuleName === null) {
|
||||
return t($string);
|
||||
} else {
|
||||
return mt($this->icingaModuleName, $string);
|
||||
}
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
@ -311,10 +353,26 @@ abstract class QuickForm extends Zend_Form
|
||||
Icinga::app()->getFrontController()->getResponse()->redirectAndExit($url);
|
||||
}
|
||||
|
||||
protected function onRequest()
|
||||
{
|
||||
}
|
||||
|
||||
public function setRequest(Request $request)
|
||||
{
|
||||
if ($this->request !== null) {
|
||||
throw new ProgrammingError('Unable to set request twice');
|
||||
}
|
||||
|
||||
$this->request = $request;
|
||||
$this->prepareElements();
|
||||
$this->onRequest();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRequest()
|
||||
{
|
||||
if ($this->request === null) {
|
||||
$this->request = Icinga::app()->getFrontController()->getRequest();
|
||||
$this->setRequest(Icinga::app()->getFrontController()->getRequest());
|
||||
}
|
||||
return $this->request;
|
||||
}
|
||||
|
@ -1,6 +1,90 @@
|
||||
form p.description {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input, select, select option, textarea {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
select::-ms-expand, input::-ms-expand, textarea::-ms-expand { /* for IE 11 */
|
||||
display: none;
|
||||
}
|
||||
|
||||
select {
|
||||
border: 1px solid #f9f9f9;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
border: 1px solid #f9f9f9;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
select:hover, input:hover, textarea:hover, select:focus, input:focus, textarea:focus {
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
select[value=""] {
|
||||
color: blue;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
select option {
|
||||
color: inherit;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
select option[value=""] {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
ul.main-actions {
|
||||
margin: 0;
|
||||
li {
|
||||
list-style-type: none;
|
||||
width: 20em;
|
||||
height: 20em;
|
||||
text-align: center;
|
||||
display: block;
|
||||
padding: 0;
|
||||
float: left;
|
||||
|
||||
a {
|
||||
i {
|
||||
width: 100%;
|
||||
height: 1.3em;
|
||||
font-size: 8em;
|
||||
display: inline-block;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
border: 1px solid #666;
|
||||
padding: 1em;
|
||||
margin: 0.5em;
|
||||
font-size: 1.1em;
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
|
||||
&:hover {
|
||||
background-color: #666;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* BEGIN Forms */
|
||||
form dt label {
|
||||
width: auto;
|
||||
font-weight: normal;
|
||||
|
||||
&.required {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
form dd {
|
||||
@ -10,15 +94,44 @@ form dd {
|
||||
|
||||
form dt {
|
||||
display: inline-block;
|
||||
min-width: 16em;
|
||||
min-width: 12em;
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
form dd:after {
|
||||
display: block;
|
||||
content: '';
|
||||
}
|
||||
textarea {
|
||||
height: 10em;
|
||||
|
||||
form textarea {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
form dd ul.errors {
|
||||
list-style-type: none;
|
||||
padding-left: 0.3em;
|
||||
font-size: 0.857em;
|
||||
|
||||
li {
|
||||
color: @colorCritical;
|
||||
padding: 0.3em;
|
||||
}
|
||||
}
|
||||
|
||||
form div.hint {
|
||||
font-size: 0.857em;
|
||||
padding: 1em;
|
||||
background-color: #f2f4fd;
|
||||
border: 1px solid lightgrey;
|
||||
margin: 1em 0;
|
||||
|
||||
pre {
|
||||
font-style: normal;
|
||||
background-color: white;
|
||||
font-size: 1.25em;
|
||||
margin: 0;
|
||||
padding: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
/* END of Forms */
|
||||
@ -145,10 +258,30 @@ table.simple {
|
||||
tr {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
td:first-child {
|
||||
border-left: 0.5em solid transparent;
|
||||
}
|
||||
|
||||
td:last-child {
|
||||
border-right: 0.5em solid transparent;
|
||||
}
|
||||
background-color: #fafcfe;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #e6e6e6;
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background-color: #888;
|
||||
td {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
tr.active td {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
th {
|
||||
@ -158,7 +291,7 @@ table.simple {
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.1em;
|
||||
padding: 0.1em 1em;
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
189
schema/pgsql-changes/upgrade_34.sql
Normal file
189
schema/pgsql-changes/upgrade_34.sql
Normal file
@ -0,0 +1,189 @@
|
||||
ALTER TABLE director_generated_file ALTER COLUMN content SET DEFAULT NULL;
|
||||
ALTER TABLE icinga_host_field ALTER COLUMN is_required SET NOT NULL;
|
||||
ALTER TABLE icinga_service_field ALTER COLUMN is_required SET NOT NULL;
|
||||
|
||||
CREATE TABLE import_source (
|
||||
id serial,
|
||||
source_name character varying(64) NOT NULL,
|
||||
key_column character varying(64) NOT NULL,
|
||||
provider_class character varying(72) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE INDEX import_source_search_idx ON import_source (key_column);
|
||||
|
||||
|
||||
CREATE TABLE import_source_setting (
|
||||
source_id integer NOT NULL,
|
||||
setting_name character varying(64) NOT NULL,
|
||||
setting_value text NOT NULL,
|
||||
PRIMARY KEY (source_id, setting_name),
|
||||
CONSTRAINT import_source_settings_source
|
||||
FOREIGN KEY (source_id)
|
||||
REFERENCES import_source (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX import_source_setting_source ON import_source_setting (source_id);
|
||||
|
||||
|
||||
CREATE TABLE imported_rowset (
|
||||
checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
PRIMARY KEY (checksum)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE import_run (
|
||||
id serial,
|
||||
source_id integer NOT NULL,
|
||||
rowset_checksum bytea CHECK(LENGTH(rowset_checksum) = 20),
|
||||
start_time timestamp with time zone NOT NULL,
|
||||
end_time timestamp with time zone NOT NULL,
|
||||
succeeded enum_boolean DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT import_run_source
|
||||
FOREIGN KEY (source_id)
|
||||
REFERENCES import_source (id)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT import_run_rowset
|
||||
FOREIGN KEY (rowset_checksum)
|
||||
REFERENCES imported_rowset (checksum)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX import_run_import_source ON import_run (source_id);
|
||||
CREATE INDEX import_run_rowset ON import_run (rowset_checksum);
|
||||
|
||||
|
||||
CREATE TABLE imported_row (
|
||||
checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
object_name character varying(255) NOT NULL,
|
||||
PRIMARY KEY (checksum)
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN imported_row.checksum IS 'sha1(object_name;property_checksum;...)';
|
||||
|
||||
|
||||
CREATE TABLE imported_rowset_row (
|
||||
rowset_checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
row_checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
PRIMARY KEY (rowset_checksum, row_checksum),
|
||||
CONSTRAINT imported_rowset_row_rowset
|
||||
FOREIGN KEY (rowset_checksum)
|
||||
REFERENCES imported_rowset (checksum)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT imported_rowset_row_row
|
||||
FOREIGN KEY (row_checksum)
|
||||
REFERENCES imported_row (checksum)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX imported_rowset_row_rowset_checksum ON imported_rowset_row (rowset_checksum);
|
||||
CREATE INDEX imported_rowset_row_row_checksum ON imported_rowset_row (row_checksum);
|
||||
|
||||
CREATE TABLE imported_property (
|
||||
checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
property_name character varying(64) NOT NULL,
|
||||
property_value text NOT NULL,
|
||||
format enum_property_format,
|
||||
PRIMARY KEY (checksum)
|
||||
);
|
||||
|
||||
CREATE INDEX imported_property_search_idx ON imported_property (property_name);
|
||||
|
||||
CREATE TABLE imported_row_property (
|
||||
row_checksum bytea CHECK(LENGTH(row_checksum) = 20),
|
||||
property_checksum bytea CHECK(LENGTH(property_checksum) = 20),
|
||||
PRIMARY KEY (row_checksum, property_checksum),
|
||||
CONSTRAINT imported_row_property_row
|
||||
FOREIGN KEY (row_checksum)
|
||||
REFERENCES imported_row (checksum)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT imported_row_property_property
|
||||
FOREIGN KEY (property_checksum)
|
||||
REFERENCES imported_property (checksum)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX imported_row_property_row_checksum ON imported_row_property (row_checksum);
|
||||
CREATE INDEX imported_row_property_property_checksum ON imported_row_property (property_checksum);
|
||||
|
||||
|
||||
CREATE TYPE enum_sync_rule_object_type AS ENUM('host', 'user');
|
||||
CREATE TYPE enum_sync_rule_update_policy AS ENUM('merge', 'override', 'ignore');
|
||||
|
||||
CREATE TABLE sync_rule (
|
||||
id serial,
|
||||
rule_name character varying(255) NOT NULL,
|
||||
object_type enum_sync_rule_object_type NOT NULL,
|
||||
update_policy enum_sync_rule_update_policy NOT NULL,
|
||||
purge_existing enum_boolean NOT NULL DEFAULT 'n',
|
||||
filter_expression text DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
|
||||
CREATE TYPE enum_sync_property_merge_policy AS ENUM('override', 'merge');
|
||||
|
||||
CREATE TABLE sync_property (
|
||||
id serial,
|
||||
rule_id integer NOT NULL,
|
||||
source_id integer NOT NULL,
|
||||
source_expression character varying(255) NOT NULL,
|
||||
destination_field character varying(64),
|
||||
priority smallint NOT NULL,
|
||||
filter_expression text DEFAULT NULL,
|
||||
merge_policy enum_sync_property_merge_policy NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT sync_property_rule
|
||||
FOREIGN KEY (rule_id)
|
||||
REFERENCES sync_rule (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT sync_property_source
|
||||
FOREIGN KEY (source_id)
|
||||
REFERENCES import_source (id)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX sync_property_rule ON sync_property (rule_id);
|
||||
CREATE INDEX sync_property_source ON sync_property (source_id);
|
||||
|
||||
|
||||
CREATE TABLE import_row_modifier (
|
||||
id serial,
|
||||
property_id integer NOT NULL,
|
||||
provider_class character varying(72) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE import_row_modifier_setting (
|
||||
modifier_id integer NOT NULL,
|
||||
setting_name character varying(64) NOT NULL,
|
||||
setting_value text DEFAULT NULL,
|
||||
PRIMARY KEY (modifier_id)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE director_datafield_setting (
|
||||
datafield_id integer NOT NULL,
|
||||
setting_name character varying(64) NOT NULL,
|
||||
setting_value text NOT NULL,
|
||||
PRIMARY KEY (datafield_id, setting_name),
|
||||
CONSTRAINT datafield_id_settings
|
||||
FOREIGN KEY (datafield_id)
|
||||
REFERENCES director_datafield (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX director_datafield_datafield ON director_datafield_setting (datafield_id);
|
197
schema/pgsql.sql
197
schema/pgsql.sql
@ -9,11 +9,6 @@
|
||||
-- INSERT INTO director_activity_log (object_type, object_name, action_name, author, change_time, checksum) VALUES('object', 'foo', 'create', 'alex', CURRENT_TIMESTAMP, decode('cf23df2207d99a74fbe169e3eba035e633b65d94', 'hex'));
|
||||
--
|
||||
|
||||
--
|
||||
-- Enumerable Types
|
||||
--
|
||||
-- TODO: what about translation of the strings?
|
||||
|
||||
CREATE TYPE enum_activity_action AS ENUM('create', 'delete', 'modify');
|
||||
CREATE TYPE enum_boolean AS ENUM('y', 'n');
|
||||
CREATE TYPE enum_property_format AS ENUM('string', 'expression', 'json');
|
||||
@ -24,6 +19,9 @@ CREATE TYPE enum_command_object_type AS ENUM('object', 'template', 'external_obj
|
||||
CREATE TYPE enum_apply_object_type AS ENUM('object', 'template', 'apply');
|
||||
CREATE TYPE enum_state_name AS ENUM('OK', 'Warning', 'Critical', 'Unknown', 'Up', 'Down');
|
||||
CREATE TYPE enum_type_name AS ENUM('DowntimeStart', 'DowntimeEnd', 'DowntimeRemoved', 'Custom', 'Acknowledgement', 'Problem', 'Recovery', 'FlappingStart', 'FlappingEnd');
|
||||
CREATE TYPE enum_sync_rule_object_type AS ENUM('host', 'user');
|
||||
CREATE TYPE enum_sync_rule_update_policy AS ENUM('merge', 'override', 'ignore');
|
||||
CREATE TYPE enum_sync_property_merge_policy AS ENUM('override', 'merge');
|
||||
|
||||
|
||||
CREATE TABLE director_dbversion (
|
||||
@ -73,7 +71,7 @@ COMMENT ON COLUMN director_generated_config.duration IS 'Config generation durat
|
||||
|
||||
CREATE TABLE director_generated_file (
|
||||
checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
content text NOT NULL,
|
||||
content text DEFAULT NULL,
|
||||
PRIMARY KEY (checksum)
|
||||
);
|
||||
|
||||
@ -486,7 +484,7 @@ CREATE INDEX host_inheritance_host_parent ON icinga_host_inheritance (parent_hos
|
||||
CREATE TABLE icinga_host_field (
|
||||
host_id integer NOT NULL,
|
||||
datafield_id integer NOT NULL,
|
||||
is_required enum_boolean DEFAULT NULL,
|
||||
is_required enum_boolean NOT NULL,
|
||||
PRIMARY KEY (host_id, datafield_id),
|
||||
CONSTRAINT icinga_host_field_host
|
||||
FOREIGN KEY (host_id)
|
||||
@ -610,7 +608,7 @@ CREATE INDEX service_inheritance_service_parent ON icinga_service_inheritance (p
|
||||
CREATE TABLE icinga_service_field (
|
||||
service_id integer NOT NULL,
|
||||
datafield_id integer NOT NULL,
|
||||
is_required enum_boolean DEFAULT NULL,
|
||||
is_required enum_boolean NOT NULL,
|
||||
PRIMARY KEY (service_id, datafield_id),
|
||||
CONSTRAINT icinga_service_field_service
|
||||
FOREIGN KEY (service_id)
|
||||
@ -963,6 +961,183 @@ CREATE TABLE icinga_usergroup_parent (
|
||||
CREATE INDEX usergroup_parent_usergroup ON icinga_usergroup_parent (usergroup_id);
|
||||
CREATE INDEX usergroup_parent_parent ON icinga_usergroup_parent (parent_usergroup_id);
|
||||
|
||||
--
|
||||
-- TODO: unfinished: see mysql.sql schema from sync_*
|
||||
--
|
||||
|
||||
CREATE TABLE import_source (
|
||||
id serial,
|
||||
source_name character varying(64) NOT NULL,
|
||||
key_column character varying(64) NOT NULL,
|
||||
provider_class character varying(72) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE INDEX import_source_search_idx ON import_source (key_column);
|
||||
|
||||
|
||||
CREATE TABLE import_source_setting (
|
||||
source_id integer NOT NULL,
|
||||
setting_name character varying(64) NOT NULL,
|
||||
setting_value text NOT NULL,
|
||||
PRIMARY KEY (source_id, setting_name),
|
||||
CONSTRAINT import_source_settings_source
|
||||
FOREIGN KEY (source_id)
|
||||
REFERENCES import_source (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX import_source_setting_source ON import_source_setting (source_id);
|
||||
|
||||
|
||||
CREATE TABLE imported_rowset (
|
||||
checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
PRIMARY KEY (checksum)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE import_run (
|
||||
id serial,
|
||||
source_id integer NOT NULL,
|
||||
rowset_checksum bytea CHECK(LENGTH(rowset_checksum) = 20),
|
||||
start_time timestamp with time zone NOT NULL,
|
||||
end_time timestamp with time zone NOT NULL,
|
||||
succeeded enum_boolean DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT import_run_source
|
||||
FOREIGN KEY (source_id)
|
||||
REFERENCES import_source (id)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT import_run_rowset
|
||||
FOREIGN KEY (rowset_checksum)
|
||||
REFERENCES imported_rowset (checksum)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX import_run_import_source ON import_run (source_id);
|
||||
CREATE INDEX import_run_rowset ON import_run (rowset_checksum);
|
||||
|
||||
|
||||
CREATE TABLE imported_row (
|
||||
checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
object_name character varying(255) NOT NULL,
|
||||
PRIMARY KEY (checksum)
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN imported_row.checksum IS 'sha1(object_name;property_checksum;...)';
|
||||
|
||||
|
||||
CREATE TABLE imported_rowset_row (
|
||||
rowset_checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
row_checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
PRIMARY KEY (rowset_checksum, row_checksum),
|
||||
CONSTRAINT imported_rowset_row_rowset
|
||||
FOREIGN KEY (rowset_checksum)
|
||||
REFERENCES imported_rowset (checksum)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT imported_rowset_row_row
|
||||
FOREIGN KEY (row_checksum)
|
||||
REFERENCES imported_row (checksum)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX imported_rowset_row_rowset_checksum ON imported_rowset_row (rowset_checksum);
|
||||
CREATE INDEX imported_rowset_row_row_checksum ON imported_rowset_row (row_checksum);
|
||||
|
||||
CREATE TABLE imported_property (
|
||||
checksum bytea CHECK(LENGTH(checksum) = 20),
|
||||
property_name character varying(64) NOT NULL,
|
||||
property_value text NOT NULL,
|
||||
format enum_property_format,
|
||||
PRIMARY KEY (checksum)
|
||||
);
|
||||
|
||||
CREATE INDEX imported_property_search_idx ON imported_property (property_name);
|
||||
|
||||
CREATE TABLE imported_row_property (
|
||||
row_checksum bytea CHECK(LENGTH(row_checksum) = 20),
|
||||
property_checksum bytea CHECK(LENGTH(property_checksum) = 20),
|
||||
PRIMARY KEY (row_checksum, property_checksum),
|
||||
CONSTRAINT imported_row_property_row
|
||||
FOREIGN KEY (row_checksum)
|
||||
REFERENCES imported_row (checksum)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT imported_row_property_property
|
||||
FOREIGN KEY (property_checksum)
|
||||
REFERENCES imported_property (checksum)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX imported_row_property_row_checksum ON imported_row_property (row_checksum);
|
||||
CREATE INDEX imported_row_property_property_checksum ON imported_row_property (property_checksum);
|
||||
|
||||
CREATE TABLE sync_rule (
|
||||
id serial,
|
||||
rule_name character varying(255) NOT NULL,
|
||||
object_type enum_sync_rule_object_type NOT NULL,
|
||||
update_policy enum_sync_rule_update_policy NOT NULL,
|
||||
purge_existing enum_boolean NOT NULL DEFAULT 'n',
|
||||
filter_expression text DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE sync_property (
|
||||
id serial,
|
||||
rule_id integer NOT NULL,
|
||||
source_id integer NOT NULL,
|
||||
source_expression character varying(255) NOT NULL,
|
||||
destination_field character varying(64),
|
||||
priority smallint NOT NULL,
|
||||
filter_expression text DEFAULT NULL,
|
||||
merge_policy enum_sync_property_merge_policy NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT sync_property_rule
|
||||
FOREIGN KEY (rule_id)
|
||||
REFERENCES sync_rule (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT sync_property_source
|
||||
FOREIGN KEY (source_id)
|
||||
REFERENCES import_source (id)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX sync_property_rule ON sync_property (rule_id);
|
||||
CREATE INDEX sync_property_source ON sync_property (source_id);
|
||||
|
||||
|
||||
CREATE TABLE import_row_modifier (
|
||||
id serial,
|
||||
property_id integer NOT NULL,
|
||||
provider_class character varying(72) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE import_row_modifier_setting (
|
||||
modifier_id integer NOT NULL,
|
||||
setting_name character varying(64) NOT NULL,
|
||||
setting_value text DEFAULT NULL,
|
||||
PRIMARY KEY (modifier_id)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE director_datafield_setting (
|
||||
datafield_id integer NOT NULL,
|
||||
setting_name character varying(64) NOT NULL,
|
||||
setting_value text NOT NULL,
|
||||
PRIMARY KEY (datafield_id, setting_name),
|
||||
CONSTRAINT datafield_id_settings
|
||||
FOREIGN KEY (datafield_id)
|
||||
REFERENCES director_datafield (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX director_datafield_datafield ON director_datafield_setting (datafield_id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user