diff --git a/pandora_console/extras/mr/52.sql b/pandora_console/extras/mr/52.sql index b32d41238c..d001b243e6 100644 --- a/pandora_console/extras/mr/52.sql +++ b/pandora_console/extras/mr/52.sql @@ -5,6 +5,12 @@ CREATE INDEX `IDX_tservice_element` ON `tservice_element`(`id_service`,`id_agent ALTER TABLE `tusuario` ADD COLUMN `local_user` tinyint(1) unsigned NOT NULL DEFAULT 0; ALTER TABLE tevent_response ADD COLUMN display_command tinyint(1) default 0; +ALTER TABLE `talert_execution_queue` + DROP COLUMN `id_alert_template_module`, + DROP COLUMN `alert_mode`, + DROP COLUMN `extra_macros`, + MODIFY COLUMN `data` LONGTEXT; + ALTER TABLE `talert_templates` ADD COLUMN `schedule` TEXT; ALTER TABLE `tevent_alert` ADD COLUMN `schedule` TEXT; diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index eaf855798e..66729f092f 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -4124,14 +4124,11 @@ ALTER TABLE `tperfil` ADD COLUMN `network_config_management`tinyint(1) NOT NULL -- Table `talert_execution_queue` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `talert_execution_queue` ( - `id` int(10) unsigned NOT NULL auto_increment, - `id_alert_template_module` int(10) unsigned NOT NULL, - `alert_mode` tinyint(1) NOT NULL, - `data` mediumtext NOT NULL, - `extra_macros` text, - `utimestamp` bigint(20) NOT NULL default '0', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `data` LONGTEXT, + `utimestamp` BIGINT NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; UPDATE `tlanguage` SET `name` = 'Deutsch' WHERE `id_language` = 'de'; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 1f4139114b..a38e4510c0 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -605,10 +605,7 @@ CREATE TABLE IF NOT EXISTS `talert_special_days` ( -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `talert_execution_queue` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `id_alert_template_module` INT UNSIGNED NOT NULL, - `alert_mode` TINYINT NOT NULL, - `data` MEDIUMTEXT, - `extra_macros` TEXT, + `data` LONGTEXT, `utimestamp` BIGINT NOT NULL DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; diff --git a/pandora_server/lib/PandoraFMS/AlertServer.pm b/pandora_server/lib/PandoraFMS/AlertServer.pm index 01cd255c64..8173ffcc7b 100644 --- a/pandora_server/lib/PandoraFMS/AlertServer.pm +++ b/pandora_server/lib/PandoraFMS/AlertServer.pm @@ -1,8 +1,8 @@ package PandoraFMS::AlertServer; -########################################################################## +################################################################################ # Pandora FMS Alert Server. # Pandora FMS. the Flexible Monitoring System. http://www.pandorafms.org -########################################################################## +################################################################################ # Copyright (c) 2005-2021 Artica Soluciones Tecnologicas S.L # # This program is free software; you can redistribute it and/or @@ -15,7 +15,7 @@ package PandoraFMS::AlertServer; # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -########################################################################## +################################################################################ use strict; use warnings; @@ -24,6 +24,7 @@ use threads; use threads::shared; use Thread::Semaphore; +use MIME::Base64; use JSON; use POSIX qw(strftime); @@ -47,9 +48,9 @@ my $AlertSem :shared; my %Alerts :shared; my $EventRef :shared = 0; -######################################################################################## +################################################################################ # Alert Server class constructor. -######################################################################################## +################################################################################ sub new ($$$) { my ($class, $config, $dbh) = @_; @@ -69,9 +70,9 @@ sub new ($$$) { return $self; } -############################################################################### +################################################################################ # Run. -############################################################################### +################################################################################ sub run ($) { my $self = shift; my $pa_config = $self->getConfig (); @@ -81,9 +82,9 @@ sub run ($) { $self->SUPER::run (\@TaskQueue, \%PendingTasks, $Sem, $TaskSem); } -############################################################################### +################################################################################ # Data producer. -############################################################################### +################################################################################ sub data_producer ($) { my $self = shift; my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); @@ -120,14 +121,16 @@ sub data_producer ($) { return @tasks; } -############################################################################### +################################################################################ # Data consumer. -############################################################################### +################################################################################ sub data_consumer ($$) { my ($self, $task_id) = @_; my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); eval {{ + local $SIG{__DIE__}; + # Get the alert from the queue. my $task = get_db_single_row ($dbh, 'SELECT * FROM talert_execution_queue WHERE id = ?', $task_id); if (! defined ($task)) { @@ -135,42 +138,40 @@ sub data_consumer ($$) { last 0; } - # Get the alert data. - my $alert = get_db_single_row ($dbh, 'SELECT talert_template_modules.id as id_template_module, - talert_template_modules.*, talert_templates.* - FROM talert_template_modules, talert_templates - WHERE talert_template_modules.id_alert_template = talert_templates.id - AND talert_template_modules.id = ?', $task->{'id_alert_template_module'}); - if (! defined ($alert)) { - logger($pa_config, "Alert ID " . $task->{'id_alert_template_module'} . " not found.", 10); - last; + my $args = PandoraFMS::Tools::p_decode_json( + $pa_config, + decode_base64($task->{'data'}) + ); + + if (ref $args ne "ARRAY") { + die ('Invalid alert queued'); } - # Get the agent and module associated with the alert - my $module = get_db_single_row ($dbh, 'SELECT * FROM tagente_modulo WHERE id_agente_modulo = ?', $alert->{'id_agent_module'}); - if (! defined ($module)) { - logger($pa_config, "Module ID " . $alert->{'id_agent_module'} . " not found for alert ID " . $alert->{'id_template_module'} . ".", 10); - last; - } - my $agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE id_agente = ?', $module->{'id_agente'}); - if (! defined ($agent)) { - logger($pa_config, "Agent ID " . $module->{'id_agente'} . " not found for module ID " . $module->{'id_agente_modulo'} . " alert ID " . $alert->{'id_template_module'} . ".", 10); - last; - } + my @args = @{$args}; - # Execute the alert. - pandora_execute_alert ($pa_config, $task->{'data'}, $agent, $module, $alert, $task->{'alert_mode'}, - $dbh, strftime ("%Y-%m-%d %H:%M:%S", localtime()), 0, decode_json($task->{'extra_macros'})); + # You cannot code a DBI object into JSON, use current. + my $execution_args = [ + $pa_config, + @args[0..4], + $dbh, + @args[5..$#args] + ]; + + # Execute. + PandoraFMS::Core::pandora_execute_alert(@$execution_args); }}; + if ($@) { + logger ($pa_config,"[ERROR] Executing alert ".$@, 0); + } # Remove the alert from the queue and unlock. db_do($dbh, 'DELETE FROM talert_execution_queue WHERE id=?', $task_id); alert_unlock($pa_config, $task_id); } -########################################################################## +################################################################################ # Get a lock on the given alert. Return 1 on success, 0 otherwise. -########################################################################## +################################################################################ sub alert_lock { my ($pa_config, $alert, $locked_alerts) = @_; @@ -186,9 +187,9 @@ sub alert_lock { return 1; } -########################################################################## +################################################################################ # Remove the lock on the given alert. -########################################################################## +################################################################################ sub alert_unlock { my ($pa_config, $alert) = @_; diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 8d74df5d68..7658f784eb 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -776,10 +776,12 @@ sub pandora_process_alert ($$$$$$$$;$$) { db_do($dbh, 'UPDATE talert_template_module_actions SET last_execution = 0 WHERE id_alert_template_module = ?', $id); } - if ($pa_config->{'alertserver'} == 1 && defined ($alert->{'id_template_module'})) { - pandora_queue_alert($pa_config, $dbh, $data, $alert, 0, $extra_macros); + if ($pa_config->{'alertserver'} == 1) { + pandora_queue_alert($pa_config, $dbh, [$data, $agent, $module, + $alert, 0, $timestamp, 0, $extra_macros, $is_correlated_alert]); } else { - pandora_execute_alert ($pa_config, $data, $agent, $module, $alert, 0, $dbh, $timestamp, 0, $extra_macros, $is_correlated_alert); + pandora_execute_alert ($pa_config, $data, $agent, $module, $alert, 0, $dbh, + $timestamp, 0, $extra_macros, $is_correlated_alert); } return; } @@ -820,8 +822,9 @@ sub pandora_process_alert ($$$$$$$$;$$) { last_fired = ?, internal_counter = ? ' . $new_interval . ' WHERE id = ?', $alert->{'times_fired'}, $utimestamp, $alert->{'internal_counter'}, $id); - if ($pa_config->{'alertserver'} == 1 && defined ($alert->{'id_template_module'})) { - pandora_queue_alert($pa_config, $dbh, $data, $alert, 1, $extra_macros); + if ($pa_config->{'alertserver'} == 1) { + pandora_queue_alert($pa_config, $dbh, [$data, $agent, $module, + $alert, 1, $timestamp, 0, $extra_macros, $is_correlated_alert]); } else { pandora_execute_alert ($pa_config, $data, $agent, $module, $alert, 1, $dbh, $timestamp, 0, $extra_macros, $is_correlated_alert); @@ -837,7 +840,7 @@ Execute the given alert. =cut ########################################################################## -sub pandora_execute_alert ($$$$$$$$$;$$) { +sub pandora_execute_alert { my ($pa_config, $data, $agent, $module, $alert, $alert_mode, $dbh, $timestamp, $forced_alert, $extra_macros, $is_correlated_alert) = @_; @@ -1081,17 +1084,15 @@ Queue the given alert for execution. =cut ########################################################################## -sub pandora_queue_alert ($$$$$;$) { - my ($pa_config, $dbh, $data, $alert, $alert_mode, $extra_macros) = @_; - my $json_macros = '{}'; +sub pandora_queue_alert ($$$) { + my ($pa_config, $dbh, $arguments) = @_; - eval { - local $SIG{__DIE__}; - $json_macros = encode_json($extra_macros); - }; + my $json_arguments = PandoraFMS::Tools::p_encode_json($pa_config, $arguments); - db_do ($dbh, "INSERT INTO talert_execution_queue (id_alert_template_module, data, alert_mode, extra_macros, utimestamp) - VALUES (?, ?, ?, ?, ?)", $alert->{'id_template_module'}, $data, $alert_mode, $json_macros, time()); + $json_arguments = encode_base64($json_arguments); + + db_do ($dbh, "INSERT INTO talert_execution_queue (data, utimestamp) + VALUES (?, ?)", $json_arguments, time()); } ########################################################################## diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index bcffd78034..d68f4e4050 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -1130,9 +1130,9 @@ sub enterprise_hook ($$) { my $output = eval { &$func (@args); }; # Discomment to debug. - if ($@) { - print STDERR $@; - } + #if ($@) { + # print STDERR $@; + #} # Check for errors #return undef if ($@); @@ -2640,7 +2640,7 @@ sub p_encode_json { }; if ($@){ if (defined($data)) { - logger($pa_config, 'Failed to encode data: '.$@, 5); + logger($pa_config, 'Failed to encode data: '.$@, 1); } }