Nagios Services

- Moved check-services.php to a poller module
    - Added performance data collection to the poller
    - Centralised DB functions to includes/services.inc.php
    - Created add/edit/delete functions off the device, services page
    - Removed legacy edit/delete interfaces.
    - Moved and modified check.inc scripts
    - Documentation Updates
    - Modified services table
This commit is contained in:
Aaron Daniels
2016-03-15 22:16:08 +10:00
parent 2d2f56c3dc
commit 0d6cfec589
61 changed files with 1040 additions and 802 deletions

View File

@@ -0,0 +1,47 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2016 Aaron Daniels <aaron@daniels.id.au>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
if (is_admin() === false) {
die('ERROR: You need to be admin');
}
$service_id = $_POST['service_id'];
$type = mres($_POST['stype']);
$desc = mres($_POST['desc']);
$ip = mres($_POST['ip']);
$param = mres($_POST['param']);
$device_id = mres($_POST['device_id']);
if (is_numeric($service_id) && $service_id > 0) {
// Need to edit.
$update = array('service_desc' => $desc, 'service_ip' => $ip, 'service_param' => $param);
if (service_edit($update, $service_id)) {
$status = array('status' =>0, 'message' => 'Modified Service: <i>'.$service_id.': '.$type.'</i>');
}
else {
$status = array('status' =>1, 'message' => 'ERROR: Failed to modify service: <i>'.$service_id.'</i>');
}
}
else {
// Need to add.
$service_id = service_add($device_id, $type, $desc, $ip, $param);
if ($service_id == false) {
$status = array('status' =>1, 'message' => 'ERROR: Failed to add Service: <i>'.$type.'</i>');
}
else {
$status = array('status' =>0, 'message' => 'Added Service: <i>'.$service_id.': '.$type.'</i>');
}
}
header('Content-Type: application/json');
echo _json_encode($status);

View File

@@ -0,0 +1,31 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2016 Aaron Daniels <aaron@daniels.id.au>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
if (is_admin() === false) {
$status = array('status' =>1, 'message' => 'ERROR: You need to be admin to delete services');
}
else {
if (!is_numeric($_POST['service_id'])) {
$status = array('status' =>1, 'message' => 'No Service has been selected');
}
else {
if (service_delete($_POST['service_id'])) {
$status = array('status' =>0, 'message' => 'Service: <i>'.$_POST['service_id'].', has been deleted.</i>');
}
else {
$status = array('status' =>1, 'message' => 'Service: <i>'.$_POST['service_id'].', has NOT been deleted.</i>');
}
}
}
header('Content-Type: application/json');
echo _json_encode($status);

View File

@@ -0,0 +1,33 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2016 Aaron Daniels <aaron@daniels.id.au>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
if (is_admin() === false) {
die('ERROR: You need to be admin');
}
$service_id = $_POST['service_id'];
if (is_numeric($service_id) && $service_id > 0) {
$service = service_get(null, $service_id);
$output = array(
'stype' => $service[0]['service_type'],
'ip' => $service[0]['service_ip'],
'desc' => $service[0]['service_desc'],
'param' => $service[0]['service_param']
);
header('Content-Type: application/json');
echo _json_encode($output);
}

View File

