diff --git a/library/Businessprocess/BpNode.php b/library/Businessprocess/BpNode.php index 2644d0b..9aeaab8 100644 --- a/library/Businessprocess/BpNode.php +++ b/library/Businessprocess/BpNode.php @@ -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; } diff --git a/library/Businessprocess/Node.php b/library/Businessprocess/Node.php index a68adc2..7849a7c 100644 --- a/library/Businessprocess/Node.php +++ b/library/Businessprocess/Node.php @@ -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' ); /** diff --git a/library/Businessprocess/Renderer/Renderer.php b/library/Businessprocess/Renderer/Renderer.php index c6fbbb6..4c9a8de 100644 --- a/library/Businessprocess/Renderer/Renderer.php +++ b/library/Businessprocess/Renderer/Renderer.php @@ -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'; } diff --git a/library/Businessprocess/Renderer/TileRenderer/NodeTile.php b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php index e4f378f..b393724 100644 --- a/library/Businessprocess/Renderer/TileRenderer/NodeTile.php +++ b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php @@ -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(); diff --git a/public/css/module.less b/public/css/module.less index 5b3584e..40d71f7 100644 --- a/public/css/module.less +++ b/public/css/module.less @@ -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 }} } /* diff --git a/public/css/state-ball.less b/public/css/state-ball.less index 54a8e7a..bc05059 100644 --- a/public/css/state-ball.less +++ b/public/css/state-ball.less @@ -26,6 +26,10 @@ background-color: @color-pending; } + &.state-empty { + background-color: @gray-light; + } + &.size-xs { line-height: 0.75em; height: 0.75em;