summaryrefslogtreecommitdiffstats
path: root/library/Director/Dashboard/Dashboard.php
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/Director/Dashboard/Dashboard.php305
1 files changed, 305 insertions, 0 deletions
diff --git a/library/Director/Dashboard/Dashboard.php b/library/Director/Dashboard/Dashboard.php
new file mode 100644
index 0000000..de8970c
--- /dev/null
+++ b/library/Director/Dashboard/Dashboard.php
@@ -0,0 +1,305 @@
+<?php
+
+namespace Icinga\Module\Director\Dashboard;
+
+use Exception;
+use gipfl\Translation\TranslationHelper;
+use gipfl\IcingaWeb2\Widget\Tabs;
+use ipl\Html\Html;
+use ipl\Html\HtmlDocument;
+use ipl\Html\HtmlString;
+use Icinga\Authentication\Auth;
+use Icinga\Module\Director\Objects\IcingaObject;
+use Icinga\Module\Director\Restriction\HostgroupRestriction;
+use Icinga\Module\Director\Dashboard\Dashlet\Dashlet;
+use Icinga\Module\Director\Db;
+use Icinga\Web\Widget\Tab;
+use ipl\Html\ValidHtml;
+use Zend_Db_Select as ZfSelect;
+
+abstract class Dashboard extends HtmlDocument
+{
+ use TranslationHelper;
+
+ protected $name;
+
+ /** @var Dashlet[] */
+ protected $dashlets;
+
+ protected $dashletNames;
+
+ /** @var Db */
+ protected $db;
+
+ final private function __construct()
+ {
+ }
+
+ /**
+ * @param $name
+ * @param Db $db
+ *
+ * @return self
+ */
+ public static function loadByName($name, Db $db)
+ {
+ $class = __NAMESPACE__ . '\\' . ucfirst($name) . 'Dashboard';
+ $dashboard = new $class();
+ $dashboard->db = $db;
+ $dashboard->name = $name;
+ return $dashboard;
+ }
+
+ public static function exists($name)
+ {
+ return class_exists(__NAMESPACE__ . '\\' . ucfirst($name) . 'Dashboard');
+ }
+
+ /**
+ * @param $description
+ * @return $this
+ */
+ protected function addDescription($description)
+ {
+ if ($description instanceof ValidHtml) {
+ $this->add(Html::tag('p', $description));
+ } elseif ($description !== null) {
+ $this->add(Html::tag(
+ 'p',
+ null,
+ HtmlString::create(nl2br(Html::escape($description)))
+ ));
+ }
+
+ return $this;
+ }
+
+ public function render()
+ {
+ $this
+ ->setSeparator("\n")
+ ->add(Html::tag('h1', null, $this->getTitle()))
+ ->addDescription($this->getDescription())
+ ->add($this->renderDashlets());
+
+ return parent::render();
+ }
+
+ public function renderDashlets()
+ {
+ $ul = Html::tag('ul', [
+ 'class' => 'main-actions',
+ 'data-base-target' => '_next'
+ ]);
+
+ foreach ($this->dashlets() as $dashlet) {
+ if ($dashlet->shouldBeShown()) {
+ $ul->add($dashlet);
+ }
+ }
+
+ return $ul;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ abstract public function getTitle();
+
+ public function getDescription()
+ {
+ return null;
+ }
+
+ public function getTabs()
+ {
+ $lName = $this->getName();
+ $tabs = new Tabs();
+ $tabs->add($lName, new Tab([
+ 'label' => $this->translate(ucfirst($this->getName())),
+ 'url' => 'director/dashboard',
+ 'urlParams' => ['name' => $lName]
+ ]));
+
+ return $tabs;
+ }
+
+ protected function createTabsForDashboards($names)
+ {
+ $tabs = new Tabs();
+ foreach ($names as $name) {
+ $dashboard = Dashboard::loadByName($name, $this->getDb());
+ if ($dashboard->isAvailable()) {
+ $tabs->add($name, $this->createTabForDashboard($dashboard));
+ }
+ }
+
+ return $tabs;
+ }
+
+ protected function createTabForDashboard(Dashboard $dashboard)
+ {
+ $name = $dashboard->getName();
+ return new Tab([
+ 'label' => $this->translate(ucfirst($name)),
+ 'url' => 'director/dashboard',
+ 'urlParams' => ['name' => $name]
+ ]);
+ }
+
+ public function count()
+ {
+ return count($this->dashlets());
+ }
+
+ public function isAvailable()
+ {
+ return $this->count() > 0;
+ }
+
+ public function getDb()
+ {
+ return $this->db;
+ }
+
+ public function dashlets()
+ {
+ if ($this->dashlets === null) {
+ $this->loadDashlets();
+ $this->fetchDashletSummaries();
+ }
+
+ return $this->dashlets;
+ }
+
+ public function loadDashlets()
+ {
+ $names = $this->getDashletNames();
+
+ if (empty($names)) {
+ $this->dashlets = array();
+ } else {
+ $this->dashlets = Dashlet::loadByNames(
+ $this->dashletNames,
+ $this->getDb()
+ );
+ }
+ }
+
+ public function getDashletNames()
+ {
+ return $this->dashletNames;
+ }
+
+ protected function fetchDashletSummaries()
+ {
+ $types = array();
+ foreach ($this->dashlets as $dashlet) {
+ foreach ($dashlet->listRequiredStats() as $objectType) {
+ $types[$objectType] = $objectType;
+ }
+ }
+
+ if (empty($types)) {
+ return;
+ }
+
+ try {
+ $stats = $this->getObjectSummary($types);
+ } catch (Exception $e) {
+ $stats = array();
+ }
+
+ $failing = array();
+ foreach ($this->dashlets as $key => $dashlet) {
+ foreach ($dashlet->listRequiredStats() as $objectType) {
+ if (array_key_exists($objectType, $stats)) {
+ $dashlet->addStats($objectType, $stats[$objectType]);
+ } else {
+ $failing[] = $key;
+ }
+ }
+ }
+
+ foreach ($failing as $key) {
+ unset($this->dashlets[$key]);
+ }
+ }
+
+ public function getObjectSummary($types)
+ {
+ $queries = array();
+
+ foreach ($types as $type) {
+ $queries[] = $this->makeSummaryQuery($type);
+ }
+ $query = $this->db->select()->union($queries, ZfSelect::SQL_UNION_ALL);
+
+ $result = array();
+ foreach ($this->db->fetchAll($query) as $row) {
+ $result[$row->icinga_type] = $row;
+ }
+
+ return $result;
+ }
+
+ protected function makeSummaryQuery($type)
+ {
+ $columns = array(
+ 'icinga_type' => "('" . $type . "')",
+ 'cnt_object' => $this->getCntSql('object'),
+ 'cnt_template' => $this->getCntSql('template'),
+ 'cnt_external' => $this->getCntSql('external_object'),
+ 'cnt_apply' => $this->getCntSql('apply'),
+ 'cnt_total' => 'COUNT(*)',
+ );
+
+ if ($this->db->isPgsql()) {
+ $dummy = IcingaObject::createByType($type);
+ if (! $dummy->supportsApplyRules()) {
+ $columns['cnt_apply'] = '(0)';
+ }
+ }
+
+ $query = $this->db->getDbAdapter()->select()->from(
+ array('o' => 'icinga_' . $type),
+ $columns
+ );
+
+ return $this->applyRestrictions($type, $query);
+ }
+
+ protected function applyRestrictions($type, $query)
+ {
+ switch ($type) {
+ case 'host':
+ case 'hostgroup':
+ $r = new HostgroupRestriction($this->getDb(), $this->getAuth());
+ $r->applyToQuery($query);
+ break;
+ }
+
+ return $query;
+ }
+
+ protected function applyHostgroupRestrictions($query)
+ {
+ $restrictions = new HostgroupRestriction($this->getDb(), $this->getAuth());
+ $restrictions->applyToHostGroupsQuery($query);
+ }
+
+ protected function getAuth()
+ {
+ return Auth::getInstance();
+ }
+
+ protected function getCntSql($objectType)
+ {
+ return sprintf(
+ "COALESCE(SUM(CASE WHEN o.object_type = '%s' THEN 1 ELSE 0 END), 0)",
+ $objectType
+ );
+ }
+}