mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
feature: Added the option to select alert rules from a collection
This commit is contained in:
@@ -32,6 +32,8 @@ require_once '../includes/defaults.inc.php';
|
||||
require_once '../config.php';
|
||||
require_once '../includes/definitions.inc.php';
|
||||
require_once '../includes/functions.php';
|
||||
require_once 'includes/functions.inc.php';
|
||||
require_once 'includes/vars.inc.php';
|
||||
|
||||
set_debug($_REQUEST['debug']);
|
||||
|
||||
@@ -122,6 +124,18 @@ if (isset($_GET['term'],$_GET['device_id'])) {
|
||||
$obj = $ret;
|
||||
}
|
||||
}
|
||||
} elseif ($vars['type'] === 'alert_rule_collection') {
|
||||
$x=0;
|
||||
foreach (get_rules_from_json() as $rule) {
|
||||
if (str_contains($rule['name'], $vars['term'], true)) {
|
||||
$rule['id'] = $x;
|
||||
$tmp[] = $rule;
|
||||
}
|
||||
$x++;
|
||||
}
|
||||
if (is_array($tmp)) {
|
||||
$obj = $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
die(json_encode($obj));
|
||||
|
@@ -18,9 +18,22 @@ if (is_admin() === false) {
|
||||
}
|
||||
|
||||
$alert_id = $_POST['alert_id'];
|
||||
$template_id = $_POST['template_id'];
|
||||
|
||||
if (is_numeric($alert_id) && $alert_id > 0) {
|
||||
$rule = dbFetchRow('SELECT * FROM `alert_rules` WHERE `id` = ? LIMIT 1', array($alert_id));
|
||||
} elseif (is_numeric($template_id) && $template_id >= 0) {
|
||||
$x=0;
|
||||
foreach (get_rules_from_json() as $tmp_rule) {
|
||||
if ($x == $template_id) {
|
||||
$rule = $tmp_rule;
|
||||
break;
|
||||
}
|
||||
$x++;
|
||||
}
|
||||
logfile(json_encode($rule));
|
||||
}
|
||||
if (is_array($rule)) {
|
||||
$rule_split = preg_split('/([a-zA-Z0-9_\-\.\=\%\<\>\ \"\'\!\~\(\)\*\/\@\|]+[&&|\|\|]{2})/', $rule['rule'], -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
|
||||
$count = (count($rule_split) - 1);
|
||||
$rule_split[$count] = $rule_split[$count].' &&';
|
||||
|
@@ -1364,3 +1364,9 @@ function file_download($filename, $content)
|
||||
header('Pragma: public');
|
||||
echo $content;
|
||||
}
|
||||
|
||||
function get_rules_from_json()
|
||||
{
|
||||
global $config;
|
||||
return json_decode(file_get_contents($config['install_dir'] . '/misc/alert_rules.json'), true);
|
||||
}
|
||||
|
120
html/includes/modal/alert_rule_collection.inc.php
Normal file
120
html/includes/modal/alert_rule_collection.inc.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* search_rule_collection.inc.php
|
||||
*
|
||||
* LibreNMS search_rule_collection modal
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2016 Neil Lathwood
|
||||
* @author Neil Lathwood <neil@lathwood.co.uk>
|
||||
*/
|
||||
|
||||
if (is_admin() === false) {
|
||||
die('ERROR: You need to be admin');
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="modal fade" id="search_rule_modal" tabindex="-1" role="dialog" aria-labelledby="search_rule" 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">×</button>
|
||||
<h5 class="modal-title" id="search_rule">Search alert rule collection</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<input type="hidden" name="template_rule_id" id="template_rule_id" value="">
|
||||
<input type="text" id="rule_suggest" name="rule_suggest" class="form-control" placeholder="Start typing..."/>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="submit" id="rule_from_collection" name="rule_from_collection" value="Create" class="btn btn-sm btn-primary">
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
Rule:
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div id="rule_display"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var rule_suggestions = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
remote: {
|
||||
url: "ajax_rulesuggest.php?type=alert_rule_collection&term=%QUERY",
|
||||
filter: function (output) {
|
||||
return $.map(output, function (item) {
|
||||
return {
|
||||
name: item.name,
|
||||
id: item.id,
|
||||
rule: item.rule,
|
||||
};
|
||||
});
|
||||
},
|
||||
wildcard: "%QUERY"
|
||||
}
|
||||
});
|
||||
rule_suggestions.initialize();
|
||||
$('#rule_suggest').typeahead({
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 1,
|
||||
classNames: {
|
||||
menu: 'typeahead-left'
|
||||
}
|
||||
},
|
||||
{
|
||||
source: rule_suggestions.ttAdapter(),
|
||||
async: true,
|
||||
displayKey: 'name',
|
||||
valueKey: 'id',
|
||||
templates: {
|
||||
suggestion: Handlebars.compile('<p> {{name}}</p>')
|
||||
},
|
||||
limit: 20
|
||||
});
|
||||
|
||||
$("#rule_suggest").on("typeahead:selected typeahead:autocompleted", function(e,datum) {
|
||||
$("#template_rule_id").val(datum.id);
|
||||
$("#rule_display").html('<mark>' + datum.rule + '</mark>');
|
||||
});
|
||||
|
||||
$("#rule_from_collection").click('', function(e) {
|
||||
e.preventDefault();
|
||||
$("#template_id").val($("#template_rule_id").val());
|
||||
$("#search_rule_modal").modal('hide');
|
||||
$("#create-alert").modal('show');
|
||||
});
|
||||
|
||||
$("#search_rule_modal").on('hidden.bs.modal', function(e) {
|
||||
$("#template_rule_id").val('');
|
||||
$("#rule_suggest").val('');
|
||||
$("#rule_display").html('');
|
||||
});
|
||||
|
||||
</script>
|
@@ -31,6 +31,7 @@ if (is_admin() !== false) {
|
||||
<input type="hidden" name="device_id" id="device_id" value="">
|
||||
<input type="hidden" name="alert_id" id="alert_id" value="">
|
||||
<input type="hidden" name="type" id="type" value="create-alert-item">
|
||||
<input type="hidden" name="template_id" id="template_id" value="">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<span id="ajax_response"></span>
|
||||
@@ -170,6 +171,25 @@ $('#create-alert').on('show.bs.modal', function (event) {
|
||||
var device_id = button.data('device_id');
|
||||
var alert_id = button.data('alert_id');
|
||||
var modal = $(this)
|
||||
var template_id = $('#template_id').val();
|
||||
$('#template_id').val('');
|
||||
var arr = [];
|
||||
if (template_id >= 0) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "ajax_form.php",
|
||||
data: { type: "parse-alert-rule", alert_id: null, template_id: template_id },
|
||||
dataType: "json",
|
||||
success: function(output) {
|
||||
$.each ( output['rules'], function( key, value ) {
|
||||
arr.push(value);
|
||||
});
|
||||
$('#response').data('tagmanager').populate(arr);
|
||||
$('#name').val(output['name']);
|
||||
$('#device_id').val("-1");
|
||||
}
|
||||
});
|
||||
}
|
||||
$('#device_id').val(device_id);
|
||||
$('#alert_id').val(alert_id);
|
||||
$('#tagmanager').tagmanager();
|
||||
@@ -182,7 +202,7 @@ $('#create-alert').on('show.bs.modal', function (event) {
|
||||
tagFieldName: 'maps[]',
|
||||
initialCap: false
|
||||
});
|
||||
if( $('#alert_id').val() == '' ) {
|
||||
if( $('#alert_id').val() == '' || template_id == '') {
|
||||
$('#preseed-maps').show();
|
||||
} else {
|
||||
$('#preseed-maps').hide();
|
||||
@@ -193,7 +213,6 @@ $('#create-alert').on('show.bs.modal', function (event) {
|
||||
data: { type: "parse-alert-rule", alert_id: alert_id },
|
||||
dataType: "json",
|
||||
success: function(output) {
|
||||
var arr = [];
|
||||
$.each ( output['rules'], function( key, value ) {
|
||||
arr.push(value);
|
||||
});
|
||||
|
@@ -37,7 +37,7 @@ if (isset($_POST['create-default'])) {
|
||||
);
|
||||
$default_rules[] = array(
|
||||
'device_id' => '-1',
|
||||
'rule' => '%bgpPeers.bgpPeerFsmEstablishedTime < "300" && %bgpPeers.bgpPeerState = "established"',
|
||||
'rule' => '%bgpPeers.bgpPeerFsmEstablishedTime < "300" && %bgpPeers.bgpPeerState = "established" && %macros.device_up = "1"',
|
||||
'severity' => 'critical',
|
||||
'extra' => '{"mute":false,"count":"1","delay":"300"}',
|
||||
'disabled' => 0,
|
||||
@@ -61,7 +61,7 @@ if (isset($_POST['create-default'])) {
|
||||
);
|
||||
$default_rules[] = array(
|
||||
'device_id' => '-1',
|
||||
'rule' => '%sensors.sensor_current > %sensors.sensor_limit && %sensors.sensor_alert = "1"',
|
||||
'rule' => '%sensors.sensor_current > %sensors.sensor_limit && %sensors.sensor_alert = "1" && %macros.device_up = "1"',
|
||||
'severity' => 'critical',
|
||||
'extra' => '{"mute":false,"count":"-1","delay":"300"}',
|
||||
'disabled' => 0,
|
||||
@@ -69,7 +69,7 @@ if (isset($_POST['create-default'])) {
|
||||
);
|
||||
$default_rules[] = array(
|
||||
'device_id' => '-1',
|
||||
'rule' => '%sensors.sensor_current < %sensors.sensor_limit_low && %sensors.sensor_alert = "1"',
|
||||
'rule' => '%sensors.sensor_current < %sensors.sensor_limit_low && %sensors.sensor_alert = "1" && %macros.device_up = "1"',
|
||||
'severity' => 'critical',
|
||||
'extra' => '{"mute":false,"count":"-1","delay":"300"}',
|
||||
'disabled' => 0,
|
||||
@@ -77,7 +77,7 @@ if (isset($_POST['create-default'])) {
|
||||
);
|
||||
$default_rules[] = array(
|
||||
'device_id' => '-1',
|
||||
'rule' => '%services.service_status != "0"',
|
||||
'rule' => '%services.service_status != "0" && %macros.device_up = "1"',
|
||||
'severity' => 'critical',
|
||||
'extra' => '{"mute":false,"count":"-1","delay":"300"}',
|
||||
'disabled' => 0,
|
||||
@@ -92,6 +92,7 @@ if (isset($_POST['create-default'])) {
|
||||
|
||||
require_once 'includes/modal/new_alert_rule.inc.php';
|
||||
require_once 'includes/modal/delete_alert_rule.inc.php';
|
||||
require_once 'includes/modal/alert_rule_collection.inc.php';
|
||||
?>
|
||||
<form method="post" action="" id="result_form">
|
||||
<?php
|
||||
@@ -117,8 +118,9 @@ echo '<div class="table-responsive">
|
||||
echo '<td colspan="7">';
|
||||
if ($_SESSION['userlevel'] >= '10') {
|
||||
echo '<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#create-alert" data-device_id="'.$device['device_id'].'"><i class="fa fa-plus"></i> Create new alert rule</button>';
|
||||
echo '<i> - OR - </i>';
|
||||
echo '<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#search_rule_modal" data-device_id="'.$device['device_id'].'"><i class="fa fa-plus"></i> Create rule from collection</button>';
|
||||
}
|
||||
|
||||
echo '</td>
|
||||
<td><select name="results" id="results" class="form-control input-sm" onChange="updateResults(this);">';
|
||||
$result_options = array(
|
||||
@@ -338,4 +340,11 @@ function changePage(page,e) {
|
||||
$('#result_form').submit();
|
||||
}
|
||||
|
||||
function newRule(data, e) {
|
||||
$('#template_id').val(data.value);
|
||||
$('#create-alert').modal({
|
||||
show: true
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
26
misc/alert_rules.json
Normal file
26
misc/alert_rules.json
Normal file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"rule": "%macros.bill_quota_over_quota >= \"75\"",
|
||||
"name": "Quota bills over 75% used"
|
||||
},
|
||||
{
|
||||
"rule": "%macros.bill_cdr_over_quota >= \"75\"",
|
||||
"name": "CDR bills over 75% used"
|
||||
},
|
||||
{
|
||||
"rule": "%ipsec_tunnels.tunnel_status != \"active\" && %macros.device_up = \"1\"",
|
||||
"name": "IPSec tunnels down"
|
||||
},
|
||||
{
|
||||
"rule": "%pollers.time_taken >= \"250\"",
|
||||
"name": "Poller is taking too long"
|
||||
},
|
||||
{
|
||||
"rule": "%macros.device_up = \"1\" && %devices.os = \"asa\" && %ciscoASA.data > \"5000\"",
|
||||
"name": "Cisco ASA connections over 5000"
|
||||
},
|
||||
{
|
||||
"rule": "%processors.processor_usage > \"85\" && %macros.device_up = \"1\"",
|
||||
"name": "Processor usage over 85%"
|
||||
}
|
||||
]
|
2
sql-schema/149.sql
Normal file
2
sql-schema/149.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
INSERT INTO `config` (config_name,config_value,config_default,config_descr,config_group,config_group_order,config_sub_group,config_sub_group_order,config_hidden,config_disabled) VALUES ('alert.macros.rule.bill_quota_over_quota','((%bills.total_data/%bills.bill_quota) * 100) && %bills.bill_type = "quota"','((%bills.total_data/%bills.bill_quota) * 100) && %bills.bill_type = "quota"','Quota bills over X perc of quota','alerting',0,'macros',0,1,0);
|
||||
INSERT INTO `config` (config_name,config_value,config_default,config_descr,config_group,config_group_order,config_sub_group,config_sub_group_order,config_hidden,config_disabled) VALUES ('alert.macros.rule.bill_cdr_over_quota','((%bills.rate_95th/%bills.bill_cdr) * 100) && %bills.bill_type = "cdr"','((%bills.rate_95th/%bills.bill_cdr) * 100) && %bills.bill_type = "cdr"','CDR bills over X perc of quota','alerting',0,'macros',0,1,0);
|
38
tests/AlertingTest.php
Normal file
38
tests/AlertingTest.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* AlertingTest.php
|
||||
*
|
||||
* Tests for alerting functionality.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2016 Neil Lathwood
|
||||
* @author Neil Lathwood <neil@lathwood.co.uk>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Tests;
|
||||
|
||||
class AlertTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testJsonAlertCollection()
|
||||
{
|
||||
$rules = get_rules_from_json();
|
||||
$this->assertInternalType('array', $rules);
|
||||
foreach ($rules as $rule) {
|
||||
$this->assertInternalType('array', $rule);
|
||||
}
|
||||
}
|
||||
}
|
@@ -37,6 +37,7 @@ $runtime_stats = array('snmpget' => 0, 'snmpwalk' => 0);
|
||||
$classLoader->registerDir($install_dir . '/tests', 'LibreNMS\Tests');
|
||||
|
||||
require $install_dir . '/includes/common.php';
|
||||
require $install_dir . '/html/includes/functions.inc.php';
|
||||
if (getenv('SNMPSIM')) {
|
||||
require $install_dir . '/includes/functions.php';
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user