diff --git a/application/controllers/HostController.php b/application/controllers/HostController.php index 54428418..198599b0 100644 --- a/application/controllers/HostController.php +++ b/application/controllers/HostController.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Controllers; use dipl\Html\Html; use dipl\Html\Link; use dipl\Web\Url; +use dipl\Web\Widget\Tabs; use Exception; use Icinga\Module\Director\CustomVariable\CustomVariableDictionary; use Icinga\Module\Director\Db\AppliedServiceSetLoader; @@ -28,7 +29,11 @@ class HostController extends ObjectController { protected function checkDirectorPermissions() { - $this->assertPermission('director/hosts'); + if (in_array($this->getRequest()->getActionName(), ['servicesro', 'findservice'])) { + $this->assertPermission('director/monitoring/services-ro'); + } else { + $this->assertPermission('director/hosts'); + } } /** @@ -92,14 +97,22 @@ class HostController extends ObjectController /** * @throws \Icinga\Exception\NotFoundError + * @throws \Icinga\Security\SecurityException */ public function findserviceAction() { $host = $this->getHostObject(); - $redirector = new HostServiceRedirector($host); - $this->redirectNow( - $redirector->getRedirectionUrl($this->params->get('service')) - ); + $redirector = new HostServiceRedirector($host, $this->getAuth()); + if ($this->hasPermission('director/hosts')) { + $this->redirectNow( + $redirector->getRedirectionUrl($this->params->get('service')) + ); + return; + } elseif ($this->hasPermission('director/monitoring/services-ro')) { + $this->redirectNow($this->url()->setPath('director/host/servicesro')); + } else { + $this->assertPermission('director/hosts'); + } } /** @@ -184,11 +197,88 @@ class HostController extends ObjectController } } + /** + * @throws \Icinga\Exception\NotFoundError + * @throws \Icinga\Security\SecurityException + * @throws \Icinga\Exception\MissingParameterException + */ + public function servicesroAction() + { + $this->assertPermission('director/monitoring/services-ro'); + $host = $this->getHostObject(); + $service = $this->params->getRequired('service'); + $db = $this->db(); + $this->controls()->setTabs(new Tabs()); + $this->addSingleTab($this->translate('Configuration: Services')); + $this->addTitle($this->translate('Services: %s'), $host->getObjectName()); + $content = $this->content(); + $table = IcingaHostServiceTable::load($host) + ->setReadonly() + ->setTitle($this->translate('Individual Service objects')); + + if (count($table)) { + $content->add($table); + } + + if ($applied = $host->vars()->get($db->settings()->magic_apply_for)) { + if ($applied instanceof CustomVariableDictionary) { + $table = IcingaHostAppliedForServiceTable::load($host, $applied) + ->setReadonly() + ->setTitle($this->translate('Generated from host vars')); + if (count($table)) { + $content->add($table); + } + } + } + + /** @var IcingaHost[] $parents */ + $parents = IcingaTemplateRepository::instanceByObject($this->object) + ->getTemplatesFor($this->object, true); + foreach ($parents as $parent) { + $table = IcingaHostServiceTable::load($parent) + ->setReadonly() + ->setInheritedBy($host); + if (count($table)) { + $content->add( + $table->setTitle(sprintf( + 'Inherited from %s', + $parent->getObjectName() + )) + ); + } + } + + $this->addHostServiceSetTables($host); + foreach ($parents as $parent) { + $this->addHostServiceSetTables($parent, $host, $service); + } + + $appliedSets = AppliedServiceSetLoader::fetchForHost($host); + foreach ($appliedSets as $set) { + $title = sprintf($this->translate('%s (Applied Service set)'), $set->getObjectName()); + + $content->add( + IcingaServiceSetServiceTable::load($set) + // ->setHost($host) + ->setAffectedHost($host) + ->setReadonly() + ->setTitle($title) + ); + } + + $table = IcingaHostAppliedServicesTable::load($host) + ->setTitle($this->translate('Applied services')); + + if (count($table)) { + $content->add($table); + } + } + /** * @param IcingaHost $host * @param IcingaHost|null $affectedHost */ - protected function addHostServiceSetTables(IcingaHost $host, IcingaHost $affectedHost = null) + protected function addHostServiceSetTables(IcingaHost $host, IcingaHost $affectedHost = null, $roService = null) { $db = $this->db(); if ($affectedHost === null) { @@ -213,12 +303,14 @@ class HostController extends ObjectController /** @var IcingaServiceSet $set*/ foreach ($sets as $name => $set) { $title = sprintf($this->translate('%s (Service set)'), $name); - $this->content()->add( - IcingaServiceSetServiceTable::load($set) - ->setHost($host) - ->setAffectedHost($affectedHost) - ->setTitle($title) - ); + $table = IcingaServiceSetServiceTable::load($set) + ->setHost($host) + ->setAffectedHost($affectedHost) + ->setTitle($title); + if ($roService) { + $table->setReadonly(); + } + $this->content()->add($table); } } diff --git a/library/Director/Web/Table/IcingaHostAppliedForServiceTable.php b/library/Director/Web/Table/IcingaHostAppliedForServiceTable.php index 60e94991..8203478d 100644 --- a/library/Director/Web/Table/IcingaHostAppliedForServiceTable.php +++ b/library/Director/Web/Table/IcingaHostAppliedForServiceTable.php @@ -21,6 +21,9 @@ class IcingaHostAppliedForServiceTable extends SimpleQueryBasedTable 'service', ]; + /** @var bool */ + protected $readonly = false; + /** * @param IcingaHost $host * @param CustomVariableDictionary $dict @@ -51,8 +54,26 @@ class IcingaHostAppliedForServiceTable extends SimpleQueryBasedTable return $this; } + /** + * Show no related links + * + * @param bool $readonly + * @return $this + */ + public function setReadonly($readonly = true) + { + $this->readonly = (bool) $readonly; + + return $this; + } + public function renderRow($row) { + if ($this->readonly) { + return $this::row([ + $row->service + ]); + } return $this::row([ Link::create( $row->service, diff --git a/library/Director/Web/Table/IcingaHostServiceTable.php b/library/Director/Web/Table/IcingaHostServiceTable.php index 3631a74e..3e9c603c 100644 --- a/library/Director/Web/Table/IcingaHostServiceTable.php +++ b/library/Director/Web/Table/IcingaHostServiceTable.php @@ -16,6 +16,9 @@ class IcingaHostServiceTable extends ZfQueryBasedTable /** @var IcingaHost */ protected $inheritedBy; + /** @var bool */ + protected $readonly = false; + protected $searchColumns = [ 'service', ]; @@ -50,6 +53,19 @@ class IcingaHostServiceTable extends ZfQueryBasedTable return $this; } + /** + * Show no related links + * + * @param bool $readonly + * @return $this + */ + public function setReadonly($readonly = true) + { + $this->readonly = (bool) $readonly; + + return $this; + } + public function renderRow($row) { $classes = []; @@ -69,6 +85,10 @@ class IcingaHostServiceTable extends ZfQueryBasedTable protected function getServiceLink($row) { + if ($this->readonly) { + return $row->service; + } + if ($target = $this->inheritedBy) { $params = array( 'name' => $target->object_name, diff --git a/library/Director/Web/Table/IcingaServiceSetServiceTable.php b/library/Director/Web/Table/IcingaServiceSetServiceTable.php index 347e4035..54ac1285 100644 --- a/library/Director/Web/Table/IcingaServiceSetServiceTable.php +++ b/library/Director/Web/Table/IcingaServiceSetServiceTable.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Director\Web\Table; +use dipl\Html\Html; use Icinga\Module\Director\Forms\RemoveLinkForm; use Icinga\Module\Director\Objects\IcingaHost; use Icinga\Module\Director\Objects\IcingaServiceSet; @@ -27,6 +28,9 @@ class IcingaServiceSetServiceTable extends ZfQueryBasedTable 'service', ]; + /** @var bool */ + protected $readonly = false; + /** * @param IcingaServiceSet $set * @return static @@ -69,6 +73,19 @@ class IcingaServiceSetServiceTable extends ZfQueryBasedTable return $this; } + /** + * Show no related links + * + * @param bool $readonly + * @return $this + */ + public function setReadonly($readonly = true) + { + $this->readonly = (bool) $readonly; + + return $this; + } + protected function addHeaderColumnsTo(HtmlElement $parent) { if ($this->host || $this->affectedHost) { @@ -86,6 +103,10 @@ class IcingaServiceSetServiceTable extends ZfQueryBasedTable */ protected function getServiceLink($row) { + if ($this->readonly) { + return $row->service; + } + if ($this->affectedHost) { $params = [ 'name' => $this->affectedHost->getObjectName(), @@ -141,6 +162,11 @@ class IcingaServiceSetServiceTable extends ZfQueryBasedTable { if (! $this->host) { $deleteLink = ''; + } elseif ($this->readonly) { + $deleteLink = Html::tag('span', [ + 'class' => 'icon-paste', + 'style' => 'float: right; font-weight: normal', + ], $this->host->getObjectName()); } elseif ($this->affectedHost->get('id') !== $this->host->get('id')) { $host = $this->host; $deleteLink = Link::create(