Merge pull request #272 from Icinga/fix/emptyNode-count1-#225

Fix problems with empty nodes
This commit is contained in:
Eric Lippmann 2020-05-14 10:29:55 +02:00 committed by GitHub
commit a212d6ea5e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 34 deletions

View file

@ -11,6 +11,7 @@ class BpNode extends Node
const OP_AND = '&';
const OP_OR = '|';
const OP_NOT = '!';
protected $operator = '&';
protected $url;
protected $info_command;
@ -23,6 +24,7 @@ class BpNode extends Node
protected $childNames = array();
protected $counters;
protected $missing = null;
protected $empty = null;
protected $missingChildren;
protected static $emptyStateSummary = array(
@ -73,9 +75,6 @@ class BpNode extends Node
$this->counters[$state]++;
}
}
if (! $this->hasChildren()) {
$this->counters['MISSING']++;
}
}
return $this->counters;
}
@ -218,11 +217,33 @@ class BpNode extends Node
}
}
$bp->endLoopDetection($this->name);
$this->missing = ! $exists;
$this->missing = ! $exists && ! empty($this->getChildren());
}
return $this->missing;
}
public function isEmpty()
{
$bp = $this->getBpConfig();
$empty = true;
if ($this->countChildren()) {
$bp->beginLoopDetection($this->name);
foreach ($this->getChildren() as $child) {
if ($child instanceof MonitoredNode) {
$empty = false;
break;
} elseif (!$child->isEmpty()) {
$empty = false;
}
}
$bp->endLoopDetection($this->name);
}
$this->empty = $empty;
return $this->empty;
}
public function getMissingChildren()
{
if ($this->missingChildren === null) {
@ -353,10 +374,9 @@ class BpNode extends Node
$sort_states = array();
$lastStateChange = 0;
if (!$this->hasChildren()) {
if ($this->isEmpty()) {
// TODO: delegate this to operators, should mostly fail
$this->setState(self::ICINGA_UNKNOWN);
$this->setMissing();
$this->setState(self::NODE_EMPTY);
return $this;
}

View file

@ -21,6 +21,7 @@ abstract class Node
const ICINGA_DOWN = 1;
const ICINGA_UNREACHABLE = 2;
const ICINGA_PENDING = 99;
const NODE_EMPTY = 128;
/** @var bool Whether to treat acknowledged hosts/services always as UP/OK */
protected static $ackIsOk = false;
@ -42,6 +43,7 @@ abstract class Node
self::ICINGA_CRITICAL => 4,
self::ICINGA_WARNING => 2,
self::ICINGA_OK => 0,
self::NODE_EMPTY => 0
);
/** @var string Alias of the node */
@ -108,6 +110,8 @@ abstract class Node
protected $missing = false;
protected $empty = false;
protected $className = 'unknown';
protected $stateNames = array(
@ -115,7 +119,8 @@ abstract class Node
'WARNING',
'CRITICAL',
'UNKNOWN',
99 => 'PENDING'
99 => 'PENDING',
128 => 'EMPTY'
);
/**

View file

@ -6,6 +6,7 @@ use Icinga\Exception\ProgrammingError;
use Icinga\Module\Businessprocess\BpNode;
use Icinga\Module\Businessprocess\BpConfig;
use Icinga\Module\Businessprocess\ImportedNode;
use Icinga\Module\Businessprocess\MonitoredNode;
use Icinga\Module\Businessprocess\Node;
use Icinga\Module\Businessprocess\Web\Url;
use ipl\Html\BaseHtmlElement;
@ -176,9 +177,13 @@ abstract class Renderer extends HtmlDocument
if ($node->isMissing()) {
$classes = array('missing');
} else {
$classes = array(
strtolower($node->getStateName())
);
if ($node->isEmpty() && ! $node instanceof MonitoredNode) {
$classes = array('empty');
} else {
$classes = array(
strtolower($node->getStateName())
);
}
if ($node->hasMissingChildren()) {
$classes[] = 'missing-children';
}

View file

@ -85,20 +85,30 @@ class NodeTile extends BaseHtmlElement
$this->addActionLinks();
}
}
if (! $node instanceof ImportedNode || $node->getBpConfig()->hasNode($node->getName())) {
$link = $this->getMainNodeLink();
if ($renderer->isBreadcrumb()) {
$link->prepend((new StateBall(strtolower($node->getStateName())))->addAttributes([
'title' => sprintf(
'%s %s',
$node->getStateName(),
DateFormatter::timeSince($node->getLastStateChange())
)
]));
}
$link = $this->getMainNodeLink();
if ($renderer->isBreadcrumb()) {
$link->prepend((new StateBall(strtolower($node->getStateName())))->addAttributes([
'title' => sprintf(
'%s %s',
$node->getStateName(),
DateFormatter::timeSince($node->getLastStateChange())
$this->add($link);
} else {
$this->add(Html::tag(
'a',
Html::tag(
'span',
['style' => 'font-size: 75%'],
sprintf('Trying to access a missing business process node "%s"', $node->getNodeName())
)
]));
));
}
$this->add($link);
if ($node instanceof BpNode && !$renderer->isBreadcrumb()) {
$this->add(Html::tag(
'p',
@ -191,19 +201,21 @@ class NodeTile extends BaseHtmlElement
],
Html::tag('i', ['class' => 'icon icon-sitemap'])
));
if ($node->getBpConfig()->getName() !== $this->renderer->getBusinessProcess()->getName()) {
$this->actions()->add(Html::tag(
'a',
[
'data-base-target' => '_next',
'href' => $this->renderer->getSourceUrl($node)->getAbsoluteUrl(),
'title' => mt(
'businessprocess',
'Show this process as part of its original configuration'
)
],
Html::tag('i', ['class' => 'icon icon-forward'])
));
if ($node instanceof ImportedNode) {
if ($node->getBpConfig()->hasNode($node->getName())) {
$this->actions()->add(Html::tag(
'a',
[
'data-base-target' => '_next',
'href' => $this->renderer->getSourceUrl($node)->getAbsoluteUrl(),
'title' => mt(
'businessprocess',
'Show this process as part of its original configuration'
)
],
Html::tag('i', ['class' => 'icon icon-forward'])
));
}
}
$url = $node->getInfoUrl();

View file

@ -519,6 +519,7 @@ td > a > .badges {
> .pending { background-color: @colorPending; > a { text-shadow: 0 0 1px mix(#000, @colorPending, 40%); }}
> .missing { background-color: @gray-light; > a { text-shadow: 0 0 1px @gray }}
> .addnew { background-color: @icinga-blue; > a { text-shadow: 0 0 1px mix(#000, @icinga-blue, 40%); }}
> .empty { background-color: @gray-light; > a { text-shadow: 0 0 1px @gray }}
}
/*

View file

@ -26,6 +26,10 @@
background-color: @color-pending;
}
&.state-empty {
background-color: @gray-light;
}
&.size-xs {
line-height: 0.75em;
height: 0.75em;