monitoring: Add new multiselection controllers

This commit is contained in:
Eric Lippmann 2014-09-23 22:47:26 -07:00
parent 1710a50d5c
commit 3229e5e587
9 changed files with 729 additions and 5 deletions

View File

@ -0,0 +1,157 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Data\Filter\Filter;
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Form\Command\Object\AcknowledgeProblemCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\CheckNowCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ObjectsCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\RemoveAcknowledgementCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleHostCheckCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleHostDowntimeCommandForm;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Module\Monitoring\Object\HostList;
use Icinga\Web\Url;
use Icinga\Web\Widget\Chart\InlinePie;
class Monitoring_HostsController extends Controller
{
/**
* @var HostList
*/
protected $hostList;
public function init()
{
$hostList = new HostList($this->backend);
$hostList->setFilter(Filter::fromQueryString((string) $this->params));
$this->hostList = $hostList;
}
protected function handleCommandForm(ObjectsCommandForm $form)
{
$form
->setObjects($this->hostList)
->setRedirectUrl(Url::fromPath('monitoring/hosts/show')->setParams($this->params))
->handleRequest();
$this->view->form = $form;
$this->_helper->viewRenderer('partials/command-form', null, true);
return $form;
}
public function showAction()
{
$this->setAutorefreshInterval(15);
$checkNowForm = new CheckNowCommandForm();
$checkNowForm
->setObjects($this->hostList)
->handleRequest();
$this->view->checkNowForm = $checkNowForm;
$this->hostList->setColumns(array(
'host_name',
'host_state',
'host_problem',
'host_handled',
'host_acknowledged',
'host_in_downtime'/*,
'host_passive_checks_enabled',
'host_notifications_enabled',
'host_event_handler_enabled',
'host_flap_detection_enabled',
'host_active_checks_enabled',
'host_obsessing'*/
));
$unhandledObjects = array();
$acknowledgedObjects = array();
$objectsInDowntime = array();
$hostStates = array(
Host::getStateText(Host::STATE_UP) => 0,
Host::getStateText(Host::STATE_DOWN) => 0,
Host::getStateText(Host::STATE_UNREACHABLE) => 0,
Host::getStateText(Host::STATE_PENDING) => 0,
);
foreach ($this->hostList as $host) {
/** @var Service $host */
if ((bool) $host->problem === true && (bool) $host->handled === false) {
$unhandledObjects[] = $host;
}
if ((bool) $host->acknowledged === true) {
$acknowledgedObjects[] = $host;
}
if ((bool) $host->in_downtime === true) {
$objectsInDowntime[] = $host;
}
++$hostStates[$host::getStateText($host->state)];
}
if (! empty($acknowledgedObjects)) {
$removeAckForm = new RemoveAcknowledgementCommandForm();
$removeAckForm
->setObjects($acknowledgedObjects)
->handleRequest();
$this->view->removeAckForm = $removeAckForm;
}
$this->setAutorefreshInterval(15);
$this->view->listAllLink = Url::fromRequest()->setPath('monitoring/list/hosts');
$this->view->rescheduleAllLink = Url::fromRequest()->setPath('monitoring/hosts/reschedule-check');
$this->view->downtimeAllLink = Url::fromRequest()->setPath('monitoring/hosts/schedule-downtime');
$this->view->hostStates = $hostStates;
$this->view->objects = $this->hostList;
$this->view->unhandledObjects = $unhandledObjects;
$this->view->acknowledgeUnhandledLink = Url::fromRequest()
->setPath('monitoring/hosts/acknowledge-problem')
->addParams(array('host_problem' => 1, 'host_handled' => 0));
$this->view->downtimeUnhandledLink = Url::fromRequest()
->setPath('monitoring/hosts/schedule-downtime')
->addParams(array('host_problem' => 1, 'host_handled' => 0));
$this->view->acknowledgedObjects = $acknowledgedObjects;
$this->view->objectsInDowntime = $objectsInDowntime;
$this->view->inDowntimeLink = Url::fromRequest()
->setPath('monitoring/list/downtimes');
$this->view->havingCommentsLink = Url::fromRequest()
->setPath('monitoring/list/comments');
$this->view->hostStatesPieChart = $this->createPieChart(
$hostStates,
$this->translate('Host State'),
array('#44bb77', '#FF5566', '#E066FF', '#77AAFF')
);
}
protected function createPieChart(array $states, $title, array $colors)
{
$chart = new InlinePie(array_values($states), $title, $colors);
return $chart
->setLabel(array_map('strtoupper', array_keys($states)))
->setHeight(100)
->setWidth(100)
->setTitle($title);
}
/**
* Acknowledge host problems
*/
public function acknowledgeProblemAction()
{
$this->view->title = $this->translate('Acknowledge Host Problems');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
}
/**
* Reschedule host checks
*/
public function rescheduleCheckAction()
{
$this->view->title = $this->translate('Reschedule Host Checks');
$this->handleCommandForm(new ScheduleHostCheckCommandForm());
}
/**
* Schedule host downtimes
*/
public function scheduleDowntimeAction()
{
$this->view->title = $this->translate('Schedule Host Downtimes');
$this->handleCommandForm(new ScheduleHostDowntimeCommandForm());
}
}

