From 6bea1eff4149148f6b4bca8132ccbb2e63997883 Mon Sep 17 00:00:00 2001 From: Marc DeTrano Date: Fri, 16 Sep 2016 16:25:11 -0600 Subject: [PATCH 1/9] Implement Icinga Dependency Configuration. --- application/clicommands/DependencyCommand.php | 15 + .../controllers/DependenciesController.php | 9 + .../controllers/DependencyController.php | 60 +++ .../DependencytemplateController.php | 16 + application/controllers/SuggestController.php | 83 ++++ application/forms/IcingaDependencyForm.php | 252 +++++++++++ application/tables/IcingaDependencyTable.php | 105 +++++ .../tables/IcingaDependencyTemplateTable.php | 13 + .../Dashlet/DependencyObjectDashlet.php | 26 ++ .../Director/Dashboard/ObjectsDashboard.php | 1 + library/Director/Db.php | 1 + .../Director/IcingaConfig/IcingaConfig.php | 4 +- library/Director/Objects/IcingaDependency.php | 421 ++++++++++++++++++ library/Director/Objects/IcingaObject.php | 3 +- .../Web/ActionBar/TemplateActionBar.php | 3 +- .../Web/Controller/ObjectsController.php | 12 +- .../Web/Controller/TemplateController.php | 2 +- .../Director/Web/Form/DirectorObjectForm.php | 41 +- library/Director/Web/Tabs/ObjectsTabs.php | 16 +- public/js/module.js | 3 +- .../mysql-migrations/upgrade_dependencies.sql | 88 ++++ .../upgrade_dependencies_2.sql | 2 + schema/mysql.sql | 88 ++++ 23 files changed, 1226 insertions(+), 38 deletions(-) create mode 100644 application/clicommands/DependencyCommand.php create mode 100644 application/controllers/DependenciesController.php create mode 100644 application/controllers/DependencyController.php create mode 100644 application/controllers/DependencytemplateController.php create mode 100644 application/forms/IcingaDependencyForm.php create mode 100644 application/tables/IcingaDependencyTable.php create mode 100644 application/tables/IcingaDependencyTemplateTable.php create mode 100644 library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php create mode 100644 library/Director/Objects/IcingaDependency.php create mode 100644 schema/mysql-migrations/upgrade_dependencies.sql create mode 100644 schema/mysql-migrations/upgrade_dependencies_2.sql diff --git a/application/clicommands/DependencyCommand.php b/application/clicommands/DependencyCommand.php new file mode 100644 index 00000000..ff5cbdc6 --- /dev/null +++ b/application/clicommands/DependencyCommand.php @@ -0,0 +1,15 @@ +params->get('apply')) { + $this->apply = IcingaDependency::load( + array('object_name' => $apply, 'object_type' => 'template'), + $this->db() + ); + } + + } + + protected function loadObject() + { + if ($this->object === null) { + if ($name = $this->params->get('name')) { + $params = array('object_name' => $name); + $db = $this->db(); + + $this->object = IcingaDependency::load($params, $db); + } else { + parent::loadObject(); + } + } + + return $this->object; + } + + public function loadForm($name) + { + $form = parent::loadForm($name); + return $form; + } + + protected function beforeHandlingAddRequest($form) + { + if ($this->apply) { + $form->createApplyRuleFor($this->apply); + } + } + + + +} diff --git a/application/controllers/DependencytemplateController.php b/application/controllers/DependencytemplateController.php new file mode 100644 index 00000000..e2bc49d1 --- /dev/null +++ b/application/controllers/DependencytemplateController.php @@ -0,0 +1,16 @@ + $this->params->get('name') + ], $this->db()); + } +} diff --git a/application/controllers/SuggestController.php b/application/controllers/SuggestController.php index dad12236..cc338155 100644 --- a/application/controllers/SuggestController.php +++ b/application/controllers/SuggestController.php @@ -6,6 +6,7 @@ use Icinga\Module\Director\Objects\IcingaService; use Icinga\Module\Director\Web\Controller\ActionController; use Icinga\Data\Filter\Filter; use ipl\Html\Util; +use Icinga\Module\Director\Objects\HostApplyMatches; class SuggestController extends ActionController { @@ -91,6 +92,48 @@ class SuggestController extends ActionController return $db->fetchCol($query); } + protected function suggestServicenames() + { + $r=array(); + $this->assertPermission('director/services'); + $db = $this->db()->getDbAdapter(); + $for_host = $this->getRequest()->getPost('for_host'); + if (!empty($for_host)) { + $tmp_host = IcingaHost::load($for_host,$this->db()); + } + + $query = $db->select()->distinct() + ->from('icinga_service', 'object_name') + ->order('object_name') + ->where("object_type IN ('object','apply')"); + if (!empty($tmp_host)) { + $query->where('host_id = ?',$tmp_host->id); + } + $r = array_merge($r,$db->fetchCol($query)); + if (!empty($tmp_host)) { + $resolver = $tmp_host->templateResolver(); + foreach ($resolver->fetchResolvedParents() as $template_obj) { + $query = $db->select()->distinct() + ->from('icinga_service', 'object_name') + ->order('object_name') + ->where("object_type IN ('object','apply')") + ->where('host_id = ?', $template_obj->id); + $r = array_merge($r,$db->fetchCol($query)); + } + + $matcher = HostApplyMatches::prepare($tmp_host); + foreach ($this->getAllApplyRules() as $rule) { + if ($matcher->matchesFilter($rule->filter)) { //TODO + $r[]=$rule->name; + } + } + + } + natcasesort($r); + return $r; + } + + protected function suggestHosttemplates() { $this->assertPermission('director/hosts'); @@ -199,6 +242,17 @@ class SuggestController extends ActionController return $res; } + protected function suggestDependencytemplates() + { + $this->assertPermission('director/hosts'); + $db = $this->db()->getDbAdapter(); + $query = $db->select() + ->from('icinga_dependency', 'object_name') + ->order('object_name') + ->where("object_type = 'template'"); + return $db->fetchCol($query); + } + protected function highlight($val, $search) { $search = ($search); @@ -209,4 +263,33 @@ class SuggestController extends ActionController $val ); } + + protected function getAllApplyRules() + { + $allApplyRules=$this->fetchAllApplyRules(); + foreach ($allApplyRules as $rule) { + $rule->filter = Filter::fromQueryString($rule->assign_filter); + } + + return $allApplyRules; + } + + protected function fetchAllApplyRules() + { + $db = $this->db()->getDbAdapter(); + $query = $db->select()->from( + array('s' => 'icinga_service'), + array( + 'id' => 's.id', + 'name' => 's.object_name', + 'assign_filter' => 's.assign_filter', + ) + )->where('object_type = ? AND assign_filter IS NOT NULL', 'apply'); + + return $db->fetchAll($query); + } + + + + } diff --git a/application/forms/IcingaDependencyForm.php b/application/forms/IcingaDependencyForm.php new file mode 100644 index 00000000..b9967196 --- /dev/null +++ b/application/forms/IcingaDependencyForm.php @@ -0,0 +1,252 @@ +setupDependencyElements(); + } + + protected function setupDependencyElements() { + + $this->addObjectTypeElement(); + if (! $this->hasObjectType()) { + $this->groupMainProperties(); + return; + } + + $this->addNameElement() + ->addDisabledElement() + ->addImportsElement() + ->addObjectsElement() + ->addBooleanElements() + ->addPeriodElement() + ->addAssignmentElements() + ->addEventFilterElements(array('states')) + ->groupMainProperties() + ->setButtons(); + } + + protected function addNameElement() + { + $this->addElement('text', 'object_name', array( + 'label' => $this->translate('Name'), + 'required' => true, + 'description' => $this->translate('Name for the Icinga dependency you are going to create') + )); + + return $this; + } + + + protected function addAssignmentElements() + { + if (!$this->object || !$this->object->isApplyRule()) { + return $this; + } + + $this->addElement('select', 'apply_to', array( + 'label' => $this->translate('Apply to'), + 'description' => $this->translate( + 'Whether this dependency should affect hosts or services' + ), + 'required' => true, + 'class' => 'autosubmit', + 'multiOptions' => $this->optionalEnum( + array( + 'host' => $this->translate('Hosts'), + 'service' => $this->translate('Services'), + ) + ) + )); + + $applyTo = $this->getSentOrObjectValue('apply_to'); + + if ($applyTo === 'host') { + $columns = IcingaHost::enumProperties($this->db, 'host.'); + } elseif ($applyTo === 'service') { + // TODO: Also add host properties + $columns = IcingaService::enumProperties($this->db, 'service.'); + } else { + return $this; + } + + $this->addAssignFilter(array( + 'columns' => $columns, + 'required' => true, + 'description' => $this->translate( + 'This allows you to configure an assignment filter. Please feel' + . ' free to combine as many nested operators as you want' + ) + )); + return $this; + } + + protected function addPeriodElement() + { + $periods = $this->db->enumTimeperiods(); + if (empty($periods)) { + return $this; + } + + $this->addElement( + 'select', + 'period_id', + array( + 'label' => $this->translate('Time period'), + 'description' => $this->translate( + 'The name of a time period which determines when this' + . ' notification should be triggered. Not set by default.' + ), + 'multiOptions' => $this->optionalEnum($periods), + ) + ); + + return $this; + } + + protected function addBooleanElements() { + + $this->addBoolean( + 'disable_checks', + array( + 'label' => $this->translate('Disable Checks'), + 'description' => $this->translate('Whether to disable checks when this dependency fails. Defaults to false.') + ), + null + ); + + $this->addBoolean( + 'disable_notifications', + array( + 'label' => $this->translate('Disable Notificiations'), + 'description' => $this->translate('Whether to disable notifications when this dependency fails. Defaults to true.') + ), + null + ); + + $this->addBoolean( + 'ignore_soft_states', + array( + 'label' => $this->translate('Ignore Soft States'), + 'description' => $this->translate('Whether to ignore soft states for the reachability calculation. Defaults to true.') + ), + null + ); + + return $this; + } + + protected function addObjectsElement() + { + $this->addElement( + 'text', + 'parent_host', + array( + 'label' => $this->translate('Parent Host'), + 'description' => $this->translate( + 'The parent host.' + ), + 'class' => "autosubmit director-suggest", + 'data-suggestion-context' => 'hostnames', + 'order' => 10, + 'value' => $this->getObject()->get('parent_host') + + ) + ); + $sent_parent=$this->getSentOrObjectValue("parent_host"); + + if (!empty($sent_parent) || $this->object->isApplyRule()) { + $this->addElement( + 'text', + 'parent_service', + array( + 'label' => $this->translate('Parent Service'), + 'description' => $this->translate( + 'Optional. The parent service. If omitted this dependency object is treated as host dependency.' + ), + 'class' => "autosubmit director-suggest", + 'data-suggestion-context' => 'servicenames', + 'data-suggestion-for-host' => $sent_parent, + 'order' => 20, + 'value' => $this->getObject()->get('parent_service') + + ) + ); + + } + + // If configuring Object, allow selection of child host and/or service, otherwise apply rules will determine child object. + if ($this->isObject()) { + $this->addElement( + 'text', + 'child_host', + array( + 'label' => $this->translate('Child Host'), + 'description' => $this->translate( + 'The child host.' + ), + 'class' => "autosubmit director-suggest", + 'data-suggestion-context' => 'hostnames', + 'order' => 30, + 'value' => $this->getObject()->get('child_host') + ) + ); + + $sent_child=$this->getSentOrObjectValue("child_host"); + + if (!empty($sent_child)) { + $this->addElement( + 'text', + 'child_service', + array( + 'label' => $this->translate('Child Service'), + 'description' => $this->translate( + 'Optional. The child service. If omitted this dependency object is treated as host dependency.' + ), + 'class' => "autosubmit director-suggest", + 'data-suggestion-context' => 'servicenames', + 'data-suggestion-for-host' => $sent_child, + 'order' => 40, + 'value' => $this->getObject()->get('child_service') + + ) + ); + + + } + } + + $elements=array('parent_host','child_host','parent_service','child_service'); + $this->addDisplayGroup($elements, 'related_objects', array( + 'decorators' => array( + 'FormElements', + array('HtmlTag', array('tag' => 'dl')), + 'Fieldset', + ), + 'order' => 25, + 'legend' => $this->translate('Related Objects') + )); + + + return $this; + } + + public function createApplyRuleFor(IcingaDependency $dependency) + { + $object = $this->object(); + $object->imports = $dependency->object_name; + $object->object_type = 'apply'; + $object->object_name = $dependency->object_name; + return $this; + } + + +} diff --git a/application/tables/IcingaDependencyTable.php b/application/tables/IcingaDependencyTable.php new file mode 100644 index 00000000..3c342f77 --- /dev/null +++ b/application/tables/IcingaDependencyTable.php @@ -0,0 +1,105 @@ + 'd.id', + 'object_type' => 'd.object_type', + 'dependency' => 'd.object_name', + ); + } + + protected function listTableClasses() + { + return array_merge(array('assignment-table'), parent::listTableClasses()); + } + + protected function getActionUrl($row) + { + return $this->url('director/dependency', array('id' => $row->id)); + } + + public function getTitles() + { + $view = $this->view(); + return array( + 'dependency' => $view->translate('Dependency'), + ); + } + + protected function renderRow($row) + { + $v = $this->view(); + $extra = $this->appliedOnes($row->id); + $htm = " getRowClassesString($row) . ">\n"; + $htm .= '' . $v->qlink($row->dependency, $this->getActionUrl($row)); + if (empty($extra)) { + $htm .= ' ' . $v->qlink( + 'Create apply-rule', + 'director/dependency/add', + array('apply' => $row->dependency, 'type' => 'apply'), + array('class' => 'icon-plus') + ); + + } else { + $htm .= '. Related apply rules: '; + $htm .= $v->qlink( + 'Add more', + 'director/dependency/add', + array('apply' => $row->dependency), + array('class' => 'icon-plus') + ); + } + $htm .= ''; + return $htm . " \n"; + } + + protected function appliedOnes($id) + { + $db = $this->db(); + $query = $db->select()->from( + array('s' => 'icinga_dependency'), + array( + 'id' => 's.id', + 'objectname' => 's.object_name', + ) + )->join( + array('i' => 'icinga_dependency_inheritance'), + 'i.dependency_id = s.id', + array() + )->where('i.parent_dependency_id = ?', $id) + ->where('s.object_type = ?', 'apply'); + + + return $db->fetchPairs($query); + } + + public function getUnfilteredQuery() + { + return $this->db()->select()->from( + array('d' => 'icinga_dependency'), + array() + ); + } + + public function getBaseQuery() + { + return $this->getUnfilteredQuery()->order('d.object_name'); + } +} diff --git a/application/tables/IcingaDependencyTemplateTable.php b/application/tables/IcingaDependencyTemplateTable.php new file mode 100644 index 00000000..60038b69 --- /dev/null +++ b/application/tables/IcingaDependencyTemplateTable.php @@ -0,0 +1,13 @@ +getUnfilteredQuery()->where('d.object_type = ?', 'template'); + } +} diff --git a/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php b/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php new file mode 100644 index 00000000..486e59b0 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php @@ -0,0 +1,26 @@ +translate('Dependencies.'); + } + + public function getSummary() + { + return $this->translate('Define object dependency relationships.') + . ' ' . parent::getSummary(); + } + + public function getUrl() + { + return 'director/dependencies'; + } +} diff --git a/library/Director/Dashboard/ObjectsDashboard.php b/library/Director/Dashboard/ObjectsDashboard.php index 5de0d866..0688d4ab 100644 --- a/library/Director/Dashboard/ObjectsDashboard.php +++ b/library/Director/Dashboard/ObjectsDashboard.php @@ -9,6 +9,7 @@ class ObjectsDashboard extends Dashboard 'ServiceObject', 'CommandObject', // 'Notifications', + 'DependencyObject', ); public function getTitle() diff --git a/library/Director/Db.php b/library/Director/Db.php index 1196d9f1..4c621501 100644 --- a/library/Director/Db.php +++ b/library/Director/Db.php @@ -389,6 +389,7 @@ class Db extends DbConnection 'apiuser', 'endpoint', 'zone', + 'dependency', ); $queries = array(); diff --git a/library/Director/IcingaConfig/IcingaConfig.php b/library/Director/IcingaConfig/IcingaConfig.php index 3713f0ed..e79e9707 100644 --- a/library/Director/IcingaConfig/IcingaConfig.php +++ b/library/Director/IcingaConfig/IcingaConfig.php @@ -477,6 +477,7 @@ class IcingaConfig ->createFileFromDb('userGroup') ->createFileFromDb('user') ->createFileFromDb('notification') + ->createFileFromDb('dependency') ; if (! $this->isLegacy()) { @@ -719,7 +720,8 @@ apply Service for (title => params in host.vars["%s"]) { 'user', 'userGroup', 'timePeriod', - 'notification' + 'notification', + 'dependency' ); return in_array($type, $types); diff --git a/library/Director/Objects/IcingaDependency.php b/library/Director/Objects/IcingaDependency.php new file mode 100644 index 00000000..43b363c9 --- /dev/null +++ b/library/Director/Objects/IcingaDependency.php @@ -0,0 +1,421 @@ + null, + 'object_name' => null, + 'object_type' => null, + 'disabled' => 'n', + 'apply_to' => null, + 'parent_host_id' => null, + 'parent_service_id' => null, + 'child_host_id' => null, + 'child_service_id' => null, + 'disable_checks' => null, + 'disable_notifications' => null, + 'ignore_soft_states' => null, + 'period_id' => null, + 'zone_id' => null, + 'assign_filter' => null, + 'parent_service_s' => null, + ); + + protected $supportsCustomVars = false; + + protected $supportsImports = true; + + protected $supportsApplyRules = true; + + protected $relatedSets = array( + 'states' => 'StateFilterSet', + ); + + protected $relations = array( + 'zone' => 'IcingaZone', + 'parent_host' => 'IcingaHost', + 'parent_service' => 'IcingaService', + 'child_host' => 'IcingaHost', + 'child_service' => 'IcingaService', + 'period' => 'IcingaTimePeriod', + ); + + protected $booleans = array( + 'disable_checks' => 'disable_checks', + 'disable_notifications' => 'disable_notifications', + 'ignore_soft_states' => 'ignore_soft_states' + ); + + /** + * Do not render internal property apply_to + * + * Avoid complaints for method names with underscore: + * @codingStandardsIgnoreStart + * + * @return string + */ + public function renderApply_to() + { + // @codingStandardsIgnoreEnd + return ''; + } + + protected function renderObjectHeader() + { + if ($this->isApplyRule()) { + if (($to = $this->get('apply_to')) === null) { + throw new ConfigurationError( + 'Applied dependency "%s" has no valid object type', + $this->getObjectName() + ); + } + + return sprintf( + "%s %s %s to %s {\n", + $this->getObjectTypeName(), + $this->getType(), + c::renderString($this->getObjectName()), + ucfirst($to) + ); + + } else { + return parent::renderObjectHeader(); + } + } + + protected function setKey($key) + { + if (is_int($key)) { + $this->id = $key; + } elseif (is_array($key)) { + foreach (array('id', 'parent_host_id', 'parent_service_id', 'child_host_id', 'child_service_id', 'object_name') as $k) { + if (array_key_exists($k, $key)) { + $this->set($k, $key[$k]); + } + } + } else { + return parent::setKey($key); + } + + return $this; + } + + protected function renderAssignments() + { + if ($this->hasBeenAssignedToServiceApply()) { + + $tmpService= $this->getRelatedObject('child_service', $this->child_service_id); + $assigns = $tmpService->assignments()->toConfigString(); + + $filter = sprintf( + '%s && service.name == "%s"', + trim($assigns), $this->child_service + ); + return "\n " . $filter . "\n"; + } + + if ($this->hasBeenAssignedToHostTemplateService()) { + $filter = sprintf( + 'assign where "%s" in host.templates && service.name == "%s"', + $this->child_host, $this->child_service + ); + return "\n " . $filter . "\n"; + } + if ($this->hasBeenAssignedToHostTemplate()) { + $filter = sprintf( + 'assign where "%s" in host.templates', + $this->child_host + ); + return "\n " . $filter . "\n"; + } + + if ($this->hasBeenAssignedToServiceTemplate()) { + $filter = sprintf( + 'assign where "%s" in service.templates', + $this->child_service + ); + return "\n " . $filter . "\n"; + } + + return parent::renderAssignments(); + } + + protected function hasBeenAssignedToHostTemplate() + { + try { + return $this->child_host_id && $this->getRelatedObject( + 'child_host', + $this->child_host_id + )->object_type === 'template'; + } catch (NotFoundError $e) { + return false; + } + } + + protected function hasBeenAssignedToServiceTemplate() + { + try { + return $this->child_service_id && $this->getRelatedObject( + 'child_service', + $this->child_service_id + )->object_type === 'template'; + } catch (NotFoundError $e) { + return false; + } + } + + protected function hasBeenAssignedToHostTemplateService() + { + if (!$this->hasBeenAssignedToHostTemplate()) return false; + try { + return $this->child_service_id && $this->getRelatedObject( + 'child_service', + $this->child_service_id + )->object_type === 'object'; + } catch (NotFoundError $e) { + return false; + } + } + + protected function hasBeenAssignedToServiceApply() + { + try { + return $this->child_service_id && $this->getRelatedObject( + 'child_service', + $this->child_service_id + )->object_type === 'apply'; + } catch (NotFoundError $e) { + return false; + } + } + + + /** + * Render child_host_id as host_name + * + * Avoid complaints for method names with underscore: + * @codingStandardsIgnoreStart + * + * @return string + */ + public function renderChild_host_id() + { + // @codingStandardsIgnoreEnd + + if ($this->hasBeenAssignedToHostTemplate()) { + return ''; + } + + return $this->renderRelationProperty('child_host', $this->child_host_id, 'child_host_name'); + } + + /** + * Render parent_host_id as parent_host_name + * + * Avoid complaints for method names with underscore: + * @codingStandardsIgnoreStart + * + * @return string + */ + public function renderParent_host_id() + { + // @codingStandardsIgnoreEnd + + return $this->renderRelationProperty('parent_host', $this->parent_host_id, 'parent_host_name'); + } + + + /** + * Render child_service_id as host_name + * + * Avoid complaints for method names with underscore: + * @codingStandardsIgnoreStart + * + * @return string + */ + public function renderChild_service_id() + { + // @codingStandardsIgnoreEnd + if ($this->hasBeenAssignedToServiceTemplate()) { + return ''; + } + + if ($this->hasBeenAssignedToHostTemplateService()) { + return ''; + } + + if ($this->hasBeenAssignedToServiceApply()) { + return ''; + } + + return $this->renderRelationProperty('child_service', $this->child_service_id, 'child_service_name'); + } + + /** + * Render parent_service_id as parent_service_name + * + * Avoid complaints for method names with underscore: + * @codingStandardsIgnoreStart + * + * @return string + */ + public function renderParent_service_id() + { + return $this->renderRelationProperty('parent_service', $this->parent_service_id, 'parent_service_name'); + } + + //special case for parent service set as plain string for Apply rules + public function renderParent_service_s() + { + return "\n parent_service_name = \"" . $this->parent_service_s ."\"\n"; + } + + public function isApplyRule() + { + if ($this->hasBeenAssignedToHostTemplate()) { + return true; + } + + if ($this->hasBeenAssignedToServiceTemplate()) { + return true; + } + + if ($this->hasBeenAssignedToServiceApply()) { + return true; + } + + return $this->hasProperty('object_type') + && $this->object_type === 'apply'; + } + + protected function resolveUnresolvedRelatedProperty($name) + { + + $short = substr($name, 0, -3); + /** @var IcingaObject $class */ + $class = $this->getRelationClass($short); + $obj_key = $this->unresolvedRelatedProperties[$name]; + + # related services need array key + if ($class == "Icinga\Module\Director\Objects\IcingaService" ) { + if ($name == "parent_service_id" && $this->object_type == 'apply' ) { //special case , parent service can be set as simple string for Apply + if ($this->properties['parent_host_id']==null) { + $this->reallySet('parent_service_s', $this->unresolvedRelatedProperties[$name]); + $this->reallySet('parent_service_id',null); + unset($this->unresolvedRelatedProperties[$name]); + return; + } + } + + $this->reallySet('parent_service_s',null); + $host_id_prop=str_replace("service","host",$name); + if (isset($this->properties[$host_id_prop])) { + $obj_key=array("host_id" => $this->properties[$host_id_prop], "object_name" => $this->unresolvedRelatedProperties[$name]); + } else { + $obj_key=array("host_id" => null, "object_name" => $this->unresolvedRelatedProperties[$name]); + } + + try { + $object = $class::load( $obj_key, $this->connection); + } catch (NotFoundError $e) { + // Not a simple service on host + // Hunt through inherited services, use service assigned to template if found + $tmp_host=IcingaHost::loadWithAutoIncId($this->properties[$host_id_prop], $this->connection); + + //services for applicable templates + $resolver = $tmp_host->templateResolver(); + foreach ($resolver->fetchResolvedParents() as $template_obj) { + $obj_key=array("host_id" => $template_obj->id, "object_name" => $this->unresolvedRelatedProperties[$name]); + try { + $object = $class::load( $obj_key, $this->connection); + } catch (NotFoundError $e) { + continue; + } + break; + } + if (!isset($object)) { //Not an inherited service, now try apply rules + $matcher = HostApplyMatches::prepare($tmp_host); + foreach ($this->getAllApplyRules() as $rule) { + if ($matcher->matchesFilter($rule->filter)) { + if ($rule->name == $this->unresolvedRelatedProperties[$name]) { + $object=IcingaService::loadWithAutoIncId($rule->id, $this->connection); + break; + } + } + } + } + } + } else { + $object = $class::load( + $obj_key, + $this->connection + ); + } + + if (isset($object)) { + $this->reallySet($name, $object->get('id')); + unset($this->unresolvedRelatedProperties[$name]); + } else { + throw new NotFoundError('Unable to resolve related property: "%s"', $name); + } + } + + protected function getAllApplyRules() + { + $allApplyRules=$this->fetchAllApplyRules(); + foreach ($allApplyRules as $rule) { + $rule->filter = Filter::fromQueryString($rule->assign_filter); + } + + return $allApplyRules; + } + + protected function fetchAllApplyRules() + { + $db = $this->connection->getDbAdapter(); + $query = $db->select()->from( + array('s' => 'icinga_service'), + array( + 'id' => 's.id', + 'name' => 's.object_name', + 'assign_filter' => 's.assign_filter', + ) + )->where('object_type = ? AND assign_filter IS NOT NULL', 'apply'); + + return $db->fetchAll($query); + } + + protected function getRelatedProperty($key) + { + $idKey = $key . '_id'; + if ($this->hasUnresolvedRelatedProperty($idKey)) { + return $this->unresolvedRelatedProperties[$idKey]; + } + + if ($id = $this->get($idKey)) { + /** @var IcingaObject $class */ + $class = $this->getRelationClass($key); + $object = $class::loadWithAutoIncId($id, $this->connection); + return $object->get('object_name'); + } else { + // handle special case for plain string parent service on Dependency Apply rules + if ($key == 'parent_service' && $this->get('parent_service_s') != null) { + return $this->get('parent_service_s'); + } + } + + return null; + } + +} diff --git a/library/Director/Objects/IcingaObject.php b/library/Director/Objects/IcingaObject.php index 9f756046..4e509ea7 100644 --- a/library/Director/Objects/IcingaObject.php +++ b/library/Director/Objects/IcingaObject.php @@ -2699,7 +2699,8 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer public function getOnDeleteUrl() { - return 'director/' . strtolower($this->getShortTableName()) . 's'; + $plural= preg_replace('/cys$/','cies', strtolower($this->getShortTableName()) . 's'); + return 'director/' . $plural; } public function toJson( diff --git a/library/Director/Web/ActionBar/TemplateActionBar.php b/library/Director/Web/ActionBar/TemplateActionBar.php index e6d7f766..c3b28a1c 100644 --- a/library/Director/Web/ActionBar/TemplateActionBar.php +++ b/library/Director/Web/ActionBar/TemplateActionBar.php @@ -9,6 +9,7 @@ class TemplateActionBar extends DirectorBaseActionBar protected function assemble() { $type = $this->type; + $pltype = preg_replace('/cys$/','cies', $type . 's'); $renderTree = $this->url->getParam('render') === 'tree'; $renderParams = $renderTree ? null : ['render' => 'tree']; $this->add( @@ -27,7 +28,7 @@ class TemplateActionBar extends DirectorBaseActionBar )->add( Link::create( $renderTree ? $this->translate('Table') : $this->translate('Tree'), - "director/${type}s/templates", + "director/$pltype/templates", $renderParams, [ 'class' => 'icon-' . ($renderTree ? 'doc-text' : 'sitemap'), diff --git a/library/Director/Web/Controller/ObjectsController.php b/library/Director/Web/Controller/ObjectsController.php index 98c39b01..7a1499e6 100644 --- a/library/Director/Web/Controller/ObjectsController.php +++ b/library/Director/Web/Controller/ObjectsController.php @@ -80,7 +80,7 @@ abstract class ObjectsController extends ActionController $this ->addObjectsTabs() ->setAutorefreshInterval(10) - ->addTitle($this->translate(ucfirst(strtolower($type)) . 's')) + ->addTitle($this->translate(ucfirst($this->getPluralType()))) ->actions(new ObjectsActionBar($type, $this->url())); if ($type === 'command' && $this->params->get('type') === 'external_object') { @@ -127,6 +127,7 @@ abstract class ObjectsController extends ActionController )->content()->add($form); } + /** * Loads the TemplatesTable or the TemplateTreeRenderer * @@ -139,7 +140,6 @@ abstract class ObjectsController extends ActionController return; } $type = $this->getType(); - $shortType = IcingaObject::createByType($type)->getShortTableName(); $this ->assertPermission('director/admin') @@ -294,8 +294,8 @@ abstract class ObjectsController extends ActionController { // Strip final 's' and upcase an eventual 'group' return preg_replace( - array('/group$/', '/period$/', '/argument$/', '/apiuser$/'), - array('Group', 'Period', 'Argument', 'ApiUser'), + array('/group$/', '/period$/', '/argument$/', '/apiuser$/', '/dependencie$/'), + array('Group', 'Period', 'Argument', 'ApiUser', 'dependency'), str_replace( 'template', '', @@ -306,11 +306,11 @@ abstract class ObjectsController extends ActionController protected function getPluralType() { - return $this->getType() . 's'; + return preg_replace("/cys$/","cies",$this->getType() . 's'); } protected function getPluralBaseType() { - return $this->getBaseType() . 's'; + return preg_replace("/cys$/","cies",$this->getBaseType() . 's'); } } diff --git a/library/Director/Web/Controller/TemplateController.php b/library/Director/Web/Controller/TemplateController.php index 98607792..4ee47702 100644 --- a/library/Director/Web/Controller/TemplateController.php +++ b/library/Director/Web/Controller/TemplateController.php @@ -177,7 +177,7 @@ abstract class TemplateController extends CompatController protected function getPluralType() { - return $this->template()->getShortTableName() . 's'; + return preg_replace('/cys$/','cies',$this->template()->getShortTableName() . 's'); } protected function getTranslatedType() diff --git a/library/Director/Web/Form/DirectorObjectForm.php b/library/Director/Web/Form/DirectorObjectForm.php index 3461624b..72a63d0a 100644 --- a/library/Director/Web/Form/DirectorObjectForm.php +++ b/library/Director/Web/Form/DirectorObjectForm.php @@ -523,6 +523,9 @@ abstract class DirectorObjectForm extends DirectorForm 'email', 'pager', 'enable_notifications', + 'disable_checks', //Dependencies + 'disable_notifications', + 'ignore_soft_states', 'apply_for', 'create_live', 'disabled', @@ -1508,28 +1511,28 @@ abstract class DirectorObjectForm extends DirectorForm return $this; } - protected function addEventFilterElements() + protected function addEventFilterElements($elements = array('states','types')) { - $this->addElement('extensibleSet', 'states', array( - 'label' => $this->translate('States'), - 'multiOptions' => $this->optionallyAddFromEnum($this->enumStates()), - 'description' => $this->translate( - 'The host/service states you want to get notifications for' - ), - )); + if (in_array('states', $elements)) { + $this->addElement('extensibleSet', 'states', array( + 'label' => $this->translate('States'), + 'multiOptions' => $this->optionallyAddFromEnum($this->enumStates()), + 'description' => $this->translate( + 'The host/service states you want to get notifications for' + ), + )); + } - $this->addElement('extensibleSet', 'types', array( - 'label' => $this->translate('Transition types'), - 'multiOptions' => $this->optionallyAddFromEnum($this->enumTypes()), - 'description' => $this->translate( - 'The state transition types you want to get notifications for' - ), - )); + if (in_array('types', $elements)) { + $this->addElement('extensibleSet', 'types', array( + 'label' => $this->translate('Transition types'), + 'multiOptions' => $this->optionallyAddFromEnum($this->enumTypes()), + 'description' => $this->translate( + 'The state transition types you want to get notifications for' + ), + )); + } - $elements = array( - 'states', - 'types', - ); $this->addDisplayGroup($elements, 'event_filters', array( 'decorators' => array( 'FormElements', diff --git a/library/Director/Web/Tabs/ObjectsTabs.php b/library/Director/Web/Tabs/ObjectsTabs.php index adef4a54..83037ae8 100644 --- a/library/Director/Web/Tabs/ObjectsTabs.php +++ b/library/Director/Web/Tabs/ObjectsTabs.php @@ -18,17 +18,17 @@ class ObjectsTabs extends Tabs $object = IcingaObject::createByType(substr($type, 0, -5)); } - // TODO: plural? - if ($auth->hasPermission("director/${type}s")) { + $pltype=strtolower(preg_replace('/cys$/','cies',$type . 's')); + if ($auth->hasPermission("director/${pltype}")) { $this->add('index', array( - 'url' => sprintf('director/%ss', strtolower($type)), - 'label' => $this->translate(ucfirst($type) . 's'), + 'url' => sprintf('director/%s', $pltype), + 'label' => $this->translate(ucfirst($pltype)), )); } if ($object->getShortTableName() === 'command') { $this->add('external', array( - 'url' => sprintf('director/%ss', strtolower($type)), + 'url' => sprintf('director/%s', strtolower($pltype)), 'urlParams' => ['type' => 'external_object'], 'label' => $this->translate('External'), )); @@ -39,7 +39,7 @@ class ObjectsTabs extends Tabs )) { if ($object->supportsApplyRules()) { $this->add('applyrules', array( - 'url' => sprintf('director/%ss/applyrules', $type), + 'url' => sprintf('director/%s/applyrules', $pltype), 'label' => $this->translate('Apply') )); } @@ -48,7 +48,7 @@ class ObjectsTabs extends Tabs if ($auth->hasPermission('director/admin') && $type !== 'zone') { if ($object->supportsImports()) { $this->add('templates', array( - 'url' => sprintf('director/%ss/templates', strtolower($type)), + 'url' => sprintf('director/%s/templates', $pltype), 'label' => $this->translate('Templates'), )); } @@ -71,7 +71,7 @@ class ObjectsTabs extends Tabs } if ($object->supportsSets() && $auth->hasPermission("director/${type}_sets")) { $this->add('sets', array( - 'url' => sprintf('director/%ss/sets', $type), + 'url' => sprintf('director/%s/sets', $pltype), 'label' => $this->translate('Sets') )); } diff --git a/public/js/module.js b/public/js/module.js index 2057e88f..c8093778 100644 --- a/public/js/module.js +++ b/public/js/module.js @@ -275,7 +275,8 @@ { $suggestions.load(this.module.icinga.config.baseUrl + '/director/suggest', { value: $el.val(), - context: $el.data('suggestion-context') + context: $el.data('suggestion-context'), + for_host: $el.data('suggestion-for-host') }, function (responseText, textStatus, jqXHR) { var $li = $suggestions.find('li'); if ($li.length) { diff --git a/schema/mysql-migrations/upgrade_dependencies.sql b/schema/mysql-migrations/upgrade_dependencies.sql new file mode 100644 index 00000000..d80098b1 --- /dev/null +++ b/schema/mysql-migrations/upgrade_dependencies.sql @@ -0,0 +1,88 @@ + +CREATE TABLE icinga_dependency ( + id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL, + object_name VARCHAR(255) DEFAULT NULL, + object_type ENUM('object', 'template', 'apply') NOT NULL, + disabled ENUM('y', 'n') NOT NULL DEFAULT 'n', + apply_to ENUM('host', 'service') DEFAULT NULL, + parent_host_id INT(10) UNSIGNED DEFAULT NULL, + parent_service_id INT(10) UNSIGNED DEFAULT NULL, + child_host_id INT(10) UNSIGNED DEFAULT NULL, + child_service_id INT(10) UNSIGNED DEFAULT NULL, + disable_checks ENUM('y', 'n'), + disable_notifications ENUM('y', 'n'), + ignore_soft_states ENUM('y', 'n'), + period_id INT(10) UNSIGNED DEFAULT NULL, + zone_id INT(10) UNSIGNED DEFAULT NULL, + assign_filter TEXT DEFAULT NULL, + PRIMARY KEY (id), + CONSTRAINT icinga_dependency_parent_host + FOREIGN KEY parent_host (parent_host_id) + REFERENCES icinga_host (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_parent_service + FOREIGN KEY parent_service (parent_service_id) + REFERENCES icinga_service (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_child_host + FOREIGN KEY child_host (child_host_id) + REFERENCES icinga_host (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_child_service + FOREIGN KEY child_service (child_service_id) + REFERENCES icinga_service (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_period + FOREIGN KEY period (period_id) + REFERENCES icinga_timeperiod (id) + ON DELETE RESTRICT + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_zone + FOREIGN KEY zone (zone_id) + REFERENCES icinga_zone (id) + ON DELETE RESTRICT + ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE icinga_dependency_inheritance ( + dependency_id INT(10) UNSIGNED NOT NULL, + parent_dependency_id INT(10) UNSIGNED NOT NULL, + weight MEDIUMINT UNSIGNED DEFAULT NULL, + PRIMARY KEY (dependency_id, parent_dependency_id), + UNIQUE KEY unique_order (dependency_id, weight), + CONSTRAINT icinga_dependency_inheritance_dependency + FOREIGN KEY dependency (dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_inheritance_parent_dependency + FOREIGN KEY parent_dependency (parent_dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE RESTRICT + ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE icinga_dependency_states_set ( + dependency_id INT(10) UNSIGNED NOT NULL, + property ENUM( + 'OK', + 'Warning', + 'Critical', + 'Unknown', + 'Up', + 'Down' + ) NOT NULL, + merge_behaviour ENUM('override', 'extend', 'blacklist') NOT NULL DEFAULT 'override' + COMMENT 'override: = [], extend: += [], blacklist: -= []', + PRIMARY KEY (dependency_id, property, merge_behaviour), + CONSTRAINT icinga_dependency_states_set_dependency + FOREIGN KEY icinga_dependency (dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE CASCADE + ON UPDATE CASCADE +) ENGINE=InnoDB; + diff --git a/schema/mysql-migrations/upgrade_dependencies_2.sql b/schema/mysql-migrations/upgrade_dependencies_2.sql new file mode 100644 index 00000000..34f2e5dc --- /dev/null +++ b/schema/mysql-migrations/upgrade_dependencies_2.sql @@ -0,0 +1,2 @@ + +ALTER TABLE icinga_dependency ADD COLUMN parent_service_s VARCHAR(255); diff --git a/schema/mysql.sql b/schema/mysql.sql index 5f0887db..b0defba1 100644 --- a/schema/mysql.sql +++ b/schema/mysql.sql @@ -1575,6 +1575,94 @@ CREATE TABLE icinga_user_resolved_var ( ON UPDATE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE icinga_dependency ( + id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL, + object_name VARCHAR(255) DEFAULT NULL, + object_type ENUM('object', 'template', 'apply') NOT NULL, + disabled ENUM('y', 'n') NOT NULL DEFAULT 'n', + apply_to ENUM('host', 'service') DEFAULT NULL, + parent_host_id INT(10) UNSIGNED DEFAULT NULL, + parent_service_id INT(10) UNSIGNED DEFAULT NULL, + child_host_id INT(10) UNSIGNED DEFAULT NULL, + child_service_id INT(10) UNSIGNED DEFAULT NULL, + disable_checks ENUM('y', 'n'), + disable_notifications ENUM('y', 'n'), + ignore_soft_states ENUM('y', 'n'), + period_id INT(10) UNSIGNED DEFAULT NULL, + zone_id INT(10) UNSIGNED DEFAULT NULL, + assign_filter TEXT DEFAULT NULL, + parent_service_s VARCHAR(255) DEFAULT NULL, + PRIMARY KEY (id), + CONSTRAINT icinga_dependency_parent_host + FOREIGN KEY parent_host (parent_host_id) + REFERENCES icinga_host (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_parent_service + FOREIGN KEY parent_service (parent_service_id) + REFERENCES icinga_service (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_child_host + FOREIGN KEY child_host (child_host_id) + REFERENCES icinga_host (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_child_service + FOREIGN KEY child_service (child_service_id) + REFERENCES icinga_service (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_period + FOREIGN KEY period (period_id) + REFERENCES icinga_timeperiod (id) + ON DELETE RESTRICT + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_zone + FOREIGN KEY zone (zone_id) + REFERENCES icinga_zone (id) + ON DELETE RESTRICT + ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE icinga_dependency_inheritance ( + dependency_id INT(10) UNSIGNED NOT NULL, + parent_dependency_id INT(10) UNSIGNED NOT NULL, + weight MEDIUMINT UNSIGNED DEFAULT NULL, + PRIMARY KEY (dependency_id, parent_dependency_id), + UNIQUE KEY unique_order (dependency_id, weight), + CONSTRAINT icinga_dependency_inheritance_dependency + FOREIGN KEY dependency (dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_inheritance_parent_dependency + FOREIGN KEY parent_dependency (parent_dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE RESTRICT + ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE icinga_dependency_states_set ( + dependency_id INT(10) UNSIGNED NOT NULL, + property ENUM( + 'OK', + 'Warning', + 'Critical', + 'Unknown', + 'Up', + 'Down' + ) NOT NULL, + merge_behaviour ENUM('override', 'extend', 'blacklist') NOT NULL DEFAULT 'override' + COMMENT 'override: = [], extend: += [], blacklist: -= []', + PRIMARY KEY (dependency_id, property, merge_behaviour), + CONSTRAINT icinga_dependency_states_set_dependency + FOREIGN KEY icinga_dependency (dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE CASCADE + ON UPDATE CASCADE +) ENGINE=InnoDB; + INSERT INTO director_schema_migration (schema_version, migration_time) VALUES (143, NOW()); From 708edfdebc4244011e762e3e77cae62ea9b5c1a0 Mon Sep 17 00:00:00 2001 From: Marc DeTrano Date: Wed, 23 Aug 2017 13:39:48 -0600 Subject: [PATCH 2/9] Updates: clean code for whitespace/standards... ...issues as reported by Travis. Add requirement for parent and child host fields when setting up a Dependency Object (these fields are not necessarily needed for Templates or Apply Rules). Renamed new table field to 'parent_service_by_name'... which is a bit more descriptive or what that field is intended for. --- .../controllers/DependencyController.php | 4 --- application/controllers/SuggestController.php | 13 +++------ application/forms/IcingaDependencyForm.php | 20 ++++++-------- application/tables/IcingaDependencyTable.php | 1 - library/Director/Objects/IcingaDependency.php | 27 ++++++++++--------- library/Director/Objects/IcingaObject.php | 2 +- .../Web/ActionBar/TemplateActionBar.php | 2 +- .../Web/Controller/ObjectsController.php | 4 +-- .../Web/Controller/TemplateController.php | 2 +- library/Director/Web/Tabs/ObjectsTabs.php | 2 +- .../upgrade_dependencies_2.sql | 2 +- schema/mysql.sql | 2 +- 12 files changed, 34 insertions(+), 47 deletions(-) diff --git a/application/controllers/DependencyController.php b/application/controllers/DependencyController.php index ed244728..28f99571 100644 --- a/application/controllers/DependencyController.php +++ b/application/controllers/DependencyController.php @@ -23,7 +23,6 @@ class DependencyController extends ObjectController $this->db() ); } - } protected function loadObject() @@ -54,7 +53,4 @@ class DependencyController extends ObjectController $form->createApplyRuleFor($this->apply); } } - - - } diff --git a/application/controllers/SuggestController.php b/application/controllers/SuggestController.php index cc338155..b3139b0e 100644 --- a/application/controllers/SuggestController.php +++ b/application/controllers/SuggestController.php @@ -99,7 +99,7 @@ class SuggestController extends ActionController $db = $this->db()->getDbAdapter(); $for_host = $this->getRequest()->getPost('for_host'); if (!empty($for_host)) { - $tmp_host = IcingaHost::load($for_host,$this->db()); + $tmp_host = IcingaHost::load($for_host, $this->db()); } $query = $db->select()->distinct() @@ -107,9 +107,9 @@ class SuggestController extends ActionController ->order('object_name') ->where("object_type IN ('object','apply')"); if (!empty($tmp_host)) { - $query->where('host_id = ?',$tmp_host->id); + $query->where('host_id = ?', $tmp_host->id); } - $r = array_merge($r,$db->fetchCol($query)); + $r = array_merge($r, $db->fetchCol($query)); if (!empty($tmp_host)) { $resolver = $tmp_host->templateResolver(); foreach ($resolver->fetchResolvedParents() as $template_obj) { @@ -118,7 +118,7 @@ class SuggestController extends ActionController ->order('object_name') ->where("object_type IN ('object','apply')") ->where('host_id = ?', $template_obj->id); - $r = array_merge($r,$db->fetchCol($query)); + $r = array_merge($r, $db->fetchCol($query)); } $matcher = HostApplyMatches::prepare($tmp_host); @@ -127,7 +127,6 @@ class SuggestController extends ActionController $r[]=$rule->name; } } - } natcasesort($r); return $r; @@ -288,8 +287,4 @@ class SuggestController extends ActionController return $db->fetchAll($query); } - - - - } diff --git a/application/forms/IcingaDependencyForm.php b/application/forms/IcingaDependencyForm.php index b9967196..79f97ffd 100644 --- a/application/forms/IcingaDependencyForm.php +++ b/application/forms/IcingaDependencyForm.php @@ -14,8 +14,8 @@ class IcingaDependencyForm extends DirectorObjectForm $this->setupDependencyElements(); } - protected function setupDependencyElements() { - + protected function setupDependencyElements() + { $this->addObjectTypeElement(); if (! $this->hasObjectType()) { $this->groupMainProperties(); @@ -112,7 +112,8 @@ class IcingaDependencyForm extends DirectorObjectForm return $this; } - protected function addBooleanElements() { + protected function addBooleanElements() + { $this->addBoolean( 'disable_checks', @@ -157,6 +158,7 @@ class IcingaDependencyForm extends DirectorObjectForm 'class' => "autosubmit director-suggest", 'data-suggestion-context' => 'hostnames', 'order' => 10, + 'required' => $this->isObject(), 'value' => $this->getObject()->get('parent_host') ) @@ -177,10 +179,8 @@ class IcingaDependencyForm extends DirectorObjectForm 'data-suggestion-for-host' => $sent_parent, 'order' => 20, 'value' => $this->getObject()->get('parent_service') - ) ); - } // If configuring Object, allow selection of child host and/or service, otherwise apply rules will determine child object. @@ -196,12 +196,13 @@ class IcingaDependencyForm extends DirectorObjectForm 'class' => "autosubmit director-suggest", 'data-suggestion-context' => 'hostnames', 'order' => 30, + 'required' => $this->isObject(), 'value' => $this->getObject()->get('child_host') ) ); - + $sent_child=$this->getSentOrObjectValue("child_host"); - + if (!empty($sent_child)) { $this->addElement( 'text', @@ -216,11 +217,8 @@ class IcingaDependencyForm extends DirectorObjectForm 'data-suggestion-for-host' => $sent_child, 'order' => 40, 'value' => $this->getObject()->get('child_service') - ) ); - - } } @@ -247,6 +245,4 @@ class IcingaDependencyForm extends DirectorObjectForm $object->object_name = $dependency->object_name; return $this; } - - } diff --git a/application/tables/IcingaDependencyTable.php b/application/tables/IcingaDependencyTable.php index 3c342f77..ac5eead9 100644 --- a/application/tables/IcingaDependencyTable.php +++ b/application/tables/IcingaDependencyTable.php @@ -50,7 +50,6 @@ class IcingaDependencyTable extends IcingaObjectTable array('apply' => $row->dependency, 'type' => 'apply'), array('class' => 'icon-plus') ); - } else { $htm .= '. Related apply rules:
    '; foreach ($extra as $id => $dependency) { diff --git a/library/Director/Objects/IcingaDependency.php b/library/Director/Objects/IcingaDependency.php index 43b363c9..746dfece 100644 --- a/library/Director/Objects/IcingaDependency.php +++ b/library/Director/Objects/IcingaDependency.php @@ -8,7 +8,6 @@ use Icinga\Exception\NotFoundError; use Icinga\Data\Filter\Filter; use Icinga\Module\Director\Objects\HostApplyMatches; - class IcingaDependency extends IcingaObject { protected $table = 'icinga_dependency'; @@ -29,7 +28,7 @@ class IcingaDependency extends IcingaObject 'period_id' => null, 'zone_id' => null, 'assign_filter' => null, - 'parent_service_s' => null, + 'parent_service_by_name' => null, ); protected $supportsCustomVars = false; @@ -88,7 +87,6 @@ class IcingaDependency extends IcingaObject c::renderString($this->getObjectName()), ucfirst($to) ); - } else { return parent::renderObjectHeader(); } @@ -114,13 +112,13 @@ class IcingaDependency extends IcingaObject protected function renderAssignments() { if ($this->hasBeenAssignedToServiceApply()) { - $tmpService= $this->getRelatedObject('child_service', $this->child_service_id); $assigns = $tmpService->assignments()->toConfigString(); $filter = sprintf( '%s && service.name == "%s"', - trim($assigns), $this->child_service + trim($assigns), + $this->child_service ); return "\n " . $filter . "\n"; } @@ -128,7 +126,8 @@ class IcingaDependency extends IcingaObject if ($this->hasBeenAssignedToHostTemplateService()) { $filter = sprintf( 'assign where "%s" in host.templates && service.name == "%s"', - $this->child_host, $this->child_service + $this->child_host, + $this->child_service ); return "\n " . $filter . "\n"; } @@ -177,7 +176,9 @@ class IcingaDependency extends IcingaObject protected function hasBeenAssignedToHostTemplateService() { - if (!$this->hasBeenAssignedToHostTemplate()) return false; + if (!$this->hasBeenAssignedToHostTemplate()) { + return false; + } try { return $this->child_service_id && $this->getRelatedObject( 'child_service', @@ -276,9 +277,9 @@ class IcingaDependency extends IcingaObject } //special case for parent service set as plain string for Apply rules - public function renderParent_service_s() + public function renderParent_service_by_name() { - return "\n parent_service_name = \"" . $this->parent_service_s ."\"\n"; + return "\n parent_service_name = \"" . $this->parent_service_by_name ."\"\n"; } public function isApplyRule() @@ -311,14 +312,14 @@ class IcingaDependency extends IcingaObject if ($class == "Icinga\Module\Director\Objects\IcingaService" ) { if ($name == "parent_service_id" && $this->object_type == 'apply' ) { //special case , parent service can be set as simple string for Apply if ($this->properties['parent_host_id']==null) { - $this->reallySet('parent_service_s', $this->unresolvedRelatedProperties[$name]); + $this->reallySet('parent_service_by_name', $this->unresolvedRelatedProperties[$name]); $this->reallySet('parent_service_id',null); unset($this->unresolvedRelatedProperties[$name]); return; } } - $this->reallySet('parent_service_s',null); + $this->reallySet('parent_service_by_name',null); $host_id_prop=str_replace("service","host",$name); if (isset($this->properties[$host_id_prop])) { $obj_key=array("host_id" => $this->properties[$host_id_prop], "object_name" => $this->unresolvedRelatedProperties[$name]); @@ -410,8 +411,8 @@ class IcingaDependency extends IcingaObject return $object->get('object_name'); } else { // handle special case for plain string parent service on Dependency Apply rules - if ($key == 'parent_service' && $this->get('parent_service_s') != null) { - return $this->get('parent_service_s'); + if ($key == 'parent_service' && $this->get('parent_service_by_name') != null) { + return $this->get('parent_service_by_name'); } } diff --git a/library/Director/Objects/IcingaObject.php b/library/Director/Objects/IcingaObject.php index 4e509ea7..a4eecfc3 100644 --- a/library/Director/Objects/IcingaObject.php +++ b/library/Director/Objects/IcingaObject.php @@ -2699,7 +2699,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer public function getOnDeleteUrl() { - $plural= preg_replace('/cys$/','cies', strtolower($this->getShortTableName()) . 's'); + $plural= preg_replace('/cys$/', 'cies', strtolower($this->getShortTableName()) . 's'); return 'director/' . $plural; } diff --git a/library/Director/Web/ActionBar/TemplateActionBar.php b/library/Director/Web/ActionBar/TemplateActionBar.php index c3b28a1c..7ba84998 100644 --- a/library/Director/Web/ActionBar/TemplateActionBar.php +++ b/library/Director/Web/ActionBar/TemplateActionBar.php @@ -9,7 +9,7 @@ class TemplateActionBar extends DirectorBaseActionBar protected function assemble() { $type = $this->type; - $pltype = preg_replace('/cys$/','cies', $type . 's'); + $pltype = preg_replace('/cys$/', 'cies', $type . 's'); $renderTree = $this->url->getParam('render') === 'tree'; $renderParams = $renderTree ? null : ['render' => 'tree']; $this->add( diff --git a/library/Director/Web/Controller/ObjectsController.php b/library/Director/Web/Controller/ObjectsController.php index 7a1499e6..0149c660 100644 --- a/library/Director/Web/Controller/ObjectsController.php +++ b/library/Director/Web/Controller/ObjectsController.php @@ -306,11 +306,11 @@ abstract class ObjectsController extends ActionController protected function getPluralType() { - return preg_replace("/cys$/","cies",$this->getType() . 's'); + return preg_replace("/cys$/", "cies", $this->getType() . 's'); } protected function getPluralBaseType() { - return preg_replace("/cys$/","cies",$this->getBaseType() . 's'); + return preg_replace("/cys$/", "cies", $this->getBaseType() . 's'); } } diff --git a/library/Director/Web/Controller/TemplateController.php b/library/Director/Web/Controller/TemplateController.php index 4ee47702..3f7d4cfb 100644 --- a/library/Director/Web/Controller/TemplateController.php +++ b/library/Director/Web/Controller/TemplateController.php @@ -177,7 +177,7 @@ abstract class TemplateController extends CompatController protected function getPluralType() { - return preg_replace('/cys$/','cies',$this->template()->getShortTableName() . 's'); + return preg_replace('/cys$/', 'cies', $this->template()->getShortTableName() . 's'); } protected function getTranslatedType() diff --git a/library/Director/Web/Tabs/ObjectsTabs.php b/library/Director/Web/Tabs/ObjectsTabs.php index 83037ae8..4cd11bf3 100644 --- a/library/Director/Web/Tabs/ObjectsTabs.php +++ b/library/Director/Web/Tabs/ObjectsTabs.php @@ -18,7 +18,7 @@ class ObjectsTabs extends Tabs $object = IcingaObject::createByType(substr($type, 0, -5)); } - $pltype=strtolower(preg_replace('/cys$/','cies',$type . 's')); + $pltype=strtolower(preg_replace('/cys$/', 'cies', $type . 's')); if ($auth->hasPermission("director/${pltype}")) { $this->add('index', array( 'url' => sprintf('director/%s', $pltype), diff --git a/schema/mysql-migrations/upgrade_dependencies_2.sql b/schema/mysql-migrations/upgrade_dependencies_2.sql index 34f2e5dc..f147e38b 100644 --- a/schema/mysql-migrations/upgrade_dependencies_2.sql +++ b/schema/mysql-migrations/upgrade_dependencies_2.sql @@ -1,2 +1,2 @@ -ALTER TABLE icinga_dependency ADD COLUMN parent_service_s VARCHAR(255); +ALTER TABLE icinga_dependency ADD COLUMN parent_service_by_name VARCHAR(255); diff --git a/schema/mysql.sql b/schema/mysql.sql index b0defba1..fa0b8e17 100644 --- a/schema/mysql.sql +++ b/schema/mysql.sql @@ -1591,7 +1591,7 @@ CREATE TABLE icinga_dependency ( period_id INT(10) UNSIGNED DEFAULT NULL, zone_id INT(10) UNSIGNED DEFAULT NULL, assign_filter TEXT DEFAULT NULL, - parent_service_s VARCHAR(255) DEFAULT NULL, + parent_service_by_name VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id), CONSTRAINT icinga_dependency_parent_host FOREIGN KEY parent_host (parent_host_id) From cd4e90e418c03bccc79498dfd9fff6038abbaad4 Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Fri, 25 Aug 2017 22:41:08 +0200 Subject: [PATCH 3/9] application/tables: remove obsolete tables --- application/tables/IcingaDependencyTable.php | 104 ------------------ .../tables/IcingaDependencyTemplateTable.php | 13 --- 2 files changed, 117 deletions(-) delete mode 100644 application/tables/IcingaDependencyTable.php delete mode 100644 application/tables/IcingaDependencyTemplateTable.php diff --git a/application/tables/IcingaDependencyTable.php b/application/tables/IcingaDependencyTable.php deleted file mode 100644 index ac5eead9..00000000 --- a/application/tables/IcingaDependencyTable.php +++ /dev/null @@ -1,104 +0,0 @@ - 'd.id', - 'object_type' => 'd.object_type', - 'dependency' => 'd.object_name', - ); - } - - protected function listTableClasses() - { - return array_merge(array('assignment-table'), parent::listTableClasses()); - } - - protected function getActionUrl($row) - { - return $this->url('director/dependency', array('id' => $row->id)); - } - - public function getTitles() - { - $view = $this->view(); - return array( - 'dependency' => $view->translate('Dependency'), - ); - } - - protected function renderRow($row) - { - $v = $this->view(); - $extra = $this->appliedOnes($row->id); - $htm = " getRowClassesString($row) . ">\n"; - $htm .= '' . $v->qlink($row->dependency, $this->getActionUrl($row)); - if (empty($extra)) { - $htm .= ' ' . $v->qlink( - 'Create apply-rule', - 'director/dependency/add', - array('apply' => $row->dependency, 'type' => 'apply'), - array('class' => 'icon-plus') - ); - } else { - $htm .= '. Related apply rules:
      '; - foreach ($extra as $id => $dependency) { - $htm .= '
    • ' - . $v->qlink($dependency, 'director/dependency', array('id' => $id)) - . '
    • '; - } - $htm .= '
    '; - $htm .= $v->qlink( - 'Add more', - 'director/dependency/add', - array('apply' => $row->dependency), - array('class' => 'icon-plus') - ); - } - $htm .= ''; - return $htm . " \n"; - } - - protected function appliedOnes($id) - { - $db = $this->db(); - $query = $db->select()->from( - array('s' => 'icinga_dependency'), - array( - 'id' => 's.id', - 'objectname' => 's.object_name', - ) - )->join( - array('i' => 'icinga_dependency_inheritance'), - 'i.dependency_id = s.id', - array() - )->where('i.parent_dependency_id = ?', $id) - ->where('s.object_type = ?', 'apply'); - - - return $db->fetchPairs($query); - } - - public function getUnfilteredQuery() - { - return $this->db()->select()->from( - array('d' => 'icinga_dependency'), - array() - ); - } - - public function getBaseQuery() - { - return $this->getUnfilteredQuery()->order('d.object_name'); - } -} diff --git a/application/tables/IcingaDependencyTemplateTable.php b/application/tables/IcingaDependencyTemplateTable.php deleted file mode 100644 index 60038b69..00000000 --- a/application/tables/IcingaDependencyTemplateTable.php +++ /dev/null @@ -1,13 +0,0 @@ -getUnfilteredQuery()->where('d.object_type = ?', 'template'); - } -} From e45962c1b970f4d3c554f8696219b91a920289ec Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Fri, 25 Aug 2017 22:42:38 +0200 Subject: [PATCH 4/9] various: shorten long line, spacing, readability --- .../controllers/DependencyController.php | 2 + application/controllers/SuggestController.php | 1 + application/forms/IcingaDependencyForm.php | 120 ++++---- .../Dashlet/DependencyObjectDashlet.php | 6 +- library/Director/Objects/IcingaDependency.php | 265 +++++++++++------- .../Web/ActionBar/TemplateActionBar.php | 4 +- .../Web/Controller/ObjectsController.php | 6 +- .../Web/Controller/TemplateController.php | 6 +- library/Director/Web/Tabs/ObjectsTabs.php | 21 +- 9 files changed, 239 insertions(+), 192 deletions(-) diff --git a/application/controllers/DependencyController.php b/application/controllers/DependencyController.php index 28f99571..f9346462 100644 --- a/application/controllers/DependencyController.php +++ b/application/controllers/DependencyController.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Director\Controllers; +use Icinga\Module\Director\Forms\IcingaDependencyForm; use Icinga\Module\Director\Web\Controller\ObjectController; use Icinga\Module\Director\Objects\IcingaDependency; @@ -49,6 +50,7 @@ class DependencyController extends ObjectController protected function beforeHandlingAddRequest($form) { + /** @var IcingaDependencyForm $form */ if ($this->apply) { $form->createApplyRuleFor($this->apply); } diff --git a/application/controllers/SuggestController.php b/application/controllers/SuggestController.php index b3139b0e..323ff4a7 100644 --- a/application/controllers/SuggestController.php +++ b/application/controllers/SuggestController.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Director\Controllers; +use Icinga\Module\Director\Objects\IcingaHost; use Icinga\Module\Director\Objects\IcingaService; use Icinga\Module\Director\Web\Controller\ActionController; use Icinga\Data\Filter\Filter; diff --git a/application/forms/IcingaDependencyForm.php b/application/forms/IcingaDependencyForm.php index 79f97ffd..7be8b313 100644 --- a/application/forms/IcingaDependencyForm.php +++ b/application/forms/IcingaDependencyForm.php @@ -36,11 +36,11 @@ class IcingaDependencyForm extends DirectorObjectForm protected function addNameElement() { - $this->addElement('text', 'object_name', array( + $this->addElement('text', 'object_name', [ 'label' => $this->translate('Name'), 'required' => true, 'description' => $this->translate('Name for the Icinga dependency you are going to create') - )); + ]); return $this; } @@ -52,20 +52,18 @@ class IcingaDependencyForm extends DirectorObjectForm return $this; } - $this->addElement('select', 'apply_to', array( + $this->addElement('select', 'apply_to', [ 'label' => $this->translate('Apply to'), 'description' => $this->translate( 'Whether this dependency should affect hosts or services' ), 'required' => true, 'class' => 'autosubmit', - 'multiOptions' => $this->optionalEnum( - array( - 'host' => $this->translate('Hosts'), - 'service' => $this->translate('Services'), - ) - ) - )); + 'multiOptions' => $this->optionalEnum([ + 'host' => $this->translate('Hosts'), + 'service' => $this->translate('Services'), + ]) + ]); $applyTo = $this->getSentOrObjectValue('apply_to'); @@ -114,33 +112,29 @@ class IcingaDependencyForm extends DirectorObjectForm protected function addBooleanElements() { + $this->addBoolean('disable_checks', [ + 'label' => $this->translate('Disable Checks'), + 'description' => $this->translate( + 'Whether to disable checks when this dependency fails.' + . ' Defaults to false.' + ) + ], null); - $this->addBoolean( - 'disable_checks', - array( - 'label' => $this->translate('Disable Checks'), - 'description' => $this->translate('Whether to disable checks when this dependency fails. Defaults to false.') - ), - null - ); + $this->addBoolean('disable_notifications', [ + 'label' => $this->translate('Disable Notificiations'), + 'description' => $this->translate( + 'Whether to disable notifications when this dependency fails.' + . ' Defaults to true.' + ) + ], null); - $this->addBoolean( - 'disable_notifications', - array( - 'label' => $this->translate('Disable Notificiations'), - 'description' => $this->translate('Whether to disable notifications when this dependency fails. Defaults to true.') - ), - null - ); - - $this->addBoolean( - 'ignore_soft_states', - array( - 'label' => $this->translate('Ignore Soft States'), - 'description' => $this->translate('Whether to ignore soft states for the reachability calculation. Defaults to true.') - ), - null - ); + $this->addBoolean('ignore_soft_states', [ + 'label' => $this->translate('Ignore Soft States'), + 'description' => $this->translate( + 'Whether to ignore soft states for the reachability calculation.' + . ' Defaults to true.' + ) + ], null); return $this; } @@ -183,7 +177,8 @@ class IcingaDependencyForm extends DirectorObjectForm ); } - // If configuring Object, allow selection of child host and/or service, otherwise apply rules will determine child object. + // If configuring Object, allow selection of child host and/or service, + // otherwise apply rules will determine child object. if ($this->isObject()) { $this->addElement( 'text', @@ -193,46 +188,42 @@ class IcingaDependencyForm extends DirectorObjectForm 'description' => $this->translate( 'The child host.' ), - 'class' => "autosubmit director-suggest", - 'data-suggestion-context' => 'hostnames', + 'value' => $this->getObject()->get('child_host'), 'order' => 30, + 'class' => "autosubmit director-suggest", 'required' => $this->isObject(), - 'value' => $this->getObject()->get('child_host') + 'data-suggestion-context' => 'hostnames', ) ); $sent_child=$this->getSentOrObjectValue("child_host"); if (!empty($sent_child)) { - $this->addElement( - 'text', - 'child_service', - array( - 'label' => $this->translate('Child Service'), - 'description' => $this->translate( - 'Optional. The child service. If omitted this dependency object is treated as host dependency.' - ), - 'class' => "autosubmit director-suggest", - 'data-suggestion-context' => 'servicenames', - 'data-suggestion-for-host' => $sent_child, - 'order' => 40, - 'value' => $this->getObject()->get('child_service') - ) - ); + $this->addElement('text', 'child_service', [ + 'label' => $this->translate('Child Service'), + 'description' => $this->translate( + 'Optional. The child service. If omitted this dependency' + . ' object is treated as host dependency.' + ), + 'class' => "autosubmit director-suggest", + 'order' => 40, + 'value' => $this->getObject()->get('child_service'), + 'data-suggestion-context' => 'servicenames', + 'data-suggestion-for-host' => $sent_child, + ]); } } - $elements=array('parent_host','child_host','parent_service','child_service'); - $this->addDisplayGroup($elements, 'related_objects', array( - 'decorators' => array( + $elements = ['parent_host', 'child_host', 'parent_service', 'child_service']; + $this->addDisplayGroup($elements, 'related_objects', [ + 'decorators' => [ 'FormElements', - array('HtmlTag', array('tag' => 'dl')), + ['HtmlTag', ['tag' => 'dl']], 'Fieldset', - ), + ], 'order' => 25, 'legend' => $this->translate('Related Objects') - )); - + ]); return $this; } @@ -240,9 +231,10 @@ class IcingaDependencyForm extends DirectorObjectForm public function createApplyRuleFor(IcingaDependency $dependency) { $object = $this->object(); - $object->imports = $dependency->object_name; - $object->object_type = 'apply'; - $object->object_name = $dependency->object_name; + $object->setImports($dependency->getObjectName()); + $object->set('object_type', 'apply'); + $object->set('object_name', $dependency->getObjectName()); + return $this; } } diff --git a/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php b/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php index 486e59b0..37ef7c34 100644 --- a/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php +++ b/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php @@ -4,18 +4,18 @@ namespace Icinga\Module\Director\Dashboard\Dashlet; class DependencyObjectDashlet extends Dashlet { - protected $icon = ''; + protected $icon = 'sitemap'; protected $requiredStats = array('dependency'); public function getTitle() { - return $this->translate('Dependencies.'); + return $this->translate('Dependencies'); } public function getSummary() { - return $this->translate('Define object dependency relationships.') + return $this->translate('Object dependency relationships.') . ' ' . parent::getSummary(); } diff --git a/library/Director/Objects/IcingaDependency.php b/library/Director/Objects/IcingaDependency.php index 746dfece..7ab0324f 100644 --- a/library/Director/Objects/IcingaDependency.php +++ b/library/Director/Objects/IcingaDependency.php @@ -6,30 +6,29 @@ use Icinga\Exception\ConfigurationError; use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c; use Icinga\Exception\NotFoundError; use Icinga\Data\Filter\Filter; -use Icinga\Module\Director\Objects\HostApplyMatches; class IcingaDependency extends IcingaObject { protected $table = 'icinga_dependency'; - protected $defaultProperties = array( - 'id' => null, - 'object_name' => null, - 'object_type' => null, - 'disabled' => 'n', - 'apply_to' => null, - 'parent_host_id' => null, - 'parent_service_id' => null, - 'child_host_id' => null, - 'child_service_id' => null, - 'disable_checks' => null, - 'disable_notifications' => null, - 'ignore_soft_states' => null, - 'period_id' => null, - 'zone_id' => null, - 'assign_filter' => null, - 'parent_service_by_name' => null, - ); + protected $defaultProperties = [ + 'id' => null, + 'object_name' => null, + 'object_type' => null, + 'disabled' => 'n', + 'apply_to' => null, + 'parent_host_id' => null, + 'parent_service_id' => null, + 'child_host_id' => null, + 'child_service_id' => null, + 'disable_checks' => null, + 'disable_notifications' => null, + 'ignore_soft_states' => null, + 'period_id' => null, + 'zone_id' => null, + 'assign_filter' => null, + 'parent_service_by_name' => null, + ]; protected $supportsCustomVars = false; @@ -37,24 +36,24 @@ class IcingaDependency extends IcingaObject protected $supportsApplyRules = true; - protected $relatedSets = array( + protected $relatedSets = [ 'states' => 'StateFilterSet', - ); + ]; - protected $relations = array( - 'zone' => 'IcingaZone', + protected $relations = [ + 'zone' => 'IcingaZone', 'parent_host' => 'IcingaHost', 'parent_service' => 'IcingaService', - 'child_host' => 'IcingaHost', - 'child_service' => 'IcingaService', - 'period' => 'IcingaTimePeriod', - ); + 'child_host' => 'IcingaHost', + 'child_service' => 'IcingaService', + 'period' => 'IcingaTimePeriod', + ]; - protected $booleans = array( - 'disable_checks' => 'disable_checks', + protected $booleans = [ + 'disable_checks' => 'disable_checks', 'disable_notifications' => 'disable_notifications', - 'ignore_soft_states' => 'ignore_soft_states' - ); + 'ignore_soft_states' => 'ignore_soft_states' + ]; /** * Do not render internal property apply_to @@ -94,10 +93,20 @@ class IcingaDependency extends IcingaObject protected function setKey($key) { + // TODO: Check if this method can be removed if (is_int($key)) { $this->id = $key; } elseif (is_array($key)) { - foreach (array('id', 'parent_host_id', 'parent_service_id', 'child_host_id', 'child_service_id', 'object_name') as $k) { + $keys = [ + 'id', + 'parent_host_id', + 'parent_service_id', + 'child_host_id', + 'child_service_id', + 'object_name' + ]; + + foreach ($keys as $k) { if (array_key_exists($k, $key)) { $this->set($k, $key[$k]); } @@ -111,14 +120,20 @@ class IcingaDependency extends IcingaObject protected function renderAssignments() { + // TODO: this will never be reached if ($this->hasBeenAssignedToServiceApply()) { - $tmpService= $this->getRelatedObject('child_service', $this->child_service_id); + /** @var IcingaService $tmpService */ + $tmpService = $this->getRelatedObject( + 'child_service', + $this->get('child_service_id') + ); + // TODO: fix this, will crash: $assigns = $tmpService->assignments()->toConfigString(); $filter = sprintf( '%s && service.name == "%s"', trim($assigns), - $this->child_service + $this->get('child_service') ); return "\n " . $filter . "\n"; } @@ -126,15 +141,15 @@ class IcingaDependency extends IcingaObject if ($this->hasBeenAssignedToHostTemplateService()) { $filter = sprintf( 'assign where "%s" in host.templates && service.name == "%s"', - $this->child_host, - $this->child_service + $this->get('child_host'), + $this->get('child_service') ); return "\n " . $filter . "\n"; } if ($this->hasBeenAssignedToHostTemplate()) { $filter = sprintf( 'assign where "%s" in host.templates', - $this->child_host + $this->get('child_host') ); return "\n " . $filter . "\n"; } @@ -142,7 +157,7 @@ class IcingaDependency extends IcingaObject if ($this->hasBeenAssignedToServiceTemplate()) { $filter = sprintf( 'assign where "%s" in service.templates', - $this->child_service + $this->get('child_service') ); return "\n " . $filter . "\n"; } @@ -153,10 +168,11 @@ class IcingaDependency extends IcingaObject protected function hasBeenAssignedToHostTemplate() { try { - return $this->child_host_id && $this->getRelatedObject( + $id = $this->get('child_host_id'); + return $id && $this->getRelatedObject( 'child_host', - $this->child_host_id - )->object_type === 'template'; + $id + )->isTemplate(); } catch (NotFoundError $e) { return false; } @@ -165,10 +181,11 @@ class IcingaDependency extends IcingaObject protected function hasBeenAssignedToServiceTemplate() { try { - return $this->child_service_id && $this->getRelatedObject( + $id = $this->get('child_service_id'); + return $id && $this->getRelatedObject( 'child_service', - $this->child_service_id - )->object_type === 'template'; + $id + )->isTemplate(); } catch (NotFoundError $e) { return false; } @@ -180,10 +197,11 @@ class IcingaDependency extends IcingaObject return false; } try { - return $this->child_service_id && $this->getRelatedObject( + $id = $this->get('child_service_id'); + return $id && $this->getRelatedObject( 'child_service', - $this->child_service_id - )->object_type === 'object'; + $id + )->isObject(); } catch (NotFoundError $e) { return false; } @@ -192,16 +210,16 @@ class IcingaDependency extends IcingaObject protected function hasBeenAssignedToServiceApply() { try { - return $this->child_service_id && $this->getRelatedObject( + $id = $this->get('child_service_id'); + return $id && $this->getRelatedObject( 'child_service', - $this->child_service_id - )->object_type === 'apply'; + $id + )->isApplyRule(); } catch (NotFoundError $e) { return false; } } - /** * Render child_host_id as host_name * @@ -218,7 +236,11 @@ class IcingaDependency extends IcingaObject return ''; } - return $this->renderRelationProperty('child_host', $this->child_host_id, 'child_host_name'); + return $this->renderRelationProperty( + 'child_host', + $this->get('child_host_id'), + 'child_host_name' + ); } /** @@ -233,10 +255,13 @@ class IcingaDependency extends IcingaObject { // @codingStandardsIgnoreEnd - return $this->renderRelationProperty('parent_host', $this->parent_host_id, 'parent_host_name'); + return $this->renderRelationProperty( + 'parent_host', + $this->get('parent_host_id'), + 'parent_host_name' + ); } - /** * Render child_service_id as host_name * @@ -248,19 +273,18 @@ class IcingaDependency extends IcingaObject public function renderChild_service_id() { // @codingStandardsIgnoreEnd - if ($this->hasBeenAssignedToServiceTemplate()) { + if ($this->hasBeenAssignedToServiceTemplate() + || $this->hasBeenAssignedToHostTemplateService() + || $this->hasBeenAssignedToServiceApply() + ) { return ''; } - if ($this->hasBeenAssignedToHostTemplateService()) { - return ''; - } - - if ($this->hasBeenAssignedToServiceApply()) { - return ''; - } - - return $this->renderRelationProperty('child_service', $this->child_service_id, 'child_service_name'); + return $this->renderRelationProperty( + 'child_service', + $this->get('child_service_id'), + 'child_service_name' + ); } /** @@ -273,84 +297,107 @@ class IcingaDependency extends IcingaObject */ public function renderParent_service_id() { - return $this->renderRelationProperty('parent_service', $this->parent_service_id, 'parent_service_name'); + return $this->renderRelationProperty( + 'parent_service', + $this->get('parent_service_id'), + 'parent_service_name' + ); } //special case for parent service set as plain string for Apply rules public function renderParent_service_by_name() { - return "\n parent_service_name = \"" . $this->parent_service_by_name ."\"\n"; + // TODO: + return c::renderKeyValue( + 'parent_service_name', + $this->get('parent_service_by_name') + ); } public function isApplyRule() { - if ($this->hasBeenAssignedToHostTemplate()) { + if ($this->hasBeenAssignedToHostTemplate() + || $this->hasBeenAssignedToServiceTemplate() + || $this->hasBeenAssignedToServiceApply() + ) { return true; } - if ($this->hasBeenAssignedToServiceTemplate()) { - return true; - } - - if ($this->hasBeenAssignedToServiceApply()) { - return true; - } - - return $this->hasProperty('object_type') - && $this->object_type === 'apply'; + return parent::isApplyRule(); } protected function resolveUnresolvedRelatedProperty($name) { - $short = substr($name, 0, -3); /** @var IcingaObject $class */ $class = $this->getRelationClass($short); - $obj_key = $this->unresolvedRelatedProperties[$name]; + $objKey = $this->unresolvedRelatedProperties[$name]; # related services need array key if ($class == "Icinga\Module\Director\Objects\IcingaService" ) { - if ($name == "parent_service_id" && $this->object_type == 'apply' ) { //special case , parent service can be set as simple string for Apply - if ($this->properties['parent_host_id']==null) { - $this->reallySet('parent_service_by_name', $this->unresolvedRelatedProperties[$name]); - $this->reallySet('parent_service_id',null); + if ($name === 'parent_service_id' && $this->object_type === 'apply' ) { + //special case , parent service can be set as simple string for Apply + if ($this->properties['parent_host_id'] === null) { + $this->reallySet( + 'parent_service_by_name', + $this->unresolvedRelatedProperties[$name] + ); + $this->reallySet('parent_service_id', null); unset($this->unresolvedRelatedProperties[$name]); return; } } - $this->reallySet('parent_service_by_name',null); - $host_id_prop=str_replace("service","host",$name); - if (isset($this->properties[$host_id_prop])) { - $obj_key=array("host_id" => $this->properties[$host_id_prop], "object_name" => $this->unresolvedRelatedProperties[$name]); + $this->reallySet('parent_service_by_name', null); + $hostIdProperty = str_replace('service', 'host', $name); + if (isset($this->properties[$hostIdProperty])) { + $objKey = [ + 'host_id' => $this->properties[$hostIdProperty], + 'object_name' => $this->unresolvedRelatedProperties[$name] + ]; } else { - $obj_key=array("host_id" => null, "object_name" => $this->unresolvedRelatedProperties[$name]); + $objKey = [ + 'host_id' => null, + 'object_name' => $this->unresolvedRelatedProperties[$name] + ]; } try { - $object = $class::load( $obj_key, $this->connection); + $class::load( $objKey, $this->connection); } catch (NotFoundError $e) { // Not a simple service on host - // Hunt through inherited services, use service assigned to template if found - $tmp_host=IcingaHost::loadWithAutoIncId($this->properties[$host_id_prop], $this->connection); + // Hunt through inherited services, use service assigned to + // template if found + $tmpHost = IcingaHost::loadWithAutoIncId( + $this->properties[$hostIdProperty], + $this->connection + ); - //services for applicable templates - $resolver = $tmp_host->templateResolver(); + //services for applicable templates + $resolver = $tmpHost->templateResolver(); foreach ($resolver->fetchResolvedParents() as $template_obj) { - $obj_key=array("host_id" => $template_obj->id, "object_name" => $this->unresolvedRelatedProperties[$name]); - try { - $object = $class::load( $obj_key, $this->connection); + $objKey = [ + 'host_id' => $template_obj->id, + 'object_name' => $this->unresolvedRelatedProperties[$name] + ]; + try { + $object = $class::load( $objKey, $this->connection); } catch (NotFoundError $e) { continue; } break; } - if (!isset($object)) { //Not an inherited service, now try apply rules - $matcher = HostApplyMatches::prepare($tmp_host); + + if (!isset($object)) { + // Not an inherited service, now try apply rules + $matcher = HostApplyMatches::prepare($tmpHost); foreach ($this->getAllApplyRules() as $rule) { if ($matcher->matchesFilter($rule->filter)) { - if ($rule->name == $this->unresolvedRelatedProperties[$name]) { - $object=IcingaService::loadWithAutoIncId($rule->id, $this->connection); + if ($rule->name === $this->unresolvedRelatedProperties[$name]) { + $object = IcingaService::loadWithAutoIncId( + $rule->get('id'), + $this->connection + ); break; } } @@ -358,10 +405,7 @@ class IcingaDependency extends IcingaObject } } } else { - $object = $class::load( - $obj_key, - $this->connection - ); + $object = $class::load($objKey, $this->connection); } if (isset($object)) { @@ -374,7 +418,7 @@ class IcingaDependency extends IcingaObject protected function getAllApplyRules() { - $allApplyRules=$this->fetchAllApplyRules(); + $allApplyRules = $this->fetchAllApplyRules(); foreach ($allApplyRules as $rule) { $rule->filter = Filter::fromQueryString($rule->assign_filter); } @@ -408,15 +452,18 @@ class IcingaDependency extends IcingaObject /** @var IcingaObject $class */ $class = $this->getRelationClass($key); $object = $class::loadWithAutoIncId($id, $this->connection); - return $object->get('object_name'); + + return $object->getObjectName(); } else { - // handle special case for plain string parent service on Dependency Apply rules - if ($key == 'parent_service' && $this->get('parent_service_by_name') != null) { + // handle special case for plain string parent service on Dependency + // Apply rules + if ($key === 'parent_service' + && null !== $this->get('parent_service_by_name') + ) { return $this->get('parent_service_by_name'); } } return null; } - } diff --git a/library/Director/Web/ActionBar/TemplateActionBar.php b/library/Director/Web/ActionBar/TemplateActionBar.php index 7ba84998..56eeee95 100644 --- a/library/Director/Web/ActionBar/TemplateActionBar.php +++ b/library/Director/Web/ActionBar/TemplateActionBar.php @@ -9,7 +9,7 @@ class TemplateActionBar extends DirectorBaseActionBar protected function assemble() { $type = $this->type; - $pltype = preg_replace('/cys$/', 'cies', $type . 's'); + $plType = preg_replace('/cys$/', 'cies', $type . 's'); $renderTree = $this->url->getParam('render') === 'tree'; $renderParams = $renderTree ? null : ['render' => 'tree']; $this->add( @@ -28,7 +28,7 @@ class TemplateActionBar extends DirectorBaseActionBar )->add( Link::create( $renderTree ? $this->translate('Table') : $this->translate('Tree'), - "director/$pltype/templates", + "director/$plType/templates", $renderParams, [ 'class' => 'icon-' . ($renderTree ? 'doc-text' : 'sitemap'), diff --git a/library/Director/Web/Controller/ObjectsController.php b/library/Director/Web/Controller/ObjectsController.php index 0149c660..975277c9 100644 --- a/library/Director/Web/Controller/ObjectsController.php +++ b/library/Director/Web/Controller/ObjectsController.php @@ -33,6 +33,7 @@ abstract class ObjectsController extends ActionController $this->assertPermission('director/' . $this->getPluralBaseType()); } } + /** * @return $this */ @@ -127,7 +128,6 @@ abstract class ObjectsController extends ActionController )->content()->add($form); } - /** * Loads the TemplatesTable or the TemplateTreeRenderer * @@ -306,11 +306,11 @@ abstract class ObjectsController extends ActionController protected function getPluralType() { - return preg_replace("/cys$/", "cies", $this->getType() . 's'); + return preg_replace('/cys$/', 'cies', $this->getType() . 's'); } protected function getPluralBaseType() { - return preg_replace("/cys$/", "cies", $this->getBaseType() . 's'); + return preg_replace('/cys$/', 'cies', $this->getBaseType() . 's'); } } diff --git a/library/Director/Web/Controller/TemplateController.php b/library/Director/Web/Controller/TemplateController.php index 3f7d4cfb..c675f32a 100644 --- a/library/Director/Web/Controller/TemplateController.php +++ b/library/Director/Web/Controller/TemplateController.php @@ -177,7 +177,11 @@ abstract class TemplateController extends CompatController protected function getPluralType() { - return preg_replace('/cys$/', 'cies', $this->template()->getShortTableName() . 's'); + return preg_replace( + '/cys$/', + 'cies', + $this->template()->getShortTableName() . 's' + ); } protected function getTranslatedType() diff --git a/library/Director/Web/Tabs/ObjectsTabs.php b/library/Director/Web/Tabs/ObjectsTabs.php index 4cd11bf3..ea3a3f09 100644 --- a/library/Director/Web/Tabs/ObjectsTabs.php +++ b/library/Director/Web/Tabs/ObjectsTabs.php @@ -18,28 +18,29 @@ class ObjectsTabs extends Tabs $object = IcingaObject::createByType(substr($type, 0, -5)); } - $pltype=strtolower(preg_replace('/cys$/', 'cies', $type . 's')); - if ($auth->hasPermission("director/${pltype}")) { + $plType = strtolower(preg_replace('/cys$/', 'cies', $type . 's')); + if ($auth->hasPermission("director/${plType}")) { $this->add('index', array( - 'url' => sprintf('director/%s', $pltype), - 'label' => $this->translate(ucfirst($pltype)), + 'url' => sprintf('director/%s', $plType), + 'label' => $this->translate(ucfirst($plType)), )); } if ($object->getShortTableName() === 'command') { $this->add('external', array( - 'url' => sprintf('director/%s', strtolower($pltype)), + 'url' => sprintf('director/%s', strtolower($plType)), 'urlParams' => ['type' => 'external_object'], 'label' => $this->translate('External'), )); } if ($auth->hasPermission('director/admin') || ( - $object->getShortTableName() === 'notification' && $auth->hasPermission('director/notifications') - )) { + $object->getShortTableName() === 'notification' + && $auth->hasPermission('director/notifications') + )) { if ($object->supportsApplyRules()) { $this->add('applyrules', array( - 'url' => sprintf('director/%s/applyrules', $pltype), + 'url' => sprintf('director/%s/applyrules', $plType), 'label' => $this->translate('Apply') )); } @@ -48,7 +49,7 @@ class ObjectsTabs extends Tabs if ($auth->hasPermission('director/admin') && $type !== 'zone') { if ($object->supportsImports()) { $this->add('templates', array( - 'url' => sprintf('director/%s/templates', $pltype), + 'url' => sprintf('director/%s/templates', $plType), 'label' => $this->translate('Templates'), )); } @@ -71,7 +72,7 @@ class ObjectsTabs extends Tabs } if ($object->supportsSets() && $auth->hasPermission("director/${type}_sets")) { $this->add('sets', array( - 'url' => sprintf('director/%s/sets', $pltype), + 'url' => sprintf('director/%s/sets', $plType), 'label' => $this->translate('Sets') )); } From 2f78d52c58d66ab73e19018de3bf810174ebe234 Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Tue, 29 Aug 2017 23:04:54 +0200 Subject: [PATCH 5/9] IcingaDependency: rule is not a DbObject here fixes #1137 --- library/Director/Objects/IcingaDependency.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/Director/Objects/IcingaDependency.php b/library/Director/Objects/IcingaDependency.php index 7ab0324f..22cd3286 100644 --- a/library/Director/Objects/IcingaDependency.php +++ b/library/Director/Objects/IcingaDependency.php @@ -395,7 +395,7 @@ class IcingaDependency extends IcingaObject if ($matcher->matchesFilter($rule->filter)) { if ($rule->name === $this->unresolvedRelatedProperties[$name]) { $object = IcingaService::loadWithAutoIncId( - $rule->get('id'), + $rule->id, $this->connection ); break; From 2e483fefba58a425ba5e6bf09a9103a3b6837aa1 Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Tue, 29 Aug 2017 23:07:26 +0200 Subject: [PATCH 6/9] IcingaDependency: render parent_service_by_name... ...as a string fixes #1136 --- library/Director/Objects/IcingaDependency.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/Director/Objects/IcingaDependency.php b/library/Director/Objects/IcingaDependency.php index 22cd3286..c73f8b44 100644 --- a/library/Director/Objects/IcingaDependency.php +++ b/library/Director/Objects/IcingaDependency.php @@ -307,10 +307,9 @@ class IcingaDependency extends IcingaObject //special case for parent service set as plain string for Apply rules public function renderParent_service_by_name() { - // TODO: return c::renderKeyValue( 'parent_service_name', - $this->get('parent_service_by_name') + c::renderString($this->get('parent_service_by_name')) ); } From c277a5be537ad4f74b8bb0c794a2aaf612fac143 Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Wed, 27 Sep 2017 21:47:45 +0200 Subject: [PATCH 7/9] IcingaDependency: just whitespace --- library/Director/Objects/IcingaDependency.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/Director/Objects/IcingaDependency.php b/library/Director/Objects/IcingaDependency.php index c73f8b44..efd481d5 100644 --- a/library/Director/Objects/IcingaDependency.php +++ b/library/Director/Objects/IcingaDependency.php @@ -372,14 +372,14 @@ class IcingaDependency extends IcingaObject $this->connection ); - //services for applicable templates + // services for applicable templates $resolver = $tmpHost->templateResolver(); foreach ($resolver->fetchResolvedParents() as $template_obj) { $objKey = [ 'host_id' => $template_obj->id, 'object_name' => $this->unresolvedRelatedProperties[$name] ]; - try { + try { $object = $class::load( $objKey, $this->connection); } catch (NotFoundError $e) { continue; From 147946e965dcefa1d4ea1c720b6a8856c179ea5f Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Thu, 28 Sep 2017 09:21:58 +0200 Subject: [PATCH 8/9] Dependencies: hide single objects, mark the... ...feature as experimental, so we can merge it to master --- .../controllers/DependenciesController.php | 18 ++++++++++++++++++ .../Dashlet/DependencyObjectDashlet.php | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/application/controllers/DependenciesController.php b/application/controllers/DependenciesController.php index dfd684d0..51e43b3e 100644 --- a/application/controllers/DependenciesController.php +++ b/application/controllers/DependenciesController.php @@ -3,7 +3,25 @@ namespace Icinga\Module\Director\Controllers; use Icinga\Module\Director\Web\Controller\ObjectsController; +use ipl\Html\Html; class DependenciesController extends ObjectsController { + protected function addObjectsTabs() + { + $res = parent::addObjectsTabs(); + $this->tabs()->remove('index'); + return $res; + } + + public function applyrulesAction() + { + $this->content()->add(Html::tag( + 'p', + ['class' => 'warning'], + $this->translate('This feature is still experimental') + )); + + parent::applyrulesAction(); + } } diff --git a/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php b/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php index 37ef7c34..47a18aa8 100644 --- a/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php +++ b/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php @@ -21,6 +21,6 @@ class DependencyObjectDashlet extends Dashlet public function getUrl() { - return 'director/dependencies'; + return 'director/dependencies/applyrules'; } } From 44c156041ad77cf5e5811776ebceed618b170866 Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Thu, 28 Sep 2017 10:58:07 +0200 Subject: [PATCH 9/9] schema: add PostgreSQL, small fixes for MySQL refs #132 --- ...grade_dependencies.sql => upgrade_144.sql} | 15 +-- .../upgrade_dependencies_2.sql | 2 - schema/mysql.sql | 22 ++--- schema/pgsql-migrations/upgrade_144.sql | 99 +++++++++++++++++++ schema/pgsql.sql | 98 +++++++++++++++++- 5 files changed, 216 insertions(+), 20 deletions(-) rename schema/mysql-migrations/{upgrade_dependencies.sql => upgrade_144.sql} (89%) delete mode 100644 schema/mysql-migrations/upgrade_dependencies_2.sql create mode 100644 schema/pgsql-migrations/upgrade_144.sql diff --git a/schema/mysql-migrations/upgrade_dependencies.sql b/schema/mysql-migrations/upgrade_144.sql similarity index 89% rename from schema/mysql-migrations/upgrade_dependencies.sql rename to schema/mysql-migrations/upgrade_144.sql index d80098b1..fff6f8f8 100644 --- a/schema/mysql-migrations/upgrade_dependencies.sql +++ b/schema/mysql-migrations/upgrade_144.sql @@ -1,4 +1,3 @@ - CREATE TABLE icinga_dependency ( id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL, object_name VARCHAR(255) DEFAULT NULL, @@ -9,22 +8,23 @@ CREATE TABLE icinga_dependency ( parent_service_id INT(10) UNSIGNED DEFAULT NULL, child_host_id INT(10) UNSIGNED DEFAULT NULL, child_service_id INT(10) UNSIGNED DEFAULT NULL, - disable_checks ENUM('y', 'n'), - disable_notifications ENUM('y', 'n'), - ignore_soft_states ENUM('y', 'n'), + disable_checks ENUM('y', 'n') DEFAULT NULL, + disable_notifications ENUM('y', 'n') DEFAULT NULL, + ignore_soft_states ENUM('y', 'n') DEFAULT NULL, period_id INT(10) UNSIGNED DEFAULT NULL, zone_id INT(10) UNSIGNED DEFAULT NULL, assign_filter TEXT DEFAULT NULL, + parent_service_by_name VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id), CONSTRAINT icinga_dependency_parent_host FOREIGN KEY parent_host (parent_host_id) REFERENCES icinga_host (id) - ON DELETE CASCADE + ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT icinga_dependency_parent_service FOREIGN KEY parent_service (parent_service_id) REFERENCES icinga_service (id) - ON DELETE CASCADE + ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT icinga_dependency_child_host FOREIGN KEY child_host (child_host_id) @@ -86,3 +86,6 @@ CREATE TABLE icinga_dependency_states_set ( ON UPDATE CASCADE ) ENGINE=InnoDB; +INSERT INTO director_schema_migration + (schema_version, migration_time) + VALUES (144, NOW()); diff --git a/schema/mysql-migrations/upgrade_dependencies_2.sql b/schema/mysql-migrations/upgrade_dependencies_2.sql deleted file mode 100644 index f147e38b..00000000 --- a/schema/mysql-migrations/upgrade_dependencies_2.sql +++ /dev/null @@ -1,2 +0,0 @@ - -ALTER TABLE icinga_dependency ADD COLUMN parent_service_by_name VARCHAR(255); diff --git a/schema/mysql.sql b/schema/mysql.sql index fa0b8e17..b8b1dfd7 100644 --- a/schema/mysql.sql +++ b/schema/mysql.sql @@ -1585,9 +1585,9 @@ CREATE TABLE icinga_dependency ( parent_service_id INT(10) UNSIGNED DEFAULT NULL, child_host_id INT(10) UNSIGNED DEFAULT NULL, child_service_id INT(10) UNSIGNED DEFAULT NULL, - disable_checks ENUM('y', 'n'), - disable_notifications ENUM('y', 'n'), - ignore_soft_states ENUM('y', 'n'), + disable_checks ENUM('y', 'n') DEFAULT NULL, + disable_notifications ENUM('y', 'n') DEFAULT NULL, + ignore_soft_states ENUM('y', 'n') DEFAULT NULL, period_id INT(10) UNSIGNED DEFAULT NULL, zone_id INT(10) UNSIGNED DEFAULT NULL, assign_filter TEXT DEFAULT NULL, @@ -1596,12 +1596,12 @@ CREATE TABLE icinga_dependency ( CONSTRAINT icinga_dependency_parent_host FOREIGN KEY parent_host (parent_host_id) REFERENCES icinga_host (id) - ON DELETE CASCADE + ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT icinga_dependency_parent_service FOREIGN KEY parent_service (parent_service_id) REFERENCES icinga_service (id) - ON DELETE CASCADE + ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT icinga_dependency_child_host FOREIGN KEY child_host (child_host_id) @@ -1632,13 +1632,13 @@ CREATE TABLE icinga_dependency_inheritance ( PRIMARY KEY (dependency_id, parent_dependency_id), UNIQUE KEY unique_order (dependency_id, weight), CONSTRAINT icinga_dependency_inheritance_dependency - FOREIGN KEY dependency (dependency_id) - REFERENCES icinga_dependency (id) + FOREIGN KEY dependency (dependency_id) + REFERENCES icinga_dependency (id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT icinga_dependency_inheritance_parent_dependency - FOREIGN KEY parent_dependency (parent_dependency_id) - REFERENCES icinga_dependency (id) + FOREIGN KEY parent_dependency (parent_dependency_id) + REFERENCES icinga_dependency (id) ON DELETE RESTRICT ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -1661,8 +1661,8 @@ CREATE TABLE icinga_dependency_states_set ( REFERENCES icinga_dependency (id) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB; +) ENGINE=InnoDB; INSERT INTO director_schema_migration (schema_version, migration_time) - VALUES (143, NOW()); + VALUES (144, NOW()); diff --git a/schema/pgsql-migrations/upgrade_144.sql b/schema/pgsql-migrations/upgrade_144.sql new file mode 100644 index 00000000..4516f5e9 --- /dev/null +++ b/schema/pgsql-migrations/upgrade_144.sql @@ -0,0 +1,99 @@ +CREATE TABLE icinga_dependency ( + id serial, + object_name character varying(255) NOT NULL, + object_type enum_object_type_all NOT NULL, + disabled enum_boolean DEFAULT 'n', + apply_to enum_host_service NULL DEFAULT NULL, + parent_host_id integer DEFAULT NULL, + parent_service_id integer DEFAULT NULL, + child_host_id integer DEFAULT NULL, + child_service_id integer DEFAULT NULL, + disable_checks enum_boolean DEFAULT NULL, + disable_notifications enum_boolean DEFAULT NULL, + ignore_soft_states enum_boolean DEFAULT NULL, + period_id integer DEFAULT NULL, + zone_id integer DEFAULT NULL, + assign_filter text DEFAULT NULL, + parent_service_by_name character varying(255), + PRIMARY KEY (id), + CONSTRAINT icinga_dependency_parent_host + FOREIGN KEY (parent_host_id) + REFERENCES icinga_host (id) + ON DELETE RESTRICT + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_parent_service + FOREIGN KEY (parent_service_id) + REFERENCES icinga_service (id) + ON DELETE RESTRICT + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_child_host + FOREIGN KEY (child_host_id) + REFERENCES icinga_host (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_child_service + FOREIGN KEY (child_service_id) + REFERENCES icinga_service (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_period + FOREIGN KEY (period_id) + REFERENCES icinga_timeperiod (id) + ON DELETE RESTRICT + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_zone + FOREIGN KEY (zone_id) + REFERENCES icinga_zone (id) + ON DELETE RESTRICT + ON UPDATE CASCADE +); + +CREATE INDEX dependency_parent_host ON icinga_dependency (parent_host_id); +CREATE INDEX dependency_parent_service ON icinga_dependency (parent_service_id); +CREATE INDEX dependency_child_host ON icinga_dependency (child_host_id); +CREATE INDEX dependency_child_service ON icinga_dependency (child_service_id); +CREATE INDEX dependency_period ON icinga_dependency (period_id); +CREATE INDEX dependency_zone ON icinga_dependency (zone_id); + + +CREATE TABLE icinga_dependency_inheritance ( + dependency_id integer NOT NULL, + parent_dependency_id integer NOT NULL, + weight integer DEFAULT NULL, + PRIMARY KEY (dependency_id, parent_dependency_id), + CONSTRAINT icinga_dependency_inheritance_dependency + FOREIGN KEY (dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_inheritance_parent_dependency + FOREIGN KEY (parent_dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE RESTRICT + ON UPDATE CASCADE +); + +CREATE UNIQUE INDEX dependency_inheritance_unique_order ON icinga_dependency_inheritance (dependency_id, weight); +CREATE INDEX dependency_inheritance_dependency ON icinga_dependency_inheritance (dependency_id); +CREATE INDEX dependency_inheritance_dependency_parent ON icinga_dependency_inheritance (parent_dependency_id); + + +CREATE TABLE icinga_dependency_states_set ( + dependency_id integer NOT NULL, + property enum_state_name NOT NULL, + merge_behaviour enum_set_merge_behaviour NOT NULL DEFAULT 'override', + PRIMARY KEY (dependency_id, property, merge_behaviour), + CONSTRAINT icinga_dependency_states_set_dependency + FOREIGN KEY (dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE INDEX dependency_states_set_dependency ON icinga_dependency_states_set (dependency_id); +COMMENT ON COLUMN icinga_dependency_states_set.merge_behaviour IS 'override: = [], extend: += [], blacklist: -= []'; + + +INSERT INTO director_schema_migration + (schema_version, migration_time) + VALUES (144, NOW()); diff --git a/schema/pgsql.sql b/schema/pgsql.sql index f227734b..5eb2233a 100644 --- a/schema/pgsql.sql +++ b/schema/pgsql.sql @@ -1855,6 +1855,102 @@ CREATE INDEX user_resolved_var_user_id ON icinga_user_resolved_var (user_id); CREATE INDEX user_resolved_var_schecksum ON icinga_user_resolved_var (checksum); +CREATE TABLE icinga_dependency ( + id serial, + object_name character varying(255) NOT NULL, + object_type enum_object_type_all NOT NULL, + disabled enum_boolean DEFAULT 'n', + apply_to enum_host_service NULL DEFAULT NULL, + parent_host_id integer DEFAULT NULL, + parent_service_id integer DEFAULT NULL, + child_host_id integer DEFAULT NULL, + child_service_id integer DEFAULT NULL, + disable_checks enum_boolean DEFAULT NULL, + disable_notifications enum_boolean DEFAULT NULL, + ignore_soft_states enum_boolean DEFAULT NULL, + period_id integer DEFAULT NULL, + zone_id integer DEFAULT NULL, + assign_filter text DEFAULT NULL, + parent_service_by_name character varying(255), + PRIMARY KEY (id), + CONSTRAINT icinga_dependency_parent_host + FOREIGN KEY (parent_host_id) + REFERENCES icinga_host (id) + ON DELETE RESTRICT + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_parent_service + FOREIGN KEY (parent_service_id) + REFERENCES icinga_service (id) + ON DELETE RESTRICT + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_child_host + FOREIGN KEY (child_host_id) + REFERENCES icinga_host (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_child_service + FOREIGN KEY (child_service_id) + REFERENCES icinga_service (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_period + FOREIGN KEY period (period_id) + REFERENCES icinga_timeperiod (id) + ON DELETE RESTRICT + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_zone + FOREIGN KEY zone (zone_id) + REFERENCES icinga_zone (id) + ON DELETE RESTRICT + ON UPDATE CASCADE +); + +CREATE INDEX dependency_parent_host ON icinga_dependency (parent_host_id); +CREATE INDEX dependency_parent_service ON icinga_dependency (parent_service_id); +CREATE INDEX dependency_child_host ON icinga_dependency (child_host_id); +CREATE INDEX dependency_child_service ON icinga_dependency (child_service_id); +CREATE INDEX dependency_period ON icinga_dependency (period_id); +CREATE INDEX dependency_zone ON icinga_dependency (zone_id); + + +CREATE TABLE icinga_dependency_inheritance ( + dependency_id integer NOT NULL, + parent_dependency_id integer NOT NULL, + weight integer DEFAULT NULL, + PRIMARY KEY (dependency_id, parent_dependency_id), + CONSTRAINT icinga_dependency_inheritance_dependency + FOREIGN KEY (dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT icinga_dependency_inheritance_parent_dependency + FOREIGN KEY (parent_dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE RESTRICT + ON UPDATE CASCADE +); + +CREATE UNIQUE INDEX dependency_inheritance_unique_order ON icinga_dependency_inheritance (dependency_id, weight); +CREATE INDEX dependency_inheritance_dependency ON icinga_dependency_inheritance (dependency_id); +CREATE INDEX dependency_inheritance_dependency_parent ON icinga_dependency_inheritance (parent_dependency_id); + + +CREATE TABLE icinga_dependency_states_set ( + icinga_dependency integer NOT NULL, + property enum_state_name NOT NULL, + merge_behaviour enum_set_merge_behaviour NOT NULL DEFAULT 'override', + PRIMARY KEY (dependency_id, property, merge_behaviour), + CONSTRAINT icinga_dependency_states_set_dependency + FOREIGN KEY (dependency_id) + REFERENCES icinga_dependency (id) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE INDEX dependency_states_set_dependency ON icinga_dependency_states_set (user_id); +COMMENT ON COLUMN icinga_dependency_states_set.merge_behaviour IS 'override: = [], extend: += [], blacklist: -= []'; + + INSERT INTO director_schema_migration (schema_version, migration_time) - VALUES (143, NOW()); + VALUES (144, NOW());