@@ -0,0 +1,97 @@
<?php
/*
* LibreNMS module to display graphing for Nagios Service
*
* Copyright (c) 2016 Aaron Daniels <aaron@daniels.id.au>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
// Get a list of all services for this device.
require_once '../includes/services.inc.php';
$services = service_get($device['device_id']);
// Determine which key is the service we want to show.
if (isset($vars['service'])) {
// Service is set, find its key.
foreach ($services as $key => $service) {
if ($service['service_id'] == $vars['service']) {
// We have found the service we want.
$vars['service'] = $key;
}
}
}
else {
// No service set, set the first one.
if (isset($services[0])) {
$vars['service'] = 0;
}
}
// We know our service. build the filename.
$filename = "services-".$services[$vars['service']]['service_id'].".rrd";
$rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/" . safename ($filename);
// if we have a script for this check, use it.
$check_script = $config['install_dir'].'/includes/services/check_'.strtolower($services[$vars['service']]['service_type']).'.inc.php';
if (is_file($check_script)) {
include $check_script;
// If we have a replacement DS use it.
if (isset($check_ds)) {
$services[$vars['service']]['service_ds'] = $check_ds;
}
}
include "includes/graphs/common.inc.php";
$rrd_options .= " -l 0 -E ";
$rrd_options .= " COMMENT:' Now Avg Max\\n'";
$rrd_additions = "";
// Remove encoded characters
$services[$vars['service']]['service_ds'] = htmlspecialchars_decode($services[$vars['service']]['service_ds']);
if ($services[$vars['service']]['service_ds'] != "") {
$graphinfo = json_decode($services[$vars['service']]['service_ds'],TRUE);
// Do we have a DS set
if (!isset($graphinfo[$vars['ds']])) {
foreach ($graphinfo as $k => $v) {
// Select a DS to display.
$vars['ds'] = $k;
}
}
// Need: DS name, Label
$ds = $vars['ds'];
$label = $graphinfo[$vars['ds']];
if (file_exists($rrd_filename)) {
if (isset($check_graph)) {
// We have a graph definition, use it.
$rrd_additions .= $check_graph[$ds];
}
else {
// Build the graph ourselves
$color = $config['graph_colours']['mixed'][2];
$rrd_additions .= " DEF:DS=" . $rrd_filename . ":".$ds.":AVERAGE ";
$rrd_additions .= " AREA:DS#" . $color . ":'" . str_pad(substr(ucfirst($ds)." (".$label.")",0,15),15) . "' ";
$rrd_additions .= " GPRINT:DS:LAST:%5.2lf%s ";
$rrd_additions .= " GPRINT:DS:AVERAGE:%5.2lf%s ";
$rrd_additions .= " GPRINT:DS:MAX:%5.2lf%s\\\l ";
}
}
}
if ($rrd_additions == "") {
// We didn't add any data points.
}
else {
$rrd_options .= $rrd_additions;
}

View File

@@ -0,0 +1,75 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2016 Aaron Daniels <aaron@daniels.id.au>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
if(is_admin() === false) {
die('ERROR: You need to be admin');
}
?>
<div class="modal fade" id="confirm-delete" tabindex="-1" role="dialog" aria-labelledby="Delete" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h5 class="modal-title" id="Delete">Confirm Delete</h5>
</div>
<div class="modal-body">
<p>Please confirm that you would like to delete this service.</p>
</div>
<div class="modal-footer">
<form role="form" class="remove_token_form">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-danger danger" id="service-removal" data-target="service-removal">Delete</button>
<input type="hidden" name="service_id" id="service_id" value="">
<input type="hidden" name="confirm" id="confirm" value="yes">
</form>
</div>
</div>
</div>
</div>
<script>
$('#confirm-delete').on('show.bs.modal', function(e) {
service_id = $(e.relatedTarget).data('service_id');
$("#service_id").val(service_id);
});
$('#service-removal').click('', function(e) {
e.preventDefault();
var service_id = $("#service_id").val();
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: { type: "delete-service", service_id: service_id },
success: function(result){
if (result.status == 0) {
// Yay.
$('#message').html('<div class="alert alert-info">' + result.message + '</div>');
$("#row_"+service_id).remove();
$("#"+service_id).remove();
$("#confirm-delete").modal('hide');
}
else {
// Nay.
$("#message").html('<div class="alert alert-danger">'+result.message+'</div>');
$("#confirm-delete").modal('hide');
}
},
error: function(){
$("#message").html('<div class="alert alert-info">An error occurred deleting this service.</div>');
$("#confirm-delete").modal('hide');
}
});
});
</script>

View File

@@ -0,0 +1,145 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2016 Aaron Daniels <aaron@daniels.id.au>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
if(is_admin() !== false) {
// Build the types list.
if ($handle = opendir($config['nagios_plugins'])) {
while (false !== ($file = readdir($handle))) {
if ($file != '.' && $file != '..' && !strstr($file, '.') && strstr($file, 'check_')) {
list(,$check_name) = explode('_',$file,2);
$stype .= "<option value='$check_name'>$check_name</option>";
}
}
closedir($handle);
}
?>
<div class="modal fade bs-example-modal-sm" id="create-service" tabindex="-1" role="dialog" aria-labelledby="Create" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h5 class="modal-title" id="Create">Services</h5>
</div>
<div class="modal-body">
<form method="post" role="form" id="service" class="form-horizontal service-form">
<input type="hidden" name="service_id" id="service_id" value="">
<input type="hidden" name="device_id" id="device_id" value="<?=$device['device_id']?>">
<input type="hidden" name="type" id="type" value="create-service">
<div class="form-service">
<div class="col-sm-12">
<span id="ajax_response">&nbsp;</span>
</div>
</div>
<div class="form-service">
<label for='stype' class='col-sm-3 control-label'>Type: </label>
<div class="col-sm-9">
<select id='stype' name='stype' placeholder='type' class='form-control has-feedback'>
<?=$stype?>
</select>
</div>
</div>
<div class='form-service'>
<label for='desc' class='col-sm-3 control-label'>Description: </label>
<div class='col-sm-9'>
<input type='text' id='desc' name='desc' class='form-control'/>
</div>
</div>
<div class="form-service">
<label for='ip' class='col-sm-3 control-label'>IP Address: </label>
<div class="col-sm-9">
<input type='text' id='ip' name='ip' class='form-control has-feedback' placeholder='<?=$device['hostname']?>'/>
</div>
</div>
<div class="form-service">
<label for='param' class='col-sm-3 control-label'>Parameters: </label>
<div class="col-sm-9">
<input type='text' id='param' name='param' class='form-control has-feedback' placeholder=''/>
</div>
</div>
<div class="form-service">
<div class="col-sm-offset-3 col-sm-9">
<button class="btn btn-success btn-sm" type="submit" name="service-submit" id="service-submit" value="save">Save Service</button>
</div>
</div>
<div class="clearfix"></div>
</form>
</div>
</div>
</div>
</div>
<script>
// on-hide
$('#create-service').on('hide.bs.modal', function (event) {
$('#stype').val('');
$("#stype").prop("disabled", false);
$('#ip').val('');
$('#desc').val('');
$('#param').val('');
});
// on-load
$('#create-service').on('show.bs.modal', function (e) {
var button = $(e.relatedTarget);
var service_id = button.data('service_id');
var modal = $(this)
$('#service_id').val(service_id);
$.ajax({
type: "POST",
url: "ajax_form.php",
data: { type: "parse-service", service_id: service_id },
dataType: "json",
success: function(output) {
$('#stype').val(output['stype']);
$("#stype").prop("disabled", true);
$('#ip').val(output['ip']);
$('#desc').val(output['desc']);
$('#param').val(output['param']);
}
});
});
// on-submit
$('#service-submit').click('', function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "ajax_form.php",
data: $('form.service-form').serialize(),
success: function(result){
if (result.status == 0) {
// Yay.
$("#create-service").modal('hide');
$('#message').html('<div class="alert alert-info">' + result.message + '</div>');
setTimeout(function() {
location.reload(1);
}, 1500);
}
else {
// Nay.
$("#ajax_response").html('<div class="alert alert-danger">'+result.message+'</div>');
}
},
error: function(){
$("#ajax_response").html('<div class="alert alert-info">An error occurred creating this service.</div>');
}
});
});
</script>
<?php
}

View File

@@ -3,7 +3,7 @@ require $config['install_dir'].'/includes/object-cache.inc.php';
// FIXME - this could do with some performance improvements, i think. possible rearranging some tables and setting flags at poller time (nothing changes outside of then anyways)
$service_alerts = dbFetchCell("SELECT COUNT(service_id) FROM services WHERE service_status = '0'");
$service_status = service_status();
$if_alerts = dbFetchCell("SELECT COUNT(port_id) FROM `ports` WHERE `ifOperStatus` = 'down' AND `ifAdminStatus` = 'up' AND `ignore` = '0'");
if ($_SESSION['userlevel'] >= 5) {
@@ -219,18 +219,20 @@ if ($config['show_services']) {
<?php
if ($service_alerts) {
echo('
<li role="presentation" class="divider"></li>
<li><a href="services/state=down/"><i class="fa fa-bell-o fa-fw fa-lg"></i> Alerts ('.$service_alerts.')</a></li>');
if (($service_status[0] > 0) || ($service_status[2] > 0)) {
echo ' <li role="presentation" class="divider"></li>';
if ($service_status[2] > 0) {
echo ' <li><a href="services/state=warning/"><i class="fa fa-bell-o fa-col-warning fa-fw fa-lg"></i> Warning ('.$service_status[2].')</a></li>';
}
if ($service_status[0] > 0) {
echo ' <li><a href="services/state=critical/"><i class="fa fa-bell-o fa-col-danger fa-fw fa-lg"></i> Critical ('.$service_status[0].')</a></li>';
}
}
if ($_SESSION['userlevel'] >= '10') {
echo('
<li role="presentation" class="divider"></li>
<li><a href="addsrv/"><i class="fa fa-cog fa-col-success fa-fw fa-lg"></i> Add Service</a></li>
<li><a href="editsrv/"><i class="fa fa-cog fa-col-primary fa-fw fa-lg"></i> Edit Service</a></li>
<li><a href="delsrv/"><i class="fa fa-cog fa-col-danger fa-fw fa-lg"></i> Delete Service</a></li>');
<li><a href="addsrv/"><i class="fa fa-cog fa-col-success fa-fw fa-lg"></i> Add Service</a></li>');
}
?>
</ul>

View File

@@ -1,36 +0,0 @@
<?php
if (isset($_POST['service']) && is_numeric($_POST['service'])) {
$service = dbFetchRow('SELECT * FROM `services` WHERE `service_id`=?', array($_POST['service']));
echo "
<h3><span class='label label-primary threeqtr-width'>Edit Service</span></h3>
<form id='confirm-editsrv' name='confirm-editsrv' method='post' action='' class='form-horizontal' role='form'>
<input type='hidden' name='device' value='".$service['device_id']."'>
<input type='hidden' name='service' value='".$service['service_id']."'>
<div class='well well-lg'>
<div class='form-group'>
<label for='descr' class='col-sm-2 control-label'>Description</label>
<div class='col-sm-5'>
<textarea name='descr' id='descr' class='form-control input-sm' rows='5'>".$service['service_desc']."</textarea>
</div>
</div>
<div class='form-group'>
<label for='ip' class='col-sm-2 control-label'>IP Address</label>
<div class='col-sm-5'>
<input name='ip' id='ip' value='".$service['service_ip']."' class='form-control input-sm' placeholder='IP Address'>
</div>
</div>
<div class='form-group'>
<label for='params' class='col-sm-2 control-label'>Parameters</label>
<div class='col-sm-5'>
<input name='params' id='params' value='".$service['service_param']."' class='form-control input-sm'>
</div>
<div class='col-sm-5'>
This may be required based on the service check.
</div>
</div>
<button type='submit' id='confirm-editsrv' name='confirm-editsrv' value='yes' class='btn btn-primary input-sm'>Edit Service</button>
</div>
</form>";
}//end if

View File

@@ -1,77 +0,0 @@
<?php
if (!$samehost) {
if ($bg == $list_colour_a) {
$bg = $list_colour_b;
}
else {
$bg = $list_colour_a;
}
}
$service_type = strtolower($service['service_type']);
if ($service[service_status] == '0') {
$status = "<span class=red><b>$service_type</b></span>";
}
else if ($service[service_status] == '1') {
$status = "<span class=green><b>$service_type</b></span>";
}
else if ($service[service_status] == '2') {
$status = "<span class=grey><b>$service_type</b></span>";
}
$message = trim($service['service_message']);
$message = str_replace("\n", '<br />', $message);
$desc = trim($service['service_desc']);
$desc = str_replace("\n", '<br />', $desc);
$since = (time() - $service['service_changed']);
$since = formatUptime($since);
if ($service['service_checked']) {
$checked = (time() - $service['service_checked']);
$checked = formatUptime($checked);
}
else {
$checked = 'Never';
}
$mini_url = 'graph.php?id='.$service['service_id'].'&amp;type=service_availability&amp;from='.$config['time']['day'].'&amp;to='.$config['time']['now'].'&amp;width=80&amp;height=20&amp;bg=efefef';
$popup = "onmouseover=\"return overlib('<div class=list-large>".$device['hostname'].' - '.$service['service_type'];
$popup .= "</div><img src=\'graph.php?id=".$service['service_id'].'&amp;type=service_availability&amp;from='.$config['time']['day'].'&amp;to='.$config['time']['now']."&amp;width=400&amp;height=125\'>";
$popup .= "', RIGHT".$config['overlib_defaults'].');" onmouseout="return nd();"';
echo "
<tr>";
if ($device_id) {
if (!$samehost) {
echo "<td>".generate_device_link($device).'</span></td>';
}
else {
echo '<td></td>';
}
}
echo "
<td>
$status
</td>
<td>
$since
</td>
<td>
<span class='box-desc'>$message</span>
</td>
<td>
<span class='box-desc'>$desc</span>
</td>
<td>
<span class='box-desc'>$checked</span>
</td>
</tr>";
$i++;

View File

@@ -1,10 +0,0 @@
<?php
$updated = '1';
$service_id = add_service(mres($_POST['device']), mres($_POST['type']), mres($_POST['descr']), mres($_POST['ip']), mres($_POST['params']));
if ($service_id) {
$message .= $message_break.'Service added ('.$service_id.')!';
$message_break .= '<br />';
}

View File

@@ -1,10 +0,0 @@
<?php
$updated = '1';
$affected = dbDelete('services', '`service_id` = ?', array($_POST['service']));
if ($affected) {
$message .= $message_break.$rows.' service deleted!';
$message_break .= '<br />';
}

View File

@@ -1,5 +0,0 @@
<?php
$updated = '1';
$updated = edit_service(mres($_POST['service']), mres($_POST['descr']), mres($_POST['ip']), mres($_POST['params']));