parent
4f3f5c3aad
commit
3f48a29c05
|
@ -45,14 +45,16 @@ class Zend_View_Helper_FormTriStateCheckbox extends Zend_View_Helper_FormElement
|
|||
{
|
||||
$class = "";
|
||||
$xhtml = '<div data-icinga-component="app/triStateCheckbox" class="form-group">'
|
||||
. '<div>' . ($value == 1 ? '{{ICON_ENABLED}}' : ($value == 0 ? '{{ICON_DISABLED}}' : '{{ICON_BLANK}}' )) . '</div>'
|
||||
. '<div>' . ($value == 1 ? '{{ICON_ENABLED}}' : ($value === 'unchanged' ? '{{ICON_MIXED}}' : '{{ICON_DISABLED}}' )) . '</div>'
|
||||
. '<input class="' . $class . '" type="radio" value=1 name="'
|
||||
. $name . '" ' . ($value == 1 ? 'checked' : '') . ' ">On</input> '
|
||||
. '<input class="' . $class . '" type="radio" value=0 name="'
|
||||
. $name . '" ' . ($value == 0 ? 'checked' : '') . ' ">Off</input> '
|
||||
. '<input class="' . $class . '" type="radio" value="unchanged" name="'
|
||||
. $name . '" ' . ($value === 'unchanged' ? 'checked' : ' disabled="disabled" ') . ' . "> Mixed </input>'
|
||||
. '</div>';
|
||||
return $xhtml;
|
||||
. $name . '" ' . ($value == 0 ? 'checked' : '') . ' ">Off</input> ';
|
||||
|
||||
if ($value === 'unchanged') {
|
||||
$xhtml = $xhtml . '<input class="' . $class . '" type="radio" value="unchanged" name="'
|
||||
. $name . '" ' . 'checked "> Mixed </input>';
|
||||
};
|
||||
return $xhtml . '</div>';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@ use \Icinga\Module\Monitoring\Backend;
|
|||
use \Icinga\Module\Monitoring\Object\Host;
|
||||
use \Icinga\Module\Monitoring\Object\Service;
|
||||
use \Icinga\Module\Monitoring\Form\Command\MultiCommandFlagForm;
|
||||
use \Icinga\Module\Monitoring\DataView\HostAndServiceStatus as HostAndServiceStatusView;
|
||||
use \Icinga\Module\Monitoring\DataView\HostStatus as HostStatusView;
|
||||
use \Icinga\Module\Monitoring\DataView\ServiceStatus as ServiceStatusView;
|
||||
use \Icinga\Module\Monitoring\DataView\Comment as CommentView;
|
||||
|
||||
/**
|
||||
|
@ -50,52 +51,72 @@ class Monitoring_MultiController extends ActionController
|
|||
|
||||
public function hostAction()
|
||||
{
|
||||
$queries = $this->view->queries;
|
||||
$hosts = array();
|
||||
$filters = $this->view->queries;
|
||||
$errors = array();
|
||||
|
||||
if ($this->_getParam('host') === '*') {
|
||||
// fetch all hosts
|
||||
$hosts = HostAndServiceStatusView::fromRequest(
|
||||
$this->_request,
|
||||
array(
|
||||
'host_name',
|
||||
'host_in_downtime',
|
||||
'host_accepts_passive_checks',
|
||||
'host_does_active_checks',
|
||||
'host_notifications_enabled',
|
||||
|
||||
// TODO: flags missing in HostAndServiceStatus:
|
||||
'host_obsessing',
|
||||
'host_event_handler_enabled',
|
||||
'host_flap_detection_enabled'
|
||||
// <<
|
||||
)
|
||||
)->getQuery()->fetchAll();
|
||||
$comments = array_keys($this->getUniqueValues(
|
||||
CommentView::fromRequest($this->_request)->getQuery()->fetchAll(),
|
||||
'comment_id'
|
||||
));
|
||||
} else {
|
||||
// fetch specified hosts
|
||||
foreach ($queries as $index => $query) {
|
||||
if (!array_key_exists('host', $query)) {
|
||||
$errors[] = 'Query ' . $index . ' misses property host.';
|
||||
continue;
|
||||
}
|
||||
$hosts[] = Host::fetch($this->backend, $query['host']);
|
||||
}
|
||||
// Hosts
|
||||
$backendQuery = HostStatusView::fromRequest(
|
||||
$this->_request,
|
||||
array(
|
||||
'host_name',
|
||||
'host_in_downtime',
|
||||
'host_unhandled_service_count',
|
||||
'host_passive_checks_enabled',
|
||||
'host_obsessing',
|
||||
'host_notifications_enabled',
|
||||
'host_event_handler_enabled',
|
||||
'host_flap_detection_enabled',
|
||||
'host_active_checks_enabled'
|
||||
)
|
||||
)->getQuery();
|
||||
if ($this->_getParam('host') !== '*') {
|
||||
$this->applyQueryFilter($backendQuery, $filters);
|
||||
}
|
||||
$hosts = $backendQuery->fetchAll();
|
||||
|
||||
// Comments
|
||||
$commentQuery = CommentView::fromRequest($this->_request)->getQuery();
|
||||
$this->applyQueryFilter($commentQuery, $filters);
|
||||
$comments = array_keys($this->getUniqueValues($commentQuery->fetchAll(), 'comment_id'));
|
||||
|
||||
$this->view->objects = $this->view->hosts = $hosts;
|
||||
$this->view->problems = $this->getProblems($hosts);
|
||||
$this->view->comments = isset($comments) ? $comments : $this->getComments($hosts);
|
||||
$this->view->hostnames = $this->getProperties($hosts, 'host_name');
|
||||
$this->view->downtimes = $this->getDowntimes($hosts);
|
||||
$this->view->errors = $errors;
|
||||
|
||||
$this->handleConfigurationForm();
|
||||
$this->handleConfigurationForm(array(
|
||||
'host_passive_checks_enabled' => 'Passive Checks',
|
||||
'host_active_checks_enabled' => 'Active Checks',
|
||||
'host_obsessing' => 'Obsessing',
|
||||
'host_notifications_enabled' => 'Notifications',
|
||||
'host_event_handler_enabled' => 'Event Handler',
|
||||
'host_flap_detection_enabled' => 'Flap Detection'
|
||||
));
|
||||
$this->view->form->setAction('/icinga2-web/monitoring/multi/host');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $backendQuery BaseQuery The query to apply the filter to
|
||||
* @param $filter array Containing the filter expressions from the request
|
||||
*/
|
||||
private function applyQueryFilter($backendQuery, $filter)
|
||||
{
|
||||
// fetch specified hosts
|
||||
foreach ($filter as $index => $expr) {
|
||||
if (!array_key_exists('host', $expr)) {
|
||||
$errors[] = 'Query ' . $index . ' misses property host.';
|
||||
continue;
|
||||
}
|
||||
// apply filter expressions from query
|
||||
$backendQuery->orWhere('host_name', $expr['host']);
|
||||
if (array_key_exists('service', $expr)) {
|
||||
$backendQuery->andWhere('service_description', $expr['service']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an array with all unique values as keys.
|
||||
*
|
||||
|
@ -118,6 +139,28 @@ class Monitoring_MultiController extends ActionController
|
|||
return $unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the numbers of problems in the given objects
|
||||
*
|
||||
* @param $object array The hosts or services
|
||||
*/
|
||||
private function getProblems(array $objects)
|
||||
{
|
||||
$problems = 0;
|
||||
foreach ($objects as $object) {
|
||||
if (property_exists($object, 'host_unhandled_service_count')) {
|
||||
$problems += $object->{'host_unhandled_service_count'};
|
||||
} else if (
|
||||
property_exists($object, 'service_handled') &&
|
||||
!$object->service_handled &&
|
||||
$object->service_state > 0
|
||||
) {
|
||||
$problems++;
|
||||
}
|
||||
}
|
||||
return $problems;
|
||||
}
|
||||
|
||||
private function getComments($objects)
|
||||
{
|
||||
$unique = array();
|
||||
|
@ -142,8 +185,8 @@ class Monitoring_MultiController extends ActionController
|
|||
foreach ($objects as $object)
|
||||
{
|
||||
if (
|
||||
isset($object->host_in_downtime) && $object->host_in_downtime ||
|
||||
isset($object->service_in_downtime) && $object->host_in_downtime
|
||||
(property_exists($object, 'host_in_downtime') && $object->host_in_downtime) ||
|
||||
(property_exists($object, 'service_in_downtime') && $object->service_in_downtime)
|
||||
) {
|
||||
$downtimes[] = true;
|
||||
}
|
||||
|
@ -153,72 +196,61 @@ class Monitoring_MultiController extends ActionController
|
|||
|
||||
public function serviceAction()
|
||||
{
|
||||
$queries = $this->view->queries;
|
||||
$services = array();
|
||||
$filters = $this->view->queries;
|
||||
$errors = array();
|
||||
|
||||
if ($this->_getParam('service') === '*' && $this->_getParam('host') === '*') {
|
||||
$services = HostAndServiceStatusView::fromRequest(
|
||||
$this->_request,
|
||||
array(
|
||||
'host_name',
|
||||
'service_name',
|
||||
'service_in_downtime',
|
||||
'service_accepts_passive_checks',
|
||||
'service_does_active_checks',
|
||||
'service_notifications_enabled',
|
||||
$backendQuery = ServiceStatusView::fromRequest(
|
||||
$this->_request,
|
||||
array(
|
||||
'host_name',
|
||||
'service_description',
|
||||
'service_handled',
|
||||
'service_state',
|
||||
'service_in_downtime',
|
||||
|
||||
// TODO: Flag misses in HostAndServiceStatus
|
||||
'service_obsessing',
|
||||
'service_event_handler_enabled',
|
||||
'service_flap_detection_enabled'
|
||||
// <<
|
||||
)
|
||||
)->getQuery()->fetchAll();
|
||||
$comments = array_keys($this->getUniqueValues(
|
||||
CommentView::fromRequest($this->_request)->getQuery()->fetchAll(),
|
||||
'comment_id'
|
||||
));
|
||||
} else {
|
||||
// fetch specified hosts
|
||||
foreach ($queries as $index => $query) {
|
||||
if (!array_key_exists('host', $query)) {
|
||||
$errors[] = 'Query ' . $index . ' misses property host.';
|
||||
continue;
|
||||
}
|
||||
if (!array_key_exists('service', $query)) {
|
||||
$errors[] = 'Query ' . $index . ' misses property service.';
|
||||
continue;
|
||||
}
|
||||
$services[] = Service::fetch($this->backend, $query['host'], $query['service']);
|
||||
}
|
||||
'service_passive_checks_enabled',
|
||||
'service_notifications_enabled',
|
||||
'service_event_handler_enabled',
|
||||
'service_flap_detection_enabled',
|
||||
'service_active_checks_enabled'
|
||||
)
|
||||
)->getQuery();
|
||||
if ($this->_getParam('service') !== '*' && $this->_getParam('host') !== '*') {
|
||||
$this->applyQueryFilter($backendQuery, $filters);
|
||||
}
|
||||
$services = $backendQuery->fetchAll();
|
||||
|
||||
// Comments
|
||||
$commentQuery = CommentView::fromRequest($this->_request)->getQuery();
|
||||
$this->applyQueryFilter($commentQuery, $filters);
|
||||
$comments = array_keys($this->getUniqueValues($commentQuery->fetchAll(), 'comment_id'));
|
||||
|
||||
$this->view->objects = $this->view->services = $services;
|
||||
$this->view->problems = $this->getProblems($services);
|
||||
$this->view->comments = isset($comments) ? $comments : $this->getComments($services);
|
||||
$this->view->hostnames = $this->getProperties($services, 'host_name');
|
||||
$this->view->servicenames = $this->getProperties($services, 'service_description');
|
||||
$this->view->downtimes = $this->getDowntimes($services);
|
||||
$this->view->errors = $errors;
|
||||
|
||||
$this->handleConfigurationForm();
|
||||
$this->handleConfigurationForm(array(
|
||||
'service_passive_checks_enabled' => 'Passive Checks',
|
||||
'service_active_checks_enabled' => 'Active Checks',
|
||||
'service_notifications_enabled' => 'Notifications',
|
||||
'service_event_handler_enabled' => 'Event Handler',
|
||||
'service_flap_detection_enabled' => 'Flap Detection'
|
||||
));
|
||||
$this->view->form->setAction('/icinga2-web/monitoring/multi/service');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form to configure configuration flags.
|
||||
* Handle the form to edit configuration flags.
|
||||
*
|
||||
* @param $flags array The used flags.
|
||||
*/
|
||||
private function handleConfigurationForm()
|
||||
private function handleConfigurationForm(array $flags)
|
||||
{
|
||||
$this->view->form = $form = new MultiCommandFlagForm(
|
||||
array(
|
||||
'passive_checks_enabled' => 'Passive Checks',
|
||||
'active_checks_enabled' => 'Active Checks',
|
||||
'obsessing' => 'Obsessing',
|
||||
'notifications_enabled' => 'Notifications',
|
||||
'event_handler_enabled' => 'Event Handler',
|
||||
'flap_detection_enabled' => 'Flap Detection'
|
||||
)
|
||||
);
|
||||
$this->view->form = $form = new MultiCommandFlagForm($flags);
|
||||
$form->setRequest($this->_request);
|
||||
if ($form->isSubmittedAndValid()) {
|
||||
// TODO: Handle commands
|
||||
|
|
|
@ -5,7 +5,7 @@ $viewHelper = $this->getHelper('MonitoringState');
|
|||
<?= $this->tabs->render($this); ?>
|
||||
<h1>Hosts Status</h1>
|
||||
<div data-icinga-component="app/mainDetailGrid" data-icinga-grid-selection-type="multi">
|
||||
<div class="container">
|
||||
<div class="container pull-left">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<?= $this->filterBox->render($this); ?>
|
||||
|
@ -17,9 +17,11 @@ $viewHelper = $this->getHelper('MonitoringState');
|
|||
<div class="row">
|
||||
<?= $this->paginationControl($hosts, null, null, array('preserve' => $this->preserve)); ?>
|
||||
</div>
|
||||
Select
|
||||
<a href='?detail=<?= urlencode($this->href('monitoring/multi/host',array( 'host' => '*' )))?>'> All </a>
|
||||
<a href='?'> None </a>
|
||||
<div>
|
||||
Select
|
||||
<a href='<?=$this->href('monitoring/multi/host',array( 'host' => '*' ))?>'> All </a>
|
||||
<a href='#'> None </a>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-condensed">
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ $viewHelper = $this->getHelper('MonitoringState');
|
|||
<?= $this->tabs->render($this); ?>
|
||||
<h1>Services Status</h1>
|
||||
<div data-icinga-component="app/mainDetailGrid" data-icinga-grid-selection-type="multi">
|
||||
<div class="container">
|
||||
<div class="container pull-left">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<?= $this->filterBox->render($this); ?>
|
||||
|
@ -17,14 +17,11 @@ $viewHelper = $this->getHelper('MonitoringState');
|
|||
<div class="row">
|
||||
<?= $this->paginationControl($services, null, null, array('preserve' => $this->preserve)); ?>
|
||||
</div>
|
||||
Select
|
||||
<a href='?detail=<?= urlencode(
|
||||
$this->href(
|
||||
'monitoring/multi/host',
|
||||
array('host' => '*', 'service' => '*')
|
||||
)
|
||||
)?>'> All </a>
|
||||
<a href='?'> None </a>
|
||||
<div>
|
||||
Select
|
||||
<a href='<?=$this->href('monitoring/multi/service',array( 'host' => '*', 'service' => '*' ))?>'> All </a>
|
||||
<a href='#'> None </a>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
$cf = $this->getHelper('CommandForm');
|
||||
$servicequery = isset($this->servicequery) ? $this->servicequery : '';
|
||||
?>
|
||||
|
||||
<h4> Selected <?= count($objects) ?> objects. </h4>
|
||||
Selected <?= count($objects) ?> objects.
|
||||
|
||||
<div class="panel-row">
|
||||
<a href="<?=
|
||||
|
@ -26,24 +25,23 @@ $this->href(
|
|||
</div>
|
||||
|
||||
<div class="panel-row">
|
||||
The selected objects have <?= $this->problems ?> service problems. <br />
|
||||
|
||||
<a href="<?=
|
||||
$this->href(
|
||||
'monitoring/command/acknowledgeproblem',
|
||||
$this->target
|
||||
);
|
||||
?>" class="button btn-cta btn-wide">
|
||||
Acknowledge Problems
|
||||
?>" class="button btn-cta btn-half-left">
|
||||
Acknowledge
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<div class="panel-row">
|
||||
|
||||
<a href="<?=
|
||||
$this->href(
|
||||
'monitoring/command/scheduledowntimes',
|
||||
$this->target
|
||||
);
|
||||
?>" class="button btn-cta btn-common btn-wide">
|
||||
?>" class="button btn-cta btn-half-right">
|
||||
Schedule Downtimes
|
||||
</a>
|
||||
|
||||
|
|
|
@ -18,6 +18,6 @@ $this->target = array(
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<?= $this->render('multi/components/downtimes.phtml'); ?>
|
||||
<?= $this->render('multi/components/comments.phtml'); ?>
|
||||
<?= $this->render('multi/components/downtimes.phtml'); ?>
|
||||
<?= $this->render('multi/components/configuration.phtml'); ?>
|
||||
|
|
|
@ -22,6 +22,6 @@ $this->target = array(
|
|||
|
||||
</div>
|
||||
|
||||
<?= $this->render('multi/components/downtimes.phtml'); ?>
|
||||
<?= $this->render('multi/components/comments.phtml'); ?>
|
||||
<?= $this->render('multi/components/downtimes.phtml'); ?>
|
||||
<?= $this->render('multi/components/configuration.phtml'); ?>
|
||||
|
|
|
@ -197,7 +197,7 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe
|
|||
if (response.statusCode.toString()[0] === '4') {
|
||||
errorReason = 'The Requested View Couldn\'t Be Found<br/>';
|
||||
} else {
|
||||
errorReason = 'An Internal Error Occured';
|
||||
errorReason = response.responseText;
|
||||
}
|
||||
this.replaceDom(
|
||||
$('<div class="alert alert-danger">').text(errorReason)
|
||||
|
|
|
@ -25,19 +25,8 @@
|
|||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
define(['components/app/container', 'jquery', 'logging', 'URIjs/URI', 'URIjs/URITemplate', 'icinga/util/url'],
|
||||
function(Container, $, logger, URI, tpl, urlMgr) {
|
||||
define(
|
||||
[
|
||||
'components/app/container',
|
||||
'jquery',
|
||||
'logging',
|
||||
'icinga/selection/selectable',
|
||||
'icinga/selection/multiSelection',
|
||||
'URIjs/URI',
|
||||
'URIjs/URITemplate'
|
||||
],
|
||||
function(Container, $, logger, Selectable, TableMultiSelection, URI) {
|
||||
define(['components/app/container', 'jquery', 'logging', 'URIjs/URI', 'URIjs/URITemplate', 'icinga/util/url', 'icinga/selection/selectable', 'icinga/selection/multiSelection'],
|
||||
function(Container, $, logger, URI, tpl, urlMgr, Selectable, TableMultiSelection) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
|
@ -142,7 +131,7 @@ function(Container, $, logger, Selectable, TableMultiSelection, URI) {
|
|||
this.showMousePointerOnRow = function(domContext) {
|
||||
domContext = domContext || contentNode;
|
||||
$('tbody tr', domContext).css('cursor' ,'pointer');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Activate a hover effect on all table rows, to indicate that
|
||||
|
@ -230,11 +219,11 @@ function(Container, $, logger, Selectable, TableMultiSelection, URI) {
|
|||
} else if (selection.size() > 1 && segments.length > 3) {
|
||||
// open detail view for multiple objects
|
||||
segments[2] = 'multi';
|
||||
url.pathname(segments.join('/'));
|
||||
url.pathname('/' + segments.join('/'));
|
||||
url.search('?');
|
||||
url.setSearch(selection.toQuery());
|
||||
}
|
||||
Container.getDetailContainer().replaceDomFromUrl(url);
|
||||
urlMgr.setDetailUrl(url);
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
@ -279,29 +268,17 @@ function(Container, $, logger, Selectable, TableMultiSelection, URI) {
|
|||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
var getSelectedRows = function() {
|
||||
return $('a[href="' + urlMgr.getDetailUrl() + '"]', determineContentTable()).
|
||||
parentsUntil('table', 'tr');
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
* Synchronize the current selection with the url displayed in the detail box
|
||||
* Create a new TableMultiSelection, attach it to the content node, and use the
|
||||
* current detail url to restore the selection state
|
||||
*/
|
||||
/*
|
||||
this.syncSelectionWithDetail = function() {
|
||||
$('tr', contentNode).removeClass('active');
|
||||
getSelectedRows().addClass('active');
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
* Register listener for history changes in the detail box
|
||||
*/
|
||||
this.registerHistoryChanges = function() {
|
||||
Container.getDetailContainer().registerOnUpdate(this.syncSelectionWithDetail.bind(this));
|
||||
this.initSelection = function() {
|
||||
var detail = urlMgr.getDetailUrl();
|
||||
if (typeof detail !== 'string') {
|
||||
detail = detail[0] || '';
|
||||
}
|
||||
selection = new TableMultiSelection(contentNode,new URI(detail));
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -317,13 +294,10 @@ function(Container, $, logger, Selectable, TableMultiSelection, URI) {
|
|||
// indicate selectable rows
|
||||
this.showMousePointerOnRow();
|
||||
this.activateRowHovering();
|
||||
selection = new TableMultiSelection(
|
||||
contentNode,
|
||||
Container.getDetailContainer().getContainerHref()
|
||||
);
|
||||
this.initSelection();
|
||||
}
|
||||
this.registerTableLinks();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create this component, setup listeners and behaviour
|
||||
|
|
|
@ -40,7 +40,7 @@ function($, URI, Selectable) {
|
|||
*
|
||||
* @param {HtmlElement} The table that contains the selectable rows.
|
||||
*
|
||||
* @param {Object} The query that contains the selected rows.
|
||||
* @param {URI} The query that contains the selected rows.
|
||||
*/
|
||||
return function MultiSelection(table, detailUrl) {
|
||||
var self = this;
|
||||
|
@ -163,9 +163,6 @@ function($, URI, Selectable) {
|
|||
if (!url) {
|
||||
return [];
|
||||
}
|
||||
if (!url.query) {
|
||||
url = new URI(url);
|
||||
}
|
||||
var segments = url.segment();
|
||||
var parts;
|
||||
// TODO: Handle it for cases when there is no /icinga-web2/ in the path
|
||||
|
|
Loading…
Reference in New Issue