Verified Commit 30616cc6 authored by David Kunz's avatar David Kunz

Adding upstream version 0.0.1+20160321.

Signed-off-by: David Kunz's avatarDavid Kunz <david.kunz@dknet.ch>
parent 37e4bc68
*.swp
sinker.sh
This diff is collapsed.
# icingaweb2-module-boxydash
An "at a view" dashboard showing the overall view of your icinga implementation
![demo view](https://raw.githubusercontent.com/morgajel/icingaweb2-module-boxydash/master/demo.png)
# Installation
Simply check this out to /usr/share/icingaweb2/modules/boxydash then symlink to it from /etc/icingaweb2/enabledModules/boxydash
it should now appear in
icingacli modules list
as well as your web interface.
<?php
use Icinga\Web\Notification;
use Icinga\Data\ResourceFactory;
use Icinga\Forms\ConfirmRemovalForm;
use Icinga\Web\Controller;
use Icinga\Module\Monitoring\Forms\Config\BackendConfigForm;
use Icinga\Module\Monitoring\Forms\Config\InstanceConfigForm;
use Icinga\Module\Monitoring\Forms\Config\SecurityConfigForm;
use Icinga\Module\Boxydash\Forms\Config\SettingConfigForm;
class BoxyDash_ConfigController extends Controller
{
public function indexAction()
{
$this->view->settingsConfig = $this->Config('settings');
$form = new SettingConfigForm();
$this->view->form = $form;
$form->setTitle($this->translate('Edit Existing Instance'));
$form->setIniConfig($this->Config('config'));
$form->setRedirectUrl('boxydash');
$form->handleRequest();
$this->view->form = $form;
$this->getTabs()->activate('config');
}
public function editSettingsAction()
{
$form = new SettingConfigForm();
$form->setTitle($this->translate('Edit Settings'));
$form->setIniConfig($this->Config('settings'));
$form->setRedirectUrl('boxydash');
$form->handleRequest();
$this->view->form = $form;
}
public function getTabs()
{
$tabs = parent::getTabs();
$tabs->add(
'dashboard',
array(
'title' => 'Dashboard',
'url' => 'boxydash'
)
);
$tabs->add(
'config',
array(
'title' => 'Configure',
'url' => 'boxydash/config'
)
);
return $tabs;
}
}
<?php
/*
TODO Things that need to be added:
- Option to show only hard or soft states
- The ability to configure box size, or set it to dynamically fill the screen
- Add a filter and custom label so two dashboards could provide different labeled views.
(you may have two boxy dashboards with two different filters open- one for each dev team/environment/project)
*/
use Icinga\Data\Filter\Filter;
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Web\Url;
use Icinga\Application\Logger;
#FIXME should this be Controller or ModuleActionController? The documentation was unclear.
class BoxyDash_IndexController extends Controller
{
protected $default_requiresAuthentication = true;
protected $default_include_softstate = false;
protected $default_boxsize = 20;
protected $default_refresh = 10;
protected $default_showlegend = true;
protected $default_path_prefix = '';
public function indexAction()
{
$this->getTabs()->activate('dashboard');
$this->config = $this->Config('config');
$this->determine_refresh();
$this->determine_showlegend();
$this->determine_boxsize();
$this->determine_path_prefix();
$this->determine_include_softstate();
$isrequired = $this->config->get( 'settings', 'requires_authentication', $this->default_requiresAuthentication );
$this->_request->getParams();
$this->getServiceData();
$this->getHostData();
}
protected function requiresLogin()
{
#Logger::error("running requiresLogin");
$this->requiresAuthentication = (bool) $this->Config()->get(
'settings',
'requires_authentication',
$this->default_requiresAuthentication
);
return parent::requiresLogin();
}
public function determine_showlegend()
{
if ($this->_hasParam("showlegend")){
$this->view->showlegend = (boolean) $this->_getParam("showlegend");
#Failing that, check to see if it's already in the configuration or use the default legend
}else{
$this->view->showlegend = (boolean) $this->config->get('settings','show_legend',$this->default_showlegend);
}
}
public function determine_refresh()
{
if (intval($this->_getParam("refresh")) >=1){
$this->refresh = intval($this->_getParam("refresh"));
#Failing that, check to see if it's already in the configuration
}elseif (is_numeric( $this->config->get('settings','setting_refresh','missing'))) {
# Note that $default_refresh should never be hit on this line.
$this->refresh = intval($this->config->get('settings','setting_refresh',$this->default_refresh));
}else{
#failing THAT, use our default.
$this->refresh = $this->default_refresh ;
}
$this->setAutorefreshInterval( $this->refresh );
}
public function determine_boxsize()
{
if (is_numeric($this->_getParam("boxsize"))){
$this->view->boxsize = intval($this->_getParam("boxsize"));
#Failing that, check to see if it's already in the configuration
}elseif (is_numeric( $this->config->get('settings','setting_boxsize','missing'))) {
# Note that $default_boxsize should never be hit on this line.
$this->view->boxsize = $this->config->get('settings','setting_boxsize',$this->default_boxsize);
}else{
#failing THAT, use our default.
$this->view->boxsize = $this->default_boxsize;
}
}
public function determine_include_softstate()
{
# First determine if uri override is being passed
if ( $this->_hasParam("include_softstate")){
$this->view->include_softstate = (boolean) $this->_getParam("include_softstate");
}else{
#Failing that, check to see if it's already in the configuration or use the default
$this->view->include_softstate = $this->config->get('settings','include_softstate',$this->default_include_softstate);
# $this->view->debug=intval($this->view->include_softstate);
}
# $this->view->debug= intval( (bool)$this->view->include_softstate);
}
public function determine_path_prefix()
{
$this->view->path_prefix = $this->config->get('settings', 'path_prefix', $this->default_path_prefix);
}
# Create the tabs for the dashboard and the configuration tab.
public function getTabs()
{
$tabs = parent::getTabs();
$tabs->add(
'dashboard',
array(
'title' => $this->translate('Dashboard'),
'url' => 'boxydash',
'tip' => $this->translate('Overview')
)
);
if($this->Auth()->isAuthenticated()){
$tabs->add(
'config',
array(
'title' => $this->translate('Configure'),
'url' => 'boxydash/config',
'tip' => $this->translate('Configure')
)
);
}
return $tabs;
}
# get the status of each host
public function getHostData()
{
$columns = array(
'host_name',
'host_display_name',
'host_state',
'host_acknowledged',
'host_in_downtime',
'host_output',
# Most of these may not be needed; included it for future integration/use (yeah, right)
'host_icon_image',
'host_handled',
'host_attempt',
'host_state_type',
'host_hard_state',
'host_last_check',
'host_notifications_enabled',
'host_action_url',
'host_notes_url',
'host_active_checks_enabled',
'host_passive_checks_enabled',
'host_current_check_attempt',
'host_max_check_attempts'
);
$query = $this->backend->select()->from('hostStatus', $columns);
$this->applyRestriction('monitoring/filter/objects', $query); // follow filter object restrictions
$query->order('host_name', 'desc');
# This might be very very bad for very very large environments. I just don't know how well it'll perform.
$this->view->hosts = $query->getQuery()->fetchAll();
foreach ($this->view->hosts as $host) {
#FIXME: using Service function for a host state. that's kinda ugly
# If we allow statetypes, or it's ack'd OR the state type is already HARD
if ( $this->view->include_softstate or $host->{'host_acknowledged'} ){
$host->{'host_state_text'}=Service::getStateText($host->{'host_state'});
}else{
$host->{'host_state_text'}=Service::getStateText($host->{'host_hard_state'});
}
}
}
# get the status of each service
public function getServiceData()
{
$columns = array(
'host_name',
'host_display_name',
'host_in_downtime',
'host_acknowledged',
'host_state',
'host_hard_state',
'service_hard_state',
'service_description',
'service_display_name',
'service_state',
'service_in_downtime',
'service_acknowledged',
'service_output',
# Most of these may not be needed; included it for future integration/use (yeah, right)
'host_last_state_change',
'service_attempt',
'service_last_state_change',
'service_is_flapping',
'service_state_type',
'service_last_check',
'current_check_attempt' => 'service_current_check_attempt',
'max_check_attempts' => 'service_max_check_attempts'
);
$query = $this->backend->select()->from('serviceStatus', $columns);
$this->applyRestriction('monitoring/filter/objects', $query); // follow filter object restrictions
$query->order('host_name', 'desc');
$this->view->services = $query->getQuery()->fetchAll();
foreach ($this->view->services as $service) {
#Loop through and make sure there's a field that says "OK" so we can grab the right css class
$service->{'service_state_text'}=Service::getStateText($service->{'service_state'});
$service->{'host_state_text'}=Service::getStateText($service->{'host_state'});
# If we allow statetypes, or it's ack'd OR the state type is already HARD
if ( $this->view->include_softstate or $service->{'service_acknowledged'} ){
$service->{'service_state_text'}=Service::getStateText($service->{'service_state'});
}else{
$service->{'service_state_text'}=Service::getStateText($service->{'service_hard_state'});
}
}
}
/* This function may be useful if I can figure out an overall way to show it that integrates well.
public function statusSummary(){
$this->view->stats = $this->backend->select()->from('statusSummary', array(
'services_total',
'services_ok',
'services_problem',
'services_problem_handled',
'services_problem_unhandled',
'services_critical',
'services_critical_unhandled',
'services_critical_handled',
'services_warning',
'services_warning_unhandled',
'services_warning_handled',
'services_unknown',
'services_unknown_unhandled',
'services_unknown_handled',
'services_pending',
))->getQuery()->fetchRow();
}
*/
}
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Module\Boxydash\Forms\Config;
use Exception;
use Icinga\Data\ConfigObject;
use Icinga\Data\ResourceFactory;
use Icinga\Web\Form;
use InvalidArgumentException;
use Icinga\Application\Config;
use Icinga\Exception\ConfigurationError;
use Icinga\Forms\ConfigForm;
use Icinga\Web\Notification;
/**
* Form class for creating/modifying monitoring Settings
*/
class SettingConfigForm extends ConfigForm
{
protected $resources;
public function init()
{
$this->setName('form_config_boxydash_settings');
$this->setSubmitLabel($this->translate('Save Changes'));
}
public function createElements(array $formData)
{
$this->addElement(
'text',
'setting_refresh',
array(
'label' => $this->translate('Dashboard Refresh'),
'description' => $this->translate('How quickly the dashboard should refresh (between 1 second and 20 minutes)'),
'value' => '10',
'validators' => array(
array(
'Between',
false,
array(
'min' => '1',
'max' => '1200',
'inclusive' => true,
)
)
)
)
);
$this->addElement(
'text',
'setting_boxsize',
array(
'label' => $this->translate('Box Size'),
'description' => $this->translate('The size of displayed boxes in pixels'),
'value' => '10',
'validators' => array(
array(
'Regex',
false,
array(
'pattern' => '/^[\d]+$/',
'messages' => array(
'regexNotMatch' => $this->translate(
'The application prefix must be a positive integer.'
)
)
)
)
)
)
);
$this->addElement(
'checkbox',
'include_softstate',
array(
'required' => true,
'value' => true,
'label' => $this->translate('Include Soft Status'),
'description' => $this->translate('Enable this to have soft status included')
)
);
$this->addElement(
'checkbox',
'requires_authentication',
array(
'required' => true,
'value' => true,
'label' => $this->translate('Require Authentication?'),
'description' => $this->translate('Does Boxydash require Authentication? Warning, this may expose sensitive network information.')
)
);
$this->addElement(
'checkbox',
'show_legend',
array(
'required' => true,
'value' => true,
'label' => $this->translate('Show the Legend'),
'description' => $this->translate('Do you want to show the legend?')
)
);
$this->addElement(
'text',
'path_prefix',
array(
'label' => $this->translate('URL path prefix'),
'description' => $this->translate('Prefix prepended to all links, eg "/icingaweb2". Required in case Icinga Web 2 is installed in a subfolder (eg "http://your-domain.tld/icingaweb2").'),
'value' => '',
)
);
}
public function onSuccess()
{
$this->config->setSection('settings', $this->getValues());
if ($this->save()) {
Notification::success($this->translate('New setings have successfully been stored'));
} else {
return false;
}
}
/**
* @see Form::onRequest()
*/
public function onRequest()
{
$this->populate($this->config->getSection('settings')->toArray());
}
}
<?php if (! $this->compact): ?>
<div class="controls">
<?= $tabs; ?>
</div>
<?php endif ?>
<div class="content">
<h1>Boxy Dashboard Configuration</h1>
<?=$this->form; ?>
</div>
<?
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Module\Monitoring\Object\Host;
?>
<div class="controls">
<?php if (! $this->compact): ?>
<?= $tabs; ?>
<?php endif ?>
</div>
<div class="content">
<h1>Boxy Dashboard</h1>
<? if ($this->showlegend){ ?>
<div class="boxy_legend">
<span class="boxy_sublegend">
<span class="legendtext">&#10004; = Acknowledged</span>
<span class="legendtext">&#8986; = In Downtime</span>
<span class="legendtext">&#8632; = Host Issue Acknowledged</span>
</span>
<span class="boxy_sublegend">
<span class="legendtext">Status:</span>
<span class="boxy_legend_box ok" >ok</span>
<span class="boxy_legend_box warning" >warning</span>
<span class="boxy_legend_box critical" >critical</span>
<span class="boxy_legend_box unknown" >unknown</span>
</span>
<span class="boxy_sublegend">
<span class="legendtext" >Acknowledged:</span>
<span class="boxy_legend_box warning-ack" >warning</span>
<span class="boxy_legend_box critical-ack" >critical</span>
<span class="boxy_legend_box unknown-ack" >unknown</span>
</span>
</div>
<? } ?>
<h2>Host Info</h2>
<?
foreach ($this->hosts as $host){
$title = htmlspecialchars($host->{'host_display_name'});
$size=$this->boxsize;
$content="&nbsp;";
$returncode=$host->{'host_state_text'};
if ($host->{'host_acknowledged'}==1 ){
$returncode.="-ack";
$content= "&#10004;";
$title.=" (Acknowledged)";
}?>
<a href='<?= $this->path_prefix ?>/monitoring/host/show?host=<?=$host->{'host_name'}?>' class='boxy_box state <?=$returncode?>' style='width:<?=$size?>px; height:<?=$size?>px; font-size:<?=$size?>px;' title="<?=$title?>"><?=$content?></a>
<? } ?>
<br clear="all"/>
<h2>Service Info</h2>
<? foreach ($this->services as $service){
$service->{'service_hard_state'} = ($service->{'service_hard_state'}) ? "hard" : "soft";
$title = $service->{'host_display_name'}.": ".$service->{'service_description'};
#."(".$service->{'current_check_attempt'} .",".$service->{'max_check_attempts'} .")(". $service->{'service_hard_state'}.")+acked:".$service->{'service_acknowledged'} ;
$size=$this->boxsize;
$content="&nbsp;";
$returncode=$service->{'service_state_text'};
if ($service->{'service_in_downtime'}==1 or $service->{'host_in_downtime'}==1 ){
$returncode.="-downtime";
$content= "&#8986;";
$title.=" (Scheduled Maintenance)";
}elseif ($service->{'service_acknowledged'}==1 ){
$returncode.="-ack";
$content= "&#10004;";
$title.=" (Acknowledged)";
}elseif ($service->{'service_state_text'} != "ok" && $service->{'host_acknowledged'} == 1 ){
$returncode.="-ack";
$content= "&#8632;";
$title.=" (Host Issue Acknowledged)";
}
$title=htmlspecialchars($title."\n ".$service->{'service_output'});?>
<a href='<?= $this->path_prefix ?>/monitoring/service/show?host=<?=$service->{'host_name'}?>&service=<?=$service->{'service_description'}?>' class='boxy_box state <?=$returncode?>' style='width:<?=$size?>px; height:<?=$size?>px; font-size:<?=$size?>px;' title="<?=$title?>"><?=$content?></a>
<? } ?>
<br clear=all>
<pre style="font-size:20px"><?=$this->debug?></pre>
</div>
<?php
$this->providePermission(
'boxydash',
$this->translate('View Boxy Dashboard')
);
$this->menuSection('Boxy Dashboard', array(
'url' => 'boxydash',
'icon' => 'dashboard',
'priority' => 20
));
demo.png

48.6 KB

<?php
namespace Icinga\Module\BoxyDash;
use Icinga\Application\Config;
use Icinga\Exception\ConfigurationError;
use Icinga\Module\Monitoring\Object\MonitoredObject;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Web\Hook\GrapherHook;
use Icinga\Web\Url;
class Grid extends WebBaseHook
{
protected $hasPreviews = true;
protected $baseUrl = '/boxydash';
protected function init()
{
$cfg = Config::module('boxydash')->getSection('boxydash');
$this->baseUrl = rtrim($cfg->get('base_url', $this->baseUrl), '/');
}
Module: boxydash
Version: 0.0.1
Description: Boxy Dashboard module
This is intended to give you another view of the status of your board.
.boxy_legend {
/* Used */
border: 0px solid blue;
float:right;
font-size:12px;
margin:2px 2px 0px 0px;
text-align:right;
display:block;
text-decoration:none;
vertical-align:middle;
}
.boxy_sublegend {
/* Used */
border: 0px solid green;
margin-left:20px;
display:inline-block;
vertical-align:middle;
}
.legendtext {
/* Used */
width:140px;
height:20px;
font-size:12px;
margin:2px 2px 0px 0px;
display:inline;
text-decoration:none;
}
.boxy_legend_box {
/* Used */
padding:4px 4px 4px 4px;
border: 0px solid red;
text-align:center;
display:inline-block;
text-decoration:none;
}
.boxy_box {
margin:2px 2px 0px 0px;
border-right: 1px solid gray;
border-bottom: 1px solid gray;
text-align:center;
display:block;
float:left;
vertical-align:middle;
text-decoration:none;
}
/* Note: @colors won't work when the board is viewed anonymously */
.ok {background-color:#44BB77;}
.ok-ack {background-color:#44BB77;}
.warning {background-color:#FFAA44;}
.warning-ack {background-color:#FFCC66;}
.warning-downtime {background-color:#dddddd;}
.critical {background-color:#FF5566}
.critical-ack {background-color:#FF99AA}
.critical-downtime {background-color:#dddddd;}
.unknown {background-color:#AA44FF}
.unknown-ack {background-color:#CC77FF;}
.unknown-downtime {background-color:#dddddd;}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment