From 976a32617f966429ed33748c7b741c2cabb98764 Mon Sep 17 00:00:00 2001 From: "felix.suarez" Date: Thu, 24 Aug 2023 17:35:07 -0600 Subject: [PATCH] Add logic to complex alerts --- pandora_console/extras/mr/66.sql | 7 +-- .../alerts/configure_alert_template.php | 2 +- pandora_console/pandoradb.sql | 6 +-- pandora_server/lib/PandoraFMS/Core.pm | 43 +++++++++++++++++++ 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/pandora_console/extras/mr/66.sql b/pandora_console/extras/mr/66.sql index f22fe338be..526602e24c 100644 --- a/pandora_console/extras/mr/66.sql +++ b/pandora_console/extras/mr/66.sql @@ -24,9 +24,9 @@ UPDATE tpolicy_modules SET `tcp_send` = '2c' WHERE `tcp_send` = '2'; UPDATE tnetwork_component SET `tcp_send` = '2c' WHERE `tcp_send` = '2'; ALTER TABLE talert_templates -ADD COLUMN `time_window` VARCHAR(25) DEFAULT NULL, -ADD COLUMN `math_function` VARCHAR(25) DEFAULT NULL, -ADD COLUMN `condition` VARCHAR(25) DEFAULT NULL, +ADD COLUMN `time_window` ENUM ('thirty_days','this_month','seven_days','this_week','one_day','today'), +ADD COLUMN `math_function` ENUM ('avg', 'min', 'max', 'sum'), +ADD COLUMN `condition` ENUM ('lower', 'greater', 'equal'), MODIFY COLUMN `type` ENUM ('regex', 'max_min', 'max', 'min', 'equal', 'not_equal', 'warning', 'critical', 'onchange', 'unknown', 'always', 'not_normal', 'complex'); ALTER TABLE `tsesion_filter_log_viewer` @@ -72,4 +72,5 @@ ALTER TABLE `treport_content` ADD COLUMN `cat_security_hardening` INT NOT NULL ALTER TABLE `treport_content` ADD COLUMN `ignore_skipped` INT NOT NULL DEFAULT 0; ALTER TABLE `treport_content` ADD COLUMN `status_of_check` TINYTEXT; + COMMIT; diff --git a/pandora_console/godmode/alerts/configure_alert_template.php b/pandora_console/godmode/alerts/configure_alert_template.php index 10d0804a52..56b2d40085 100644 --- a/pandora_console/godmode/alerts/configure_alert_template.php +++ b/pandora_console/godmode/alerts/configure_alert_template.php @@ -1461,7 +1461,7 @@ function render_example () { /* Set condition */ var vCondition = $("select#condition").val(); - var conditionMessage = "[condition]"; + var conditionMessage = "" ; switch (vCondition){ case "greater": conditionMessage = (vfunction == "avg") ? "increases" : "is more than"; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 7271f62e7f..b8efa4b701 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -489,9 +489,9 @@ CREATE TABLE IF NOT EXISTS `talert_templates` ( `matches_value` TINYINT DEFAULT 0, `max_value` DOUBLE DEFAULT NULL, `min_value` DOUBLE DEFAULT NULL, - `time_window` VARCHAR(25) DEFAULT NULL, - `math_function` VARCHAR(25) DEFAULT NULL, - `condition` VARCHAR(25) DEFAULT NULL, + `time_window` ENUM ('thirty_days','this_month','seven_days','this_week','one_day','today'), + `math_function` ENUM ('avg', 'min', 'max', 'sum'), + `condition` ENUM ('lower', 'greater', 'equal'), `time_threshold` INT NOT NULL DEFAULT 0, `max_alerts` INT UNSIGNED NOT NULL DEFAULT 1, `min_alerts` INT UNSIGNED NOT NULL DEFAULT 0, diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index f2c7d46143..f7fb9be07b 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -704,6 +704,49 @@ sub pandora_evaluate_alert ($$$$$$$;$$$$) { return $status if (valid_regex ($alert->{'value'}) == 1 && $data =~ m/$alert->{'value'}/i); } } + + if($alert-> {'type'} eq "complex") { + + my @allowed_functions = ("sum", "min", "max", "avg"); + my %condition_map = ( + lower => '<', + greater => '>', + equal => '==', + ); + my %time_windows_map = ( + thirty_days => sub { return time - 30 * 24 * 60 * 60 }, + this_month => sub { return timelocal(0, 0, 0, 1, (localtime)[4, 5]) }, + seven_days => sub { return time - 7 * 24 * 60 * 60 }, + this_week => sub { return time - ((localtime)[6] % 7) * 24 * 60 * 60 }, + one_day => sub { return time - 1 * 24 * 60 * 60 }, + today => sub { return timelocal(0, 0, 0, (localtime)[3, 4, 5]) }, + ); + + my $function = $alert-> {'math_function'}; + my $condition = $condition_map{$alert->{'condition'}}; + my $window = $time_windows_map{$alert->{'time_window'}}; + my $value = defined $alert->{'value'} && $alert->{'value'} ne "" ? $alert->{'value'} : 0; + + if((grep { $_ eq $function } @allowed_functions) == 1 && defined($condition) && defined($window)){ + + my $query = "SELECT IFNULL($function(datos), 0) AS $function + FROM tagente_datos + WHERE id_agente_modulo = ? AND utimestamp > ?"; + + my $historical_value = get_db_value($dbh, $query, $alert->{"id_agent_module"}, $window->()); + + my $activate_alert = 0; + if($function eq "avg"){ + # Check if the received value meets the condition compared to the avg. + $activate_alert = eval("$historical_value $condition $data"); + }else{ + # Check if the hiscorical value meets the condition compared to the val. + $activate_alert = eval("$historical_value $condition $value"); + } + + return $status if $activate_alert; + } + } return $status if ($last_status != 1 && $alert->{'type'} eq 'critical'); return $status if ($last_status != 2 && $alert->{'type'} eq 'warning');