mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-28 08:14:04 +02:00
parent
8fb2c26d7f
commit
fda7acc855
@ -2,7 +2,10 @@
|
||||
|
||||
namespace Icinga\Module\Director\Controllers;
|
||||
|
||||
use dipl\Html\Html;
|
||||
use Icinga\Module\Director\Web\Widget\HealthCheckPluginOutput;
|
||||
use Icinga\Module\Director\Dashboard\Dashboard;
|
||||
use Icinga\Module\Director\Health;
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
use Icinga\Module\Director\Web\Form\DbSelectorForm;
|
||||
|
||||
@ -43,7 +46,19 @@ class DashboardController extends ActionController
|
||||
$dashboard = Dashboard::loadByName($name, $this->db());
|
||||
$this->tabs($dashboard->getTabs())->activate($name);
|
||||
} else {
|
||||
$this->addSingleTab($this->translate('Overview'));
|
||||
$this->tabs()->add('main', [
|
||||
'label' => $this->translate('Overview'),
|
||||
'url' => 'director'
|
||||
])->add('health', [
|
||||
'label' => $this->translate('Health'),
|
||||
'url' => 'director/health'
|
||||
])->activate('main');
|
||||
$state = $this->getHealthState();
|
||||
if ($state->isProblem()) {
|
||||
$this->tabs()->get('health')->setTagParams([
|
||||
'class' => 'state-' . strtolower($state->getName())
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$cntDashboards = 0;
|
||||
@ -66,4 +81,16 @@ class DashboardController extends ActionController
|
||||
$this->content()->add($msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Icinga\Module\Director\CheckPlugin\PluginState
|
||||
*/
|
||||
protected function getHealthState()
|
||||
{
|
||||
$health = new Health();
|
||||
$health->setDbResourceName($this->getDbResourceName());
|
||||
$output = new HealthCheckPluginOutput($health);
|
||||
|
||||
return $output->getState();
|
||||
}
|
||||
}
|
||||
|
37
application/controllers/HealthController.php
Normal file
37
application/controllers/HealthController.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Controllers;
|
||||
|
||||
use dipl\Html\Html;
|
||||
use dipl\Html\Icon;
|
||||
use Icinga\Module\Director\Web\Widget\HealthCheckPluginOutput;
|
||||
use Icinga\Module\Director\Health;
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
|
||||
class HealthController extends ActionController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->tabs()->add('main', [
|
||||
'label' => $this->translate('Overview'),
|
||||
'url' => 'director'
|
||||
])->add('health', [
|
||||
'label' => $this->translate('Health'),
|
||||
'url' => 'director/health'
|
||||
])->activate('health');
|
||||
|
||||
$this->addTitle($this->translate('Director Health'));
|
||||
$health = new Health();
|
||||
$health->setDbResourceName($this->getDbResourceName());
|
||||
$output = new HealthCheckPluginOutput($health);
|
||||
$this->content()->add($output);
|
||||
$this->content()->add([
|
||||
Html::tag('h1', ['class' => 'icon-pin'], $this->translate('Hint: Check Plugin')),
|
||||
Html::tag('p', $this->translate(
|
||||
'Did you know that you can run this entire Health Check'
|
||||
. ' (or just some sections) as an Icinga Check on a regular'
|
||||
. ' base?'
|
||||
))
|
||||
]);
|
||||
}
|
||||
}
|
@ -28,6 +28,11 @@ class CheckResults
|
||||
$this->state = new PluginState(0);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function add(CheckResult $result)
|
||||
{
|
||||
$this->results[] = $result;
|
||||
@ -37,7 +42,26 @@ class CheckResults
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getStateSummaryString()
|
||||
public function getStateCounters()
|
||||
{
|
||||
return $this->stateCounters;
|
||||
}
|
||||
|
||||
public function getProblemSummary()
|
||||
{
|
||||
$summary = [];
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
$count = $this->stateCounters[$i];
|
||||
if ($count === 0) {
|
||||
continue;
|
||||
}
|
||||
$summary[PluginState::create($i)->getName()] = $count;
|
||||
}
|
||||
|
||||
return $summary;
|
||||
}
|
||||
|
||||
public function getStateSummaryString()
|
||||
{
|
||||
$summary = [sprintf(
|
||||
'%d tests OK',
|
||||
|
@ -30,6 +30,11 @@ class PluginState
|
||||
$this->set($state);
|
||||
}
|
||||
|
||||
public function isProblem()
|
||||
{
|
||||
return $this->state > 0;
|
||||
}
|
||||
|
||||
public function set($state)
|
||||
{
|
||||
$this->state = $this->getNumericStateFor($state);
|
||||
|
98
library/Director/Web/Widget/HealthCheckPluginOutput.php
Normal file
98
library/Director/Web/Widget/HealthCheckPluginOutput.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Web\Widget;
|
||||
|
||||
use dipl\Html\Html;
|
||||
use dipl\Html\HtmlDocument;
|
||||
use dipl\Html\HtmlString;
|
||||
use dipl\Translation\TranslationHelper;
|
||||
use Icinga\Module\Director\CheckPlugin\PluginState;
|
||||
use Icinga\Module\Director\Health;
|
||||
|
||||
class HealthCheckPluginOutput extends HtmlDocument
|
||||
{
|
||||
use TranslationHelper;
|
||||
|
||||
/** @var Health */
|
||||
protected $health;
|
||||
|
||||
/** @var PluginState */
|
||||
protected $state;
|
||||
|
||||
public function __construct(Health $health)
|
||||
{
|
||||
$this->state = new PluginState('OK');
|
||||
$this->health = $health;
|
||||
$this->process();
|
||||
}
|
||||
|
||||
protected function process()
|
||||
{
|
||||
$checks = $this->health->getAllChecks();
|
||||
|
||||
foreach ($checks as $check) {
|
||||
$this->add([
|
||||
$title = Html::tag('h2', $check->getName()),
|
||||
$ul = Html::tag('ul', ['class' => 'health-check-result'])
|
||||
]);
|
||||
|
||||
$problems = $check->getProblemSummary();
|
||||
if (! empty($problems)) {
|
||||
$badges = Html::tag('span', ['class' => 'title-badges']);
|
||||
foreach ($problems as $state => $count) {
|
||||
$badges->add(Html::tag('span', [
|
||||
'class' => ['badge', 'state-' . strtolower($state)],
|
||||
'title' => $this->translate('Critical Checks'),
|
||||
], $count));
|
||||
}
|
||||
$title->add($badges);
|
||||
}
|
||||
|
||||
foreach ($check->getResults() as $result) {
|
||||
$ul->add(Html::tag('li', [
|
||||
$this->colorizeState($result->getState()->getName()),
|
||||
$this->colorizeStates($result->getOutput())
|
||||
])->setSeparator(' '));
|
||||
}
|
||||
$this->state->raise($check->getState());
|
||||
}
|
||||
}
|
||||
|
||||
public function getState()
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
protected function colorizeStates($string)
|
||||
{
|
||||
$string = Html::escape($string);
|
||||
$string = preg_replace_callback(
|
||||
"/'([^']+)'/",
|
||||
[$this, 'highlightNames'],
|
||||
$string
|
||||
);
|
||||
|
||||
$string = preg_replace_callback(
|
||||
'/(OK|WARNING|CRITICAL|UNKNOWN)/',
|
||||
[$this, 'getColorized'],
|
||||
$string
|
||||
);
|
||||
|
||||
return new HtmlString($string);
|
||||
}
|
||||
|
||||
protected function colorizeState($state)
|
||||
{
|
||||
return Html::tag('span', ['class' => 'badge state-' . strtolower($state)], $state);
|
||||
}
|
||||
|
||||
protected function highlightNames($match)
|
||||
{
|
||||
return '"' . Html::tag('strong', $match[1]) . '"';
|
||||
}
|
||||
|
||||
protected function getColorized($match)
|
||||
{
|
||||
return $this->colorizeState($match[1]);
|
||||
}
|
||||
}
|
@ -599,6 +599,26 @@ a {
|
||||
color: @color-pending;
|
||||
}
|
||||
}
|
||||
ul.tabs a.state-critical {
|
||||
background-color: @colorCritical;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
ul.tabs a.state-warning {
|
||||
background-color: @colorWarning;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
ul.tabs a.state-ok {
|
||||
background-color: @colorOk;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
ul.tabs a.state-unknown {
|
||||
background-color: @colorUnknown;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
a:hover::before {
|
||||
text-decoration: none;
|
||||
@ -1033,6 +1053,25 @@ form div.hint {
|
||||
|
||||
/* END of Forms */
|
||||
|
||||
ul.health-check-result {
|
||||
list-style-type: none;
|
||||
padding-left: 2em;
|
||||
margin-bottom: 2em;
|
||||
li {
|
||||
line-height: 2em;
|
||||
}
|
||||
.badge {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.title-badges {
|
||||
.badge {
|
||||
font-size: 0.75em;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
span.error {
|
||||
color: @colorCritical;
|
||||
|
||||
@ -1040,6 +1079,7 @@ span.error {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
p.error {
|
||||
color: white;
|
||||
padding: 1em 2em;
|
||||
|
Loading…
x
Reference in New Issue
Block a user