diff --git a/library/Icingadb/Common/StateBadges.php b/library/Icingadb/Common/StateBadges.php index f476e060d..799239327 100644 --- a/library/Icingadb/Common/StateBadges.php +++ b/library/Icingadb/Common/StateBadges.php @@ -169,7 +169,8 @@ protected function createGroup(string $state) new StateBadge($this->item->$unhandledKey, $state), Filter::all( Filter::equal($this->type . '.state.soft_state', $this->getStateInt($state)), - Filter::equal($this->type . '.state.is_handled', 'n') + Filter::equal($this->type . '.state.is_handled', 'n'), + Filter::equal($this->type . '.state.is_reachable', 'y') ) )); } @@ -179,7 +180,10 @@ protected function createGroup(string $state) new StateBadge($this->item->$handledKey, $state, true), Filter::all( Filter::equal($this->type . '.state.soft_state', $this->getStateInt($state)), - Filter::equal($this->type . '.state.is_handled', 'y') + Filter::any( + Filter::equal($this->type . '.state.is_handled', 'y'), + Filter::equal($this->type . '.state.is_reachable', 'n') + ) ) )); } diff --git a/library/Icingadb/Model/Hostgroupsummary.php b/library/Icingadb/Model/Hostgroupsummary.php index 364f64ee1..b751059af 100644 --- a/library/Icingadb/Model/Hostgroupsummary.php +++ b/library/Icingadb/Model/Hostgroupsummary.php @@ -57,10 +57,10 @@ public function getColumns() return [ 'display_name' => 'hostgroup_display_name', 'hosts_down_handled' => new Expression( - 'SUM(CASE WHEN host_state = 1 AND host_handled = \'y\' THEN 1 ELSE 0 END)' + 'SUM(CASE WHEN host_state = 1 AND (host_handled = \'y\' OR host_reachable = \'n\') THEN 1 ELSE 0 END)' ), 'hosts_down_unhandled' => new Expression( - 'SUM(CASE WHEN host_state = 1 AND host_handled = \'n\' THEN 1 ELSE 0 END)' + 'SUM(CASE WHEN host_state = 1 AND host_handled = \'n\' AND host_reachable = \'y\' THEN 1 ELSE 0 END)' ), 'hosts_pending' => new Expression( 'SUM(CASE WHEN host_state = 99 THEN 1 ELSE 0 END)' @@ -68,9 +68,6 @@ public function getColumns() 'hosts_total' => new Expression( 'SUM(CASE WHEN host_id IS NOT NULL THEN 1 ELSE 0 END)' ), - 'hosts_unreachable' => new Expression( - 'SUM(CASE WHEN host_state = 2 THEN 1 ELSE 0 END)' - ), 'hosts_up' => new Expression( 'SUM(CASE WHEN host_state = 0 THEN 1 ELSE 0 END)' ), @@ -132,6 +129,7 @@ public function getUnions() 'host_id' => 'host.id', 'host_state' => 'state.soft_state', 'host_handled' => 'state.is_handled', + 'host_reachable' => 'state.is_reachable', 'host_severity' => 'state.severity', 'service_id' => new Expression('NULL'), 'service_state' => new Expression('NULL'), @@ -151,6 +149,7 @@ public function getUnions() 'host_id' => new Expression('NULL'), 'host_state' => new Expression('NULL'), 'host_handled' => new Expression('NULL'), + 'host_reachable' => new Expression('NULL'), 'host_severity' => new Expression('0'), 'service_id' => 'service.id', 'service_state' => 'state.soft_state', @@ -167,6 +166,7 @@ public function getUnions() 'host_id' => new Expression('NULL'), 'host_state' => new Expression('NULL'), 'host_handled' => new Expression('NULL'), + 'host_reachable' => new Expression('NULL'), 'host_severity' => new Expression('0'), 'service_id' => new Expression('NULL'), 'service_state' => new Expression('NULL'), diff --git a/library/Icingadb/Model/HoststateSummary.php b/library/Icingadb/Model/HoststateSummary.php index f59de2740..93268f348 100644 --- a/library/Icingadb/Model/HoststateSummary.php +++ b/library/Icingadb/Model/HoststateSummary.php @@ -23,11 +23,11 @@ public function getSummaryColumns() ), 'hosts_down_handled' => new Expression( 'SUM(CASE WHEN host_state.soft_state = 1' - . ' AND host_state.is_handled = \'y\' THEN 1 ELSE 0 END)' + . ' AND (host_state.is_handled = \'y\' OR host_state.is_reachable = \'n\') THEN 1 ELSE 0 END)' ), 'hosts_down_unhandled' => new Expression( 'SUM(CASE WHEN host_state.soft_state = 1' - . ' AND host_state.is_handled = \'n\' THEN 1 ELSE 0 END)' + . ' AND host_state.is_handled = \'n\' AND host_state.is_reachable = \'y\' THEN 1 ELSE 0 END)' ), 'hosts_event_handler_enabled' => new Expression( 'SUM(CASE WHEN host.event_handler_enabled = \'y\' THEN 1 ELSE 0 END)' @@ -48,9 +48,6 @@ public function getSummaryColumns() 'hosts_total' => new Expression( 'SUM(CASE WHEN host.id IS NOT NULL THEN 1 ELSE 0 END)' ), - 'hosts_unreachable' => new Expression( - 'SUM(CASE WHEN host_state.soft_state = 2 THEN 1 ELSE 0 END)' - ), 'hosts_up' => new Expression( 'SUM(CASE WHEN host_state.soft_state = 0 THEN 1 ELSE 0 END)' ) diff --git a/library/Icingadb/Model/State.php b/library/Icingadb/Model/State.php index 143420d97..160f765de 100644 --- a/library/Icingadb/Model/State.php +++ b/library/Icingadb/Model/State.php @@ -92,6 +92,7 @@ public function getIcon(): ?Icon switch (true) { case $this->is_acknowledged: $icon = new Icon(Icons::IS_ACKNOWLEDGED); + break; case $this->in_downtime: $icon = new Icon( @@ -106,9 +107,21 @@ public function getIcon(): ?Icon break; case $this->is_flapping: $icon = new Icon(Icons::IS_FLAPPING); + + break; + case ! $this->is_reachable: + $icon = new Icon(Icons::HOST_DOWN, [ + 'title' => sprintf( + '%s (%s)', + strtoupper($this->getStateTextTranslated()), + t('is unreachable') + ) + ]); + break; case $this->is_handled: $icon = new Icon(Icons::HOST_DOWN); + break; } diff --git a/library/Icingadb/Widget/Detail/CheckStatistics.php b/library/Icingadb/Widget/Detail/CheckStatistics.php index fc0db5a29..94e325d80 100644 --- a/library/Icingadb/Widget/Detail/CheckStatistics.php +++ b/library/Icingadb/Widget/Detail/CheckStatistics.php @@ -115,6 +115,11 @@ protected function assembleBody(BaseHtmlElement $body) $leftNow = 100; } elseif ($nextCheckTime === null) { $leftNow = 0; + } elseif (! $this->object->state->is_reachable && time() - $executionEndTime > $checkInterval * 2) { + // We have no way of knowing whether the dependency pauses check scheduling. + // The only way to detect this, is to measure how old the last update is. + $nextCheckTime = null; + $leftNow = 0; } else { $leftNow = 100 * (1 - ($nextCheckTime - time()) / ($nextCheckTime - $lastUpdateTime)); if ($leftNow > 100) { diff --git a/library/Icingadb/Widget/ItemList/HostDetailHeader.php b/library/Icingadb/Widget/ItemList/HostDetailHeader.php index 3d10ad3ff..7b187dcb7 100644 --- a/library/Icingadb/Widget/ItemList/HostDetailHeader.php +++ b/library/Icingadb/Widget/ItemList/HostDetailHeader.php @@ -50,7 +50,7 @@ protected function assembleVisual(BaseHtmlElement $visual) } $stateChange->setIcon($this->state->getIcon()); - $stateChange->setHandled($this->state->is_handled); + $stateChange->setHandled($this->state->is_handled || ! $this->state->is_reachable); $visual->addHtml($stateChange); } diff --git a/library/Icingadb/Widget/ItemList/StateListItem.php b/library/Icingadb/Widget/ItemList/StateListItem.php index 7a6a20965..5b54ea174 100644 --- a/library/Icingadb/Widget/ItemList/StateListItem.php +++ b/library/Icingadb/Widget/ItemList/StateListItem.php @@ -77,7 +77,7 @@ protected function assembleVisual(BaseHtmlElement $visual) { $stateBall = new StateBall($this->state->getStateText(), $this->getStateBallSize()); $stateBall->add($this->state->getIcon()); - if ($this->state->is_handled) { + if ($this->state->is_handled || ! $this->state->is_reachable) { $stateBall->getAttributes()->add('class', 'handled'); } diff --git a/library/Icingadb/Widget/ItemTable/HostgroupGridCell.php b/library/Icingadb/Widget/ItemTable/HostgroupGridCell.php index 8d619a811..f9202051e 100644 --- a/library/Icingadb/Widget/ItemTable/HostgroupGridCell.php +++ b/library/Icingadb/Widget/ItemTable/HostgroupGridCell.php @@ -4,6 +4,8 @@ namespace Icinga\Module\Icingadb\Widget\ItemTable; +use ipl\Stdlib\Filter; +use ipl\Web\Filter\QueryString; use ipl\Web\Url; use ipl\Web\Widget\Link; use ipl\Web\Widget\StateBadge; @@ -16,15 +18,17 @@ class HostgroupGridCell extends BaseHostGroupItem protected function createGroupBadge(): Link { - $url = Url::fromPath('icingadb/hosts')->addParams(['hostgroup.name' => $this->item->name]); + $url = Url::fromPath('icingadb/hosts'); + $urlFilter = Filter::all(Filter::equal('hostgroup.name', $this->item->name)); if ($this->item->hosts_down_unhandled > 0) { + $urlFilter->add(Filter::equal('host.state.soft_state', 1)) + ->add(Filter::equal('host.state.is_handled', 'n')) + ->add(Filter::equal('host.state.is_reachable', 'y')); + return new Link( new StateBadge($this->item->hosts_down_unhandled, 'down'), - $url->addParams([ - 'state.soft_state' => 1, - 'state.is_handled' => 'n' - ]), + $url->setQueryString(QueryString::render($urlFilter)), [ 'title' => sprintf( $this->translatePlural( @@ -38,12 +42,15 @@ protected function createGroupBadge(): Link ] ); } elseif ($this->item->hosts_down_handled > 0) { + $urlFilter->add(Filter::equal('host.state.soft_state', 1)) + ->add(Filter::any( + Filter::equal('host.state.is_handled', 'y'), + Filter::equal('host.state.is_reachable', 'n') + )); + return new Link( new StateBadge($this->item->hosts_down_handled, 'down', true), - $url->addParams([ - 'state.soft_state' => 1, - 'state.is_handled' => 'y' - ]), + $url->setQueryString(QueryString::render($urlFilter)), [ 'title' => sprintf( $this->translatePlural( @@ -57,9 +64,11 @@ protected function createGroupBadge(): Link ] ); } elseif ($this->item->hosts_pending > 0) { + $urlFilter->add(Filter::equal('host.state.soft_state', 99)); + return new Link( new StateBadge($this->item->hosts_pending, 'pending'), - $url->addParams(['state.soft_state' => 99]), + $url->setQueryString(QueryString::render($urlFilter)), [ 'title' => sprintf( $this->translatePlural( @@ -73,9 +82,11 @@ protected function createGroupBadge(): Link ] ); } elseif ($this->item->hosts_up > 0) { + $urlFilter->add(Filter::equal('host.state.soft_state', 0)); + return new Link( new StateBadge($this->item->hosts_up, 'up'), - $url->addParams(['state.soft_state' => 0]), + $url->setQueryString(QueryString::render($urlFilter)), [ 'title' => sprintf( $this->translatePlural(