diff --git a/library/Director/Objects/IcingaServiceSet.php b/library/Director/Objects/IcingaServiceSet.php index 42dd6bb8e..032d87d0c 100644 --- a/library/Director/Objects/IcingaServiceSet.php +++ b/library/Director/Objects/IcingaServiceSet.php @@ -78,6 +78,12 @@ protected function setKey($key) */ public function getServiceObjects() { + // don't try to resolve services for unstored objects - as in getServiceObjectsForSet() + // also for diff in activity log + if ($this->get('id') === null) { + return []; + } + if ($this->get('host_id')) { $imports = $this->imports()->getObjects(); if (empty($imports)) { @@ -280,6 +286,9 @@ public function onDelete() */ public function renderToConfig(IcingaConfig $config) { + // always print the header, so you have minimal info present + $file = $this->getConfigFileWithHeader($config); + if ($this->get('assign_filter') === null && $this->isTemplate()) { return; } @@ -293,7 +302,6 @@ public function renderToConfig(IcingaConfig $config) if (empty($services)) { return; } - $file = $this->getConfigFileWithHeader($config); // Loop over all services belonging to this set // add our assign rules and then add the service to the config @@ -350,17 +358,38 @@ protected function getConfigFileWithHeader(IcingaConfig $config) protected function getConfigHeaderComment(IcingaConfig $config) { + $name = $this->getObjectName(); + $assign = $this->get('assign_filter'); + if ($config->isLegacy()) { - if ($this->get('assign_filter')) { - $comment = "## applied Service Set '%s'\n\n"; + if ($assign !== null) { + return "## applied Service Set '${name}'\n\n"; } else { - $comment = "## Service Set '%s' on this host\n\n"; + return "## Service Set '${name}' on this host\n\n"; } } else { - $comment = "/** Service Set '%s' **/\n\n"; - } + $comment = [ + "Service Set: ${name}", + ]; - return sprintf($comment, $this->getObjectName()); + if (($host = $this->get('host')) !== null) { + $comment[] = 'on host ' . $host; + } + + if (($description = $this->get('description')) !== null) { + $comment[] = ''; + foreach (preg_split('~\\n~', $description) as $line) { + $comment[] = $line; + } + } + + if ($assign !== null) { + $comment[] = ''; + $comment[] = trim($this->renderAssign_Filter()); + } + + return "/**\n * " . join("\n * ", $comment) . "\n */\n\n"; + } } public function copyVarsToService(IcingaService $service) diff --git a/library/Director/Web/Controller/ObjectController.php b/library/Director/Web/Controller/ObjectController.php index 780839578..0dbcba347 100644 --- a/library/Director/Web/Controller/ObjectController.php +++ b/library/Director/Web/Controller/ObjectController.php @@ -234,10 +234,10 @@ public function historyAction() $this->addTitle($this->translate('Activity Log: %s'), $name); $db = $this->db(); - $type = $this->getType(); + $objectTable = $this->object->getTableName(); $table = (new ActivityLogTable($db)) ->setLastDeployedId($db->getLastDeploymentActivityLogId()) - ->filterObject('icinga_' . $type, $name); + ->filterObject($objectTable, $name); if ($host = $this->params->get('host')) { $table->filterHost($host); } diff --git a/library/Director/Web/Widget/ActivityLogInfo.php b/library/Director/Web/Widget/ActivityLogInfo.php index 7471af2df..abb548f0a 100644 --- a/library/Director/Web/Widget/ActivityLogInfo.php +++ b/library/Director/Web/Widget/ActivityLogInfo.php @@ -11,6 +11,8 @@ use Icinga\Module\Director\Forms\RestoreObjectForm; use Icinga\Module\Director\IcingaConfig\IcingaConfig; use Icinga\Module\Director\Objects\IcingaObject; +use Icinga\Module\Director\Objects\IcingaService; +use Icinga\Module\Director\Objects\IcingaServiceSet; use dipl\Html\Html; use dipl\Html\Icon; use dipl\Html\Link; @@ -39,6 +41,10 @@ class ActivityLogInfo extends HtmlDocument protected $entry; + protected $oldProperties; + + protected $newProperties; + protected $oldObject; /** @var Tabs */ @@ -200,6 +206,7 @@ public function getCurrentObject() /** * @return bool + * @deprecated No longer used? */ public function objectStillExists() { @@ -210,6 +217,117 @@ public function objectStillExists() ); } + protected function oldProperties() + { + if ($this->oldProperties === null) { + if (property_exists($this->entry, 'old_properties')) { + $this->oldProperties = json_decode($this->entry->old_properties); + } + if ($this->oldProperties === null) { + $this->oldProperties = new \stdClass; + } + } + + return $this->oldProperties; + } + + protected function newProperties() + { + if ($this->newProperties === null) { + if (property_exists($this->entry, 'new_properties')) { + $this->newProperties = json_decode($this->entry->new_properties); + } else { + $this->newProperties = new \stdClass; + } + } + + return $this->newProperties; + } + + protected function getEntryProperty($key) + { + $entry = $this->entry; + + if (property_exists($entry, $key)) { + return $entry->{$key}; + } elseif (property_exists($this->newProperties(), $key)) { + return $this->newProperties->{$key}; + } elseif (property_exists($this->oldProperties(), $key)) { + return $this->oldProperties->{$key}; + } else { + return null; + } + } + + protected function objectLinkParams() + { + $entry = $this->entry; + + $params = ['name' => $entry->object_name]; + + if ($entry->object_type === 'icinga_service') { + if (($set = $this->getEntryProperty('service_set')) !== null) { + $params['set'] = $set; + return $params; + } elseif (($host = $this->getEntryProperty('host')) !== null) { + $params['host'] = $host; + return $params; + } else { + return $params; + } + } elseif ($entry->object_type === 'icinga_service_set') { + return $params; + } else { + return $params; + } + } + + protected function getActionExtraHtml() + { + $entry = $this->entry; + + $info = ''; + $host = null; + + if ($entry->object_type === 'icinga_service') { + if (($set = $this->getEntryProperty('service_set')) !== null) { + $info = Html::sprintf( + '%s "%s"', + $this->translate('on service set'), + Link::create( + $set, + 'director/serviceset', + ['name' => $set], + ['data-base-target' => '_next'] + ) + ); + } else { + $host = $this->getEntryProperty('host'); + } + } elseif ($entry->object_type === 'icinga_service_set') { + $host = $this->getEntryProperty('host'); + } + + if ($host !== null) { + $info = Html::sprintf( + '%s "%s"', + $this->translate('on host'), + Link::create( + $host, + 'director/host', + ['name' => $host], + ['data-base-target' => '_next'] + ) + ); + } + + return $info; + } + + /** + * @return array + * @deprecated No longer used? + */ protected function objectKey() { $entry = $this->entry; @@ -341,13 +459,38 @@ protected function newObject() ); } + protected function objectToConfig(IcingaObject $object) + { + if ($object instanceof IcingaService) { + return $this->previewService($object); + } else { + return $object->toSingleIcingaConfig(); + } + } + + protected function previewService(IcingaService $service) + { + if (($set = $service->get('service_set')) !== null) { + // simulate rendering of service in set + $set = IcingaServiceSet::load($set, $this->db); + + $service->set('service_set_id', null); + if (($assign = $set->get('assign_filter')) !== null) { + $service->set('object_type', 'apply'); + $service->set('assign_filter', $assign); + } + } + + return $service->toSingleIcingaConfig(); + } + /** * @return IcingaConfig * @throws \Icinga\Exception\IcingaException */ protected function newConfig() { - return $this->newObject()->toSingleIcingaConfig(); + return $this->objectToConfig($this->newObject()); } /** @@ -356,17 +499,23 @@ protected function newConfig() */ protected function oldConfig() { - return $this->oldObject()->toSingleIcingaConfig(); + return $this->objectToConfig($this->oldObject()); } protected function getLinkToObject() { $entry = $this->entry; $name = $entry->object_name; + $controller = preg_replace('/^icinga_/', '', $entry->object_type); + + if ($controller === 'service_set') { + $controller = 'serviceset'; + } + return Link::create( $name, - 'director/' . preg_replace('/^icinga_/', '', $entry->object_type), - ['name' => $name], + 'director/' . $controller, + $this->objectLinkParams(), ['data-base-target' => '_next'] ); } @@ -390,10 +539,11 @@ public function getInfoTable() $table->addNameValueRow( $this->translate('Action'), Html::sprintf( - '%s %s "%s"', + '%s %s "%s" %s', $entry->action_name, $entry->object_type, - $this->getLinkToObject() + $this->getLinkToObject(), + $this->getActionExtraHtml() ) ); } else {