diff --git a/LibreNMS/Alert/AlertUtil.php b/LibreNMS/Alert/AlertUtil.php index 31278909cd..877171ab39 100644 --- a/LibreNMS/Alert/AlertUtil.php +++ b/LibreNMS/Alert/AlertUtil.php @@ -175,12 +175,16 @@ class AlertUtil public static function getRules($device_id) { $query = "SELECT DISTINCT a.* FROM alert_rules a - LEFT JOIN alert_device_map d ON a.id=d.rule_id - LEFT JOIN alert_group_map g ON a.id=g.rule_id - LEFT JOIN device_group_device dg ON g.group_id=dg.device_group_id - WHERE a.disabled = 0 AND ((d.device_id IS NULL AND g.group_id IS NULL) OR d.device_id=? OR dg.device_id=?)"; + LEFT JOIN alert_device_map d ON a.id=d.rule_id AND d.device_id = ? + LEFT JOIN alert_group_map g ON a.id=g.rule_id AND (a.invert_map = 0 OR a.invert_map = 1 AND g.group_id IN (SELECT DISTINCT device_group_id FROM device_group_device WHERE device_id = ?)) + LEFT JOIN device_group_device dg ON g.group_id=dg.device_group_id AND dg.device_id = ? + WHERE a.disabled = 0 AND ( + (d.device_id IS NULL AND g.group_id IS NULL) + OR (a.invert_map = 0 AND (d.device_id=? OR dg.device_id=?)) + OR (a.invert_map = 1 AND (d.device_id != ? OR d.device_id IS NULL) AND (dg.device_id != ? OR dg.device_id IS NULL)) + )"; - $params = [$device_id, $device_id]; + $params = [$device_id, $device_id, $device_id, $device_id, $device_id, $device_id, $device_id]; return dbFetchRows($query, $params); } diff --git a/database/migrations/2019_12_17_151314_add_invert_map_to_alert_rules.php b/database/migrations/2019_12_17_151314_add_invert_map_to_alert_rules.php new file mode 100644 index 0000000000..a8caf5d17d --- /dev/null +++ b/database/migrations/2019_12_17_151314_add_invert_map_to_alert_rules.php @@ -0,0 +1,32 @@ +boolean('invert_map')->default(0); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('alert_rules', function (Blueprint $table) { + $table->dropColumn(['invert_map']); + }); + } +} diff --git a/includes/html/forms/alert-rules.inc.php b/includes/html/forms/alert-rules.inc.php index 1204acb10c..92cf6eb96a 100644 --- a/includes/html/forms/alert-rules.inc.php +++ b/includes/html/forms/alert-rules.inc.php @@ -58,6 +58,7 @@ $invert = mres(isset($_POST['invert']) ? $_POST['invert'] : null); $name = mres($_POST['name']); $proc = mres($_POST['proc']); $recovery = ($vars['recovery']); +$invert_map = mres(isset($_POST['invert_map']) ? $_POST['invert_map'] : null); $severity = mres($_POST['severity']); if (!is_numeric($count)) { @@ -81,6 +82,12 @@ if ($invert == 'on') { $recovery = empty($recovery) ? $recovery = false : true; +if ($invert_map == 'on') { + $invert_map = true; +} else { + $invert_map = false; +} + $extra = array( 'mute' => $mute, 'count' => $count, @@ -101,7 +108,8 @@ if (is_numeric($rule_id) && $rule_id > 0) { 'name' => $name, 'proc' => $proc, 'query' => $query, - 'builder' => $builder_json + 'builder' => $builder_json, + 'invert_map' => $invert_map ), 'alert_rules', 'id=?', @@ -128,7 +136,8 @@ if (is_numeric($rule_id) && $rule_id > 0) { 'name' => $name, 'proc' => $proc, 'query' => $query, - 'builder' => $builder_json + 'builder' => $builder_json, + 'invert_map' => $invert_map ), 'alert_rules'); if ($rule_id) { diff --git a/includes/html/forms/parse-alert-rule.inc.php b/includes/html/forms/parse-alert-rule.inc.php index bd04744a29..4e521bc929 100644 --- a/includes/html/forms/parse-alert-rule.inc.php +++ b/includes/html/forms/parse-alert-rule.inc.php @@ -77,5 +77,6 @@ if (is_array($rule)) { 'builder' => $builder, 'severity' => $rule['severity'], 'adv_query' => $rule['query'], + 'invert_map' => $rule['invert_map'], ]); } diff --git a/includes/html/modal/new_alert_rule.inc.php b/includes/html/modal/new_alert_rule.inc.php index 54d47dd585..44d287f3c5 100644 --- a/includes/html/modal/new_alert_rule.inc.php +++ b/includes/html/modal/new_alert_rule.inc.php @@ -98,7 +98,7 @@ if (Auth::user()->hasGlobalAdmin()) {
- +
@@ -109,11 +109,15 @@ if (Auth::user()->hasGlobalAdmin()) { -
- -
+
+ +
+
+ + +
@@ -292,6 +296,7 @@ if (Auth::user()->hasGlobalAdmin()) { $("#invert").bootstrapSwitch('state', false); $("#recovery").bootstrapSwitch('state', true); $("#override_query").bootstrapSwitch('state', false); + $("#invert_map").bootstrapSwitch('state', false); $(this).find("input[type=text]").val(""); $('#count').val('-1'); $('#delay').val('1m'); @@ -365,12 +370,12 @@ if (Auth::user()->hasGlobalAdmin()) { if (extra.adv_query) { $('#adv_query').val(extra.adv_query); } - $("[name='mute']").bootstrapSwitch('state', extra.mute); $("[name='invert']").bootstrapSwitch('state', extra.invert); if (typeof extra.recovery == 'undefined') { extra.recovery = true; } + if (typeof extra.options == 'undefined') { extra.options = new Array(); } @@ -378,6 +383,13 @@ if (Auth::user()->hasGlobalAdmin()) { extra.options.override_query = false; } $("[name='recovery']").bootstrapSwitch('state', extra.recovery); + + if (rule.invert_map == 1) { + $("[name='invert_map']").bootstrapSwitch('state', true); + }else{ + $("[name='invert_map']").bootstrapSwitch('state', false); + } + $("[name='override_query']").bootstrapSwitch('state', extra.options.override_query); } else { $('#count').val('-1'); diff --git a/misc/db_schema.yaml b/misc/db_schema.yaml index 0c28c0f2a5..8a2991ea0e 100644 --- a/misc/db_schema.yaml +++ b/misc/db_schema.yaml @@ -75,6 +75,7 @@ alert_rules: - { Field: query, Type: text, 'Null': false, Extra: '' } - { Field: builder, Type: text, 'Null': false, Extra: '' } - { Field: proc, Type: varchar(80), 'Null': true, Extra: '' } + - { Field: invert_map, Type: tinyint(1), 'Null': false, Extra: '', Default: '0' } Indexes: PRIMARY: { Name: PRIMARY, Columns: [id], Unique: true, Type: BTREE } name: { Name: name, Columns: [name], Unique: true, Type: BTREE }