View File

@ -0,0 +1,177 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Data\Filter\Filter;
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Form\Command\Object\AcknowledgeProblemCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\CheckNowCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ObjectsCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\RemoveAcknowledgementCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleServiceCheckCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleServiceDowntimeCommandForm;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Module\Monitoring\Object\ServiceList;
use Icinga\Web\Url;
use Icinga\Web\Widget\Chart\InlinePie;
class Monitoring_ServicesController extends Controller
{
/**
* @var ServiceList
*/
protected $serviceList;
public function init()
{
$serviceList = new ServiceList($this->backend);
$serviceList->setFilter(Filter::fromQueryString((string) $this->params));
$this->serviceList = $serviceList;
}
protected function handleCommandForm(ObjectsCommandForm $form)
{
$form
->setObjects($this->serviceList)
->setRedirectUrl(Url::fromPath('monitoring/services/show')->setParams($this->params))
->handleRequest();
$this->view->form = $form;
$this->_helper->viewRenderer('partials/command-form', null, true);
return $form;
}
public function showAction()
{
$this->setAutorefreshInterval(15);
$checkNowForm = new CheckNowCommandForm();
$checkNowForm
->setObjects($this->serviceList)
->handleRequest();
$this->view->checkNowForm = $checkNowForm;
$this->serviceList->setColumns(array(
'host_name',
'host_state',
'service_description',
'service_state',
'service_problem',
'service_handled',
'service_acknowledged',
'service_in_downtime'/*,
'service_passive_checks_enabled',
'service_notifications_enabled',
'service_event_handler_enabled',
'service_flap_detection_enabled',
'service_active_checks_enabled',
'service_obsessing'*/
));
$unhandledObjects = array();
$acknowledgedObjects = array();
$objectsInDowntime = array();
$serviceStates = array(
Service::getStateText(Service::STATE_OK) => 0,
Service::getStateText(Service::STATE_WARNING) => 0,
Service::getStateText(Service::STATE_CRITICAL) => 0,
Service::getStateText(Service::STATE_UNKNOWN) => 0,
Service::getStateText(Service::STATE_PENDING) => 0
);
$knownHostStates = array();
$hostStates = array(
Host::getStateText(Host::STATE_UP) => 0,
Host::getStateText(Host::STATE_DOWN) => 0,
Host::getStateText(Host::STATE_UNREACHABLE) => 0,
Host::getStateText(Host::STATE_PENDING) => 0,
);
foreach ($this->serviceList as $service) {
/** @var Service $service */
if ((bool) $service->problem === true && (bool) $service->handled === false) {
$unhandledObjects[] = $service;
}
if ((bool) $service->acknowledged === true) {
$acknowledgedObjects[] = $service;
}
if ((bool) $service->in_downtime === true) {
$objectsInDowntime[] = $service;
}
++$serviceStates[$service::getStateText($service->state)];
if (! isset($knownHostStates[$service->getHost()->getName()])) {
$knownHostStates[$service->getHost()->getName()] = true;
++$hostStates[$service->getHost()->getStateText($service->host_state)];
}
}
if (! empty($acknowledgedObjects)) {
$removeAckForm = new RemoveAcknowledgementCommandForm();
$removeAckForm
->setObjects($acknowledgedObjects)
->handleRequest();
$this->view->removeAckForm = $removeAckForm;
}
$this->setAutorefreshInterval(15);
$this->view->listAllLink = Url::fromRequest()->setPath('monitoring/list/services');
$this->view->rescheduleAllLink = Url::fromRequest()->setPath('monitoring/services/reschedule-check');
$this->view->downtimeAllLink = Url::fromRequest()->setPath('monitoring/services/schedule-downtime');
$this->view->hostStates = $hostStates;
$this->view->serviceStates = $serviceStates;
$this->view->objects = $this->serviceList;
$this->view->unhandledObjects = $unhandledObjects;
$this->view->acknowledgeUnhandledLink = Url::fromRequest()
->setPath('monitoring/services/acknowledge-problem')
->addParams(array('service_problem' => 1, 'service_handled' => 0));
$this->view->downtimeUnhandledLink = Url::fromRequest()
->setPath('monitoring/services/schedule-downtime')
->addParams(array('service_problem' => 1, 'service_handled' => 0));
$this->view->acknowledgedObjects = $acknowledgedObjects;
$this->view->objectsInDowntime = $objectsInDowntime;
$this->view->inDowntimeLink = Url::fromRequest()
->setPath('monitoring/list/downtimes');
$this->view->havingCommentsLink = Url::fromRequest()
->setPath('monitoring/list/comments');
$this->view->serviceStatesPieChart = $this->createPieChart(
$serviceStates,
$this->translate('Service State'),
array('#44bb77', '#FFCC66', '#FF5566', '#E066FF', '#77AAFF')
);
$this->view->hostStatesPieChart = $this->createPieChart(
$hostStates,
$this->translate('Host State'),
array('#44bb77', '#FF5566', '#E066FF', '#77AAFF')
);
}
protected function createPieChart(array $states, $title, array $colors)
{
$chart = new InlinePie(array_values($states), $title, $colors);
return $chart
->setLabel(array_map('strtoupper', array_keys($states)))
->setHeight(100)
->setWidth(100)
->setTitle($title);
}
/**
* Acknowledge service problems
*/
public function acknowledgeProblemAction()
{
$this->view->title = $this->translate('Acknowledge Service Problems');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
}
/**
* Reschedule service checks
*/
public function rescheduleCheckAction()
{
$this->view->title = $this->translate('Reschedule Service Checks');
$this->handleCommandForm(new ScheduleServiceCheckCommandForm());
}
/**
* Schedule service downtimes
*/
public function scheduleDowntimeAction()
{
$this->view->title = $this->translate('Schedule Service Downtimes');
$this->handleCommandForm(new ScheduleServiceDowntimeCommandForm());
}
}

