Added ability to set a custom SQL query for alert rules. (#9094)

* Added support for AVG in rules

* More updates

* Final work to have advanced sql queries

* Added missing use

* Fix exception when invalid json is passed

* Fixed api for alert rules

* updated docs
This commit is contained in:
Neil Lathwood
2018-09-19 13:47:45 +01:00
committed by Tony Murray
parent 53a1730fc7
commit 466b5a35a8
10 changed files with 200 additions and 116 deletions

View File

@@ -13,6 +13,7 @@
*/
use LibreNMS\Authentication\LegacyAuth;
use LibreNMS\Alerting\QueryBuilderParser;
function authToken(\Slim\Route $route)
{
@@ -1063,20 +1064,28 @@ function add_edit_rule()
check_is_admin();
$app = \Slim\Slim::getInstance();
$data = json_decode(file_get_contents('php://input'), true);
if (json_last_error()) {
api_error(500, "We couldn't parse the provided json");
}
$rule_id = mres($data['rule_id']);
$device_id = mres($data['device_id']);
if (empty($device_id) && !isset($rule_id)) {
api_error(400, 'Missing the device id or global device id (-1)');
$tmp_devices = (array)mres($data['devices']);
$groups = (array)$data['groups'];
if (empty($tmp_devices) && !isset($rule_id)) {
api_error(400, 'Missing the devices or global device (-1)');
}
if ($device_id == 0) {
$device_id = '-1';
$devices = [];
foreach ($tmp_devices as $device) {
if ($device == "-1") {
continue;
}
$devices[] = ctype_digit($device) ? $device : getidbyname($device);
}
$rule = $data['rule'];
if (empty($rule)) {
api_error(400, 'Missing the alert rule');
$builder = $data['builder'] ?: $data['rule'];
if (empty($builder)) {
api_error(400, 'Missing the alert builder rule');
}
$name = mres($data['name']);
@@ -1102,6 +1111,8 @@ function add_edit_rule()
$count = mres($data['count']);
$mute = mres($data['mute']);
$delay = mres($data['delay']);
$override_query = $data['override_query'];
$adv_query = $data['adv_query'];
$delay_sec = convert_delay($delay);
if ($mute == 1) {
$mute = true;
@@ -1109,31 +1120,46 @@ function add_edit_rule()
$mute = false;
}
$extra = array(
$extra = [
'mute' => $mute,
'count' => $count,
'delay' => $delay_sec,
);
'options' =>
[
'override_query' => $override_query
],
];
$extra_json = json_encode($extra);
if ($override_query === 'on') {
$query = $adv_query;
} else {
$query = QueryBuilderParser::fromJson($builder)->toSql();
if (empty($query)) {
api_error(500, "We couldn't parse your rule");
}
}
if (!isset($rule_id)) {
if (dbFetchCell('SELECT `name` FROM `alert_rules` WHERE `name`=?', array($name)) == $name) {
api_error(500, 'Addition failed : Name has already been used');
}
} else {
if (dbFetchCell("SELECT name FROM alert_rules WHERE name=? AND id !=? ", array($name, $rule_id)) == $name) {
api_error(500, 'Addition failed : Name has already been used');
api_error(500, 'Update failed : Invalid rule id');
}
}
if (is_numeric($rule_id)) {
if (!(dbUpdate(array('name' => $name, 'rule' => $rule, 'severity' => $severity, 'disabled' => $disabled, 'extra' => $extra_json), 'alert_rules', 'id=?', array($rule_id)) >= 0)) {
if (!(dbUpdate(array('name' => $name, 'builder' => $builder, 'query' => $query, 'severity' => $severity, 'disabled' => $disabled, 'extra' => $extra_json), 'alert_rules', 'id=?', array($rule_id)) >= 0)) {
api_error(500, 'Failed to update existing alert rule');
}
} elseif (!dbInsert(array('name' => $name, 'device_id' => $device_id, 'rule' => $rule, 'severity' => $severity, 'disabled' => $disabled, 'extra' => $extra_json), 'alert_rules')) {
} elseif (!$rule_id = dbInsert(array('name' => $name, 'builder' => $builder, 'query' => $query, 'severity' => $severity, 'disabled' => $disabled, 'extra' => $extra_json), 'alert_rules')) {
api_error(500, 'Failed to create new alert rule');
}
dbSyncRelationship('alert_device_map', 'rule_id', $rule_id, 'device_id', $devices);
dbSyncRelationship('alert_group_map', 'rule_id', $rule_id, 'group_id', $groups);
api_success_noresult(200);
}