diff options
Diffstat (limited to 'library/Director/Web/Table/IcingaHostAppliedServicesTable.php')
-rw-r--r-- | library/Director/Web/Table/IcingaHostAppliedServicesTable.php | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/library/Director/Web/Table/IcingaHostAppliedServicesTable.php b/library/Director/Web/Table/IcingaHostAppliedServicesTable.php new file mode 100644 index 0000000..415903b --- /dev/null +++ b/library/Director/Web/Table/IcingaHostAppliedServicesTable.php @@ -0,0 +1,207 @@ +<?php + +namespace Icinga\Module\Director\Web\Table; + +use ipl\Html\Html; +use Icinga\Data\DataArray\ArrayDatasource; +use Icinga\Data\Filter\Filter; +use Icinga\Exception\IcingaException; +use Icinga\Module\Director\IcingaConfig\AssignRenderer; +use Icinga\Module\Director\Objects\HostApplyMatches; +use Icinga\Module\Director\Objects\IcingaHost; +use gipfl\IcingaWeb2\Link; +use gipfl\IcingaWeb2\Table\SimpleQueryBasedTable; + +class IcingaHostAppliedServicesTable extends SimpleQueryBasedTable +{ + protected $title; + + /** @var IcingaHost */ + protected $host; + + /** @var \Zend_Db_Adapter_Abstract */ + protected $db; + + /** @var bool */ + protected $readonly = false; + + /** @var string|null */ + protected $highlightedService; + + private $allApplyRules; + + /** + * @param IcingaHost $host + * @return static + */ + public static function load(IcingaHost $host) + { + $table = (new static())->setHost($host); + $table->getAttributes()->set('data-base-target', '_self'); + return $table; + } + + public function setTitle($title) + { + $this->title = $title; + return $this; + } + + public function getColumnsToBeRendered() + { + return [$this->title]; + } + + public function setHost(IcingaHost $host) + { + $this->host = $host; + $this->db = $host->getDb(); + return $this; + } + + /** + * Show no related links + * + * @param bool $readonly + * @return $this + */ + public function setReadonly($readonly = true) + { + $this->readonly = (bool) $readonly; + + return $this; + } + + public function highlightService($service) + { + $this->highlightedService = $service; + + return $this; + } + + public function renderRow($row) + { + $classes = []; + if ($row->blacklisted === 'y') { + $classes[] = 'strike-links'; + } + if ($row->disabled === 'y') { + $classes[] = 'disabled'; + } + + $attributes = empty($classes) ? null : ['class' => $classes]; + + if ($this->readonly) { + if ($this->highlightedService === $row->name) { + $link = Html::tag('a', ['class' => 'icon-right-big'], $row->name); + } else { + $link = Html::tag('a', $row->name); + } + } else { + $applyFor = ''; + if (! empty($row->apply_for)) { + $applyFor = sprintf('(apply for %s) ', $row->apply_for); + } + + $link = Link::create(sprintf( + $this->translate('%s %s(%s)'), + $row->name, + $applyFor, + $this->renderApplyFilter($row->filter) + ), 'director/host/appliedservice', [ + 'name' => $this->host->getObjectName(), + 'service_id' => $row->id, + ]); + } + + return $this::row([$link], $attributes); + } + + /** + * @param Filter $assignFilter + * + * @return string + */ + protected function renderApplyFilter(Filter $assignFilter) + { + try { + $string = AssignRenderer::forFilter($assignFilter)->renderAssign(); + } catch (IcingaException $e) { + $string = 'Error in Filter rendering: ' . $e->getMessage(); + } + + return $string; + } + + /** + * @return \Icinga\Data\SimpleQuery + */ + public function prepareQuery() + { + $services = []; + $matcher = HostApplyMatches::prepare($this->host); + foreach ($this->getAllApplyRules() as $rule) { + if ($matcher->matchesFilter($rule->filter)) { + $services[] = $rule; + } + } + + $ds = new ArrayDatasource($services); + return $ds->select()->columns([ + 'id' => 'id', + 'uuid' => 'uuid', + 'name' => 'name', + 'filter' => 'filter', + 'disabled' => 'disabled', + 'blacklisted' => 'blacklisted', + 'assign_filter' => 'assign_filter', + 'apply_for' => 'apply_for', + ]); + } + + /*** + * @return array + */ + protected function getAllApplyRules() + { + if ($this->allApplyRules === null) { + $this->allApplyRules = $this->fetchAllApplyRules(); + foreach ($this->allApplyRules as $rule) { + $rule->filter = Filter::fromQueryString($rule->assign_filter); + } + } + + return $this->allApplyRules; + } + + /** + * @return array + */ + protected function fetchAllApplyRules() + { + $db = $this->db; + $hostId = $this->host->get('id'); + $query = $db->select()->from( + ['s' => 'icinga_service'], + [ + 'id' => 's.id', + 'uuid' => 's.uuid', + 'name' => 's.object_name', + 'assign_filter' => 's.assign_filter', + 'apply_for' => 's.apply_for', + 'disabled' => 's.disabled', + 'blacklisted' => $hostId ? "CASE WHEN hsb.service_id IS NULL THEN 'n' ELSE 'y' END" : "('n')", + ] + )->where('object_type = ? AND assign_filter IS NOT NULL', 'apply') + ->order('s.object_name'); + if ($hostId) { + $query->joinLeft( + ['hsb' => 'icinga_host_service_blacklist'], + $db->quoteInto('s.id = hsb.service_id AND hsb.host_id = ?', $hostId), + [] + ); + } + + return $db->fetchAll($query); + } +} |