From 18db2a7b91f7db69edba5514fef322cf1f3a90c4 Mon Sep 17 00:00:00 2001 From: raviks789 Date: Thu, 26 Sep 2024 12:11:36 +0200 Subject: [PATCH] Add `HasRootProblem` behavior for service --- application/controllers/ServiceController.php | 4 +- .../Model/Behavior/HasRootProblem.php | 75 +++++++++++++++++++ library/Icingadb/Model/Service.php | 3 + .../Icingadb/Widget/Detail/ObjectDetail.php | 6 +- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 library/Icingadb/Model/Behavior/HasRootProblem.php diff --git a/application/controllers/ServiceController.php b/application/controllers/ServiceController.php index 8867e9185..ebe83773b 100644 --- a/application/controllers/ServiceController.php +++ b/application/controllers/ServiceController.php @@ -38,7 +38,9 @@ public function init() $name = $this->params->getRequired('name'); $hostName = $this->params->getRequired('host.name'); - $query = Service::on($this->getDb())->with([ + $query = Service::on($this->getDb()) + ->withColumns(['has_root_problem']) + ->with([ 'state', 'icon_image', 'host', diff --git a/library/Icingadb/Model/Behavior/HasRootProblem.php b/library/Icingadb/Model/Behavior/HasRootProblem.php new file mode 100644 index 000000000..0945876e8 --- /dev/null +++ b/library/Icingadb/Model/Behavior/HasRootProblem.php @@ -0,0 +1,75 @@ +query = $query; + + return $this; + } + + public function rewriteColumn($column, ?string $relation = null) + { + if ($this->isSelectableColumn($column)) { + $path = 'from.dependency_node'; + $subQueryRelation = $relation !== null ? $relation . $path : $path; + $subQuery = $this->query->createSubQuery(new DependencyEdge(), $subQueryRelation) + ->limit(1) + ->columns([new Expression('1')]); + + $subQuery->getSelectBase()->join( + ['root_dependency' => 'dependency'], + [$subQuery->getResolver()->getAlias($subQuery->getModel()) . '.dependency_id = root_dependency.id'] + )->join( + ['root_dependency_state' => 'dependency_state'], + ['root_dependency.id = root_dependency_state.dependency_id'] + )->where(new Expression("root_dependency_state.failed = 'y'")); + + $column = $relation !== null ? str_replace('.', '_', $relation) . "_$column" : $column; + + $alias = $this->query->getDb()->quoteIdentifier([$column]); + + list($select, $values) = $this->query->getDb() + ->getQueryBuilder() + ->assembleSelect($subQuery->assembleSelect()); + + return new AliasedExpression($alias, "($select)", null, ...$values); + } + } + + public function isSelectableColumn(string $name): bool + { + return $name === 'has_root_problem'; + } + + public function rewriteColumnDefinition(ColumnDefinition $def, string $relation): void + { + } + + public function rewriteCondition(Filter\Condition $condition, $relation = null) + { + $column = substr($condition->getColumn(), strlen($relation)); + + if ($this->isSelectableColumn($column)) { + throw new InvalidColumnException($column, $this->query->getModel()); + } + } +} diff --git a/library/Icingadb/Model/Service.php b/library/Icingadb/Model/Service.php index 5a0d52843..456dcd993 100644 --- a/library/Icingadb/Model/Service.php +++ b/library/Icingadb/Model/Service.php @@ -6,6 +6,7 @@ use Icinga\Module\Icingadb\Common\Auth; use Icinga\Module\Icingadb\Model\Behavior\BoolCast; +use Icinga\Module\Icingadb\Model\Behavior\HasRootProblem; use Icinga\Module\Icingadb\Model\Behavior\ReRoute; use ipl\Orm\Behavior\Binary; use ipl\Orm\Behaviors; @@ -191,6 +192,8 @@ public function createBehaviors(Behaviors $behaviors) 'zone_id', 'command_endpoint_id' ])); + + $behaviors->add(new HasRootProblem()); } public function createDefaults(Defaults $defaults) diff --git a/library/Icingadb/Widget/Detail/ObjectDetail.php b/library/Icingadb/Widget/Detail/ObjectDetail.php index 0c95cd903..bb421ba63 100644 --- a/library/Icingadb/Widget/Detail/ObjectDetail.php +++ b/library/Icingadb/Widget/Detail/ObjectDetail.php @@ -21,6 +21,7 @@ use Icinga\Module\Icingadb\Common\Macros; use Icinga\Module\Icingadb\Compat\CompatHost; use Icinga\Module\Icingadb\Model\CustomvarFlat; +use Icinga\Module\Icingadb\Model\Service; use Icinga\Module\Icingadb\Model\UnreachableParent; use Icinga\Module\Icingadb\Web\Navigation\Action; use Icinga\Module\Icingadb\Widget\ItemList\DependencyNodeList; @@ -606,7 +607,10 @@ protected function fetchCustomVars() protected function createRootProblems(): ?array { - if ($this->object->state->is_reachable) { + if ( + $this->object->state->is_reachable + || ($this->object instanceof Service && ! $this->object->has_root_problem) + ) { return null; }