View File

@ -0,0 +1,118 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<?php if (count($objects) === 0): ?>
<?= $this->translate('No hosts matching the filter') ?>
<?php else: ?>
<h1><?= sprintf($this->translate('Summary For %u Hosts'), count($objects)) ?></h1>
<table style="width: 100%; font-size: 0.8em;">
<tr>
<th colspan="2"><?= sprintf($this->translate('%u Hosts'), array_sum(array_values($hostStates))) ?></th>
</tr>
<tr>
<td align="center">
<?= $this->hostStatesPieChart ?>
</td>
<td>
<?php
foreach (array_filter($hostStates) as $text => $count) {
echo sprintf('%s: %u<br>', strtoupper($text), $count);
}
?>
</td>
</tr>
</table>
<div>
<a href="<?= $listAllLink ?>" title="<?= $this->translate('List all') ?>">
<?= $this->translate('List all') ?>
</a>
</div>
<hr>
<div>
<?= $checkNowForm ?>
</div>
<div>
<a href="<?= $rescheduleAllLink ?>">
<?= $this->icon('reschedule_petrol.png') ?>
<?= $this->translate('Reschedule host checks') ?>
</a>
</div>
<div>
<a href="<?= $downtimeAllLink ?>">
<?= $this->icon('in_downtime_petrol.png') ?>
<?= $this->translate('Schedule host downtimes') ?>
</a>
</div>
<?php if (! empty($unhandledObjects)): ?>
<h2>
<?= sprintf(
$this->translatePlural(
'%u Unhandled Host Problem',
'%u Unhandled Host Problems',
count($unhandledObjects)
),
count($unhandledObjects)
) ?>
</h2>
<div>
<a href="<?= $downtimeUnhandledLink ?>"
title="<?= $this->translate('Schedule downtimes for unhandled problem hosts') ?>">
<?= $this->icon('in_downtime_petrol.png') ?>
<?= $this->translate('Schedule downtimes for unhandled problem hosts') ?>
</a>
</div>
<div>
<a href="<?= $acknowledgeUnhandledLink ?>"
title="<?= $this->translate('Acknowledge unhandled problem hosts') ?>">
<?= $this->icon('acknowledgement_petrol.png') ?>
<?= $this->translate('Acknowledge unhandled problem hosts') ?>
</a>
</div>
<?php endif ?>
<?php if (! empty($acknowledgedObjects)): ?>
<h2>
<?= sprintf(
$this->translatePlural(
'%u Acknowledged Host Problem',
'%u Acknowledged Host Problems',
count($acknowledgedObjects)
),
count($acknowledgedObjects)
) ?>
</h2>
<div>
<?= $removeAckForm ?>
</div>
<?php endif ?>
<?php if (! empty($objectsInDowntime)): ?>
<h2>
<a href="<?= $inDowntimeLink ?>"
title="<?= $this->translate('Hosts in downtime') ?>">
<?= $this->icon('in_downtime_petrol.png') ?>
<?= $this->translate(sprintf('%u hosts are in downtime', count($objectsInDowntime))) ?>
</a>
</h2>
<?php endif ?>
<?php if (count($objects->getComments())): ?>
<h2>
<a href="<?= $havingCommentsLink ?>"
title="<?= $this->translate('Comments') ?>">
<?= $this->icon('comment.png') ?>
<?= $this->translate(sprintf('%u comments', count($objects->getComments()))) ?>
</a>
</h2>
<?php endif ?>
<?php endif ?>
</div>

