Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show root problem list for objects with problem and are part of dependency #1057

Merged
merged 8 commits into from
Oct 31, 2024
16 changes: 9 additions & 7 deletions application/controllers/ServiceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ public function init()
$name = $this->params->getRequired('name');
$hostName = $this->params->getRequired('host.name');

$query = Service::on($this->getDb())->with([
'state',
'icon_image',
'host',
'host.state',
'timeperiod'
]);
$query = Service::on($this->getDb())
->withColumns(['has_problematic_parent'])
->with([
sukhwinder33445 marked this conversation as resolved.
Show resolved Hide resolved
'state',
'icon_image',
'host',
'host.state',
'timeperiod'
]);
$query
->setResultSetClass(VolatileStateResults::class)
sukhwinder33445 marked this conversation as resolved.
Show resolved Hide resolved
->filter(Filter::all(
Expand Down
100 changes: 63 additions & 37 deletions library/Icingadb/Common/StateBadges.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

namespace Icinga\Module\Icingadb\Common;

use InvalidArgumentException;
use ipl\Html\BaseHtmlElement;
use ipl\Html\Html;
use ipl\Html\HtmlElement;
use ipl\Stdlib\BaseFilter;
use ipl\Stdlib\Filter;
use ipl\Web\Filter\QueryString;
use ipl\Web\Url;
use ipl\Web\Widget\Link;
use ipl\Web\Widget\StateBadge;
Expand All @@ -26,7 +27,7 @@
/** @var string Prefix */
protected $prefix;

/** @var Url Badge link */
/** @var ?Url Badge link */
protected $url;

protected $tag = 'ul';
Expand All @@ -46,13 +47,6 @@
$this->url = $this->getBaseUrl();
}

/**
* Get the badge base URL
*
* @return Url
*/
abstract protected function getBaseUrl(): Url;

/**
* Get the type of the items
*
Expand All @@ -67,21 +61,36 @@
*/
abstract protected function getPrefix(): string;

/**
* Get the badge base URL
*
* @return ?Url
*/
protected function getBaseUrl(): ?Url
{
return null;
}

/**
* Get the integer of the given state text
*
* @param string $state
*
* @return int
*
* @throws InvalidArgumentException if the given state is not valid
*/
abstract protected function getStateInt(string $state): int;
protected function getStateInt(string $state): int
{
throw new InvalidArgumentException(sprintf('%s is not a valid state', $state));
}

/**
* Get the badge URL
*
* @return Url
* @return ?Url
*/
public function getUrl(): Url
public function getUrl(): ?Url
{
return $this->url;
}
Expand All @@ -108,9 +117,9 @@
*
* @return Link
*/
public function createLink($content, Filter\Rule $filter = null): Link
protected function createLink($content, Filter\Rule $filter = null): Link
{
$url = clone $this->getUrl();

Check failure on line 122 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Cannot clone ipl\Web\Url|null.

Check failure on line 122 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.2 on ubuntu-latest

Cannot clone ipl\Web\Url|null.

Check failure on line 122 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.4 on ubuntu-latest

Cannot clone ipl\Web\Url|null.

Check failure on line 122 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Cannot clone ipl\Web\Url|null.

Check failure on line 122 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Cannot clone ipl\Web\Url|null.

Check failure on line 122 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.3 on ubuntu-latest

Cannot clone ipl\Web\Url|null.

Check failure on line 122 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Cannot clone ipl\Web\Url|null.

$urlFilter = Filter::all();
if ($filter !== null) {
Expand All @@ -122,10 +131,10 @@
}

if (! $urlFilter->isEmpty()) {
$url->setFilter($urlFilter);

Check failure on line 134 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Cannot call method setFilter() on ipl\Web\Url|null.

Check failure on line 134 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.2 on ubuntu-latest

Cannot call method setFilter() on ipl\Web\Url|null.

Check failure on line 134 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.4 on ubuntu-latest

Cannot call method setFilter() on ipl\Web\Url|null.

Check failure on line 134 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Cannot call method setFilter() on ipl\Web\Url|null.

Check failure on line 134 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Cannot call method setFilter() on ipl\Web\Url|null.

Check failure on line 134 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.3 on ubuntu-latest

Cannot call method setFilter() on ipl\Web\Url|null.

Check failure on line 134 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Cannot call method setFilter() on ipl\Web\Url|null.
}

return new Link($content, $url);

Check failure on line 137 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Parameter #2 $url of class ipl\Web\Widget\Link constructor expects ipl\Web\Url|string, ipl\Web\Url|null given.

Check failure on line 137 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.2 on ubuntu-latest

Parameter #2 $url of class ipl\Web\Widget\Link constructor expects ipl\Web\Url|string, ipl\Web\Url|null given.

Check failure on line 137 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.4 on ubuntu-latest

Parameter #2 $url of class ipl\Web\Widget\Link constructor expects ipl\Web\Url|string, ipl\Web\Url|null given.

Check failure on line 137 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Parameter #2 $url of class ipl\Web\Widget\Link constructor expects ipl\Web\Url|string, ipl\Web\Url|null given.

Check failure on line 137 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Parameter #2 $url of class ipl\Web\Widget\Link constructor expects ipl\Web\Url|string, ipl\Web\Url|null given.

Check failure on line 137 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.3 on ubuntu-latest

Parameter #2 $url of class ipl\Web\Widget\Link constructor expects ipl\Web\Url|string, ipl\Web\Url|null given.

Check failure on line 137 in library/Icingadb/Common/StateBadges.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Parameter #2 $url of class ipl\Web\Widget\Link constructor expects ipl\Web\Url|string, ipl\Web\Url|null given.
}

/**
Expand All @@ -135,18 +144,23 @@
*
* @return ?BaseHtmlElement
*/
protected function createBadge(string $state)
protected function createBadge(string $state): ?BaseHtmlElement
{
$key = $this->prefix . "_{$state}";
if (empty($this->item->$key)) {
return null;
}

if (isset($this->item->$key) && $this->item->$key) {
return Html::tag('li', $this->createLink(
new StateBadge($this->item->$key, $state),
$stateBadge = new StateBadge($this->item->$key, $state);

if ($this->url !== null) {
$this->createLink(
$stateBadge,
Filter::equal($this->type . '.state.soft_state', $this->getStateInt($state))
));
);
}

return null;
return new HtmlElement('li', null, $stateBadge);
}

/**
Expand All @@ -156,34 +170,46 @@
*
* @return ?BaseHtmlElement
*/
protected function createGroup(string $state)
protected function createGroup(string $state): ?BaseHtmlElement
{
$content = [];
$handledKey = $this->prefix . "_{$state}_handled";
$unhandledKey = $this->prefix . "_{$state}_unhandled";

if (isset($this->item->$unhandledKey) && $this->item->$unhandledKey) {
$content[] = Html::tag('li', $this->createLink(
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_reachable', 'y')
)
));
$unhandledStateBadge = new StateBadge($this->item->$unhandledKey, $state);

if ($this->url !== null) {
$unhandledStateBadge = $this->createLink(
$unhandledStateBadge,
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_reachable', 'y')
)
);
}

$content[] = new HtmlElement('li', null, $unhandledStateBadge);
}

if (isset($this->item->$handledKey) && $this->item->$handledKey) {
nilmerg marked this conversation as resolved.
Show resolved Hide resolved
$content[] = Html::tag('li', $this->createLink(
new StateBadge($this->item->$handledKey, $state, true),
Filter::all(
Filter::equal($this->type . '.state.soft_state', $this->getStateInt($state)),
Filter::any(
Filter::equal($this->type . '.state.is_handled', 'y'),
Filter::equal($this->type . '.state.is_reachable', 'n')
$handledStateBadge = new StateBadge($this->item->$handledKey, $state, true);

if ($this->url !== null) {
$handledStateBadge = $this->createLink(
$handledStateBadge,
Filter::all(
Filter::equal($this->type . '.state.soft_state', $this->getStateInt($state)),
Filter::any(
Filter::equal($this->type . '.state.is_handled', 'y'),
Filter::equal($this->type . '.state.is_reachable', 'n')
)
)
)
));
);
}

$content[] = new HtmlElement('li', null, $handledStateBadge);
}

if (empty($content)) {
Expand Down
94 changes: 94 additions & 0 deletions library/Icingadb/Model/Behavior/HasProblematicParent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

/* Icinga DB Web | (c) 2024 Icinga GmbH | GPLv2 */

namespace Icinga\Module\Icingadb\Model\Behavior;

use Icinga\Module\Icingadb\Model\DependencyEdge;
use ipl\Orm\AliasedExpression;
use ipl\Orm\ColumnDefinition;
use ipl\Orm\Exception\InvalidColumnException;
use ipl\Orm\Query;
use ipl\Sql\Expression;
use ipl\Stdlib\Filter;
use ipl\Orm\Contract\RewriteColumnBehavior;
use ipl\Orm\Contract\QueryAwareBehavior;

/**
* Behavior to check if the service has a problematic parent
*/
class HasProblematicParent implements RewriteColumnBehavior, QueryAwareBehavior
{
/** @var Query */
protected $query;

public function setQuery(Query $query): self
{
$this->query = $query;

return $this;
}

public function rewriteColumn($column, ?string $relation = null): ?AliasedExpression
{
if (! $this->isSelectableColumn($column)) {

Check failure on line 34 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Parameter #1 $name of method Icinga\Module\Icingadb\Model\Behavior\HasProblematicParent::isSelectableColumn() expects string, mixed given.

Check failure on line 34 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.2 on ubuntu-latest

Parameter #1 $name of method Icinga\Module\Icingadb\Model\Behavior\HasProblematicParent::isSelectableColumn() expects string, mixed given.

Check failure on line 34 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.4 on ubuntu-latest

Parameter #1 $name of method Icinga\Module\Icingadb\Model\Behavior\HasProblematicParent::isSelectableColumn() expects string, mixed given.

Check failure on line 34 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Parameter #1 $name of method Icinga\Module\Icingadb\Model\Behavior\HasProblematicParent::isSelectableColumn() expects string, mixed given.

Check failure on line 34 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Parameter #1 $name of method Icinga\Module\Icingadb\Model\Behavior\HasProblematicParent::isSelectableColumn() expects string, mixed given.

Check failure on line 34 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.3 on ubuntu-latest

Parameter #1 $name of method Icinga\Module\Icingadb\Model\Behavior\HasProblematicParent::isSelectableColumn() expects string, mixed given.

Check failure on line 34 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Parameter #1 $name of method Icinga\Module\Icingadb\Model\Behavior\HasProblematicParent::isSelectableColumn() expects string, mixed given.
return null;
}

$resolver = $this->query->getResolver();
if ($relation !== null) {
$serviceTableAlias = $resolver->getAlias($resolver->resolveRelation($relation)->getTarget());
$column = $resolver->qualifyColumnAlias($column, $serviceTableAlias);

Check failure on line 41 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Parameter #1 $alias of method ipl\Orm\Resolver::qualifyColumnAlias() expects string, mixed given.

Check failure on line 41 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.2 on ubuntu-latest

Parameter #1 $alias of method ipl\Orm\Resolver::qualifyColumnAlias() expects string, mixed given.

Check failure on line 41 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.4 on ubuntu-latest

Parameter #1 $alias of method ipl\Orm\Resolver::qualifyColumnAlias() expects string, mixed given.

Check failure on line 41 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Parameter #1 $alias of method ipl\Orm\Resolver::qualifyColumnAlias() expects string, mixed given.

Check failure on line 41 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Parameter #1 $alias of method ipl\Orm\Resolver::qualifyColumnAlias() expects string, mixed given.

Check failure on line 41 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 7.3 on ubuntu-latest

Parameter #1 $alias of method ipl\Orm\Resolver::qualifyColumnAlias() expects string, mixed given.

Check failure on line 41 in library/Icingadb/Model/Behavior/HasProblematicParent.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Parameter #1 $alias of method ipl\Orm\Resolver::qualifyColumnAlias() expects string, mixed given.
} else {
$serviceTableAlias = $resolver->getAlias($this->query->getModel());
}

$subQueryModel = new DependencyEdge();
$subQuery = (new Query())
->setDb($this->query->getDb())
->setModel($subQueryModel)
->columns([new Expression('1')])
->utilize('from')
->limit(1)
->filter(Filter::equal('dependency.state.failed', 'y'));

$subQueryResolver = $subQuery->getResolver()->setAliasPrefix('hpp_');
$subQueryTarget = $subQueryResolver->resolveRelation($subQueryModel->getTableName() . '.from')->getTarget();
$targetForeignKey = $subQueryResolver->qualifyColumn(
'service_id',
$subQueryResolver->getAlias($subQueryTarget)
);

$subQuery->getSelectBase()
->where("$targetForeignKey = {$resolver->qualifyColumn('id', $serviceTableAlias)}");

[$select, $values] = $this->query->getDb()
->getQueryBuilder()
->assembleSelect($subQuery->assembleSelect());

return new AliasedExpression(
$this->query->getDb()->quoteIdentifier([$column]),
"($select)",
null,
...$values
);
}

public function isSelectableColumn(string $name): bool
{
return $name === 'has_problematic_parent';
}

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());
}
}
}
3 changes: 2 additions & 1 deletion library/Icingadb/Model/RedundancyGroupState.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public function createRelations(Relations $relations): void

public function getStateText(): string
{
return $this->failed ? 'problem' : 'ok';
// The method should only be called to fake state balls and not to show the group's state
return $this->failed ? 'unreachable' : 'reachable';
}
}
Loading
Loading