diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php index 0ccff99c85..d6e231ce8b 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( @@ -712,6 +726,18 @@ public function servicegridAction() $this->view->horizontalPaginator = $pivot->paginateXAxis(); $this->view->verticalPaginator = $pivot->paginateYAxis(); list($pivotData, $pivotHeader) = $pivot->toArray(); + + $sortByDns = (bool) $this->params->get('sortbydnshierarchy', false) ? !true : null; + if ($sortByDns !== null) { + $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 +745,74 @@ 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) { + 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; + $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); + if (!filter_var($a, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + $keysA = array_reverse($keysA); + } + + $keysB = explode('.', $b); + if (!filter_var($b, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + $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 * @@ -733,7 +827,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 d7b4c78ddc..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): ?>