From 8ac6e4874c0c318a736351a4978115208b88d8ce Mon Sep 17 00:00:00 2001 From: Korbinian Rosenegger Date: Tue, 24 Jan 2023 19:42:49 +0100 Subject: [PATCH 1/3] Sort and group hosts in service grid by DNS hierarchy --- .../controllers/ListController.php | 70 +++++++++++++++++++ .../scripts/list/servicegrid-flipped.phtml | 6 ++ .../views/scripts/list/servicegrid.phtml | 3 + .../monitoring/public/css/service-grid.less | 12 ++++ 4 files changed, 91 insertions(+) diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php index 0ccff99c85..7fc84f8cac 100644 --- a/modules/monitoring/application/controllers/ListController.php +++ b/modules/monitoring/application/controllers/ListController.php @@ -712,6 +712,17 @@ public function servicegridAction() $this->view->horizontalPaginator = $pivot->paginateXAxis(); $this->view->verticalPaginator = $pivot->paginateYAxis(); list($pivotData, $pivotHeader) = $pivot->toArray(); + + if (true) { + $keySort = ($this->params->get('flipped', false) ? 'cols' : 'rows'); + + uksort($pivotData, [ $this, "compareByDnsHierarchy" ]); + uksort($pivotHeader[$keySort], [ $this, "compareByDnsHierarchy" ]); + + $pivotHeader[$keySort] = $this->addGroupHeader($pivotHeader[$keySort]); + + } + $this->view->pivotData = $pivotData; $this->view->pivotHeader = $pivotHeader; if ($this->params->get('flipped', false)) { @@ -719,6 +730,65 @@ public function servicegridAction() } } + /** + * Add group headers to the header array + * The group name will be the FQDN without the the part before the first dot. + */ + + private function addGroupHeader($header) { + $newHeader = []; + $previousGroup = null; + foreach ($header as $key => $val) { + $hostnameElements = explode('.', $key); + if (count($hostnameElements) > 2) { + array_shift($hostnameElements); + $group = join('.', $hostnameElements); + if (is_null($previousGroup) || $previousGroup != $group) { + $newHeader['GROUP:' . $group] = $group; + $previousGroup = $group; + } + } + $newHeader[$key] = $val; + } + return $newHeader; + } + + /** + * Split a FQDN by dots and compare each part beginning from top level + */ + + private function compareByDnsHierarchy($a, $b) { + $keysA = explode('.', $a); + $keysA = array_reverse($keysA); + + $keysB = explode('.', $b); + $keysB = array_reverse($keysB); + + $cnt = min([$cntA = count($keysA), $cntB = count($keysB)]); + + $firstDiff = -1; + $cmp = [ -1 => 0 ]; + + for ($i = 0; $i <= $cnt; $i++) { + $ka = isset($keysA[$i]) ? $keysA[$i] : ""; + $kb = isset($keysB[$i]) ? $keysB[$i] : ""; + + if ($cmp[$i] = $ka <=> $kb) { + if ($firstDiff === -1) { + $firstDiff = $i; + } + } + } + + if (count($keysA) != count($keysB)) { + return count($keysA) <=> count($keysB); + } + else { + return ($cmp[$firstDiff]); + } + } + + /** * Apply filters on a DataView * diff --git a/modules/monitoring/application/views/scripts/list/servicegrid-flipped.phtml b/modules/monitoring/application/views/scripts/list/servicegrid-flipped.phtml index d7b4c78ddc..f2fb6e14aa 100644 --- a/modules/monitoring/application/views/scripts/list/servicegrid-flipped.phtml +++ b/modules/monitoring/application/views/scripts/list/servicegrid-flipped.phtml @@ -36,6 +36,9 @@ foreach ($pivotData as $serviceDescription => $_) { ) ) ?> $hostAlias): ?> + +
+
qlink( $this->ellipsis($hostAlias, 24), Url::fromPath('monitoring/list/services')->addFilter( @@ -71,6 +74,9 @@ foreach ($pivotData as $serviceDescription => $_) { ); ?> + + + diff --git a/modules/monitoring/application/views/scripts/list/servicegrid.phtml b/modules/monitoring/application/views/scripts/list/servicegrid.phtml index d0ed4bc49a..245123ca38 100644 --- a/modules/monitoring/application/views/scripts/list/servicegrid.phtml +++ b/modules/monitoring/application/views/scripts/list/servicegrid.phtml @@ -55,6 +55,9 @@ foreach ($pivotData as $hostName => $_) { $hostDisplayName): ?> + + + Date: Tue, 24 Jan 2023 21:48:04 +0100 Subject: [PATCH 2/3] Add toggle for DNS hierarchy sorting --- .../controllers/ListController.php | 20 +++++++++++++++++-- .../scripts/list/servicegrid-flipped.phtml | 1 + .../views/scripts/list/servicegrid.phtml | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php index 7fc84f8cac..4bf916938f 100644 --- a/modules/monitoring/application/controllers/ListController.php +++ b/modules/monitoring/application/controllers/ListController.php @@ -684,6 +684,20 @@ public function servicegridAction() 'decorators' => ['ViewHelper', ['Label', ['placement' => 'APPEND']]] ]); + + $sortByDns = (bool) $this->params->get('sortbydnshierarchy', false) ? true : null; + $this->view->sortByDnsToggle = $sortByDnsToggle = new Form(['method' => 'GET']); + $sortByDnsToggle->setUidDisabled(); + $sortByDnsToggle->setTokenDisabled(); + $sortByDnsToggle->setAttrib('class', 'filter-toggle inline icinga-controls'); + $sortByDnsToggle->addElement('checkbox', 'sortbydnshierarchy', [ + 'disableHidden' => true, + 'autosubmit' => true, + 'value' => $sortByDns !== null, + 'label' => $this->translate('Sort by DNS hierarchy'), + 'decorators' => ['ViewHelper', ['Label', ['placement' => 'APPEND']]] + ]); + if ($this->params->get('flipped', false)) { $pivot = $query ->pivot( @@ -713,7 +727,8 @@ public function servicegridAction() $this->view->verticalPaginator = $pivot->paginateYAxis(); list($pivotData, $pivotHeader) = $pivot->toArray(); - if (true) { + $sortByDns = (bool) $this->params->get('sortbydnshierarchy', false) ? !true : null; + if ($sortByDns !== null) { $keySort = ($this->params->get('flipped', false) ? 'cols' : 'rows'); uksort($pivotData, [ $this, "compareByDnsHierarchy" ]); @@ -803,7 +818,8 @@ protected function filterQuery(DataView $dataView) 'stateType', // hostsAction() and servicesAction() 'addColumns', // addColumns() 'problems', // servicegridAction() - 'flipped' // servicegridAction() + 'flipped', // servicegridAction() + 'sortbydnshierarchy' // servicegridAction() )); if ($this->params->get('format') !== 'sql' || $this->hasPermission('config/authentication/roles/show')) { diff --git a/modules/monitoring/application/views/scripts/list/servicegrid-flipped.phtml b/modules/monitoring/application/views/scripts/list/servicegrid-flipped.phtml index f2fb6e14aa..e812d74762 100644 --- a/modules/monitoring/application/views/scripts/list/servicegrid-flipped.phtml +++ b/modules/monitoring/application/views/scripts/list/servicegrid-flipped.phtml @@ -7,6 +7,7 @@ if (! $this->compact): ?>
tabs ?> problemToggle ?> + sortByDnsToggle ?>
sortBox ?>
diff --git a/modules/monitoring/application/views/scripts/list/servicegrid.phtml b/modules/monitoring/application/views/scripts/list/servicegrid.phtml index 245123ca38..3de2be7e7d 100644 --- a/modules/monitoring/application/views/scripts/list/servicegrid.phtml +++ b/modules/monitoring/application/views/scripts/list/servicegrid.phtml @@ -7,6 +7,7 @@ if (! $this->compact): ?>
tabs ?> problemToggle ?> + sortByDnsToggle ?>
sortBox ?>
From b070213f33865c38198ecb21cfed63704c636f0d Mon Sep 17 00:00:00 2001 From: Korbinian Rosenegger Date: Tue, 24 Jan 2023 22:42:30 +0100 Subject: [PATCH 3/3] Don't reverse IPv4 addresses --- .../application/controllers/ListController.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php index 4bf916938f..d6e231ce8b 100644 --- a/modules/monitoring/application/controllers/ListController.php +++ b/modules/monitoring/application/controllers/ListController.php @@ -756,7 +756,12 @@ private function addGroupHeader($header) { foreach ($header as $key => $val) { $hostnameElements = explode('.', $key); if (count($hostnameElements) > 2) { - array_shift($hostnameElements); + if (filter_var($key, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + array_pop($hostnameElements); + } + else { + array_shift($hostnameElements); + } $group = join('.', $hostnameElements); if (is_null($previousGroup) || $previousGroup != $group) { $newHeader['GROUP:' . $group] = $group; @@ -774,10 +779,14 @@ private function addGroupHeader($header) { private function compareByDnsHierarchy($a, $b) { $keysA = explode('.', $a); - $keysA = array_reverse($keysA); + if (!filter_var($a, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + $keysA = array_reverse($keysA); + } $keysB = explode('.', $b); - $keysB = array_reverse($keysB); + if (!filter_var($b, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + $keysB = array_reverse($keysB); + } $cnt = min([$cntA = count($keysA), $cntB = count($keysB)]);