View File

@ -15,7 +15,7 @@ if ($this->compact): ?>
<?= $this->widget('limiter')->setMaxLimit($this->hosts->count()) ?>
<?= $this->paginationControl($hosts, null, null, array('preserve' => $this->preserve)) ?>
<?= $this->selectionToolbar('multi', $this->href('monitoring/multi/host?' . $this->filter->toQueryString())) ?>
<?= $this->selectionToolbar('multi', $this->href('monitoring/hosts/show?' . $this->filter->toQueryString())) ?>
</div>
<div class="content">
@ -36,14 +36,14 @@ if ($hosts->count() === 0) {
<table
data-base-target="_next"
class="action multiselect"
data-icinga-multiselect-url="<?= $this->href('/monitoring/multi/host') ?>"
data-icinga-multiselect-url="<?= $this->href('monitoring/hosts/show') ?>"
data-icinga-multiselect-data="host"
>
<tbody>
<?php foreach($hosts as $host):
$hostStateName = strtolower($this->util()->getHostStateName($host->host_state));
$hostLink = $this->href('/monitoring/show/host', array('host' => $host->host_name));
$hostLink = $this->href('monitoring/host/show', array('host' => $host->host_name));
$icons = array();
if (! $host->host_handled && $host->host_state > 0){

View File

@ -19,7 +19,7 @@ if (!$this->compact): ?>
<?= $this->widget('limiter')->setCurrentPageCount($this->services->count()) ?>
<?= $this->paginationControl($services, null, null, array('preserve' => $this->preserve)) ?>
<?php endif ?>
<?= $this->selectionToolbar('multi', $this->href('monitoring/multi/service?' . $this->filter->toQueryString())) ?>
<?= $this->selectionToolbar('multi', $this->href('monitoring/services/show?' . $this->filter->toQueryString())) ?>
</div>
<div class="content">
@ -30,7 +30,7 @@ if (!$this->compact): ?>
<?php endif ?>
<table data-base-target="_next"
class="action multiselect <?php if ($this->compact): ?> compact<?php endif ?>" style="table-layout: auto;"
data-icinga-multiselect-url="<?= $this->href("monitoring/multi/service") ?>"
data-icinga-multiselect-url="<?= $this->href("monitoring/services/show") ?>"
data-icinga-multiselect-data="service,host">
<tbody>
<?php

View File

@ -0,0 +1,131 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<?php if (count($objects) === 0): ?>
<?= $this->translate('No services matching the filter') ?>
<?php else: ?>
<h1><?= sprintf($this->translate('Summary For %u Services'), count($objects)) ?></h1>
<table style="width: 100%; font-size: 0.8em;">
<tr>
<th colspan="2"><?= sprintf($this->translate('%u Services'), array_sum(array_values($serviceStates))) ?></th>
<th colspan="2"><?= sprintf($this->translate('%u Hosts'), array_sum(array_values($hostStates))) ?></th>
</tr>
<tr>
<td align="center">
<?= $this->serviceStatesPieChart ?>
</td>
<td>
<?php
foreach (array_filter($serviceStates) as $text => $count) {
echo sprintf('%s: %u<br>', strtoupper($text), $count);
}
?>
</td>
<td align="center">
<?= $this->hostStatesPieChart ?>
</td>
<td>
<?php
foreach (array_filter($hostStates) as $text => $count) {
echo sprintf('%s: %u<br>', strtoupper($text), $count);
}
?>
</td>
</tr>
</table>
<div>
<a href="<?= $listAllLink ?>" title="<?= $this->translate('List all') ?>">
<?= $this->translate('List all') ?>
</a>
</div>
<hr>
<div>
<?= $checkNowForm ?>
</div>
<div>
<a href="<?= $rescheduleAllLink ?>">
<?= $this->icon('reschedule_petrol.png') ?>
<?= $this->translate('Reschedule service checks') ?>
</a>
</div>
<div>
<a href="<?= $downtimeAllLink ?>">
<?= $this->icon('in_downtime_petrol.png') ?>
<?= $this->translate('Schedule service downtimes') ?>
</a>
</div>
<?php if (! empty($unhandledObjects)): ?>
<h2>
<?= sprintf(
$this->translatePlural(
'%u Unhandled Service Problem',
'%u Unhandled Service Problems',
count($unhandledObjects)
),
count($unhandledObjects)
) ?>
</h2>
<div>
<a href="<?= $downtimeUnhandledLink ?>"
title="<?= $this->translate('Schedule downtimes for unhandled problem services') ?>">
<?= $this->icon('in_downtime_petrol.png') ?>
<?= $this->translate('Schedule downtimes for unhandled problem services') ?>
</a>
</div>
<div>
<a href="<?= $acknowledgeUnhandledLink ?>"
title="<?= $this->translate('Acknowledge unhandled problem services') ?>">
<?= $this->icon('acknowledgement_petrol.png') ?>
<?= $this->translate('Acknowledge unhandled problem services') ?>
</a>
</div>
<?php endif ?>
<?php if (! empty($acknowledgedObjects)): ?>
<h2>
<?= sprintf(
$this->translatePlural(
'%u Acknowledged Service Problem',
'%u Acknowledged Service Problems',
count($acknowledgedObjects)
),
count($acknowledgedObjects)
) ?>
</h2>
<div>
<?= $removeAckForm ?>
</div>
<?php endif ?>
<?php if (! empty($objectsInDowntime)): ?>
<h2>
<a href="<?= $inDowntimeLink ?>"
title="<?= $this->translate('Services in downtime') ?>">
<?= $this->icon('in_downtime_petrol.png') ?>
<?= $this->translate(sprintf('%u services are in downtime', count($objectsInDowntime))) ?>
</a>
</h2>
<?php endif ?>
<?php if (count($objects->getComments())): ?>
<h2>
<a href="<?= $havingCommentsLink ?>"
title="<?= $this->translate('Comments') ?>">
<?= $this->icon('comment.png') ?>
<?= $this->translate(sprintf('%u comments', count($objects->getComments()))) ?>
</a>
</h2>
<?php endif ?>
<?php endif ?>
</div>

View File

@ -0,0 +1,27 @@
<?php
namespace Icinga\Module\Monitoring\Object;
/**
* A host list
*/
class HostList extends ObjectList
{
protected $dataViewName = 'hostStatus';
protected $columns = array('host_name');
protected function fetchObjects()
{
$hosts = array();
$query = $this->backend->select()->from($this->dataViewName, $this->columns)->applyFilter($this->filter)
->getQuery()->getSelectQuery()->query();
foreach ($query as $row) {
/** @var object $row */
$host = new Host($this->backend, $row->host_name);
$host->setProperties($row);
$hosts[] = $host;
}
return $hosts;
}
}

View File

@ -0,0 +1,87 @@
<?php
namespace Icinga\Module\Monitoring\Object;
use ArrayIterator;
use Countable;
use IteratorAggregate;
use Icinga\Module\Monitoring\Backend;
abstract class ObjectList implements Countable, IteratorAggregate
{
protected $dataViewName;
protected $backend;
protected $columns;
protected $filter;
protected $objects;
protected $count;
public function __construct(Backend $backend)
{
$this->backend = $backend;
}
public function setColumns(array $columns)
{
$this->columns = $columns;
return $this;
}
public function getColumns()
{
return $this->columns;
}
public function setFilter($filter)
{
$this->filter = $filter;
return $this;
}
public function getFilter()
{
return $this->filter;
}
abstract protected function fetchObjects();
public function fetch()
{
if ($this->objects === null) {
$this->objects = $this->fetchObjects();
}
return $this->objects;
}
public function count()
{
if ($this->count === null) {
$this->count = (int) $this->backend->select()->from($this->dataViewName)->applyFilter($this->filter)
->getQuery()->count();
}
return $this->count;
}
public function getIterator()
{
if ($this->objects === null) {
$this->fetch();
}
return new ArrayIterator($this->objects);
}
/**
* Get the comments
*
* @return \Icinga\Module\Monitoring\DataView\Comment
*/
public function getComments()
{
return $this->backend->select()->from('comment')->applyFilter($this->filter);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Icinga\Module\Monitoring\Object;
/**
* A service list
*/
class ServiceList extends ObjectList
{
protected $dataViewName = 'serviceStatus';
protected $columns = array('host_name', 'service_description');
protected function fetchObjects()
{
$services = array();
$query = $this->backend->select()->from($this->dataViewName, $this->columns)->applyFilter($this->filter)
->getQuery()->getSelectQuery()->query();
foreach ($query as $row) {
/** @var object $row */
$service = new Service($this->backend, $row->host_name, $row->service_description);
$service->setProperties($row);
$services[] = $service;
}
return $services;
}
}