From dec77331486cf75aa82337f41ee5d9c9be11956f Mon Sep 17 00:00:00 2001 From: marcos Date: Wed, 12 Feb 2020 11:47:43 +0100 Subject: [PATCH 001/112] add discovery_app_microsoft_sql_serve on task list --- .../godmode/wizards/DiscoveryTaskList.class.php | 16 +++++++++++++++- pandora_console/include/constants.php | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index da6f4e572e..d2bd3ac065 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -375,7 +375,7 @@ class DiscoveryTaskList extends Wizard // Status. $table->headstyle[5] .= 'min-width: 100px; width: 100px;'; // Task type. - $table->headstyle[6] .= 'min-width: 200px; width: 150px;'; + $table->headstyle[6] .= 'min-width: 200px; width: 250px;'; // Progress. $table->headstyle[7] .= 'min-width: 150px; width: 150px;'; // Updated at. @@ -564,6 +564,16 @@ class DiscoveryTaskList extends Wizard $data[6] .= __('Discovery.Agent.Deployment'); break; + case DISCOVERY_APP_MICROSOFT_SQL_SERVER: + // Discovery Applications Oracle. + $data[6] = html_print_image( + 'images/network.png', + true, + ['title' => __('Discovery Applications Microsoft SQL Server')] + ).'  '; + $data[6] .= __('Discovery.App.Microsoft SQL Server'); + break; + case DISCOVERY_HOSTDEVICES: default: if ($task['id_recon_script'] == 0) { @@ -621,6 +631,7 @@ class DiscoveryTaskList extends Wizard && $task['type'] != DISCOVERY_APP_MYSQL && $task['type'] != DISCOVERY_APP_ORACLE && $task['type'] != DISCOVERY_CLOUD_AWS_RDS + && $task['type'] != DISCOVERY_APP_MICROSOFT_SQL_SERVER ) { if (check_acl($config['id_user'], 0, 'MR')) { $data[9] .= ''; @@ -763,6 +774,9 @@ class DiscoveryTaskList extends Wizard case DISCOVERY_APP_MYSQL: return 'wiz=app&mode=mysql&page=0'; + case DISCOVERY_APP_MICROSOFT_SQL_SERVER: + return 'wiz=app&mode=MicrosoftSQLServer&page=0'; + case DISCOVERY_APP_ORACLE: return 'wiz=app&mode=oracle&page=0'; diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index 1f0764bfaf..de3c4599fe 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -591,6 +591,8 @@ define('DISCOVERY_CLOUD_AWS_RDS', 7); define('DISCOVERY_CLOUD_AZURE_COMPUTE', 8); define('DISCOVERY_DEPLOY_AGENTS', 9); define('DISCOVERY_APP_SAP', 10); +define('DISCOVERY_APP_MICROSOFT_SQL_SERVER', 11); + // Discovery types matching definition. From 85f512db5c46f5733060ea8cfb0f48077a7cc01e Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 18 Feb 2020 16:43:36 +0100 Subject: [PATCH 002/112] mssql driver settings --- pandora_server/conf/pandora_server.conf.new | 3 +++ pandora_server/lib/PandoraFMS/Config.pm | 4 ++++ pandora_server/lib/PandoraFMS/Recon/Base.pm | 13 +++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/pandora_server/conf/pandora_server.conf.new b/pandora_server/conf/pandora_server.conf.new index af335694d5..1007c5e610 100644 --- a/pandora_server/conf/pandora_server.conf.new +++ b/pandora_server/conf/pandora_server.conf.new @@ -140,6 +140,9 @@ discoveryserver 1 # Discovery SAP utils (PANDORA FMS ENTERPRISE ONLY) # sap_utils /usr/share/pandora_server/util/recon_scripts/SAP +# Discovery Microsoft SQL ODBC driver (PANDORA FMS ENTERPRISE ONLY) +# mssql_driver ODBC Driver 17 for SQL Server + # pluginserver : 1 or 0. Set to 1 to activate plugin server with this setup pluginserver 1 diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 7b7e6c50f1..a3436da038 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -332,6 +332,7 @@ sub pandora_load_config { $pa_config->{"dynamic_updates"} = 5; # 7.0 $pa_config->{"dynamic_warning"} = 25; # 7.0 $pa_config->{"dynamic_constant"} = 10; # 7.0 + $pa_config->{"mssql_driver"} = undef; # 745 # Internal MTA for alerts, each server need its own config. $pa_config->{"mta_address"} = ''; # Introduced on 2.0 @@ -1180,6 +1181,9 @@ sub pandora_load_config { elsif ($parametro =~ m/^dynamic_constant\s+([0-9]*)/i) { $pa_config->{'dynamic_constant'}= clean_blank($1); } + elsif ($parametro =~ m/^mssql_driver\s+(.*)/i) { + $pa_config->{'mssql_driver'}= clean_blank($1); + } elsif ($parametro =~ m/^logstash_host\s+(.*)/i) { $pa_config->{'logstash_host'}= clean_blank($1); diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index ce6048a6f9..918ce95a8f 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -35,6 +35,7 @@ use constant { DISCOVERY_CLOUD_AZURE_COMPUTE => 8, DISCOVERY_DEPLOY_AGENTS => 9, DISCOVERY_APP_SAP => 10, + DISCOVERY_APP_MICROSOFT_SQL_SERVER => 11, }; # $DEVNULL @@ -1577,6 +1578,8 @@ sub app_scan($) { $type = 'MySQL'; } elsif ($self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE) { $type = 'Oracle'; + } elsif ($self->{'task_data'}->{'type'} == DISCOVERY_APP_MICROSOFT_SQL_SERVER) { + $type = 'MSSQL'; } elsif ($self->{'task_data'}->{'type'} == DISCOVERY_APP_SAP) { $type = 'SAP'; } else { @@ -1659,13 +1662,13 @@ sub app_scan($) { # Scan connected obj. if ( $self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL - || $self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE) { - + || $self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE + || $self->{'task_data'}->{'type'} == DISCOVERY_APP_MICROSOFT_SQL_SERVER + ) { # Database. $results = $self->database_scan($type, $obj, $global_percent, \@targets); } elsif ($self->{'task_data'}->{'type'} == DISCOVERY_APP_SAP) { - # SAP scan $results = $obj->scan(); @@ -1766,7 +1769,9 @@ sub scan($) { if (defined($self->{'task_data'})) { if ( $self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL || $self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE - || $self->{'task_data'}->{'type'} == DISCOVERY_APP_SAP) { + || $self->{'task_data'}->{'type'} == DISCOVERY_APP_SAP + || $self->{'task_data'}->{'type'} == DISCOVERY_APP_MICROSOFT_SQL_SERVER + ) { # Application scan. $self->call('message', "Scanning application ...", 6); return $self->app_scan(); From 188fa62849dc8caf868c316ef7e252e46c950687 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 17 Jun 2020 14:20:15 +0200 Subject: [PATCH 003/112] Minor fixes --- pandora_server/lib/PandoraFMS/Recon/Base.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 9089a0c6c0..73922496f3 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1798,7 +1798,7 @@ sub app_scan($) { if ( $self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL || $self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE || $self->{'task_data'}->{'type'} == DISCOVERY_APP_DB2 - || $self->{'task_data'}->{'type'} == DISCOVERY_APP_MICROSOFT_SQL_SERVER) + || $self->{'task_data'}->{'type'} == DISCOVERY_APP_MICROSOFT_SQL_SERVER ) { # Database. From 430457b30a5fa73f29a957d5da364e1254079d1b Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Tue, 15 Dec 2020 13:12:00 +0100 Subject: [PATCH 004/112] Deleted logstash references --- pandora_console/include/class/ConsoleSupervisor.php | 2 -- pandora_server/conf/pandora_server.conf.new | 4 ---- pandora_server/lib/PandoraFMS/Config.pm | 11 ----------- 3 files changed, 17 deletions(-) diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php index 2d14003ba2..5bfd50624b 100644 --- a/pandora_console/include/class/ConsoleSupervisor.php +++ b/pandora_console/include/class/ConsoleSupervisor.php @@ -658,7 +658,6 @@ class ConsoleSupervisor case 'NOTIF.PANDORADB.HISTORICAL': case 'NOTIF.HISTORYDB.MR': case 'NOTIF.EXT.ELASTICSEARCH': - case 'NOTIF.EXT.LOGSTASH': case 'NOTIF.METACONSOLE.DB_CONNECTION': case 'NOTIF.DOWNTIME': case 'NOTIF.UPDATEMANAGER.REGISTRATION': @@ -1790,7 +1789,6 @@ class ConsoleSupervisor { global $config; - // Cannot check logstash, configuration is only available from server. // Cannot check selenium, configuration is only available from server. if (isset($config['log_collector']) && $config['log_collector'] == 1 diff --git a/pandora_server/conf/pandora_server.conf.new b/pandora_server/conf/pandora_server.conf.new index ed561e2909..a951508b5d 100644 --- a/pandora_server/conf/pandora_server.conf.new +++ b/pandora_server/conf/pandora_server.conf.new @@ -668,10 +668,6 @@ syslog_max 65535 # Address # sync_address -# Target LogStash server, to allow Dataserver and SyslogServer store log information in ElasticSearch -#logstash_host ip -#logstash_port 10514 - # Pandora FMS Database HA Tool execution interval in seconds (PANDORA FMS ENTERPRISE ONLY). ha_interval 30 diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index f20ed49263..8e6a389c77 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -518,10 +518,6 @@ sub pandora_load_config { $pa_config->{"warmup_unknown_interval"} = 300; # 6.1 $pa_config->{"warmup_unknown_on"} = 1; # 6.1 - # Logstash - $pa_config->{"logstash_host"} = ''; - $pa_config->{"logstash_port"} = 0; - $pa_config->{"wuxserver"} = 1; # 7.0 $pa_config->{"wux_host"} = undef; # 7.0 $pa_config->{"wux_port"} = 4444; # 7.0 @@ -1192,13 +1188,6 @@ sub pandora_load_config { elsif ($parametro =~ m/^dynamic_constant\s+([0-9]*)/i) { $pa_config->{'dynamic_constant'}= clean_blank($1); } - - elsif ($parametro =~ m/^logstash_host\s+(.*)/i) { - $pa_config->{'logstash_host'}= clean_blank($1); - } - elsif ($parametro =~ m/^logstash_port\s+([0-9]*)/i) { - $pa_config->{'logstash_port'}= clean_blank($1); - } elsif ($parametro =~ m/^wuxserver\s+([0-1]*)/i) { $pa_config->{"wuxserver"} = clean_blank($1); } From 1f7a68cacc39dfd6e18c2de94bf2b60f2d1cbdd8 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 7 Jan 2021 16:37:13 +0100 Subject: [PATCH 005/112] Added group_password to print_agent --- pandora_server/lib/PandoraFMS/PluginTools.pm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pandora_server/lib/PandoraFMS/PluginTools.pm b/pandora_server/lib/PandoraFMS/PluginTools.pm index ecffeef396..62ed06e010 100644 --- a/pandora_server/lib/PandoraFMS/PluginTools.pm +++ b/pandora_server/lib/PandoraFMS/PluginTools.pm @@ -504,10 +504,20 @@ sub print_agent { # print header $xml .= "{'group_password'})) { + $xml .= " group_password='".$config->{'group_password'}."' "; } $xml .= ">"; From 32d09a23535f742fb6500020d36211d085147398 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 7 Jan 2021 18:24:51 +0100 Subject: [PATCH 006/112] added name method alias of nombre to Group class --- pandora_console/include/lib/Group.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pandora_console/include/lib/Group.php b/pandora_console/include/lib/Group.php index fc9615cfce..3bd6585344 100644 --- a/pandora_console/include/lib/Group.php +++ b/pandora_console/include/lib/Group.php @@ -105,6 +105,23 @@ class Group extends Entity } + /** + * Alias of 'nombre'. + * + * @param string|null $name Name of group. + * + * @return string|void Name assigned or void if set operation. + */ + public function name(?string $name=null) + { + if ($name === null) { + return $this->nombre(); + } + + return $this->nombre($name); + } + + /** * Retrieves a list of groups fitered. * From 96a8dbd0c8ed9b9dbe63c0f1b0f2c2976e9569e6 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 7 Jan 2021 18:25:59 +0100 Subject: [PATCH 007/112] added name method alias of nombre to Group class --- pandora_console/include/lib/Group.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/lib/Group.php b/pandora_console/include/lib/Group.php index 3bd6585344..a9c2ef6494 100644 --- a/pandora_console/include/lib/Group.php +++ b/pandora_console/include/lib/Group.php @@ -136,7 +136,7 @@ class Group extends Entity if (empty($filter['id_user']) === true) { // By default query current user groups. $filter['id_user'] = false; - } else if (!\users_is_admin()) { + } else if ((bool) \users_is_admin() === false) { // Override user queried if user is not an admin. $filter['id_user'] = false; } @@ -243,8 +243,9 @@ class Group extends Entity if (isset($config['centralized_management']) === true && $config['centralized_management'] > 0 ) { + $msg = 'cannot be modified in a centralized management environment'; throw new \Exception( - get_class($this).' error, cannot be modified while centralized management environment.' + get_class($this).' error, '.$msg ); } From f38ea57c5f6f1bd05ad9b8f3b3f646f5c7139b82 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 8 Jan 2021 17:15:23 +0100 Subject: [PATCH 008/112] group selector updates for report, required --- .../reporting/reporting_builder.main.php | 24 +++++++++++-------- .../godmode/reporting/reporting_builder.php | 2 +- .../reporting/visual_console_builder.data.php | 24 +++++++++++-------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/pandora_console/godmode/reporting/reporting_builder.main.php b/pandora_console/godmode/reporting/reporting_builder.main.php index c6c9c410f9..38d5e0a2d7 100755 --- a/pandora_console/godmode/reporting/reporting_builder.main.php +++ b/pandora_console/godmode/reporting/reporting_builder.main.php @@ -115,16 +115,20 @@ if (isset($write_groups[$idGroupReport]) === false && $idGroupReport) { } $table->data['group'][1] = '
'; -$table->data['group'][1] .= html_print_select_groups( - $config['id_user'], - 'AR', - true, - 'id_group', - $idGroupReport, - '', - '', - '', - true +$table->data['group'][1] .= html_print_input( + [ + 'type' => 'select_groups', + 'id_user' => $config['id_user'], + 'privilege' => 'AR', + 'returnAllGroup' => true, + 'name' => 'id_group', + 'selected' => $idGroupReport, + 'script' => '', + 'nothing' => '', + 'nothing_value' => '', + 'return' => true, + 'required' => true, + ] ); $table->data['group'][1] .= '
'; diff --git a/pandora_console/godmode/reporting/reporting_builder.php b/pandora_console/godmode/reporting/reporting_builder.php index 3180fb918e..65cd8c0c1a 100755 --- a/pandora_console/godmode/reporting/reporting_builder.php +++ b/pandora_console/godmode/reporting/reporting_builder.php @@ -1173,7 +1173,7 @@ switch ($action) { switch ($activeTab) { case 'main': $reportName = ''; - $idGroupReport = 0; + $idGroupReport = null; // All groups. $description = ''; $resultOperationDB = null; diff --git a/pandora_console/godmode/reporting/visual_console_builder.data.php b/pandora_console/godmode/reporting/visual_console_builder.data.php index 2f648541ea..a4c79b1eb7 100644 --- a/pandora_console/godmode/reporting/visual_console_builder.data.php +++ b/pandora_console/godmode/reporting/visual_console_builder.data.php @@ -136,16 +136,20 @@ if ($action == 'new') { $table->data[1][0] = __('Group:'); -$table->data[1][1] = '
'.html_print_select_groups( - $config['id_user'], - 'RW', - true, - 'id_group', - $idGroup, - '', - '', - '', - true +$table->data[1][1] = '
'.html_print_input( + [ + 'type' => 'select_groups', + 'id_user' => $config['id_user'], + 'privilege' => 'RW', + 'returnAllGroup' => true, + 'name' => 'id_group', + 'selected' => $idGroup, + 'script' => '', + 'nothing' => '', + 'nothing_value' => '', + 'return' => true, + 'required' => true, + ] ).'
'; $backgrounds_list = list_files( $config['homedir'].'/images/console/background/', From 6962c34f4859b301dd937ec035ddaf44338c5bc9 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 8 Jan 2021 18:54:04 +0100 Subject: [PATCH 009/112] Force user to actively select a group while defining a new dashboard --- pandora_console/include/javascript/pandora_ui.js | 4 ++++ pandora_console/views/dashboard/formDashboard.php | 3 ++- pandora_console/views/dashboard/list.php | 7 ++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/javascript/pandora_ui.js b/pandora_console/include/javascript/pandora_ui.js index 35d46f79f0..6a9ff477da 100644 --- a/pandora_console/include/javascript/pandora_ui.js +++ b/pandora_console/include/javascript/pandora_ui.js @@ -201,6 +201,7 @@ function load_modal(settings) { var flagError = false; if (Array.isArray(settings.form) === false) { $("#" + settings.form + " :input").each(function() { + var input = this; if (this.checkValidity() === false) { $(this).attr("title", this.validationMessage); $(this).tooltip({ @@ -209,6 +210,9 @@ function load_modal(settings) { my: "right bottom", at: "right top", using: function(position, feedback) { + if (input.className == "select2-hidden-accessible") + position.left += width / 1.7; + console.log(position); $(this).css(position); $("
") .addClass("arrow") diff --git a/pandora_console/views/dashboard/formDashboard.php b/pandora_console/views/dashboard/formDashboard.php index c11e0b92e4..9fbaf555f3 100644 --- a/pandora_console/views/dashboard/formDashboard.php +++ b/pandora_console/views/dashboard/formDashboard.php @@ -33,7 +33,7 @@ if (empty($arrayDashboard) === true) { $arrayDashboard['name'] = 'Default'; $arrayDashboard['id_user'] = ''; $private = 0; - $arrayDashboard['id_group'] = 0; + $arrayDashboard['id_group'] = null; $arrayDashboard['active'] = 0; $arrayDashboard['cells_slideshow'] = 0; } else { @@ -105,6 +105,7 @@ $inputs = [ 'type' => 'select_groups', 'selected' => $arrayDashboard['id_group'], 'return' => true, + 'required' => true, ], ], ], diff --git a/pandora_console/views/dashboard/list.php b/pandora_console/views/dashboard/list.php index 2fafdae999..0362a97854 100644 --- a/pandora_console/views/dashboard/list.php +++ b/pandora_console/views/dashboard/list.php @@ -202,11 +202,16 @@ if (empty($dashboards) === true) { } if ($writeDashboards === 1) { + $text = __('Create a new dashboard'); + if ($dashboard !== null) { + $text = __('Update Dashboard'); + } + // Button for display modal options dashboard. $output = ' __('Update Dashboard'), + 'title' => $text, 'btn_text' => __('Ok'), 'btn_cancel' => __('Cancel'), 'url' => $ajaxController, From b102d427931568d1a04ea3241d3767ef23a9059b Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 11 Jan 2021 13:09:09 +0100 Subject: [PATCH 010/112] minor fix - group containers must be rebuilt... --- .../godmode/reporting/create_container.php | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/pandora_console/godmode/reporting/create_container.php b/pandora_console/godmode/reporting/create_container.php index 394231c227..37bf559c06 100644 --- a/pandora_console/godmode/reporting/create_container.php +++ b/pandora_console/godmode/reporting/create_container.php @@ -132,7 +132,7 @@ if ($edit_container) { $id_parent = get_parameter('id_parent', 0); $description = io_safe_input(get_parameter('description', '')); $id_group = get_parameter('container_id_group', 0); - } else { + } else if ((bool) $id_container !== false) { $tcontainer = db_get_row_sql('SELECT * FROM tcontainer WHERE id_container = '.$id_container); $name = $tcontainer['name']; $id_parent = $tcontainer['parent']; @@ -142,13 +142,21 @@ if ($edit_container) { } if ($add_container) { - $values = [ - 'name' => $name, - 'description' => $description, - 'parent' => $id_parent, - 'id_group' => $id_group, - ]; - $id_container = db_process_sql_insert('tcontainer', $values); + if ((bool) $name !== false) { + $values = [ + 'name' => $name, + 'description' => $description, + 'parent' => $id_parent, + 'id_group' => $id_group, + ]; + $id_container = db_process_sql_insert('tcontainer', $values); + } else { + $error = ui_print_error_message( + __('Container name is missing.'), + '', + true + ); + } } if ($update_container) { @@ -188,6 +196,9 @@ ui_print_page_header( if ($add_container) { ui_print_result_message($id_container, __('Container stored successfully'), __('There was a problem storing container')); + if (empty($error) === false) { + echo $error; + } } if ($update_container) { @@ -207,6 +218,8 @@ if ($id_container === '1') { echo "".__('Group').''; echo '
'; -if ($id_container === '1') { - echo html_print_select_groups($config['id_user'], '', $return_all_groups, 'container_id_group', $id_group, '', '', '', true, false, true, '', true); -} else { - echo html_print_select_groups($config['id_user'], '', $return_all_groups, 'container_id_group', $id_group, '', '', '', true, false, true, '', false); -} - +echo html_print_input( + [ + 'type' => 'select_groups', + 'id_user' => $config['id_user'], + 'privilege' => 'RW', + 'returnAllGroup' => $return_all_groups, + 'name' => 'container_id_group', + 'selected' => $id_group, + 'script' => '', + 'nothing' => '', + 'nothing_value' => '', + 'return' => false, + 'required' => true, + 'disabled' => ($id_container === '1'), + ] +); echo '
'; echo ''; @@ -575,11 +598,13 @@ if ($edit_container) { echo ''; echo ''; - $total_item = db_get_all_rows_sql('SELECT count(*) FROM tcontainer_item WHERE id_container = '.$id_container); - $result_item = db_get_all_rows_sql('SELECT * FROM tcontainer_item WHERE id_container = '.$id_container.' LIMIT 10 OFFSET '.$offset); + if ((bool) $id_container !== false) { + $total_item = db_get_all_rows_sql('SELECT count(*) FROM tcontainer_item WHERE id_container = '.$id_container); + $result_item = db_get_all_rows_sql('SELECT * FROM tcontainer_item WHERE id_container = '.$id_container.' LIMIT 10 OFFSET '.$offset); + } if (!$result_item) { - echo "
".__('There are no defined item container').'
'; + echo "
".__('There are no items in this container.').'
'; } else { ui_pagination($total_item[0]['count(*)'], false, $offset, 10); $table = new stdClass(); From 6e910f9a68a32f13434973831ebcdb4fe1cc8c53 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 11 Jan 2021 13:09:33 +0100 Subject: [PATCH 011/112] group select style consistency --- .../godmode/reporting/graph_builder.main.php | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/pandora_console/godmode/reporting/graph_builder.main.php b/pandora_console/godmode/reporting/graph_builder.main.php index a1f0494b23..1e466e7f14 100644 --- a/pandora_console/godmode/reporting/graph_builder.main.php +++ b/pandora_console/godmode/reporting/graph_builder.main.php @@ -94,7 +94,7 @@ if ($edit_graph) { } else { $id_agent = 0; $id_module = 0; - $id_group = 0; + $id_group = null; $period = SECONDS_1DAY; $factor = 1; $stacked = 4; @@ -134,28 +134,36 @@ $own_info = get_user_info($config['id_user']); $output .= ''.__('Group').''; if (check_acl($config['id_user'], 0, 'RW')) { - $output .= html_print_select_groups( - $config['id_user'], - 'RW', - true, - 'graph_id_group', - $id_group, - '', - '', - '', - true + $output .= html_print_input( + [ + 'type' => 'select_groups', + 'id_user' => $config['id_user'], + 'privilege' => 'RW', + 'returnAllGroup' => true, + 'name' => 'graph_id_group', + 'selected' => $id_group, + 'script' => '', + 'nothing' => '', + 'nothing_value' => '', + 'return' => true, + 'required' => true, + ] ); } else if (check_acl($config['id_user'], 0, 'RM')) { - $output .= html_print_select_groups( - $config['id_user'], - 'RM', - true, - 'graph_id_group', - $id_group, - '', - '', - '', - true + $output .= html_print_input( + [ + 'type' => 'select_groups', + 'id_user' => $config['id_user'], + 'privilege' => 'RM', + 'returnAllGroup' => true, + 'name' => 'graph_id_group', + 'selected' => $id_group, + 'script' => '', + 'nothing' => '', + 'nothing_value' => '', + 'return' => true, + 'required' => true, + ] ); } From 9fa16decfa242fb14b58b475b1e73324c8f993d9 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 11 Jan 2021 13:53:52 +0100 Subject: [PATCH 012/112] Force language message validation (groups) --- pandora_console/include/functions_html.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index b4d8445d0e..8b781c6952 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -566,6 +566,10 @@ function html_print_select_groups( $required ); + if ($required !== false) { + $require_message = __('Please select an item from this list.'); + } + if (empty($size) === true) { $size = '100%'; } @@ -585,6 +589,13 @@ function html_print_select_groups( $(document).ready(function() { $('select[name=""]').each( function() { + + this.setCustomValidity(''); + $(this).select2({ multiple: , placeholder: "", From e43e9f12392620cdc2dea2f5e70366f6e1a8f6e2 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 18 Jan 2021 10:50:56 +0100 Subject: [PATCH 013/112] minor changes --- pandora_console/include/functions_agents.php | 2 +- pandora_console/include/functions_api.php | 109 ------------------- 2 files changed, 1 insertion(+), 110 deletions(-) diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index 8be043fb98..866dbfe519 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -147,7 +147,7 @@ function agents_locate_agent(string $field) * * @param string $alias Agent alias. * - * @return integer Id from the agent. + * @return array|boolean Agents ids or false if error. */ function agents_get_agent_id_by_alias($alias) { diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 980bfc0d25..03743c6907 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -6867,115 +6867,6 @@ function api_set_planned_downtimes_additem($id, $thrash1, $other, $thrash3) } -/** - * Add data module to policy. And return id from new module. - * - * @param string $id Id of the target policy. - * @param $thrash1 Don't use. - * @param array $other it's array, $other as param is ;;; - * ;;;;;;;; - * ;;;;; - * ;;;;; - * ;; in this order - * and separator char (after text ; ) and separator (pass in param othermode as othermode=url_encode_separator_) - * example: - * - * example: - * - * api.php?op=set&op2=add_data_module_policy&id=1&other=data_module_policy_example_name~2~data%20module%20created%20by%20Api~2~0~0~50.00~10~20~180~~21~35~~1~module_begin%0dmodule_name%20pandora_process%0dmodule_type%20generic_data%0dmodule_exec%20ps%20aux%20|%20grep%20pandora%20|%20wc%20-l%0dmodule_end&other_mode=url_encode_separator_~ - * - * @param $thrash3 Don't use - */ -function api_set_add_data_module_policy($id, $thrash1, $other, $thrash3) -{ - if (defined('METACONSOLE')) { - return; - } - - if ($id == '') { - returnError('error_add_data_module_policy', __('Error adding data module to policy. Id_policy cannot be left blank.')); - return; - } - - if (enterprise_hook('policies_check_user_policy', [$id]) === false) { - returnError('forbidden', 'string'); - return; - } - - if ($other['data'][0] == '') { - returnError('error_add_data_module_policy', __('Error adding data module to policy. Module_name cannot be left blank.')); - return; - } - - // Check if the module is already in the policy - $name_module_policy = enterprise_hook('policies_get_modules', [$id, ['name' => $other['data'][0]], 'name']); - - if ($name_module_policy === ENTERPRISE_NOT_HOOK) { - returnError('error_add_data_module_policy', __('Error adding data module to policy.')); - return; - } - - $disabled_types_event = []; - $disabled_types_event[EVENTS_GOING_UNKNOWN] = (int) !$other['data'][16]; - $disabled_types_event = json_encode($disabled_types_event); - - $values = []; - $values['id_tipo_modulo'] = $other['data'][1]; - $values['description'] = $other['data'][2]; - $values['id_module_group'] = $other['data'][3]; - $values['min'] = $other['data'][4]; - $values['max'] = $other['data'][5]; - $values['post_process'] = $other['data'][6]; - $values['module_interval'] = $other['data'][7]; - $values['min_warning'] = $other['data'][8]; - $values['max_warning'] = $other['data'][9]; - $values['str_warning'] = $other['data'][10]; - $values['min_critical'] = $other['data'][11]; - $values['max_critical'] = $other['data'][12]; - $values['str_critical'] = $other['data'][13]; - $values['history_data'] = $other['data'][14]; - $values['configuration_data'] = $other['data'][15]; - $values['disabled_types_event'] = $disabled_types_event; - $values['module_macros'] = $other['data'][17]; - $values['min_ff_event'] = $other['data'][18]; - $values['each_ff'] = $other['data'][19]; - $values['min_ff_event_normal'] = $other['data'][20]; - $values['min_ff_event_warning'] = $other['data'][21]; - $values['min_ff_event_critical'] = $other['data'][22]; - $values['ff_timeout'] = $other['data'][23]; - $values['ff_type'] = $other['data'][24]; - - if ($name_module_policy !== false) { - if ($name_module_policy[0]['name'] == $other['data'][0]) { - returnError( - 'error_add_data_module_policy', - __('Error adding data module to policy. The module is already in the policy.') - ); - return; - } - } - - $success = enterprise_hook( - 'policies_create_module', - [ - $other['data'][0], - $id, - 1, - $values, - false, - ] - ); - - if ($success) { - // returnData('string', array('type' => 'string', 'data' => __('Data module added to policy. Is necessary to apply the policy in order to changes take effect.'))); - returnData('string', ['type' => 'string', 'data' => $success]); - } else { - returnError('error_add_data_module_policy', 'Error adding data module to policy.'); - } - -} - - /** * Update data module in policy. And return id from new module. * From 6ea19ac5fa3b408b9d62effc5784bfbd7a5461b5 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 19 Jan 2021 18:00:28 +0100 Subject: [PATCH 014/112] External changes from #6158 --- pandora_console/godmode/wizards/Wizard.main.php | 3 --- pandora_console/include/lib/Entity.php | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index 6783ba20e1..39ffb2121d 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -31,9 +31,6 @@ global $config; require_once $config['homedir'].'/vendor/autoload.php'; require_once $config['homedir'].'/include/class/HTML.class.php'; - -use \HTML; - /** * Global Wizard generic class. Needs to be inherited. * diff --git a/pandora_console/include/lib/Entity.php b/pandora_console/include/lib/Entity.php index 8ef3354bb8..ead8d8fe14 100644 --- a/pandora_console/include/lib/Entity.php +++ b/pandora_console/include/lib/Entity.php @@ -61,12 +61,12 @@ abstract class Entity /** * Instances a new object using array definition. * - * @param string $class_str Class name. * @param array $data Fields data. + * @param string $class_str Class name. * * @return object With current definition. */ - public static function build(string $class_str, array $data=[]) + public static function build(array $data=[], string $class_str=__CLASS__) { $obj = new $class_str(); // Set values. From 16029f7fafaf8763072b60c174d3294ecce73906 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 20 Jan 2021 20:08:34 +0100 Subject: [PATCH 015/112] Significant fixes --- pandora_console/include/lib/Entity.php | 5 ++- pandora_console/include/lib/ModuleType.php | 47 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/lib/Entity.php b/pandora_console/include/lib/Entity.php index ead8d8fe14..40581266f3 100644 --- a/pandora_console/include/lib/Entity.php +++ b/pandora_console/include/lib/Entity.php @@ -149,7 +149,10 @@ abstract class Entity { // Prioritize written methods over dynamic ones. if (method_exists($this, $methodName) === true) { - return $this->{$methodName}($params); + return call_user_func_array( + $this->{$methodName}, + $params + ); } // Enterprise capabilities. diff --git a/pandora_console/include/lib/ModuleType.php b/pandora_console/include/lib/ModuleType.php index c14a709298..c9bb192a9a 100644 --- a/pandora_console/include/lib/ModuleType.php +++ b/pandora_console/include/lib/ModuleType.php @@ -91,4 +91,51 @@ class ModuleType extends Entity } + /** + * Validate id_module and id_module_type pair. + * + * @param integer $id_module_type Id module_type. + * @param integer $id_modulo Id modulo. + * + * @return boolean True success, false if not. + */ + public static function validate(int $id_module_type, int $id_modulo) + { + switch ($id_modulo) { + default: + case MODULE_PLUGIN: + case MODULE_PREDICTION: + case MODULE_DATA: + case MODULE_WMI: + if (($id_module_type < 6 || $id_module_type > 18) === false + && ($id_module_type < 29 || $id_module_type > 34) === false + && ($id_module_type === 25) + ) { + return false; + } + break; + case MODULE_NETWORK: + case MODULE_SNMP: + if ($id_module_type < 6 || $id_module_type > 18) { + return false; + } + break; + + case MODULE_WEB: + if ($id_module_type !== 25) { + return false; + } + break; + + case MODULE_WUX: + if ($id_module_type < 29 || $id_module_type > 34) { + return false; + } + break; + } + + return true; + } + + } From 9d2133187f806ff50f2345506c96b9d7ccee773f Mon Sep 17 00:00:00 2001 From: rafael Date: Fri, 22 Jan 2021 14:59:42 +0100 Subject: [PATCH 016/112] messaging integrations --- .../.vscode/settings.json | 3 + .../message_app_connectors/discord/.gitignore | 1 + .../discord/pandora_discord_cli.py | 173 +++++++++++++++++ .../discord/requirements.txt | 6 + .../discord/test-exec.txt | 19 ++ .../gchat/pandora-gchat-cli.py | 111 +++++++++++ .../gchat/requirements.txt | 5 + .../gchat/test-exec.txt | 14 ++ .../ms-teams/pandora-msteams-cli.py | 83 ++++++++ .../ms-teams/pandora-teams-cli.py | 81 ++++++++ .../ms-teams/requirements.txt | 6 + .../ms-teams/test-exec.txt | 15 ++ .../message_app_connectors/slack/.gitignore | 1 + .../slack/pandora-slack-cli.py | 177 ++++++++++++++++++ .../slack/requirements.txt | 6 + .../slack/test_exec.txt | 14 ++ .../telegram-bot-cli/pandora-telegram-cli.py | 27 +++ .../telegram-bot-cli/requirements.txt | 5 + .../telegram-bot-cli/test_exec.txt | 6 + 19 files changed, 753 insertions(+) create mode 100644 pandora_plugins/message_app_connectors/.vscode/settings.json create mode 100644 pandora_plugins/message_app_connectors/discord/.gitignore create mode 100644 pandora_plugins/message_app_connectors/discord/pandora_discord_cli.py create mode 100644 pandora_plugins/message_app_connectors/discord/requirements.txt create mode 100644 pandora_plugins/message_app_connectors/discord/test-exec.txt create mode 100644 pandora_plugins/message_app_connectors/gchat/pandora-gchat-cli.py create mode 100644 pandora_plugins/message_app_connectors/gchat/requirements.txt create mode 100644 pandora_plugins/message_app_connectors/gchat/test-exec.txt create mode 100755 pandora_plugins/message_app_connectors/ms-teams/pandora-msteams-cli.py create mode 100755 pandora_plugins/message_app_connectors/ms-teams/pandora-teams-cli.py create mode 100644 pandora_plugins/message_app_connectors/ms-teams/requirements.txt create mode 100644 pandora_plugins/message_app_connectors/ms-teams/test-exec.txt create mode 100644 pandora_plugins/message_app_connectors/slack/.gitignore create mode 100644 pandora_plugins/message_app_connectors/slack/pandora-slack-cli.py create mode 100644 pandora_plugins/message_app_connectors/slack/requirements.txt create mode 100644 pandora_plugins/message_app_connectors/slack/test_exec.txt create mode 100644 pandora_plugins/message_app_connectors/telegram-bot-cli/pandora-telegram-cli.py create mode 100644 pandora_plugins/message_app_connectors/telegram-bot-cli/requirements.txt create mode 100644 pandora_plugins/message_app_connectors/telegram-bot-cli/test_exec.txt diff --git a/pandora_plugins/message_app_connectors/.vscode/settings.json b/pandora_plugins/message_app_connectors/.vscode/settings.json new file mode 100644 index 0000000000..dd432a8cda --- /dev/null +++ b/pandora_plugins/message_app_connectors/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "slack/venv/bin/python" +} \ No newline at end of file diff --git a/pandora_plugins/message_app_connectors/discord/.gitignore b/pandora_plugins/message_app_connectors/discord/.gitignore new file mode 100644 index 0000000000..5ceb3864c2 --- /dev/null +++ b/pandora_plugins/message_app_connectors/discord/.gitignore @@ -0,0 +1 @@ +venv diff --git a/pandora_plugins/message_app_connectors/discord/pandora_discord_cli.py b/pandora_plugins/message_app_connectors/discord/pandora_discord_cli.py new file mode 100644 index 0000000000..5a278a0e6b --- /dev/null +++ b/pandora_plugins/message_app_connectors/discord/pandora_discord_cli.py @@ -0,0 +1,173 @@ +import requests, argparse, sys, os +from datetime import datetime +from re import search +from base64 import b64decode +from discord_webhook import DiscordWebhook, DiscordEmbed + + +### Variables and arg parser ### +parser = argparse.ArgumentParser(description='Test parser dic') +parser.add_argument('-d', '--data', help='Data in coma separate keypairs. Ex: test=5,house=2', required=True) +parser.add_argument('-u', '--url', help='Discord webhook URL', required=True) +parser.add_argument('-t', '--alert_tittle', help='Alert tittle', default='PandoraFMS alert fired') +parser.add_argument('-D', '--alert_desc', help='Alert description', default='alert') +parser.add_argument('-m', '--message', help='Discord message', default='') +parser.add_argument('-T','--tittle_color', help='Alert tittle descripcion in HEX EX: 53e514', default="53e514") +parser.add_argument('-A','--author', help='Alert custom author', default='PandoraFMS') +parser.add_argument('-F','--footer', help='Custom footer', default='') +parser.add_argument('--avatar_url', help='Custom avatar URL for the user which send the alert', default='') +parser.add_argument('--author_url', help='Alert custom url author', default='') +parser.add_argument('--author_icon_url', help='Alert custom author icon url ', default='') +parser.add_argument('--thumb', help='Custom thumbnail url', default='') +parser.add_argument('--api_conf', help='Api configuration parameters in coma separate keypairs. EX "user=admin,pass=pandora,api_pass=1234,api_url=http://test.artica.es/pandora_console/include/api.php"') +parser.add_argument('--module_graph', help='Uses pandora API to generate a module graph and attach it to the alert needs module_id and interval parameters in coma separate keypairs. EX "module_id=55,interval=3600"') +parser.add_argument('--tmp_dir', help='Temporary path to store grph images', default='/tmp') + + +args = parser.parse_args() + +### Functions: +def parse_dic(cValues): + """convert coma separate keypairs into a dic. EX "test=5,house=8,market=2" wil return "{'test': '5', 'casa': '8', 'mercado': '2'}" """ + data={} + try : + for kv in cValues.split(","): + k,v = kv.strip().split("=") + data[k.strip()]=v.strip() + except Exception as e : + print(f"Warning, error parsing keypairs values: {e}") + return data + +def add_embed_itmes(data): + """iterate dictionary and set webhook fields, one for eacj keypair""" + for k, v in data.items() : + embed.add_embed_field(name=k, value=v) + +def parse_api_conf(cConf): + if args.api_conf : + # Parse Api config + print ("Api config enable") + apid = parse_dic(cConf) + + if apid.get("user") is None: + print ("Error no user defined in api_conf keypairs, skiping graph generation.") + return + + if apid.get("pass") is None: + print ("Error no password defined in api_conf keypairs, skiping graph generation.") + return + + if apid.get("api_pass") is None: + print ("Error no Api pass defined in api_conf keypairs, skiping graph generation.") + return + + if apid.get("api_url") is None: + apid['api_url'] = "http://127.0.0.1/pandora_console/include/api.php" + #print(f"api_url: {apid['api_url']}") + + return apid + else: + return None + +def parse_graph_conf(cGraph): + if not args.api_conf: + print ("To get graph data api conf shoul be provided please set an api config") + return + + if cGraph : + # Parse Api config + graphd = parse_dic(cGraph) + if graphd.get("module_id") is None: + print ("error no module_id defined in module_graph keypairs, skiping graph generation.") + return + + if graphd.get("interval") is None: + graphd["interval"] = 3600 + + return graphd + else: + return None + +def get_graph_by_moduleid (baseUrl,pUser, pPass, apiPass, moduleId, graphInterval) : + sep="url_encode_separator_%7C" + try: + url = f"{baseUrl}?op=get&op2=module_graph&id={moduleId}&other={graphInterval}%7C1&other_mode={sep}C&apipass={apiPass}&api=1&user={pUser}&pass={pPass}" + graph = requests.get(url) + if graph.status_code != 200: + print (f"Error requested api url, status code: {graph.status_code}. Skiping graph generation") + return None + if graph.text == "auth error": + print (f"Error requested Pandora api url, status code: {graph.text}. Skiping graph generation") + return None + if graph.text == "Id does not exist in database.": + print (f"Error requested Pandora api url, status code: {graph.text}. Skiping graph generation") + return None + except: + print("Error requested api url. Skiping graph generation") + return None + + return graph + +## Main +## Basic message +webhook = DiscordWebhook(url=args.url, content=args.message, avatar_url=args.avatar_url) +# create embed object for webhook +embed = DiscordEmbed(title=args.alert_tittle, description=args.alert_desc, color=int(args.tittle_color, 16)) +# set author +embed.set_author(name=args.author, url=args.author_url, icon_url=args.author_icon_url) +# set thumbnail +if args.thumb: embed.set_thumbnail(url=args.thumb) +# set footer +if args.footer : embed.set_footer(text=args.footer) +# set timestamp (default is now) +embed.set_timestamp() +# Parse data keys +data = parse_dic(args.data) +# add fields to embed +add_embed_itmes(data) + +# Parse api config +api = parse_api_conf(args.api_conf) +# Parse graph config +graph_cfg = parse_graph_conf(args.module_graph) + +## Generate module graph + +if graph_cfg is not None and api is not None: + graph = get_graph_by_moduleid (api["api_url"],api["user"], api["pass"], api["api_pass"], graph_cfg["module_id"], graph_cfg["interval"]) + + if graph is not None: + try: + namef = f"graph_{graph_cfg['module_id']}.{datetime.now().strftime('%s')}.png" + filename = f"{args.tmp_dir}/{namef}" + with open(filename, "wb") as f: + f.write(b64decode(graph.text)) + f.close + print (f"Graph generated on temporary file {filename}") + except Exception as e : + print(f"Error, cant generate graph file: {e}") + filename = None + + try: + with open(filename, "rb") as F: + webhook.add_file(file=F.read(), filename=namef) + f.close + embed.set_image(url=f'attachment://{namef}') + except Exception as e : + print(f"Error, cant add graph file: {e}") + filename = None + +# add embed object to webhook +webhook.add_embed(embed) + +# Execute webhook send +response = webhook.execute() + +# clean temp file if exist +try: + os.remove(filename) +except: + pass + +# print response +print (f"Message sent. status code: {response[0].status_code}") if response[0].status_code == 200 else print (f"Error status code: {response[0].status_code}") diff --git a/pandora_plugins/message_app_connectors/discord/requirements.txt b/pandora_plugins/message_app_connectors/discord/requirements.txt new file mode 100644 index 0000000000..edbda16382 --- /dev/null +++ b/pandora_plugins/message_app_connectors/discord/requirements.txt @@ -0,0 +1,6 @@ +certifi==2020.11.8 +chardet==3.0.4 +discord-webhook==0.11.0 +idna==2.10 +requests==2.24.0 +urllib3==1.25.11 diff --git a/pandora_plugins/message_app_connectors/discord/test-exec.txt b/pandora_plugins/message_app_connectors/discord/test-exec.txt new file mode 100644 index 0000000000..f63e7f5084 --- /dev/null +++ b/pandora_plugins/message_app_connectors/discord/test-exec.txt @@ -0,0 +1,19 @@ +#exetution example + +python3 pandora_discord_cli.py -d "Agent=Server22,Module=test_module,Group=Servers,State=Critical,Data=22,Timestamp=2020-11-04 11:14:00" \ +-u https://discord.com/api/webhooks/702868786843353179/YI1LOUzC64EcYcpPVB_ \ +--tittle_color ed2512 \ +--footer "PandoraFMS Alert" \ +-A "Sauron Systems" \ +--author_icon_url "https://pandorafms.com/wp-content/uploads/2019/04/software-de-monitorizacion-pandorafms-logo.png" \ +-m "We have bad news for you. Something is on CRITICAL status 2" \ +--author_url https://pandorafms.com/ \ +-D "Module test is going to critical" \ +--thumb https://pandorafms.com/images/alerta_roja.png \ +--avatar_url https://pandorafms.com/images/alerta_roja.png \ +--api_conf "user=admin,pass=pandora,api_pass=pandora,api_url=http://192.168.80.222/pandora_console/include/api.php" \ +--module_graph "module_id=6266, interval=3600" \ +--tmp_dir /tmp + +# Pandora FMS command definition example +python3 /usr/share/pandora_server/util/pandora-discord/pandora_discord_cli.py -u "_field1_" -d "_field2_" -D "_field3_" --tittle_color _field4_ --thumb _field5_ --api_conf "_field6_" --module_graph "_field7_" -A "Pandora FMS Alert system" --footer "PandoraFMS" --author_icon_url "https://pandorafms.com/wp-content/uploads/2019/04/software-de-monitorizacion-pandorafms-logo.png" --author_url https://pandorafms.com/ --tmp_dir /tmp \ No newline at end of file diff --git a/pandora_plugins/message_app_connectors/gchat/pandora-gchat-cli.py b/pandora_plugins/message_app_connectors/gchat/pandora-gchat-cli.py new file mode 100644 index 0000000000..5e2a47b3f8 --- /dev/null +++ b/pandora_plugins/message_app_connectors/gchat/pandora-gchat-cli.py @@ -0,0 +1,111 @@ +import requests +import argparse +import sys +import os +import json + +### Variables and arg parser ### +parser = argparse.ArgumentParser(description='Google chat webhook conector') +parser.add_argument( + '-d', '--data', help='Data in coma separate keypairs. Ex: test=5,house=2', required=True) +parser.add_argument( + '-u', '--url', help='Google chat webhook URL', required=True) +parser.add_argument('-t', '--alert_title', help='Alert title', + default='PandoraFMS alert system') +parser.add_argument('-D', '--alert_desc', + help='Alert description', default='Alert Fired') +parser.add_argument('--thumb', help='Custom thumbnail url', + default="https://pandorafms.com/images/alerta_roja.png") +parser.add_argument('--btn_desc', help='button description', default=None) +parser.add_argument('--btn_url', help='button url', + default="https://pandorafms.com/") + + +args = parser.parse_args() + +# classes + + +class Message(): + def __init__(self, title, subtitle, imageurl='https://goo.gl/aeDtrS'): + """ Initialize message object, setting header options""" + self.dic = { + 'cards': [] + } + + header = {'header': {'title': title, + 'subtitle': subtitle, 'imageUrl': imageurl}} + self.dic['cards'].append(header) + + sections = {'sections': []} + self.dic['cards'].append(sections) + + def add_header(self, title, subtitle, imageurl='https://goo.gl/aeDtrS'): + """Add header to message object""" + header = {'header': {'title': title, + 'subtitle': subtitle, 'imageUrl': imageurl}} + self.dic['cards'].append(header) + + def add_value(self, keyval): + """Add key value pairs data to message object, keyval should be a dictionary""" + m = '' + arr = [] + for k, v in keyval.items(): + m += f"{k}: {v} \n" + + arr.append({'textParagraph': {'text': m}}) + + widgets = {'widgets': arr} + self.dic['cards'][1]['sections'].append(widgets) + + def add_buttom(self, desc, url): + """Add button to message object""" + btn = [{"textButton": {"text": desc, "onClick": {"openLink": {'url': url}}}}] + arr = [({'buttons': btn})] + + widgets = {'widgets': arr} + self.dic['cards'][1]['sections'].append(widgets) + +# functions + + +def parse_dic(cValues): + """convert coma separate keypairs into a dic. EX "test=5,house=8,market=2" wil return "{'test': '5', 'casa': '8', 'mercado': '2'}" """ + data = {} + try: + for kv in cValues.split(","): + k, v = kv.strip().split("=") + data[k.strip()] = v.strip() + except Exception as e: + print(f"Warning, error parsing keypairs values: {e}") + return data + + +def sendMessage(url, message): + """sends google chat message""" + message = json.dumps(message) + try: + header = {'Content-Type': 'application/json; charset: UTF-8'} + response = requests.post(url, headers=header, data=message) + + print(f"Mesage sent succefuly: {response.status_code}") + except: + print("Error requested api url. Skiping graph generation") + return None + return response + + +if __name__ == '__main__': + + # Initializaate message object + a = Message(args.alert_title, args.alert_desc, args.thumb) + # Parse data values + data = parse_dic(args.data) + # Add datavalues into message object + a.add_value(data) + # Chek button parameters and add it to the message object + if args.btn_desc != None: + a.add_buttom(args.btn_desc, args.btn_url) + + # Send message + sendMessage(args.url, a.dic) diff --git a/pandora_plugins/message_app_connectors/gchat/requirements.txt b/pandora_plugins/message_app_connectors/gchat/requirements.txt new file mode 100644 index 0000000000..2d0a3be144 --- /dev/null +++ b/pandora_plugins/message_app_connectors/gchat/requirements.txt @@ -0,0 +1,5 @@ +certifi==2020.12.5 +chardet==3.0.4 +idna==2.10 +requests==2.25.0 +urllib3==1.26.2 diff --git a/pandora_plugins/message_app_connectors/gchat/test-exec.txt b/pandora_plugins/message_app_connectors/gchat/test-exec.txt new file mode 100644 index 0000000000..d2703d9e9a --- /dev/null +++ b/pandora_plugins/message_app_connectors/gchat/test-exec.txt @@ -0,0 +1,14 @@ +#exetution example + +python3 pandora-gchat-cli.py \ +-d 'Agent=Server22,Module=test_module,Group=Servers,State=Critical,Data=22,Timestamp=2020-11-04 11:14:00' \ +-u https://chat.googleapis.com/v1/spaces/AAAA6-AOZQ8/messages\?key\=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI\&token\=_ZGwKN4lue8ZiDKGVMLfMay3hLRrYjmgYr2fXPqPy0c%3D \ +-t 'PandoraFMS Alert' \ +-D 'Alert Fired' \ +--thumb https://pandorafms.com/images/alerta_roja.png \ +--btn_desc pandorafms.com \ +--btn_url https://pandorafms.com/ + + +# Pandora FMS command definition example +python3 /usr/share/pandora_server/util/pandora-gchat/pandora-gchat-cli.py -d '_field1_' -u '_field2_' -t '_field3_' -D '_field4_' --thumb '_field5_' --btn_desc pandorafms.com --btn_url https://pandorafms.com/ \ No newline at end of file diff --git a/pandora_plugins/message_app_connectors/ms-teams/pandora-msteams-cli.py b/pandora_plugins/message_app_connectors/ms-teams/pandora-msteams-cli.py new file mode 100755 index 0000000000..f0d4ac89a8 --- /dev/null +++ b/pandora_plugins/message_app_connectors/ms-teams/pandora-msteams-cli.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import argparse, pymsteams + +parser = argparse.ArgumentParser(description='MS Teams connector') +parser.add_argument('-d', '--data', help='Data in coma separate keypairs. Ex: test=5,house=2', required=True) +parser.add_argument('-u', '--url', help='Teams webhook URL', required=True) +parser.add_argument('-t', '--alert_tittle', help='Alert tittle', default='PandoraFMS alert fired') +parser.add_argument('-D', '--alert_desc', help='Alert description', default='Alert Fired') +parser.add_argument('-m', '--message', help='Alert message', default='') +parser.add_argument('-T','--tittle_color', help='Alert tittle descripcion in HEX EX: 53e514', default="ff0000") +parser.add_argument('--sub_desc', help='Alert sub description', default='Alert Fired') +parser.add_argument('--thumb', help='Custom thumbnail url', default="https://pandorafms.com/images/alerta_roja.png") +parser.add_argument('--button', help='Pandora button Url', default='https://pandorafms.com') +parser.add_argument('--button_desc', help='Pandora button description', default='Open web console') + +args = parser.parse_args() + +### Functions: +def parse_dic(cValues): + """convert coma separate keypairs into a dic. EX "test=5,house=8,market=2" wil return "{'test': '5', 'casa': '8', 'mercado': '2'}" """ + data={} + try : + for kv in cValues.split(","): + k,v = kv.strip().split("=") + data[k.strip()]=v.strip() + except Exception as e : + print(f"Warning, error parsing keypairs values: {e}") + return data + +def add_embed_itmes(data): + """iterate dictionary and set webhook fields, one for eacj keypair""" + for k, v in data.items() : + myMessageSection.addFact(f"{k}:", v) + +##Main + +# You must create the connectorcard object with the Microsoft Webhook URL +myTeamsMessage = pymsteams.connectorcard(args.url) + +# Set Summary +myTeamsMessage.summary('Pandora FMS') + +# Set Alert tittle +myTeamsMessage.title(args.alert_tittle) + +# Set link buttom +myTeamsMessage.addLinkButton(args.button_desc, args.button) + +# Set message color +myTeamsMessage.color(args.tittle_color) + +# create the section +myMessageSection = pymsteams.cardsection() + +# Section Title +myMessageSection.title(args.message) + +# Activity Elements +myMessageSection.activityTitle(args.alert_desc) +myMessageSection.activitySubtitle(args.sub_desc) +myMessageSection.activityImage(args.thumb) + +# Facts are key value pairs displayed in a list. +data = parse_dic(args.data) +add_embed_itmes(data) + +# Section Text +# myMessageSection.text("This is my section text") + +# Section Images +# myMessageSection.addImage("http://i.imgur.com/c4jt321l.png", ititle="This Is Fine") + +# Add your section to the connector card object before sending +myTeamsMessage.addSection(myMessageSection) + +# Then send the card +try: + myTeamsMessage.send() +except Exception as e : + exit(f"Error sending to message: {e}") + +print (f"Mesage sent succefuly: {myTeamsMessage.last_http_status}") \ No newline at end of file diff --git a/pandora_plugins/message_app_connectors/ms-teams/pandora-teams-cli.py b/pandora_plugins/message_app_connectors/ms-teams/pandora-teams-cli.py new file mode 100755 index 0000000000..4bd997b38f --- /dev/null +++ b/pandora_plugins/message_app_connectors/ms-teams/pandora-teams-cli.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import argparse, pymsteams + +parser = argparse.ArgumentParser(description='MsTeams connector') +parser.add_argument('-d', '--data', help='Data in coma separate keypairs. Ex: test=5,house=2', required=True) +parser.add_argument('-u', '--url', help='Teams webhook URL', required=True) +parser.add_argument('-t', '--alert_tittle', help='Alert tittle', default='PandoraFMS alert fired') +parser.add_argument('-D', '--alert_desc', help='Alert description', default='Alert Fired') +parser.add_argument('-m', '--message', help='Alert message', default='') +parser.add_argument('-T','--tittle_color', help='Alert tittle descripcion in HEX EX: 53e514', default="53e514") +parser.add_argument('--sub_desc', help='Alert sub description', default='Alert Fired') +parser.add_argument('--thumb', help='Custom thumbnail url', default="https://pandorafms.com/images/alerta_roja.png") +parser.add_argument('--button', help='Pandora button Url', default='https://pandorafms.com') +parser.add_argument('--button_desc', help='Pandora button description', default='Open web console') + +args = parser.parse_args() + +### Functions: +def parse_dic(cValues): + """convert coma separate keypairs into a dic. EX "test=5,house=8,market=2" wil return "{'test': '5', 'casa': '8', 'mercado': '2'}" """ + data={} + try : + for kv in cValues.split(","): + k,v = kv.strip().split("=") + data[k.strip()]=v.strip() + except Exception as e : + print(f"Warning, error parsing keypairs values: {e}") + return data + +def add_embed_itmes(data): + """iterate dictionary and set webhook fields, one for eacj keypair""" + for k, v in data.items() : + myMessageSection.addFact(f"{k}:", v) + +##Main + +# You must create the connectorcard object with the Microsoft Webhook URL +myTeamsMessage = pymsteams.connectorcard(args.url) + +# Set Summary +myTeamsMessage.summary(args.message) + +# Set Alert tittle +myTeamsMessage.title(args.alert_tittle) + +# Set link buttom +myTeamsMessage.addLinkButton(args.button_desc, args.button) + +# Set message color +myTeamsMessage.color(args.tittle_color) + +# create the section +myMessageSection = pymsteams.cardsection() + +# Section Title +myMessageSection.title(args.message) + +# Activity Elements +myMessageSection.activityTitle(args.alert_desc) +myMessageSection.activitySubtitle(args.sub_desc) +myMessageSection.activityImage(args.thumb) + +# Facts are key value pairs displayed in a list. +data = parse_dic(args.data) +add_embed_itmes(data) + +# Section Text +# myMessageSection.text("This is my section text") + +# Section Images +# myMessageSection.addImage("http://i.imgur.com/c4jt321l.png", ititle="This Is Fine") + +# Add your section to the connector card object before sending +myTeamsMessage.addSection(myMessageSection) + +# Then send the card +try: + myTeamsMessage.send() +except Exception as e : + print(f"Error sending to message: {e}") \ No newline at end of file diff --git a/pandora_plugins/message_app_connectors/ms-teams/requirements.txt b/pandora_plugins/message_app_connectors/ms-teams/requirements.txt new file mode 100644 index 0000000000..da3bc60eee --- /dev/null +++ b/pandora_plugins/message_app_connectors/ms-teams/requirements.txt @@ -0,0 +1,6 @@ +certifi==2020.11.8 +chardet==3.0.4 +idna==2.10 +pymsteams==0.1.14 +requests==2.25.0 +urllib3==1.26.2 diff --git a/pandora_plugins/message_app_connectors/ms-teams/test-exec.txt b/pandora_plugins/message_app_connectors/ms-teams/test-exec.txt new file mode 100644 index 0000000000..f92f6ae2c9 --- /dev/null +++ b/pandora_plugins/message_app_connectors/ms-teams/test-exec.txt @@ -0,0 +1,15 @@ +#exetution example + +python3 pandora-teams-cli.py -d "Agent=Server22,Module=test_module,Group=Servers,State=Critical,Data=22,Timestamp=2020-11-04 11:14:00" \ +-u https://outlook.office.com/webhook/6f819e54-9c3f-4f87-94f4-90159496ef12@b3b55021-a812-46af-a5ef-127cc662d5b7/IncomingWebhook/634dafb7fe6549c9a214dd7fa9b97416/76c50d52-8678-49c2-9279-9f7bb3bb5a07 \ +-t "Alert Tittle" \ +-D "Alert description" \ +-m "Pandora FMS Alert message" \ +-T 53e514 \ +--sub_desc "Alert subdescription" \ +--thumb "https://pandorafms.com/images/alerta_roja.png" \ +--button https://pandorafms.com \ +--button_desc "Open PandoraFMS" + +# Pandora FMS command definition example +python3 /usr/share/pandora_server/util/pandora-teams/pandora-msteams-cli.py -d "_field1_" -u "_field2_" -t "_field3_" -D "_field4_" -m "_field5_" -T _field6_ --sub_desc "_field7_" --thumb "_field8_" --button http://newfork.artica.es/pandora_console/ --button_desc "Open PandoraFMS Console" diff --git a/pandora_plugins/message_app_connectors/slack/.gitignore b/pandora_plugins/message_app_connectors/slack/.gitignore new file mode 100644 index 0000000000..5ceb3864c2 --- /dev/null +++ b/pandora_plugins/message_app_connectors/slack/.gitignore @@ -0,0 +1 @@ +venv diff --git a/pandora_plugins/message_app_connectors/slack/pandora-slack-cli.py b/pandora_plugins/message_app_connectors/slack/pandora-slack-cli.py new file mode 100644 index 0000000000..31cfa97811 --- /dev/null +++ b/pandora_plugins/message_app_connectors/slack/pandora-slack-cli.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import requests, argparse, sys, os +from slack_sdk import WebClient +from slack_sdk.errors import SlackApiError +from datetime import datetime +from re import search +from base64 import b64decode + + + +### Variables and arg parser ### +parser = argparse.ArgumentParser(description='Slack BOT APP conector') +parser.add_argument('-d', '--data', help='Data in coma separate keypairs. Ex: test=5,house=2', required=True) +parser.add_argument('-t', '--token', help='BOT Token', required=True) +parser.add_argument('-c', '--channel', help='Slack channel id/name', required=True) +parser.add_argument('-e', '--emoji', help='Slack emoji for tittle, default: :red_circle:', default=':red_circle:') +parser.add_argument('-T', '--tittle', help='Alert tittle, default: PandoraFMS alert', default='PandoraFMS alert') +parser.add_argument('-D', '--desc', help='Slack description message', default='') +parser.add_argument('-F','--footer', help='Custom footer, default: PandoraFMS', default='PandoraFMS') +parser.add_argument('--api_conf', help='Api configuration parameters in coma separate keypairs. EX "user=admin,pass=pandora,api_pass=1234,api_url=http://test.artica.es/pandora_console/include/api.php"') +parser.add_argument('--module_graph', help='Uses pandora API to generate a module graph and attach it to the alert needs module_id and interval parameters in coma separate keypairs. EX "module_id=55,interval=3600"') +parser.add_argument('--tmp_dir', help='Temporary path to store grph images', default='/tmp') + +args = parser.parse_args() +filename = None + +#Functions + +def parse_dic(cValues): + """convert coma separate keypairs into a dic. EX "test=5,house=8,market=2" wil return "{'test': '5', 'casa': '8', 'mercado': '2'}" """ + data={} + try : + for kv in cValues.split(","): + k,v = kv.strip().split("=") + data[k.strip()]=v.strip() + except Exception as e : + print(f"Warning, error parsing keypairs values: {e}") + return data + +def compose_message (values, tittle, emoji, message, footer): + """Format Text""" + values = parse_dic(values) + m = f"{emoji} *{tittle}*\n_{message}_\n\n" + + for k, v in values.items() : + m += f"*{k}* : {v}\n" + return m + +def parse_api_conf(cConf): + """Check apiconfiguration parameters """ + if args.api_conf : + # Parse Api config + print ("Api config enable") + apid = parse_dic(cConf) + + if apid.get("user") is None: + print ("Warning. no user defined in api_conf keypairs, skiping graph generation.") + return None + + if apid.get("pass") is None: + print ("Warning. no password defined in api_conf keypairs, skiping graph generation.") + return None + + if apid.get("api_pass") is None: + print ("Warning. no api pass defined in api_conf keypairs, skiping graph generation.") + return None + + if apid.get("api_url") is None: + apid['api_url'] = "http://127.0.0.1/pandora_console/include/api.php" + #print(f"api_url: {apid['api_url']}") + + return apid + else: + return None + +def parse_graph_conf(cGraph): + """Check module graph parameters """ + if cGraph : + # Parse Api config + graphd = parse_dic(cGraph) + if graphd.get("module_id") is None: + print ("Warning. no module_id defined in module_graph keypairs, skiping graph generation.") + return + + if graphd.get("interval") is None: + graphd["interval"] = 3600 + + return graphd + else: + print("Warning. no module_graph keypairs defined, skiping graph generation") + return None + +def get_graph_by_moduleid (baseUrl,pUser, pPass, apiPass, moduleId, graphInterval, sep="url_encode_separator_%7C") : + """Call Pandorafms api to get graph""" + try: + url = f"{baseUrl}?op=get&op2=module_graph&id={moduleId}&other={graphInterval}%7C1&other_mode={sep}C&apipass={apiPass}&api=1&user={pUser}&pass={pPass}" + graph = requests.get(url) + if graph.status_code != 200: + print (f"Error requested api url, status code: {graph.status_code}. Skiping graph generation") + return None + if graph.text == "auth error": + print (f"Error requested Pandora api url, status code: {graph.text}. Skiping graph generation") + return None + if graph.text == "Id does not exist in database.": + print (f"Error requested Pandora api url, status code: {graph.text}. Skiping graph generation") + return None + + except: + print("Error requested api url. Skiping graph generation") + return None + return graph + +def send_message(message, channel, client, feddback=None): + """Send text message as slack bot""" + try: + response = client.chat_postMessage(channel=channel, text=message) + assert response["message"]["text"] == message + if feddback is not None: print(feddback) + except SlackApiError as e: + # You will get a SlackApiError if "ok" is False + assert e.response["ok"] is False + assert e.response["error"] # str like 'invalid_auth', 'channel_not_found' + print(f"Got an Slack auth error: {e.response['error']}") + exit() + +def send_image(imagepath, channel, client) : + """Send file as slack bot""" + try: + response = client.files_upload(channels=channel, file=imagepath) + assert response["file"] # the uploaded file + except SlackApiError as e: + # You will get a SlackApiError if "ok" is False + assert e.response["ok"] is False + assert e.response["error"] # str like 'invalid_auth', 'channel_not_found' + print(f"File Got an error: {e.response['error']}") + +# Main +# Intance the client object +client = WebClient(token=args.token) +# Compose message +messageString = compose_message(args.data, args.tittle, args.emoji, args.desc, args.footer) + +# Parse api config +if args.api_conf : + api = parse_api_conf(args.api_conf) + # Parse graph config + if api is not None: + graph_cfg = parse_graph_conf(args.module_graph) + + ## Generate graph + if graph_cfg is not None : + graph = get_graph_by_moduleid (api["api_url"],api["user"], api["pass"], api["api_pass"], graph_cfg["module_id"], graph_cfg["interval"]) + + if graph is not None: + try: + filename = f"{args.tmp_dir}/graph_{graph_cfg['module_id']}.{datetime.now().strftime('%s')}.png" + with open(filename, "wb") as f: + f.write(b64decode(graph.text)) + f.close + print (f"Graph generated on temporary file {filename}") + except Exception as e : + print(f"Error, cant generate graph file: {e}") + filename = None + else: filename = None + +# Send message +send_message(messageString, args.channel, client, "> Mesage sent succefuly") +if filename is not None: + if os.path.isfile(filename): send_image(filename, args.channel, client) +if args.footer: send_message(args.footer, args.channel, client) + +try: + os.remove(filename) +except: + exit() \ No newline at end of file diff --git a/pandora_plugins/message_app_connectors/slack/requirements.txt b/pandora_plugins/message_app_connectors/slack/requirements.txt new file mode 100644 index 0000000000..cdb6237a13 --- /dev/null +++ b/pandora_plugins/message_app_connectors/slack/requirements.txt @@ -0,0 +1,6 @@ +certifi==2020.11.8 +chardet==3.0.4 +idna==2.10 +requests==2.24.0 +slack-sdk==3.0.0 +urllib3==1.25.11 diff --git a/pandora_plugins/message_app_connectors/slack/test_exec.txt b/pandora_plugins/message_app_connectors/slack/test_exec.txt new file mode 100644 index 0000000000..f4639dd282 --- /dev/null +++ b/pandora_plugins/message_app_connectors/slack/test_exec.txt @@ -0,0 +1,14 @@ +#exetution example + +python3 pandora-slack-cli.py -d "Agent=Server22,Module=test_module,Group=Servers,State=Critical,Data=22,Timestamp=2020-11-04 11:14:00" \ +-t xoxb-1506287138481-1518221486533-V3QVzyBbS6lQnTKdfrdwCqYI \ +-c "varios" \ +-e ":red_circle:" \ +-T "PandoraFMS alert" \ +-D "El agente x esta en estado critico" \ +-F "Pandora FMS" \ +--api_conf "user=admin,pass=pandora,api_pass=pandora,api_url=http://192.168.80.43/pandora_console/include/api.php" \ +--module_graph "module_id=62, interval=3600" --tmp_dir /tmp + +# Pandora FMS command definition example +python3 /usr/share/pandora_server/util/pandora-slack/pandora-slack-cli.py -d "_field1_" -t _field2_ -c "_field3_" -e "_field4_" -T "_field5_" -D "_field6_" -F "Pandora FMS" --api_conf "_field7_" --module_graph "_field8_" --tmp_dir /tmp \ No newline at end of file diff --git a/pandora_plugins/message_app_connectors/telegram-bot-cli/pandora-telegram-cli.py b/pandora_plugins/message_app_connectors/telegram-bot-cli/pandora-telegram-cli.py new file mode 100644 index 0000000000..bcba8b65b0 --- /dev/null +++ b/pandora_plugins/message_app_connectors/telegram-bot-cli/pandora-telegram-cli.py @@ -0,0 +1,27 @@ +import requests, argparse, json, sys, os + +### Variables and arg parser ### +parser = argparse.ArgumentParser(description='Bot telegram cli') +parser.add_argument('-m', '--message', help='Message to be send', required=True) +parser.add_argument('-t', '--token', help='Bot token', required=True) +parser.add_argument('-c', '--chat_id', help='chat id to send messages', required=True) + + +args = parser.parse_args() + + +def send(mssg, chatId, token): + url = f"https://api.telegram.org/bot{token}/sendMessage" + headers = {'content-type': 'application/json'} + + data = { + "chat_id": chatId, + "text": mssg + } + + response = requests.get(url, data=json.dumps(data), headers=headers) + + r = response.json() + print(r) + +send(mssg=args.message, chatId=args.chat_id, token=args.token) diff --git a/pandora_plugins/message_app_connectors/telegram-bot-cli/requirements.txt b/pandora_plugins/message_app_connectors/telegram-bot-cli/requirements.txt new file mode 100644 index 0000000000..d8b263c7fb --- /dev/null +++ b/pandora_plugins/message_app_connectors/telegram-bot-cli/requirements.txt @@ -0,0 +1,5 @@ +certifi==2020.11.8 +chardet==3.0.4 +idna==2.10 +requests==2.24.0 +urllib3==1.25.11 diff --git a/pandora_plugins/message_app_connectors/telegram-bot-cli/test_exec.txt b/pandora_plugins/message_app_connectors/telegram-bot-cli/test_exec.txt new file mode 100644 index 0000000000..86844d04c2 --- /dev/null +++ b/pandora_plugins/message_app_connectors/telegram-bot-cli/test_exec.txt @@ -0,0 +1,6 @@ +#exetution example + +python3 pandora-telegram-cli.py -t 1412764845:AAG-OxOKISOXwhITLFFNm6oq5YD2KI72fTQ -c -432610056 -m "Testing pandora telegram cli" + +# Pandora FMS command definition example +python3 pandora-telegram-cli.py -t _field1_ -c _field2_ -m" _field3_" From d9428ce2158c83d5f82c35d0ba1b0ab9107ae6dd Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 25 Jan 2021 13:33:02 +0100 Subject: [PATCH 017/112] WIP DBMainainer, fixed Websockets library placement --- .../extras/delete_files/delete_files.txt | 5 +- pandora_console/include/lib/Core/Config.php | 79 ++++++ .../include/lib/Core/DBMantainer.php | 250 ++++++++++++++++++ .../lib/{ => Websockets}/WSManager.php | 10 +- .../lib/{ => Websockets}/WebSocketServer.php | 0 .../lib/{ => Websockets}/WebSocketUser.php | 0 .../vendor/composer/ClassLoader.php | 6 +- .../vendor/composer/autoload_classmap.php | 40 +-- .../vendor/composer/autoload_real.php | 4 +- .../vendor/composer/autoload_static.php | 40 +-- .../vendor/composer/platform_check.php | 26 ++ pandora_console/ws.php | 2 +- 12 files changed, 380 insertions(+), 82 deletions(-) create mode 100644 pandora_console/include/lib/Core/Config.php create mode 100644 pandora_console/include/lib/Core/DBMantainer.php rename pandora_console/include/lib/{ => Websockets}/WSManager.php (98%) rename pandora_console/include/lib/{ => Websockets}/WebSocketServer.php (100%) rename pandora_console/include/lib/{ => Websockets}/WebSocketUser.php (100%) create mode 100644 pandora_console/vendor/composer/platform_check.php diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index c647447c84..d18163093d 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -68,4 +68,7 @@ enterprise/extensions/ipam/include/javascript/ipam.js enterprise/extensions/ipam/include/javascript/IpamMapController.js enterprise/extensions/ipam/ipam_action.php enterprise/extensions/ipam.php -enterprise/extensions/ipam \ No newline at end of file +enterprise/extensions/ipam +include/lib/WSManager.php +include/lib/WebSocketServer.php +include/lib/WebSocketUser.php \ No newline at end of file diff --git a/pandora_console/include/lib/Core/Config.php b/pandora_console/include/lib/Core/Config.php new file mode 100644 index 0000000000..cda3581ed7 --- /dev/null +++ b/pandora_console/include/lib/Core/Config.php @@ -0,0 +1,79 @@ +user = $params['user']; + $this->pass = $params['pass']; + $this->host = $params['host']; + $this->port = $params['port']; + $this->name = $params['name']; + $this->charset = $params['charset']; + + // Try to connect. + $this->connect(); + } + + + /** + * Connects (if not connected) to current definition. + * + * @return boolean True if successfully connected, false if not. + */ + private function connect() + { + if ($this->connected === true) { + return true; + } + + $dbc = new \mysqli( + $this->host, + $this->user, + $this->pass, + $this->name, + $this->port + ); + + if ($dbc->connect_error === false) { + $this->dbh = null; + $this->connected = false; + $this->lastError = $dbc->connect_errno.': '.$dbc->connect_error; + } else { + $this->dbh = $dbc; + if (empty($this->charset) === false) { + $dbc->set_charset($this->charset); + } + + $this->connected = true; + $this->lastError = null; + } + + } + + + /** + * Retrieve last error. + * + * @return string Error message. + */ + public function getLastError() + { + if ($this->lastError !== null) { + return $this->lastError; + } + + return ''; + } + + + /** + * Install PandoraFMS database schema in current target. + * + * @return boolean Installation is success or not. + */ + public function install() + { + if ($this->connect() !== true) { + return false; + } + + if ($this->installed === true) { + return true; + } + + $this->lastError = 'Pending installation'; + return false; + + } + + + /** + * Updates PandoraFMS database schema in current target. + * + * @return boolean Current installation is up to date. + */ + public function update() + { + if ($this->connect() !== true) { + return false; + } + + if ($this->install() !== true) { + return false; + } + + $this->lastError = 'Pending update'; + return false; + + } + + + /** + * Verifies current target database is connected, installed and updated. + * + * @return boolean Status of the installation. + */ + public function check() + { + if ($this->connect() !== true) { + return false; + } + + if ($this->install() !== true) { + return false; + } + + if ($this->update() !== true) { + return false; + } + + return true; + } + + +} diff --git a/pandora_console/include/lib/WSManager.php b/pandora_console/include/lib/Websockets/WSManager.php similarity index 98% rename from pandora_console/include/lib/WSManager.php rename to pandora_console/include/lib/Websockets/WSManager.php index f7ab3dbddc..a8d4226af7 100644 --- a/pandora_console/include/lib/WSManager.php +++ b/pandora_console/include/lib/Websockets/WSManager.php @@ -40,14 +40,12 @@ */ // Begin. -namespace PandoraFMS\WebSockets; +namespace PandoraFMS\Websockets; use \PandoraFMS\Websockets\WebSocketServer; -use \PandoraFMS\Websockets\WebSocketUser; use \PandoraFMS\User; - -require_once __DIR__.'/../functions.php'; +require_once __DIR__.'/../../functions.php'; /** * Redirects ws communication between two endpoints. @@ -212,7 +210,7 @@ class WSManager extends WebSocketServer */ public function readSocket($user) { - $buffer; + $buffer = ''; $numBytes = socket_recv( $user->socket, @@ -271,7 +269,7 @@ class WSManager extends WebSocketServer { global $config; - $match; + $match = []; $php_session_id = ''; \preg_match( '/PHPSESSID=(.*)/', diff --git a/pandora_console/include/lib/WebSocketServer.php b/pandora_console/include/lib/Websockets/WebSocketServer.php similarity index 100% rename from pandora_console/include/lib/WebSocketServer.php rename to pandora_console/include/lib/Websockets/WebSocketServer.php diff --git a/pandora_console/include/lib/WebSocketUser.php b/pandora_console/include/lib/Websockets/WebSocketUser.php similarity index 100% rename from pandora_console/include/lib/WebSocketUser.php rename to pandora_console/include/lib/Websockets/WebSocketUser.php diff --git a/pandora_console/vendor/composer/ClassLoader.php b/pandora_console/vendor/composer/ClassLoader.php index fce8549f07..1a58957d25 100644 --- a/pandora_console/vendor/composer/ClassLoader.php +++ b/pandora_console/vendor/composer/ClassLoader.php @@ -37,8 +37,8 @@ namespace Composer\Autoload; * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { @@ -60,7 +60,7 @@ class ClassLoader public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); diff --git a/pandora_console/vendor/composer/autoload_classmap.php b/pandora_console/vendor/composer/autoload_classmap.php index ef8c54358d..3cbf2a6065 100644 --- a/pandora_console/vendor/composer/autoload_classmap.php +++ b/pandora_console/vendor/composer/autoload_classmap.php @@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'DeepCopy\\DeepCopy' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/DeepCopy.php', 'DeepCopy\\Exception\\CloneException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php', 'DeepCopy\\Exception\\PropertyException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php', @@ -44,7 +45,6 @@ return array( 'Egulias\\EmailValidator\\Exception\\DomainHyphened' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/DomainHyphened.php', 'Egulias\\EmailValidator\\Exception\\DotAtEnd' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/DotAtEnd.php', 'Egulias\\EmailValidator\\Exception\\DotAtStart' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/DotAtStart.php', - 'Egulias\\EmailValidator\\Exception\\ExpectedQPair' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingQPair.php', 'Egulias\\EmailValidator\\Exception\\ExpectingAT' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingAT.php', 'Egulias\\EmailValidator\\Exception\\ExpectingATEXT' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingATEXT.php', 'Egulias\\EmailValidator\\Exception\\ExpectingCTEXT' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingCTEXT.php', @@ -309,49 +309,20 @@ return array( 'Mpdf\\Utils\\PdfDate' => $vendorDir . '/mpdf/mpdf/src/Utils/PdfDate.php', 'Mpdf\\Utils\\UtfString' => $vendorDir . '/mpdf/mpdf/src/Utils/UtfString.php', 'PandoraFMS\\Agent' => $baseDir . '/include/lib/Agent.php', - 'PandoraFMS\\Dashboard\\AgentModuleWidget' => $baseDir . '/include/lib/Dashboard/Widgets/agent_module.php', - 'PandoraFMS\\Dashboard\\AlertsFiredWidget' => $baseDir . '/include/lib/Dashboard/Widgets/alerts_fired.php', 'PandoraFMS\\Dashboard\\Cell' => $baseDir . '/include/lib/Dashboard/Cell.php', - 'PandoraFMS\\Dashboard\\ClockWidget' => $baseDir . '/include/lib/Dashboard/Widgets/clock.php', - 'PandoraFMS\\Dashboard\\CustomGraphWidget' => $baseDir . '/include/lib/Dashboard/Widgets/custom_graph.php', - 'PandoraFMS\\Dashboard\\EventsListWidget' => $baseDir . '/include/lib/Dashboard/Widgets/events_list.php', - 'PandoraFMS\\Dashboard\\GraphModuleHistogramWidget' => $baseDir . '/include/lib/Dashboard/Widgets/graph_module_histogram.php', - 'PandoraFMS\\Dashboard\\GroupsStatusWidget' => $baseDir . '/include/lib/Dashboard/Widgets/groups_status.php', 'PandoraFMS\\Dashboard\\Manager' => $baseDir . '/include/lib/Dashboard/Manager.php', - 'PandoraFMS\\Dashboard\\MapsMadeByUser' => $baseDir . '/include/lib/Dashboard/Widgets/maps_made_by_user.php', - 'PandoraFMS\\Dashboard\\MapsStatusWidget' => $baseDir . '/include/lib/Dashboard/Widgets/maps_status.php', - 'PandoraFMS\\Dashboard\\ModuleIconWidget' => $baseDir . '/include/lib/Dashboard/Widgets/module_icon.php', - 'PandoraFMS\\Dashboard\\ModuleStatusWidget' => $baseDir . '/include/lib/Dashboard/Widgets/module_status.php', - 'PandoraFMS\\Dashboard\\ModuleTableValueWidget' => $baseDir . '/include/lib/Dashboard/Widgets/module_table_value.php', - 'PandoraFMS\\Dashboard\\ModuleValueWidget' => $baseDir . '/include/lib/Dashboard/Widgets/module_value.php', - 'PandoraFMS\\Dashboard\\MonitorHealthWidget' => $baseDir . '/include/lib/Dashboard/Widgets/monitor_health.php', - 'PandoraFMS\\Dashboard\\NetworkMapWidget' => $baseDir . '/include/lib/Dashboard/Widgets/network_map.php', - 'PandoraFMS\\Dashboard\\PostWidget' => $baseDir . '/include/lib/Dashboard/Widgets/post.php', - 'PandoraFMS\\Dashboard\\ReportsWidget' => $baseDir . '/include/lib/Dashboard/Widgets/reports.php', - 'PandoraFMS\\Dashboard\\SLAPercentWidget' => $baseDir . '/include/lib/Dashboard/Widgets/sla_percent.php', - 'PandoraFMS\\Dashboard\\ServiceMapWidget' => $baseDir . '/include/lib/Dashboard/Widgets/service_map.php', - 'PandoraFMS\\Dashboard\\SingleGraphWidget' => $baseDir . '/include/lib/Dashboard/Widgets/single_graph.php', - 'PandoraFMS\\Dashboard\\SystemGroupStatusWidget' => $baseDir . '/include/lib/Dashboard/Widgets/system_group_status.php', - 'PandoraFMS\\Dashboard\\TacticalWidget' => $baseDir . '/include/lib/Dashboard/Widgets/tactical.php', - 'PandoraFMS\\Dashboard\\TopNEventByGroupWidget' => $baseDir . '/include/lib/Dashboard/Widgets/top_n_events_by_group.php', - 'PandoraFMS\\Dashboard\\TopNEventByModuleWidget' => $baseDir . '/include/lib/Dashboard/Widgets/top_n_events_by_module.php', - 'PandoraFMS\\Dashboard\\TopNWidget' => $baseDir . '/include/lib/Dashboard/Widgets/top_n.php', - 'PandoraFMS\\Dashboard\\TreeViewWidget' => $baseDir . '/include/lib/Dashboard/Widgets/tree_view.php', - 'PandoraFMS\\Dashboard\\UrlWidget' => $baseDir . '/include/lib/Dashboard/Widgets/url.php', - 'PandoraFMS\\Dashboard\\WelcomeWidget' => $baseDir . '/include/lib/Dashboard/Widgets/example.php', 'PandoraFMS\\Dashboard\\Widget' => $baseDir . '/include/lib/Dashboard/Widget.php', - 'PandoraFMS\\Dashboard\\WuxStatsWidget' => $baseDir . '/include/lib/Dashboard/Widgets/wux_transaction_stats.php', - 'PandoraFMS\\Dashboard\\WuxWidget' => $baseDir . '/include/lib/Dashboard/Widgets/wux_transaction.php', 'PandoraFMS\\Entity' => $baseDir . '/include/lib/Entity.php', + 'PandoraFMS\\Event' => $baseDir . '/include/lib/Event.php', 'PandoraFMS\\Group' => $baseDir . '/include/lib/Group.php', 'PandoraFMS\\Module' => $baseDir . '/include/lib/Module.php', 'PandoraFMS\\ModuleStatus' => $baseDir . '/include/lib/ModuleStatus.php', 'PandoraFMS\\ModuleType' => $baseDir . '/include/lib/ModuleType.php', 'PandoraFMS\\User' => $baseDir . '/include/lib/User.php', 'PandoraFMS\\View' => $baseDir . '/include/lib/View.php', - 'PandoraFMS\\WebSockets\\WSManager' => $baseDir . '/include/lib/WSManager.php', - 'PandoraFMS\\Websockets\\WebSocketServer' => $baseDir . '/include/lib/WebSocketServer.php', - 'PandoraFMS\\Websockets\\WebSocketUser' => $baseDir . '/include/lib/WebSocketUser.php', + 'PandoraFMS\\Websockets\\WSManager' => $baseDir . '/include/lib/Websockets/WSManager.php', + 'PandoraFMS\\Websockets\\WebSocketServer' => $baseDir . '/include/lib/Websockets/WebSocketServer.php', + 'PandoraFMS\\Websockets\\WebSocketUser' => $baseDir . '/include/lib/Websockets/WebSocketUser.php', 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php', 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php', 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php', @@ -360,7 +331,6 @@ return array( 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', - 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', 'fpdi_pdf_parser' => $vendorDir . '/setasign/fpdi/fpdi_pdf_parser.php', 'pdf_context' => $vendorDir . '/setasign/fpdi/pdf_context.php', diff --git a/pandora_console/vendor/composer/autoload_real.php b/pandora_console/vendor/composer/autoload_real.php index 8576380cc1..33d719ba60 100644 --- a/pandora_console/vendor/composer/autoload_real.php +++ b/pandora_console/vendor/composer/autoload_real.php @@ -22,13 +22,15 @@ class ComposerAutoloaderInitfdecadadce22e6dde51e9535fe4ad7aa return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInitfdecadadce22e6dde51e9535fe4ad7aa', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInitfdecadadce22e6dde51e9535fe4ad7aa', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + require __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa::getInitializer($loader)); } else { diff --git a/pandora_console/vendor/composer/autoload_static.php b/pandora_console/vendor/composer/autoload_static.php index ee0f05a330..62260fc4b8 100644 --- a/pandora_console/vendor/composer/autoload_static.php +++ b/pandora_console/vendor/composer/autoload_static.php @@ -88,6 +88,7 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa ); public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'DeepCopy\\DeepCopy' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/DeepCopy.php', 'DeepCopy\\Exception\\CloneException' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php', 'DeepCopy\\Exception\\PropertyException' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php', @@ -126,7 +127,6 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa 'Egulias\\EmailValidator\\Exception\\DomainHyphened' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/DomainHyphened.php', 'Egulias\\EmailValidator\\Exception\\DotAtEnd' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/DotAtEnd.php', 'Egulias\\EmailValidator\\Exception\\DotAtStart' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/DotAtStart.php', - 'Egulias\\EmailValidator\\Exception\\ExpectedQPair' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingQPair.php', 'Egulias\\EmailValidator\\Exception\\ExpectingAT' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingAT.php', 'Egulias\\EmailValidator\\Exception\\ExpectingATEXT' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingATEXT.php', 'Egulias\\EmailValidator\\Exception\\ExpectingCTEXT' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingCTEXT.php', @@ -391,49 +391,20 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa 'Mpdf\\Utils\\PdfDate' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/PdfDate.php', 'Mpdf\\Utils\\UtfString' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/UtfString.php', 'PandoraFMS\\Agent' => __DIR__ . '/../..' . '/include/lib/Agent.php', - 'PandoraFMS\\Dashboard\\AgentModuleWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/agent_module.php', - 'PandoraFMS\\Dashboard\\AlertsFiredWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/alerts_fired.php', 'PandoraFMS\\Dashboard\\Cell' => __DIR__ . '/../..' . '/include/lib/Dashboard/Cell.php', - 'PandoraFMS\\Dashboard\\ClockWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/clock.php', - 'PandoraFMS\\Dashboard\\CustomGraphWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/custom_graph.php', - 'PandoraFMS\\Dashboard\\EventsListWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/events_list.php', - 'PandoraFMS\\Dashboard\\GraphModuleHistogramWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/graph_module_histogram.php', - 'PandoraFMS\\Dashboard\\GroupsStatusWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/groups_status.php', 'PandoraFMS\\Dashboard\\Manager' => __DIR__ . '/../..' . '/include/lib/Dashboard/Manager.php', - 'PandoraFMS\\Dashboard\\MapsMadeByUser' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/maps_made_by_user.php', - 'PandoraFMS\\Dashboard\\MapsStatusWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/maps_status.php', - 'PandoraFMS\\Dashboard\\ModuleIconWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/module_icon.php', - 'PandoraFMS\\Dashboard\\ModuleStatusWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/module_status.php', - 'PandoraFMS\\Dashboard\\ModuleTableValueWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/module_table_value.php', - 'PandoraFMS\\Dashboard\\ModuleValueWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/module_value.php', - 'PandoraFMS\\Dashboard\\MonitorHealthWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/monitor_health.php', - 'PandoraFMS\\Dashboard\\NetworkMapWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/network_map.php', - 'PandoraFMS\\Dashboard\\PostWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/post.php', - 'PandoraFMS\\Dashboard\\ReportsWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/reports.php', - 'PandoraFMS\\Dashboard\\SLAPercentWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/sla_percent.php', - 'PandoraFMS\\Dashboard\\ServiceMapWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/service_map.php', - 'PandoraFMS\\Dashboard\\SingleGraphWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/single_graph.php', - 'PandoraFMS\\Dashboard\\SystemGroupStatusWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/system_group_status.php', - 'PandoraFMS\\Dashboard\\TacticalWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/tactical.php', - 'PandoraFMS\\Dashboard\\TopNEventByGroupWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/top_n_events_by_group.php', - 'PandoraFMS\\Dashboard\\TopNEventByModuleWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/top_n_events_by_module.php', - 'PandoraFMS\\Dashboard\\TopNWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/top_n.php', - 'PandoraFMS\\Dashboard\\TreeViewWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/tree_view.php', - 'PandoraFMS\\Dashboard\\UrlWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/url.php', - 'PandoraFMS\\Dashboard\\WelcomeWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/example.php', 'PandoraFMS\\Dashboard\\Widget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widget.php', - 'PandoraFMS\\Dashboard\\WuxStatsWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/wux_transaction_stats.php', - 'PandoraFMS\\Dashboard\\WuxWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/wux_transaction.php', 'PandoraFMS\\Entity' => __DIR__ . '/../..' . '/include/lib/Entity.php', + 'PandoraFMS\\Event' => __DIR__ . '/../..' . '/include/lib/Event.php', 'PandoraFMS\\Group' => __DIR__ . '/../..' . '/include/lib/Group.php', 'PandoraFMS\\Module' => __DIR__ . '/../..' . '/include/lib/Module.php', 'PandoraFMS\\ModuleStatus' => __DIR__ . '/../..' . '/include/lib/ModuleStatus.php', 'PandoraFMS\\ModuleType' => __DIR__ . '/../..' . '/include/lib/ModuleType.php', 'PandoraFMS\\User' => __DIR__ . '/../..' . '/include/lib/User.php', 'PandoraFMS\\View' => __DIR__ . '/../..' . '/include/lib/View.php', - 'PandoraFMS\\WebSockets\\WSManager' => __DIR__ . '/../..' . '/include/lib/WSManager.php', - 'PandoraFMS\\Websockets\\WebSocketServer' => __DIR__ . '/../..' . '/include/lib/WebSocketServer.php', - 'PandoraFMS\\Websockets\\WebSocketUser' => __DIR__ . '/../..' . '/include/lib/WebSocketUser.php', + 'PandoraFMS\\Websockets\\WSManager' => __DIR__ . '/../..' . '/include/lib/Websockets/WSManager.php', + 'PandoraFMS\\Websockets\\WebSocketServer' => __DIR__ . '/../..' . '/include/lib/Websockets/WebSocketServer.php', + 'PandoraFMS\\Websockets\\WebSocketUser' => __DIR__ . '/../..' . '/include/lib/Websockets/WebSocketUser.php', 'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php', 'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php', 'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/Psr/Log/LogLevel.php', @@ -442,7 +413,6 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa 'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php', - 'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', 'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', 'fpdi_pdf_parser' => __DIR__ . '/..' . '/setasign/fpdi/fpdi_pdf_parser.php', 'pdf_context' => __DIR__ . '/..' . '/setasign/fpdi/pdf_context.php', diff --git a/pandora_console/vendor/composer/platform_check.php b/pandora_console/vendor/composer/platform_check.php new file mode 100644 index 0000000000..f79e574be7 --- /dev/null +++ b/pandora_console/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70000)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/pandora_console/ws.php b/pandora_console/ws.php index 0c9509720c..96148761b9 100644 --- a/pandora_console/ws.php +++ b/pandora_console/ws.php @@ -28,7 +28,7 @@ // Begin. require_once __DIR__.'/vendor/autoload.php'; -use \PandoraFMS\WebSockets\WSManager; +use \PandoraFMS\Websockets\WSManager; // Set to true to get full output. $debug = false; From 5799c3e19987a3029ef27a70a7a62cbfa057a6a3 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 25 Jan 2021 13:35:58 +0100 Subject: [PATCH 018/112] composer paths updated --- pandora_console/vendor/composer/autoload_classmap.php | 2 ++ pandora_console/vendor/composer/autoload_static.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pandora_console/vendor/composer/autoload_classmap.php b/pandora_console/vendor/composer/autoload_classmap.php index 3cbf2a6065..4938966edb 100644 --- a/pandora_console/vendor/composer/autoload_classmap.php +++ b/pandora_console/vendor/composer/autoload_classmap.php @@ -309,6 +309,8 @@ return array( 'Mpdf\\Utils\\PdfDate' => $vendorDir . '/mpdf/mpdf/src/Utils/PdfDate.php', 'Mpdf\\Utils\\UtfString' => $vendorDir . '/mpdf/mpdf/src/Utils/UtfString.php', 'PandoraFMS\\Agent' => $baseDir . '/include/lib/Agent.php', + 'PandoraFMS\\Core\\Config' => $baseDir . '/include/lib/Core/Config.php', + 'PandoraFMS\\Core\\DBMantainer' => $baseDir . '/include/lib/Core/DBMantainer.php', 'PandoraFMS\\Dashboard\\Cell' => $baseDir . '/include/lib/Dashboard/Cell.php', 'PandoraFMS\\Dashboard\\Manager' => $baseDir . '/include/lib/Dashboard/Manager.php', 'PandoraFMS\\Dashboard\\Widget' => $baseDir . '/include/lib/Dashboard/Widget.php', diff --git a/pandora_console/vendor/composer/autoload_static.php b/pandora_console/vendor/composer/autoload_static.php index 62260fc4b8..dcc588664c 100644 --- a/pandora_console/vendor/composer/autoload_static.php +++ b/pandora_console/vendor/composer/autoload_static.php @@ -391,6 +391,8 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa 'Mpdf\\Utils\\PdfDate' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/PdfDate.php', 'Mpdf\\Utils\\UtfString' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/UtfString.php', 'PandoraFMS\\Agent' => __DIR__ . '/../..' . '/include/lib/Agent.php', + 'PandoraFMS\\Core\\Config' => __DIR__ . '/../..' . '/include/lib/Core/Config.php', + 'PandoraFMS\\Core\\DBMantainer' => __DIR__ . '/../..' . '/include/lib/Core/DBMantainer.php', 'PandoraFMS\\Dashboard\\Cell' => __DIR__ . '/../..' . '/include/lib/Dashboard/Cell.php', 'PandoraFMS\\Dashboard\\Manager' => __DIR__ . '/../..' . '/include/lib/Dashboard/Manager.php', 'PandoraFMS\\Dashboard\\Widget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widget.php', From 192a635599975cdb5b80ebbd54ef347dedcb5947 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 25 Jan 2021 19:29:22 +0100 Subject: [PATCH 019/112] WIP setup.hdb --- .../godmode/wizards/Wizard.main.php | 2 - pandora_console/include/functions_ui.php | 14 +- pandora_console/include/lib/Core/Config.php | 70 +++++-- .../include/lib/Core/DBMantainer.php | 194 +++++++++++++++++- pandora_console/include/styles/pandora.css | 4 + pandora_console/include/styles/setup.css | 5 + 6 files changed, 265 insertions(+), 24 deletions(-) create mode 100644 pandora_console/include/styles/setup.css diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index 6783ba20e1..3485dec627 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -32,8 +32,6 @@ global $config; require_once $config['homedir'].'/vendor/autoload.php'; require_once $config['homedir'].'/include/class/HTML.class.php'; -use \HTML; - /** * Global Wizard generic class. Needs to be inherited. * diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index cc72d93f5f..3ec6eec22c 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -3935,7 +3935,19 @@ function ui_toggle( /** * Simplified way of ui_toggle ussage. * - * @param array $data Arguments. + * @param array $data Arguments: + * - content + * - name + * - title + * - id + * - hidden_default + * - return + * - toggle_class + * - container_class + * - main_class + * - img_a + * - img_b + * - clean. * * @return string HTML code with toggle content. */ diff --git a/pandora_console/include/lib/Core/Config.php b/pandora_console/include/lib/Core/Config.php index cda3581ed7..51b9f09c63 100644 --- a/pandora_console/include/lib/Core/Config.php +++ b/pandora_console/include/lib/Core/Config.php @@ -29,8 +29,8 @@ // Begin. namespace PandoraFMS\Core; -require_once __DIR__.'/../../include/config.php'; -require_once __DIR__.'/../../include/functions_config.php'; +require_once __DIR__.'/../../config.php'; +require_once __DIR__.'/../../functions_config.php'; /** * Config class to operate console configuration. @@ -38,21 +38,57 @@ require_once __DIR__.'/../../include/functions_config.php'; final class Config { + /** + * History database settings (tconfig). + * + * @var array + */ + private static $settings = []; + + + /** + * Load history database settings. + */ + private static function loadHistoryDBSettings() + { + if (self::$settings === null) { + $data = \db_get_all_rows_filter('tconfig', [], false, 'AND', true); + self::$settings = array_reduce( + $data, + function ($carry, $item) { + $carry[$item['token']] = $item['value']; + }, + [] + ); + } + } + /** * Retrieve configuration token. * - * @param string $token Token to retrieve. - * @param mixed $default Default value if not found. + * @param string $token Token to retrieve. + * @param mixed $default Default value if not found. + * @param boolean $history_db Search for token in history_db. * * @return mixed Configuration token. */ - public static function get(string $token, $default=null) - { - global $config; + public static function get( + string $token, + $default=null, + bool $history_db=false + ) { + if ($history_db === true) { + self::loadHistoryDBSettings(); + if (isset(self::$settings[$token]) === true) { + return self::$settings[$token]; + } + } else { + global $config; - if (isset($config[$token]) === true) { - return $config[$token]; + if (isset($config[$token]) === true) { + return $config[$token]; + } } return $default; @@ -63,15 +99,21 @@ final class Config /** * Set configuration token. * - * @param string $token Token to set. - * @param mixed $value Value to be. + * @param string $token Token to set. + * @param mixed $value Value to be. + * @param boolean $history_db Save to history_db settings. * * @return void */ - public static function set(string $token, $value) + public static function set(string $token, $value, bool $history_db=false) { - if (self::get($token) === null) { - config_update_value($token, $value); + if ($history_db !== false) { + if (self::get($token, null, $history_db) === null) { + } + } else { + if (self::get($token) === null) { + config_update_value($token, $value); + } } } diff --git a/pandora_console/include/lib/Core/DBMantainer.php b/pandora_console/include/lib/Core/DBMantainer.php index 1e8b6d80c3..d08a34bbd7 100644 --- a/pandora_console/include/lib/Core/DBMantainer.php +++ b/pandora_console/include/lib/Core/DBMantainer.php @@ -34,6 +34,12 @@ namespace PandoraFMS\Core; */ final class DBMantainer { + const ESSENTIAL_TABLES = [ + 'tagente_datos', + 'tagente_datos_string', + 'tevento', + 'tconfig', + ]; /** * Database user. @@ -105,6 +111,13 @@ final class DBMantainer */ private $lastError; + /** + * Connected to engine and database. + * + * @var boolean + */ + private $ready; + /** * Initialize DBMaintainer object. @@ -146,11 +159,11 @@ final class DBMantainer $this->host, $this->user, $this->pass, - $this->name, + null, $this->port ); - if ($dbc->connect_error === false) { + if ((bool) $dbc->connect_error === true) { $this->dbh = null; $this->connected = false; $this->lastError = $dbc->connect_errno.': '.$dbc->connect_error; @@ -160,10 +173,16 @@ final class DBMantainer $dbc->set_charset($this->charset); } - $this->connected = true; - $this->lastError = null; - } + if ($this->dbh->select_db($this->name) === false) { + $this->lastError = $this->dbh->errno.': '.$this->dbh->error; + $this->ready = false; + } else { + $this->lastError = null; + $this->ready = true; + } + $this->connected = true; + } } @@ -182,6 +201,100 @@ final class DBMantainer } + /** + * Retrieve all rows from given query in array format. + * + * @param string $query Query. + * + * @return array Results. + */ + private function getAllRows(string $query) + { + if ($this->ready !== true) { + $this->lastError = $this->dbh->errno.': '.$this->dbh->error; + return []; + } + + $rs = $this->dbh->query($query); + + $results = []; + + do { + $row = $rs->fetch_array(MYSQLI_ASSOC); + if ((bool) $row !== false) { + $results[] = $row; + } + } while ((bool) $row !== false); + + return $results; + } + + + /** + * Verifies schema against running db. + * + * @return boolean Success or not. + */ + public function verifySchema() + { + if ($this->ready !== true) { + return false; + } + + $missing_essential_tables = $this->verifyTables(); + + return !(bool) count($missing_essential_tables); + } + + + /** + * Verifies tables against running db. + * + * @return boolean Applied or not. + */ + public function verifyTables() + { + global $config; + + $t = \db_get_all_rows_sql( + sprintf( + 'SHOW TABLES FROM %s', + $config['dbname'] + ) + ); + + $tables = []; + foreach ($t as $v) { + $tables[] = array_shift($v); + } + + $t = $this->getAllRows( + sprintf( + 'SHOW TABLES FROM %s', + $this->name + ) + ); + $myTables = []; + foreach ($t as $k => $v) { + $myTables[] = array_shift($v); + } + + $differences = array_diff($tables, $myTables); + + if (count($differences) > 0) { + $this->lastError = sprintf( + 'Warning, following tables does not exist in target: %s', + join(', ', $differences) + ); + } + + // Exclude extension tables. + $differences = array_intersect($differences, self::ESSENTIAL_TABLES); + + return $differences; + } + + /** * Install PandoraFMS database schema in current target. * @@ -197,8 +310,33 @@ final class DBMantainer return true; } - $this->lastError = 'Pending installation'; - return false; + if ($this->ready !== true) { + // Not ready, create database in target. + $rc = $this->dbh->query( + sprintf( + 'CREATE DATABASE %s', + $this->name + ) + ); + + if ($rc === false) { + $this->lastError = $this->dbh->errno.': '.$this->dbh->error; + return false; + } + + if ($this->dbh->select_db($this->name) === false) { + $this->lastError = $this->dbh->errno.': '.$this->dbh->error; + return false; + } + + // Already connected and ready to execute commands. + $this->ready = true; + } else if ($this->verifySchema() === true) { + $this->installed = true; + return true; + } + + return $this->applyDump(Config::get('homedir', '').'/pandoradb.sql'); } @@ -247,4 +385,46 @@ final class DBMantainer } + /** + * This function keeps same functionality as install.php:parse_mysqli_dump. + * + * @param string $path Path where SQL dump file is stored. + * + * @return boolean Success or not. + */ + private function applyDump(string $path) + { + if (file_exists($path) === true) { + $file_content = file($path); + $query = ''; + foreach ($file_content as $sql_line) { + if (trim($sql_line) !== '' + && strpos($sql_line, '-- ') === false + ) { + $query .= $sql_line; + if ((bool) preg_match("/;[\040]*\$/", $sql_line) === true) { + $result = $this->dbh->query($query); + if ((bool) $result === false) { + $this->lastError = $this->dbh->errnum.': '; + $this->lastERror .= $this->dbh->error; + return false; + } + + $query = ''; + } + } + } + + return true; + } + + // File does not exist. + $this->lastError = sprintf( + 'File %s does not exist', + $path + ); + return false; + } + + } diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index f3a6959cba..a1b21bd24b 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -478,6 +478,10 @@ select:-internal-list-box { width: 290px; max-width: 290px; } +.w600px { + width: 600px; + max-width: 600px; +} .mw120px { min-width: 120px; } diff --git a/pandora_console/include/styles/setup.css b/pandora_console/include/styles/setup.css new file mode 100644 index 0000000000..331bc7aa2e --- /dev/null +++ b/pandora_console/include/styles/setup.css @@ -0,0 +1,5 @@ +span.subtitle { + font-size: 1.3em; + font-weight: normal; + font-family: "lato-bolder"; +} From c7706a6bfaaa8cbb33080af0208baeccca6ac8f7 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 27 Jan 2021 12:35:37 +0100 Subject: [PATCH 020/112] WIP Historical database manager (setup) --- pandora_console/godmode/setup/setup.php | 12 ++ pandora_console/include/functions_config.php | 114 ++++++++++++++++-- pandora_console/include/functions_ui.php | 59 ++++++--- pandora_console/include/lib/Core/Config.php | 84 +++++++++++-- .../{DBMantainer.php => DBMaintainer.php} | 2 +- pandora_console/include/styles/pandora.css | 2 +- pandora_console/include/styles/setup.css | 10 ++ .../vendor/composer/autoload_classmap.php | 2 +- .../vendor/composer/autoload_static.php | 2 +- 9 files changed, 237 insertions(+), 50 deletions(-) rename pandora_console/include/lib/Core/{DBMantainer.php => DBMaintainer.php} (99%) diff --git a/pandora_console/godmode/setup/setup.php b/pandora_console/godmode/setup/setup.php index e77d314f4c..d1df683325 100644 --- a/pandora_console/godmode/setup/setup.php +++ b/pandora_console/godmode/setup/setup.php @@ -248,6 +248,18 @@ if (isset($config['error_config_update_config'])) { ui_print_success_message(__('Correct update the setup options')); } + if (is_array($config['error_config_update_config']['errors']) === true) { + foreach ($config['error_config_update_config']['errors'] as $msg) { + ui_print_error_message($msg); + } + } + + if (is_array($config['error_config_update_config']['warnings']) === true) { + foreach ($config['error_config_update_config']['warnings'] as $msg) { + ui_print_warning_message($msg); + } + } + unset($config['error_config_update_config']); } diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index b9b06fabc6..57058a59a0 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -26,7 +26,10 @@ * ============================================================================ */ - // Config functions. +// Config functions. +require_once __DIR__.'/../vendor/autoload.php'; +use PandoraFMS\Core\DBMaintainer; +use PandoraFMS\Core\Config; /** @@ -147,6 +150,8 @@ function config_update_config() } $error_update = []; + $errors = []; + $warnings = []; $sec2 = get_parameter('sec2'); @@ -1448,6 +1453,27 @@ function config_update_config() break; case 'hist_db': + if ($config['dbname'] == get_parameter('history_db_name') + && $config['dbport'] == get_parameter('history_db_port') + && $config['dbhost'] == io_input_password(get_parameter('history_db_host')) + ) { + // Same definition for active and historical database! + // This is a critical error. + $errors[] = __('Active and historical database cannot be the same.'); + } else { + if (!config_update_value('history_db_host', get_parameter('history_db_host'))) { + $error_update[] = __('Host'); + } + + if (!config_update_value('history_db_port', get_parameter('history_db_port'))) { + $error_update[] = __('Port'); + } + + if (!config_update_value('history_db_name', get_parameter('history_db_name'))) { + $error_update[] = __('Database name'); + } + } + if (!config_update_value('history_db_enabled', get_parameter('history_db_enabled'))) { $error_update[] = __('Enable history database'); } @@ -1456,18 +1482,6 @@ function config_update_config() $error_update[] = __('Enable history event'); } - if (!config_update_value('history_db_host', get_parameter('history_db_host'))) { - $error_update[] = __('Host'); - } - - if (!config_update_value('history_db_port', get_parameter('history_db_port'))) { - $error_update[] = __('Port'); - } - - if (!config_update_value('history_db_name', get_parameter('history_db_name'))) { - $error_update[] = __('Database name'); - } - if (!config_update_value('history_db_user', get_parameter('history_db_user'))) { $error_update[] = __('Database user'); } @@ -1507,6 +1521,72 @@ function config_update_config() ) { $error_update[] = __('Delay'); } + + if ((bool) $config['history_db_enabled'] === true) { + $dbm = new DBMaintainer( + [ + 'host' => $config['history_db_host'], + 'port' => $config['history_db_port'], + 'name' => $config['history_db_name'], + 'user' => $config['history_db_user'], + 'pass' => $config['history_db_pass'], + ] + ); + + // Performs several checks and installs if needed. + if ($dbm->check() === false) { + $errors[] = $dbm->getLastError(); + } + } + + // Historical configuration tokens (stored in historical db). + if (Config::set( + 'days_purge', + get_parameter('history_dbh_purge'), + true + ) !== true + ) { + $error_update[] = __('Historical database purge'); + } + + if (Config::set( + 'days_compact', + get_parameter('history_dbh_days_compact'), + true + ) !== true + ) { + $error_update[] = __('Historical database days compact'); + } + + if (Config::set( + 'step_compact', + get_parameter('history_dbh_step_compact'), + true + ) !== true + ) { + $error_update[] = __('Historical database step compact'); + } + + if (Config::set( + 'event_purge', + get_parameter('history_dbh_events_purge'), + true + ) !== true + ) { + $error_update[] = __('Historical database events purge'); + } + + if (Config::set( + 'string_purge', + get_parameter('history_dbh_string_purge'), + true + ) !== true + ) { + $error_update[] = __('Historical database string purge'); + } + + // Disable history db in history db. + Config::set('history_db_enabled', 0, true); break; case 'ehorus': @@ -1675,6 +1755,14 @@ function config_update_config() $config['error_config_update_config']['correct'] = true; } + if (count($errors) > 0) { + $config['error_config_update_config']['errors'] = $errors; + } + + if (count($warnings) > 0) { + $config['error_config_update_config']['warnings'] = $warnings; + } + enterprise_include_once('include/functions_policies.php'); $enterprise = enterprise_include_once('include/functions_skins.php'); if ($enterprise !== ENTERPRISE_NOT_HOOK) { diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 3ec6eec22c..5b57d81870 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -3747,18 +3747,22 @@ function ui_print_event_priority( /** * Print a code into a DIV and enable a toggle to show and hide it. * - * @param string $code Html code. - * @param string $name Name of the link. - * @param string $title Title of the link. - * @param string $id Block id. - * @param boolean $hidden_default If the div will be hidden by default (default: true). - * @param boolean $return Whether to return an output string or echo now (default: true). - * @param string $toggle_class Toggle class. - * @param string $container_class Container class. - * @param string $main_class Main object class. - * @param string $img_a Image (closed). - * @param string $img_b Image (opened). - * @param string $clean Do not encapsulate with class boxes, clean print. + * @param string $code Html code. + * @param string $name Name of the link. + * @param string $title Title of the link. + * @param string $id Block id. + * @param boolean $hidden_default If the div will be hidden by default (default: true). + * @param boolean $return Whether to return an output string or echo now (default: true). + * @param string $toggle_class Toggle class. + * @param string $container_class Container class. + * @param string $main_class Main object class. + * @param string $img_a Image (closed). + * @param string $img_b Image (opened). + * @param string $clean Do not encapsulate with class boxes, clean print. + * @param boolean $reverseImg Reverse image. + * @param boolean $swtich Use switch input instead image. + * @param string $attributes_switch Switch attributes (class...). + * @param string|null $switch_name Use custom switch input name or generate one. * * @return string HTML. */ @@ -3777,7 +3781,8 @@ function ui_toggle( $clean=false, $reverseImg=false, $switch=false, - $attributes_switch='' + $attributes_switch='', + $switch_name=null ) { // Generate unique Id. $uniqid = uniqid(''); @@ -3813,7 +3818,9 @@ function ui_toggle( $main_class = ''; } - $container_class = 'white-box-content-clean'; + if ($container_class == 'white-box-content') { + $container_class = 'white-box-content-clean'; + } } // Link to toggle. @@ -3821,11 +3828,15 @@ function ui_toggle( $output .= '
'; if ($reverseImg === false) { if ($switch === true) { + if (empty($switch_name) === true) { + $switch_name = 'box_enable_toggle'.$uniqid; + } + $output .= html_print_div( [ 'class' => 'float-left', 'content' => html_print_checkbox_switch_extended( - 'box_enable_toggle'.$uniqid, + $switch_name, 1, ($hidden_default === true) ? 0 : 1, false, @@ -3895,7 +3906,7 @@ function ui_toggle( $output .= ' var hide_tgl_ctrl_'.$uniqid.' = '.(int) $hidden_default.";\n"; $output .= ' /* $vendorDir . '/mpdf/mpdf/src/Utils/UtfString.php', 'PandoraFMS\\Agent' => $baseDir . '/include/lib/Agent.php', 'PandoraFMS\\Core\\Config' => $baseDir . '/include/lib/Core/Config.php', - 'PandoraFMS\\Core\\DBMantainer' => $baseDir . '/include/lib/Core/DBMantainer.php', + 'PandoraFMS\\Core\\DBMaintainer' => $baseDir . '/include/lib/Core/DBMaintainer.php', 'PandoraFMS\\Dashboard\\Cell' => $baseDir . '/include/lib/Dashboard/Cell.php', 'PandoraFMS\\Dashboard\\Manager' => $baseDir . '/include/lib/Dashboard/Manager.php', 'PandoraFMS\\Dashboard\\Widget' => $baseDir . '/include/lib/Dashboard/Widget.php', diff --git a/pandora_console/vendor/composer/autoload_static.php b/pandora_console/vendor/composer/autoload_static.php index dcc588664c..e1953333f9 100644 --- a/pandora_console/vendor/composer/autoload_static.php +++ b/pandora_console/vendor/composer/autoload_static.php @@ -392,7 +392,7 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa 'Mpdf\\Utils\\UtfString' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/UtfString.php', 'PandoraFMS\\Agent' => __DIR__ . '/../..' . '/include/lib/Agent.php', 'PandoraFMS\\Core\\Config' => __DIR__ . '/../..' . '/include/lib/Core/Config.php', - 'PandoraFMS\\Core\\DBMantainer' => __DIR__ . '/../..' . '/include/lib/Core/DBMantainer.php', + 'PandoraFMS\\Core\\DBMaintainer' => __DIR__ . '/../..' . '/include/lib/Core/DBMaintainer.php', 'PandoraFMS\\Dashboard\\Cell' => __DIR__ . '/../..' . '/include/lib/Dashboard/Cell.php', 'PandoraFMS\\Dashboard\\Manager' => __DIR__ . '/../..' . '/include/lib/Dashboard/Manager.php', 'PandoraFMS\\Dashboard\\Widget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widget.php', From bcb2447edb2a9798a99fad407ecc22fb76a7c253 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 27 Jan 2021 13:03:57 +0100 Subject: [PATCH 021/112] WIP Historical database manager (setup) --- pandora_console/godmode/setup/performance.php | 48 ++++--------------- 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/pandora_console/godmode/setup/performance.php b/pandora_console/godmode/setup/performance.php index 366d55d4d9..14e376415c 100644 --- a/pandora_console/godmode/setup/performance.php +++ b/pandora_console/godmode/setup/performance.php @@ -29,7 +29,10 @@ // Load global vars. global $config; -require_once 'include/config.php'; +require_once $config['homedir'].'/include/config.php'; +require_once $config['homedir'].'/vendor/autoload.php'; + +use PandoraFMS\Core\Config; check_login(); @@ -388,44 +391,11 @@ if ($config['history_db_enabled'] == 1) { ); } - $config_history = false; - if ($config['history_db_connection']) { - $history_connect = mysql_db_process_sql( - 'DESCRIBE tconfig', - 'affected_rows', - $config['history_db_connection'], - false - ); - - if ($history_connect !== false) { - $config_history_array = mysql_db_process_sql( - 'SELECT * FROM tconfig', - 'affected_rows', - $config['history_db_connection'], - false - ); - - if (isset($config_history_array) && is_array($config_history_array)) { - foreach ($config_history_array as $key => $value) { - $config_history[$value['token']] = $value['value']; - $config_history = true; - } - } - } else { - echo ui_print_error_message( - __('The tconfig table does not exist in the historical database') - ); - } - } - - if ($config_history === false) { - $config_history = []; - $config_history['days_purge'] = 180; - $config_history['days_compact'] = 120; - $config_history['step_compact'] = 1; - $config_history['event_purge'] = 180; - $config_history['string_purge'] = 180; - } + $config_history['days_purge'] = Config::get('days_purge', 180, true); + $config_history['days_compact'] = Config::get('days_compact', 120, true); + $config_history['step_compact'] = Config::get('step_compact', 1, true); + $config_history['event_purge'] = Config::get('event_purge', 180, true); + $config_history['string_purge'] = Config::get('string_purge', 180, true); $table_historical = new StdClass(); $table_historical->width = '100%'; From bbab6d9fe1dfc52b1cc575be066c8129f7e481c2 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 27 Jan 2021 14:06:22 +0100 Subject: [PATCH 022/112] WIP update process --- .../include/lib/Core/DBMaintainer.php | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/lib/Core/DBMaintainer.php b/pandora_console/include/lib/Core/DBMaintainer.php index 2193f74421..a8c5fbc7b9 100644 --- a/pandora_console/include/lib/Core/DBMaintainer.php +++ b/pandora_console/include/lib/Core/DBMaintainer.php @@ -230,6 +230,62 @@ final class DBMaintainer } + /** + * Return first row available for given query. + * + * @param string $query Query to retrieve (1 row only). + * + * @return array Row. + */ + private function getRow(string $query) + { + if ($this->ready !== true) { + $this->lastError = $this->dbh->errno.': '.$this->dbh->error; + return []; + } + + $query .= ' LIMIT 1'; + $rs = $this->dbh->query($query); + if ($rs !== false) { + return $rs->fetch_array(MYSQLI_ASSOC); + } + + // Error. + return false; + } + + + /** + * Retrieve value from given query. + * + * @param string $table Table to query. + * @param string $key Field to retrieve. + * @param array $filter Filters to apply. + * @param string $join AND by default. + * + * @return mixed|null Value retrieved or null if not found. + */ + private function getValue( + string $table, + string $key, + array $filter, + string $join='AND' + ) { + $query = sprintf( + 'SELECT %s FROM %s WHERE 1=1 %s', + $key, + $table, + \db_format_array_where_clause_sql($filter, $join) + ); + $result = $this->getRow($query); + if ($result !== false) { + return $result[$key]; + } + + return false; + } + + /** * Verifies schema against running db. * @@ -356,9 +412,14 @@ final class DBMaintainer return false; } + $last_mr = Config::get('MR', null); + $last_mr_curr = $this->getValue('tconfig', 'value', ['token' => 'MR']); + + hd($last_mr); + hd($last_mr_curr); + $this->lastError = 'Pending update'; return false; - } From 25b15182e35a9ce4d144177d86f89d2331eda80f Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 27 Jan 2021 15:48:00 +0100 Subject: [PATCH 023/112] DBH auto-updater --- .../include/lib/Core/DBMaintainer.php | 107 ++++++++++++++++-- 1 file changed, 98 insertions(+), 9 deletions(-) diff --git a/pandora_console/include/lib/Core/DBMaintainer.php b/pandora_console/include/lib/Core/DBMaintainer.php index a8c5fbc7b9..db7aaa3670 100644 --- a/pandora_console/include/lib/Core/DBMaintainer.php +++ b/pandora_console/include/lib/Core/DBMaintainer.php @@ -272,7 +272,7 @@ final class DBMaintainer string $join='AND' ) { $query = sprintf( - 'SELECT %s FROM %s WHERE 1=1 %s', + 'SELECT %s FROM %s WHERE %s', $key, $table, \db_format_array_where_clause_sql($filter, $join) @@ -351,6 +351,45 @@ final class DBMaintainer } + /** + * Updates or creates a token in remote tconfig. + * + * @param string $token Token to be set. + * @param mixed $value Value for given token. + * + * @return boolean Success or not. + */ + private function setConfigToken(string $token, $value) + { + $prev = $this->getValue('tconfig', 'value', ['token' => $token]); + // If failed or not found, then insert. + if ($prev === false || $prev === null) { + // Create. + $rs = $this->dbh->query( + sprintf( + 'INSERT INTO `tconfig` (`token`, `value`) + VALUES ("%s", "%s")', + $token, + $value + ) + ); + } else { + // Update. + $rs = $this->dbh->query( + sprintf( + 'UPDATE `tconfig` + SET `value`= "%s" + WHERE `token` = "%s"', + $value, + $token + ) + ); + } + + return ($rs !== false); + } + + /** * Install PandoraFMS database schema in current target. * @@ -392,7 +431,19 @@ final class DBMaintainer return true; } - return $this->applyDump(Config::get('homedir', '').'/pandoradb.sql'); + $result = $this->applyDump(Config::get('homedir', '').'/pandoradb.sql'); + + // Set MR version according pandoradb_data. + $data_content = file_get_contents( + Config::get('homedir', '').'/pandoradb_data.sql' + ); + if (preg_match('/\(\'MR\'\,\s*(\d+)\)/', $data_content, $matches) > 0) { + $target_mr = $matches[1]; + } + + $cnf_update = $this->setConfigToken('MR', (int) $target_mr); + + return $result && $cnf_update; } @@ -412,13 +463,51 @@ final class DBMaintainer return false; } - $last_mr = Config::get('MR', null); - $last_mr_curr = $this->getValue('tconfig', 'value', ['token' => 'MR']); + $last_mr = (int) Config::get('MR', null); + $last_mr_curr = (int) $this->getValue( + 'tconfig', + 'value', + ['token' => 'MR'] + ); - hd($last_mr); - hd($last_mr_curr); + if ($last_mr_curr < $last_mr) { + while ($last_mr_curr < $last_mr) { + $last_mr_curr++; - $this->lastError = 'Pending update'; + $path = Config::get('homedir', ''); + $file = sprintf('/extras/mr/%d.sql', $last_mr_curr); + $updated_file = sprintf( + '/extras/mr/updated/%d.sql', + $last_mr_curr + ); + + $filename = $path.$file; + if (file_exists($path.$file) !== true) { + // File does not exist, maybe already udpated in active DB? + $filename = $path.$updated_file; + if (file_exists($filename) !== false) { + $this->lastError = 'Unable to locate MR update #'; + $this->lastError .= $last_mr_curr; + return false; + } + } + + if ($this->applyDump($filename) !== true) { + $err = 'Unable to apply MR update #'; + $err .= $last_mr_curr.': '; + $this->lastError = $err.$this->lastError; + return false; + } + } + } + + if ($last_mr_curr === $last_mr) { + $this->setConfigToken('MR', $last_mr_curr); + + return true; + } + + $this->lastError = 'Unknown database schema version, check MR in both active and historical database'; return false; } @@ -466,8 +555,8 @@ final class DBMaintainer if ((bool) preg_match("/;[\040]*\$/", $sql_line) === true) { $result = $this->dbh->query($query); if ((bool) $result === false) { - $this->lastError = $this->dbh->errnum.': '; - $this->lastERror .= $this->dbh->error; + $this->lastError = $this->dbh->errno.': '; + $this->lastError .= $this->dbh->error; return false; } From dd4849f7c355f805f53abe02bbf8f91c2d8ca625 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 27 Jan 2021 19:23:31 +0100 Subject: [PATCH 024/112] WIP Scheduled install & update of history database processes --- .../include/class/ConsoleSupervisor.php | 3 +- .../include/lib/Core/DBMaintainer.php | 106 ++++++++++++++++-- 2 files changed, 100 insertions(+), 9 deletions(-) diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php index cc52f2062f..558aebde8d 100644 --- a/pandora_console/include/class/ConsoleSupervisor.php +++ b/pandora_console/include/class/ConsoleSupervisor.php @@ -149,7 +149,8 @@ class ConsoleSupervisor */ public function runBasic() { - global $config; + // Ensure functions are installed and up to date. + enterprise_hook('cron_extension_install_functions'); /* * PHP configuration warnings: diff --git a/pandora_console/include/lib/Core/DBMaintainer.php b/pandora_console/include/lib/Core/DBMaintainer.php index db7aaa3670..cf7b78abdb 100644 --- a/pandora_console/include/lib/Core/DBMaintainer.php +++ b/pandora_console/include/lib/Core/DBMaintainer.php @@ -393,9 +393,11 @@ final class DBMaintainer /** * Install PandoraFMS database schema in current target. * + * @param boolean $check_only Check and return, do not perform actions. + * * @return boolean Installation is success or not. */ - public function install() + public function install(bool $check_only=false) { if ($this->connect() !== true) { return false; @@ -407,6 +409,11 @@ final class DBMaintainer if ($this->ready !== true) { // Not ready, create database in target. + if ($check_only === true) { + $this->lastError = 'Database does not exist in target'; + return false; + } + $rc = $this->dbh->query( sprintf( 'CREATE DATABASE %s', @@ -428,9 +435,15 @@ final class DBMaintainer $this->ready = true; } else if ($this->verifySchema() === true) { $this->installed = true; + $this->lastError = null; return true; } + if ($check_only === true) { + $this->lastError = 'Schema not applied in target'; + return false; + } + $result = $this->applyDump(Config::get('homedir', '').'/pandoradb.sql'); // Set MR version according pandoradb_data. @@ -451,9 +464,11 @@ final class DBMaintainer /** * Updates PandoraFMS database schema in current target. * + * @param boolean $check_only Perform only test without update. + * * @return boolean Current installation is up to date. */ - public function update() + public function update(bool $check_only=false) { if ($this->connect() !== true) { return false; @@ -463,15 +478,43 @@ final class DBMaintainer return false; } - $last_mr = (int) Config::get('MR', null); + // Set MR version according pandoradb_data. + $data_content = file_get_contents( + Config::get('homedir', '').'/pandoradb_data.sql' + ); + if (preg_match('/\(\'MR\'\,\s*(\d+)\)/', $data_content, $matches) > 0) { + $target_mr = $matches[1]; + } + + $active_mr = (int) Config::get('MR', null); $last_mr_curr = (int) $this->getValue( 'tconfig', 'value', ['token' => 'MR'] ); - if ($last_mr_curr < $last_mr) { - while ($last_mr_curr < $last_mr) { + if ($check_only === true) { + if ($active_mr === $last_mr_curr) { + return true; + } + + $this->lastError = sprintf( + 'Database schema not up to date: #%d should be #%d', + $last_mr_curr, + $active_mr + ); + if ($active_mr < $target_mr) { + $this->lastError .= sprintf( + ' (latest available: #%d)', + $target_mr + ); + } + + return false; + } + + if ($last_mr_curr < $active_mr) { + while ($last_mr_curr < $active_mr) { $last_mr_curr++; $path = Config::get('homedir', ''); @@ -501,7 +544,7 @@ final class DBMaintainer } } - if ($last_mr_curr === $last_mr) { + if ($last_mr_curr === $active_mr) { $this->setConfigToken('MR', $last_mr_curr); return true; @@ -513,11 +556,12 @@ final class DBMaintainer /** - * Verifies current target database is connected, installed and updated. + * Process database checks perform required actions. + * Returns true if it is connected, installed and updated. * * @return boolean Status of the installation. */ - public function check() + public function process() { if ($this->connect() !== true) { return false; @@ -535,6 +579,52 @@ final class DBMaintainer } + /** + * Check if target has schema updated. + * + * @return boolean + */ + public function isUpdated() + { + return $this->update(true); + } + + + /** + * Check if target has schema installed. + * + * @return boolean + */ + public function isInstalled() + { + return $this->install(true); + } + + + /** + * Checks if current target is connected, installed and updated. + * + * @return boolean Status of the database schema. + */ + public function check() + { + if ($this->connect() !== true) { + return false; + } + + if ($this->isInstalled() !== true) { + return false; + } + + if ($this->isUpdated() !== true) { + return false; + } + + return true; + + } + + /** * This function keeps same functionality as install.php:parse_mysqli_dump. * From 9fc3856f835a676e7cd515c234afb00bff13591d Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 28 Jan 2021 13:20:36 +0100 Subject: [PATCH 025/112] WIP historical database automaintenance + minor fixes --- .../include/class/HelpFeedBack.class.php | 1 + pandora_console/include/config_process.php | 2 +- pandora_console/include/functions_config.php | 9 +++- pandora_console/include/lib/Core/Config.php | 6 +++ .../include/lib/Core/DBMaintainer.php | 52 +++++++++++++------ 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/pandora_console/include/class/HelpFeedBack.class.php b/pandora_console/include/class/HelpFeedBack.class.php index 77b54794ab..9c99fcf9db 100644 --- a/pandora_console/include/class/HelpFeedBack.class.php +++ b/pandora_console/include/class/HelpFeedBack.class.php @@ -236,6 +236,7 @@ class HelpFeedBack extends Wizard */ public function sendMailMethod() { + global $config; $suggestion = get_parameter('type', 'false'); $feedback_text = get_parameter('feedback_text', null); $feedback_mail = get_parameter('feedback_email', null); diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 20ef0ffd12..093cfa0286 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -101,7 +101,7 @@ require_once $ownDir.'functions.php'; // We need a timezone BEFORE calling config_process_config. // If not we will get ugly warnings. Set Europe/Madrid by default // Later will be replaced by the good one. -if (!is_dir($_SERVER['DOCUMENT_ROOT'].$config['homeurl']) || !is_dir($_SERVER['DOCUMENT_ROOT'].$config['homeurl_static'])) { +if (!is_dir($config['homedir'])) { $url = explode('/', $_SERVER['REQUEST_URI']); $flag_url = 0; foreach ($url as $key => $value) { diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index 57058a59a0..97cb856511 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -28,6 +28,8 @@ // Config functions. require_once __DIR__.'/../vendor/autoload.php'; +require_once __DIR__.'/functions.php'; +enterprise_include_once('include/functions_config.php'); use PandoraFMS\Core\DBMaintainer; use PandoraFMS\Core\Config; @@ -1534,7 +1536,12 @@ function config_update_config() ); // Performs several checks and installs if needed. - if ($dbm->check() === false) { + if ($dbm->checkDatabaseDefinition() === true + && $dbm->isInstalled() === false + ) { + // Target is ready but several tasks are pending. + $dbm->process(); + } else if ($dbm->check() !== true) { $errors[] = $dbm->getLastError(); } } diff --git a/pandora_console/include/lib/Core/Config.php b/pandora_console/include/lib/Core/Config.php index fe73fe327d..4891cabcce 100644 --- a/pandora_console/include/lib/Core/Config.php +++ b/pandora_console/include/lib/Core/Config.php @@ -75,12 +75,18 @@ final class Config ob_get_clean(); } + ob_start(); $data = \db_get_all_rows_sql( 'SELECT * FROM `tconfig`', false, false, $config['history_db_connection'] ); + ob_get_clean(); + + if (is_array($data) !== true) { + return []; + } self::$settings = array_reduce( $data, diff --git a/pandora_console/include/lib/Core/DBMaintainer.php b/pandora_console/include/lib/Core/DBMaintainer.php index cf7b78abdb..b53311581c 100644 --- a/pandora_console/include/lib/Core/DBMaintainer.php +++ b/pandora_console/include/lib/Core/DBMaintainer.php @@ -390,6 +390,40 @@ final class DBMaintainer } + /** + * Create database only (not schema) in target. + * + * @return boolean Success or not. + */ + public function checkDatabaseDefinition() + { + if ($this->ready === true) { + return true; + } + + $rc = $this->dbh->query( + sprintf( + 'CREATE DATABASE %s', + $this->name + ) + ); + + if ($rc === false) { + $this->lastError = $this->dbh->errno.': '.$this->dbh->error; + return false; + } + + if ($this->dbh->select_db($this->name) === false) { + $this->lastError = $this->dbh->errno.': '.$this->dbh->error; + return false; + } + + // Already connected and ready to execute commands. + $this->ready = true; + return true; + } + + /** * Install PandoraFMS database schema in current target. * @@ -414,25 +448,9 @@ final class DBMaintainer return false; } - $rc = $this->dbh->query( - sprintf( - 'CREATE DATABASE %s', - $this->name - ) - ); - - if ($rc === false) { - $this->lastError = $this->dbh->errno.': '.$this->dbh->error; + if ($this->checkDatabaseDefinition() === false) { return false; } - - if ($this->dbh->select_db($this->name) === false) { - $this->lastError = $this->dbh->errno.': '.$this->dbh->error; - return false; - } - - // Already connected and ready to execute commands. - $this->ready = true; } else if ($this->verifySchema() === true) { $this->installed = true; $this->lastError = null; From b8980c189c2434e9c3c67ff4dd62d56b47b3ce8c Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 28 Jan 2021 18:50:55 +0100 Subject: [PATCH 026/112] Schedule history db schema check after MR update --- pandora_console/include/ajax/rolling_release.ajax.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandora_console/include/ajax/rolling_release.ajax.php b/pandora_console/include/ajax/rolling_release.ajax.php index 43ceaa5f1d..194123aaac 100644 --- a/pandora_console/include/ajax/rolling_release.ajax.php +++ b/pandora_console/include/ajax/rolling_release.ajax.php @@ -88,6 +88,11 @@ if (is_ajax()) { $file_dest = $config['homedir']."/extras/mr/updated/$number.sql"; copy($file, $file_dest); + + // After successfully update, schedule history + // database upgrade. + enterprise_include_once('include/functions_config.php'); + enterprise_hook('history_db_install'); } } else { $error_file = fopen($config['homedir'].'/extras/mr/error.txt', 'w'); From 279bd5456d5ee44b7b865d07b491ac339fbe43cc Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 29 Jan 2021 10:25:14 +0100 Subject: [PATCH 027/112] Disabled compactdb while running in historical database --- pandora_server/util/pandora_db.pl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 874c8bd758..27db50c38b 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -1021,8 +1021,8 @@ sub pandora_delete_old_session_data { ############################################################################### # Main ############################################################################### -sub pandoradb_main ($$$) { - my ($conf, $dbh, $history_dbh) = @_; +sub pandoradb_main ($$$;$) { + my ($conf, $dbh, $history_dbh, $running_in_history) = @_; log_message ('', "Starting at ". strftime ("%Y-%m-%d %H:%M:%S", localtime()) . "\n"); @@ -1043,8 +1043,12 @@ sub pandoradb_main ($$$) { } } + # Only active database should be compacted. Disabled for historical database. # Compact on if enable and DaysCompact are below DaysPurge - if (($conf->{'_onlypurge'} == 0) && ($conf->{'_days_compact'} < $conf->{'_days_purge'})) { + if (!$running_in_history + && ($conf->{'_onlypurge'} == 0) + && ($conf->{'_days_compact'} < $conf->{'_days_purge'}) + ) { pandora_compactdb ($conf, defined ($history_dbh) ? $history_dbh : $dbh, $dbh); } @@ -1126,7 +1130,8 @@ if (defined($history_dbh)) { pandoradb_main( $h_conf, $history_dbh, - undef + undef, + 1 # Disable certain funcionality while runningn in historical database. ); } From 04be237b7af78aa82f17a26b111197ebd75d6be1 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 29 Jan 2021 14:30:16 +0100 Subject: [PATCH 028/112] minor method added --- pandora_console/include/lib/Core/DBMaintainer.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pandora_console/include/lib/Core/DBMaintainer.php b/pandora_console/include/lib/Core/DBMaintainer.php index b53311581c..685ca1b126 100644 --- a/pandora_console/include/lib/Core/DBMaintainer.php +++ b/pandora_console/include/lib/Core/DBMaintainer.php @@ -186,6 +186,17 @@ final class DBMaintainer } + /** + * Return connection statuis. + * + * @return boolean + */ + public function isConnected() + { + return $this->connected; + } + + /** * Retrieve last error. * From 96c218f21ee1f6bb92a29bb35e62b1d9877b10b8 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 1 Feb 2021 13:31:42 +0100 Subject: [PATCH 029/112] Some updates and minor fixes DBMaintainer --- pandora_console/include/lib/Core/Config.php | 21 ++--- .../include/lib/Core/DBMaintainer.php | 81 +++++++++++++------ pandora_console/include/styles/pandora.css | 5 ++ pandora_console/include/styles/setup.css | 4 + 4 files changed, 77 insertions(+), 34 deletions(-) diff --git a/pandora_console/include/lib/Core/Config.php b/pandora_console/include/lib/Core/Config.php index 4891cabcce..620c63f84a 100644 --- a/pandora_console/include/lib/Core/Config.php +++ b/pandora_console/include/lib/Core/Config.php @@ -72,18 +72,19 @@ final class Config $config['history_db_port'], false ); + + if ($config['history_db_connection'] !== false) { + $data = \db_get_all_rows_sql( + 'SELECT * FROM `tconfig`', + false, + false, + $config['history_db_connection'] + ); + } + ob_get_clean(); } - ob_start(); - $data = \db_get_all_rows_sql( - 'SELECT * FROM `tconfig`', - false, - false, - $config['history_db_connection'] - ); - ob_get_clean(); - if (is_array($data) !== true) { return []; } @@ -119,6 +120,8 @@ final class Config if (isset(self::$settings[$token]) === true) { return self::$settings[$token]; } + + return $default; } else { global $config; diff --git a/pandora_console/include/lib/Core/DBMaintainer.php b/pandora_console/include/lib/Core/DBMaintainer.php index 685ca1b126..8b3fc75bab 100644 --- a/pandora_console/include/lib/Core/DBMaintainer.php +++ b/pandora_console/include/lib/Core/DBMaintainer.php @@ -230,12 +230,14 @@ final class DBMaintainer $results = []; - do { - $row = $rs->fetch_array(MYSQLI_ASSOC); - if ((bool) $row !== false) { - $results[] = $row; - } - } while ((bool) $row !== false); + if ($rs !== false) { + do { + $row = $rs->fetch_array(MYSQLI_ASSOC); + if ((bool) $row !== false) { + $results[] = $row; + } + } while ((bool) $row !== false); + } return $results; } @@ -412,6 +414,10 @@ final class DBMaintainer return true; } + if ($this->dbh === null) { + return false; + } + $rc = $this->dbh->query( sprintf( 'CREATE DATABASE %s', @@ -503,7 +509,7 @@ final class DBMaintainer return false; } - if ($this->install() !== true) { + if ($this->install($check_only) !== true) { return false; } @@ -564,7 +570,7 @@ final class DBMaintainer } } - if ($this->applyDump($filename) !== true) { + if ($this->applyDump($filename, true) !== true) { $err = 'Unable to apply MR update #'; $err .= $last_mr_curr.': '; $this->lastError = $err.$this->lastError; @@ -630,6 +636,23 @@ final class DBMaintainer } + /** + * Checks if target is ready to connect. + * + * @return boolean + */ + public function isReady() + { + if ($this->ready === true) { + return true; + } + + $this->connect(); + + return $this->ready; + } + + /** * Checks if current target is connected, installed and updated. * @@ -657,29 +680,37 @@ final class DBMaintainer /** * This function keeps same functionality as install.php:parse_mysqli_dump. * - * @param string $path Path where SQL dump file is stored. + * @param string $path Path where SQL dump file is stored. + * @param boolean $transactional Use transactions from file (true) (MRs). * * @return boolean Success or not. */ - private function applyDump(string $path) + private function applyDump(string $path, bool $transactional=false) { if (file_exists($path) === true) { - $file_content = file($path); - $query = ''; - foreach ($file_content as $sql_line) { - if (trim($sql_line) !== '' - && strpos($sql_line, '-- ') === false - ) { - $query .= $sql_line; - if ((bool) preg_match("/;[\040]*\$/", $sql_line) === true) { - $result = $this->dbh->query($query); - if ((bool) $result === false) { - $this->lastError = $this->dbh->errno.': '; - $this->lastError .= $this->dbh->error; - return false; - } + if ($transactional === true) { + global $config; + // MR are loaded in transactions. + include_once $config['homedir'].'/include/db/mysql.php'; + return db_run_sql_file($path); + } else { + $file_content = file($path); + $query = ''; + foreach ($file_content as $sql_line) { + if (trim($sql_line) !== '' + && strpos($sql_line, '-- ') === false + ) { + $query .= $sql_line; + if ((bool) preg_match("/;[\040]*\$/", $sql_line) === true) { + $result = $this->dbh->query($query); + if ((bool) $result === false) { + $this->lastError = $this->dbh->errno.': '; + $this->lastError .= $this->dbh->error; + return false; + } - $query = ''; + $query = ''; + } } } } diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 12f5825a8f..aff419a62a 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -603,6 +603,11 @@ select:-internal-list-box { .flex-nowrap { flex-wrap: nowrap; } + +.flex-evenly { + justify-content: space-evenly; +} + .flex-row-baseline { display: flex; flex-direction: row; diff --git a/pandora_console/include/styles/setup.css b/pandora_console/include/styles/setup.css index 5c7b304772..c7f9ededaf 100644 --- a/pandora_console/include/styles/setup.css +++ b/pandora_console/include/styles/setup.css @@ -18,3 +18,7 @@ input[type="text"], input[type="number"] { width: 220px; } + +.fit > tbody > tr > td img { + width: 15px; +} From 712079c30e1edd9fd43c43dbbcf1349ce941e613 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 1 Feb 2021 15:00:54 +0100 Subject: [PATCH 030/112] RC1 #4755 --- pandora_console/include/functions_config.php | 4 ++-- pandora_console/include/lib/Core/Config.php | 18 +++++++++--------- pandora_server/util/pandora_db.pl | 3 +++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index 55a78f16da..601741a0c5 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -1558,11 +1558,11 @@ function config_update_config() if (Config::set( 'history_partitions_auto', - get_parameter_switch('history_partitions_auto'), + get_parameter_switch('history_partitions_auto', 0), true ) !== true ) { - $error_update[] = __('Historical database days compact'); + $error_update[] = __('Historical database partitions'); } if (Config::set( diff --git a/pandora_console/include/lib/Core/Config.php b/pandora_console/include/lib/Core/Config.php index 620c63f84a..8970d03835 100644 --- a/pandora_console/include/lib/Core/Config.php +++ b/pandora_console/include/lib/Core/Config.php @@ -73,18 +73,18 @@ final class Config false ); - if ($config['history_db_connection'] !== false) { - $data = \db_get_all_rows_sql( - 'SELECT * FROM `tconfig`', - false, - false, - $config['history_db_connection'] - ); - } - ob_get_clean(); } + if ($config['history_db_connection'] !== false) { + $data = \db_get_all_rows_sql( + 'SELECT * FROM `tconfig`', + false, + false, + $config['history_db_connection'] + ); + } + if (is_array($data) !== true) { return []; } diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 27db50c38b..d3d7387d7e 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -1134,6 +1134,9 @@ if (defined($history_dbh)) { 1 # Disable certain funcionality while runningn in historical database. ); + # Handle partitions. + enterprise_hook('handle_partitions', [$h_conf, $history_dbh]); + } # Release the lock From 4978ac30813e22c2aecdcc47db8ee2708e3fe998 Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Thu, 4 Feb 2021 16:41:47 +0100 Subject: [PATCH 031/112] Fix issue --- pandora_server/lib/PandoraFMS/Recon/Base.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 5f01f1630f..2831fc44c3 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -2112,14 +2112,14 @@ sub snmp_get_command { my $command = "snmpwalk -M$DEVNULL -r$self->{'snmp_checks'} -t$self->{'snmp_timeout'} -v$self->{'snmp_version'} -On -Oe "; if ($self->{'snmp_version'} eq "3") { if ($self->{'community'}) { # Context - $command .= " -N $self->{'community'} "; + $command .= " -N \'$self->{'community'}\' "; } $command .= " -l$self->{'snmp_security_level'} "; if ($self->{'snmp_security_level'} ne "noAuthNoPriv") { - $command .= " -u$self->{'snmp_auth_user'} -a$self->{'snmp_auth_method'} -A$self->{'snmp_auth_pass'} "; + $command .= " -u$self->{'snmp_auth_user'} -a $self->{'snmp_auth_method'} -A \'$self->{'snmp_auth_pass'}\' "; } if ($self->{'snmp_security_level'} eq "authPriv") { - $command .= " -x$self->{'snmp_privacy_method'} -X$self->{'snmp_privacy_pass'} "; + $command .= " -x$self->{'snmp_privacy_method'} -X \'$self->{'snmp_privacy_pass'}\' "; } } else { $command .= " -c$community$vlan "; From 0be3e0ab90cddc49622817126f4089896dcb9999 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 10 Feb 2021 15:00:23 +0100 Subject: [PATCH 032/112] Event widget and some notices fixed --- pandora_console/general/header.php | 6 +- pandora_console/general/register.php | 7 +- .../include/class/ConsoleSupervisor.php | 30 +- pandora_console/include/class/HTML.class.php | 36 ++- pandora_console/include/functions_config.php | 2 +- pandora_console/include/functions_events.php | 128 ++++++++- .../include/lib/Dashboard/Manager.php | 38 +++ .../include/lib/Dashboard/Widget.php | 37 ++- .../lib/Dashboard/Widgets/events_list.php | 269 +++++++++++------- pandora_console/views/dashboard/header.php | 8 +- 10 files changed, 435 insertions(+), 126 deletions(-) diff --git a/pandora_console/general/header.php b/pandora_console/general/header.php index 1f573749e7..272af10720 100644 --- a/pandora_console/general/header.php +++ b/pandora_console/general/header.php @@ -877,7 +877,9 @@ if ($config['menu_type'] == 'classic') { blinkpubli(); var fb64 = ''; diff --git a/pandora_console/general/register.php b/pandora_console/general/register.php index 9f90e7ad39..3d598383c1 100644 --- a/pandora_console/general/register.php +++ b/pandora_console/general/register.php @@ -188,7 +188,12 @@ try { $double_auth_enabled = (bool) db_get_value('id', 'tuser_double_auth', 'id_user', $config['id_user']); -if (!$double_auth_enabled && $config['2FA_all_users'] != '' +if (isset($config['2FA_all_users']) === false) { + $config['2FA_all_users'] = null; +} + +if (!$double_auth_enabled + && $config['2FA_all_users'] != '' && $config['2Fa_auth'] != '1' && $config['double_auth_enabled'] ) { diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php index cc52f2062f..378eb29d68 100644 --- a/pandora_console/include/class/ConsoleSupervisor.php +++ b/pandora_console/include/class/ConsoleSupervisor.php @@ -118,8 +118,14 @@ class ConsoleSupervisor // Assign targets. $targets = get_notification_source_targets($this->sourceId); - $this->targetGroups = $targets['groups']; - $this->targetUsers = $targets['users']; + if (isset($targets['groups']) === true) { + $this->targetGroups = $targets['groups']; + } + + if (isset($targets['users']) === true) { + $this->targetUsers = $targets['users']; + } + $this->targetUpdated = true; } @@ -622,8 +628,14 @@ class ConsoleSupervisor if ($this->targetUpdated === false) { $targets = get_notification_source_targets($this->sourceId); - $this->targetGroups = $targets['groups']; - $this->targetUsers = $targets['users']; + if (isset($targets['groups']) === true) { + $this->targetGroups = $targets['groups']; + } + + if (isset($targets['users']) === true) { + $this->targetUsers = $targets['users']; + } + $this->targetUpdated = false; } @@ -631,8 +643,14 @@ class ConsoleSupervisor $source_id = $this->sourceId; // Assign targets. $targets = get_notification_source_targets($source_id); - $this->targetGroups = $targets['groups']; - $this->targetUsers = $targets['users']; + if (isset($targets['groups']) === true) { + $this->targetGroups = $targets['groups']; + } + + if (isset($targets['users']) === true) { + $this->targetUsers = $targets['users']; + } + $this->targetUpdated = false; } diff --git a/pandora_console/include/class/HTML.class.php b/pandora_console/include/class/HTML.class.php index 820062d7bc..6335d05e37 100644 --- a/pandora_console/include/class/HTML.class.php +++ b/pandora_console/include/class/HTML.class.php @@ -782,8 +782,40 @@ class HTML } if (isset($data['form']) === true) { - $output_head .= '
'; + $output_head .= ' 0) { - $children = groups_get_children($groups); + if ((bool) $user_is_admin === false + && isset($groups) === false + ) { + // Not being filtered by group but not an admin, limit results. + $groups = array_keys(users_get_groups(false, 'AR')); + } - $_groups = [ $groups ]; - if (empty($children) === false) { - foreach ($children as $child) { - $_groups[] = (int) $child['id_grupo']; + if (isset($groups) === true + && (is_array($groups) === true || ($groups > 0)) + ) { + if ($recursiveGroups === true) { + // Add children groups. + $children = []; + if (is_array($groups) === true) { + foreach ($groups as $g) { + $children = array_merge( + groups_get_children($g), + $children + ); + } + } else { + $children = groups_get_children($groups); } + + if (is_array($groups) === true) { + $_groups = $groups; + } else { + $_groups = [ $groups ]; + } + + if (empty($children) === false) { + foreach ($children as $child) { + $_groups[] = (int) $child['id_grupo']; + } + } + + if ((bool) $user_is_admin === false) { + $user_groups = users_get_groups(false, 'AR'); + $_groups = array_intersect( + $_groups, + array_keys($user_groups) + ); + } + + $groups = $_groups; } - $groups = $_groups; + if (is_array($groups) === false) { + $groups = [ $groups ]; + } $sql_filters[] = sprintf( ' AND (te.id_grupo IN (%s) OR tasg.id_group IN (%s))', @@ -1466,6 +1535,8 @@ function events_get_all( /** + * @deprecated Use events_get_all instead. + * * Get all rows of events from the database, that * pass the filter, and can get only some fields. * @@ -1502,7 +1573,9 @@ function events_get_all( */ function events_get_events($filter=false, $fields=false) { - if ($filter['criticity'] == EVENT_CRIT_WARNING_OR_CRITICAL) { + if (isset($filter['criticity']) === true + && (int) $filter['criticity'] === EVENT_CRIT_WARNING_OR_CRITICAL + ) { $filter['criticity'] = [ EVENT_CRIT_WARNING, EVENT_CRIT_CRITICAL, @@ -7363,3 +7436,40 @@ function events_get_instructions($event) return $output; } + + +/** + * Return class name matching criticity received. + * + * @param integer $criticity Event's criticity. + * + * @return string + */ +function events_get_criticity_class($criticity) +{ + switch ($criticity) { + case EVENT_CRIT_CRITICAL: + return 'datos_red'; + + case EVENT_CRIT_MAINTENANCE: + return 'datos_grey'; + + case EVENT_CRIT_INFORMATIONAL: + return 'datos_blue'; + + case EVENT_CRIT_MAJOR: + return 'datos_pink'; + + case EVENT_CRIT_MINOR: + return 'datos_pink'; + + case EVENT_CRIT_NORMAL: + return 'datos_green'; + + case EVENT_CRIT_WARNING: + return 'datos_yellow'; + + default: + return 'datos_blue'; + } +} diff --git a/pandora_console/include/lib/Dashboard/Manager.php b/pandora_console/include/lib/Dashboard/Manager.php index 891ef524df..337027d426 100644 --- a/pandora_console/include/lib/Dashboard/Manager.php +++ b/pandora_console/include/lib/Dashboard/Manager.php @@ -257,6 +257,23 @@ class Manager $extradata = \get_parameter('extradata', ''); if (empty($extradata) === false) { $extradata = json_decode(\io_safe_output($extradata), true); + + if (isset($extradata['dashboardId']) === false) { + $extradata['dashboardId'] = null; + } + + if (isset($extradata['cellId']) === false) { + $extradata['cellId'] = null; + } + + if (isset($extradata['offset']) === false) { + $extradata['offset'] = null; + } + + if (isset($extradata['widgetId']) === false) { + $extradata['widgetId'] = null; + } + $this->dashboardId = (int) $extradata['dashboardId']; $this->cellId = (int) $extradata['cellId']; $this->offset = (int) $extradata['offset']; @@ -1031,6 +1048,10 @@ class Manager ); } + if (isset($config['public_dashboard']) === false) { + $config['public_dashboard'] = false; + } + // View. if ($this->slides === 0 || $this->cellModeSlides === 0) { View::render( @@ -1450,4 +1471,21 @@ class Manager } + /** + * Prints error. + * + * @param string $msg Message. + * + * @return void + */ + public function error(string $msg) + { + if ((bool) \is_ajax() === true) { + echo json_encode(['error' => $msg]); + } else { + \ui_print_error_message($msg); + } + } + + } diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php index bfc640eaf0..6e843803d5 100644 --- a/pandora_console/include/lib/Dashboard/Widget.php +++ b/pandora_console/include/lib/Dashboard/Widget.php @@ -21,7 +21,7 @@ class Widget * * @var integer */ - private $cellId; + protected $cellId; /** * Widget Id. @@ -99,8 +99,6 @@ class Widget */ public function getOptionsWidget():array { - global $config; - $result = []; if (empty($this->dataCell['options']) === false) { $result = \json_decode($this->dataCell['options'], true); @@ -591,4 +589,37 @@ class Widget } + /** + * Get description should be implemented for each child. + * + * @return string + */ + public static function getDescription() + { + return '**NOT DEFINED**'; + } + + + /** + * Load should be implemented for each child. + * + * @return string + */ + public function load() + { + return '**NOT DEFINED**'; + } + + + /** + * Get name should be implemented for each child. + * + * @return string + */ + public static function getName() + { + return '**NOT DEFINED**'; + } + + } diff --git a/pandora_console/include/lib/Dashboard/Widgets/events_list.php b/pandora_console/include/lib/Dashboard/Widgets/events_list.php index 5cce5ae1d7..b00fb7cde6 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/events_list.php +++ b/pandora_console/include/lib/Dashboard/Widgets/events_list.php @@ -172,7 +172,7 @@ class EventsListWidget extends Widget $this->className = $class->getShortName(); // Title. - $this->title = __('List of latest events'); + $this->title = \__('List of latest events'); // Name. if (empty($this->name) === true) { @@ -242,6 +242,10 @@ class EventsListWidget extends Widget $values['groupId'] = $decoder['id_groups']; } + if (isset($decoder['groupRecursion']) === true) { + $values['groupRecursion'] = $decoder['groupRecursion']; + } + if (isset($decoder['groupId']) === true) { $values['groupId'] = $decoder['groupId']; } @@ -271,7 +275,7 @@ class EventsListWidget extends Widget $inputs = parent::getFormInputs(); $fields = \get_event_types(); - $fields['not_normal'] = __('Not normal'); + $fields['not_normal'] = \__('Not normal'); // Default values. if (isset($values['maxHours']) === false) { @@ -284,21 +288,21 @@ class EventsListWidget extends Widget // Event Type. $inputs[] = [ - 'label' => __('Event type'), + 'label' => \__('Event type'), 'arguments' => [ 'type' => 'select', 'fields' => $fields, 'name' => 'eventType', 'selected' => $values['eventType'], 'return' => true, - 'nothing' => __('Any'), + 'nothing' => \__('Any'), 'nothing_value' => 0, ], ]; // Max. hours old. Default 8. $inputs[] = [ - 'label' => __('Max. hours old'), + 'label' => \__('Max. hours old'), 'arguments' => [ 'name' => 'maxHours', 'type' => 'number', @@ -320,7 +324,7 @@ class EventsListWidget extends Widget ]; $inputs[] = [ - 'label' => __('Limit'), + 'label' => \__('Limit'), 'arguments' => [ 'type' => 'select', 'fields' => $fields, @@ -332,13 +336,13 @@ class EventsListWidget extends Widget // Event status. $fields = [ - -1 => __('All event'), - 1 => __('Only validated'), - 0 => __('Only pending'), + -1 => \__('All event'), + 1 => \__('Only validated'), + 0 => \__('Only pending'), ]; $inputs[] = [ - 'label' => __('Event status'), + 'label' => \__('Event status'), 'arguments' => [ 'type' => 'select', 'fields' => $fields, @@ -352,14 +356,14 @@ class EventsListWidget extends Widget $fields = \get_priorities(); $inputs[] = [ - 'label' => __('Severity'), + 'label' => \__('Severity'), 'arguments' => [ 'type' => 'select', 'fields' => $fields, 'name' => 'severity', 'selected' => $values['severity'], 'return' => true, - 'nothing' => __('All'), + 'nothing' => \__('All'), 'nothing_value' => -1, ], ]; @@ -367,14 +371,18 @@ class EventsListWidget extends Widget $return_all_group = false; $selected_groups_array = explode(',', $values['groupId'][0]); - if (users_can_manage_group_all('RM') || ($selected_groups_array[0] !== '' && in_array(0, $selected_groups_array) === true)) { - // Return all group if user has permissions or it is a currently selected group. + if ((bool) \users_can_manage_group_all('RM') === true + || ($selected_groups_array[0] !== '' + && in_array(0, $selected_groups_array) === true) + ) { + // Return all group if user has permissions or it is a currently + // selected group. $return_all_group = true; } // Groups. $inputs[] = [ - 'label' => __('Groups'), + 'label' => \__('Groups'), 'arguments' => [ 'type' => 'select_groups', 'name' => 'groupId[]', @@ -387,18 +395,31 @@ class EventsListWidget extends Widget ], ]; + // Group recursion. + $inputs[] = [ + 'label' => \__('Group recursion'), + 'arguments' => [ + 'type' => 'switch', + 'name' => 'groupRecursion', + 'value' => $values['groupRecursion'], + 'return' => true, + ], + ]; + // Tags. - $fields = tags_get_user_tags($config['id_user'], 'AR'); + $fields = \tags_get_user_tags($config['id_user'], 'AR'); $inputs[] = [ - 'label' => __('Tags'), + 'label' => \__('Tags'), 'arguments' => [ - 'type' => 'select', - 'fields' => $fields, - 'name' => 'tagsId[]', - 'selected' => explode(',', $values['tagsId'][0]), - 'return' => true, - 'multiple' => true, + 'type' => 'select', + 'fields' => $fields, + 'name' => 'tagsId[]', + 'selected' => explode(',', $values['tagsId'][0]), + 'return' => true, + 'multiple' => true, + 'nothing' => __('None'), + 'nothing_value' => 0, ], ]; @@ -423,6 +444,7 @@ class EventsListWidget extends Widget $values['severity'] = \get_parameter_switch('severity', -1); $values['groupId'] = \get_parameter_switch('groupId', []); $values['tagsId'] = \get_parameter_switch('tagsId', []); + $values['groupRecursion'] = \get_parameter_switch('groupRecursion', 0); return $values; } @@ -441,97 +463,138 @@ class EventsListWidget extends Widget $return_all_group = false; - if (users_can_manage_group_all('RM')) { + if ((bool) \users_can_manage_group_all('RM') === true) { $return_all_group = true; } $user_groups = \users_get_groups(false, 'AR', $return_all_group); - ui_require_css_file('events', 'include/styles/', true); - ui_require_css_file('tables', 'include/styles/', true); + \ui_require_css_file('events', 'include/styles/', true); + \ui_require_css_file('tables', 'include/styles/', true); $this->values['groupId'] = explode(',', $this->values['groupId'][0]); $this->values['tagsId'] = explode(',', $this->values['tagsId'][0]); if (empty($this->values['groupId']) === true) { - $output .= __('You must select some group'); + $output .= \__('You must select some group'); return $output; } - $useTags = \tags_has_user_acl_tags($config['id_user']); - if ($useTags) { + $useTags = (bool) \tags_has_user_acl_tags($config['id_user']); + if ($useTags === true) { if (empty($this->values['tagsId']) === true) { - $output .= __('You don\'t have access'); + $output .= \__('You don\'t have access'); return; } } $hours = ($this->values['maxHours'] * SECONDS_1HOUR); - $unixtime = (get_system_time() - $hours); // Put hours in seconds. $filter = []; - // Group all. - if (in_array(0, $this->values['groupId'])) { - $filter['id_grupo'] = array_keys($user_groups); - } else { - $filter['id_grupo'] = array_intersect($this->values['groupId'], array_keys($user_groups)); + $order = []; + + // Filtering. + $filter['event_view_hr'] = $hours; + + // Group. + $filter['id_group_filter'] = $this->values['groupId']; + if (empty($filter['id_group_filter']) === true + || $filter['id_group_filter'][0] === '' + || $filter['id_group_filter'][0] === '0' + ) { + // No filter specified. Don't filter at all... + $filter['id_group_filter'] = null; } - if (empty($filter['id_grupo'])) { - $output .= '
'; - $output .= \ui_print_error_message( - __('You have no access'), - '', - true + // Tags. + if (empty($this->values['tagsId']) === false) { + $filter['tag_with'] = base64_encode( + json_encode($this->values['tagsId']) ); - $output .= '
'; - return $output; } - $filter['utimestamp'] = '>'.$unixtime; + // Severity. + if (isset($this->values['severity']) === true) { + $filter['severity'] = $this->values['severity']; + } + // Event types. if (empty($this->values['eventType']) === false) { $filter['event_type'] = $this->values['eventType']; - - if ($filter['event_type'] === 'warning' - || $filter['event_type'] === 'critical' - || $filter['event_type'] === 'normal' - ) { - $filter['event_type'] = '%'.$filter['event_type'].'%'; - } else if ($filter['event_type'] === 'not_normal') { - unset($filter['event_type']); - $filter[] = '(event_type REGEXP "warning|critical|unknown")'; - } } + // Event status. if ((int) $this->values['eventStatus'] !== -1) { - $filter['estado'] = $this->values['eventStatus']; + $filter['status'] = $this->values['eventStatus']; } - $filter['limit'] = $this->values['limit']; - $filter['order'] = '`utimestamp` DESC'; + // Order. + $order['field'] = 'timestamp'; + $order['direction'] = 'DESC'; - if (isset($this->values['severity']) === true) { - if ((int) $this->values['severity'] === 20) { - $filter['criticity'] = [ - EVENT_CRIT_WARNING, - EVENT_CRIT_CRITICAL, - ]; - } else if ((int) $this->values['severity'] !== -1) { - $filter['criticity'] = $this->values['severity']; - } + $fields = [ + 'te.id_evento', + 'te.id_agente', + 'te.id_usuario', + 'te.id_grupo', + 'te.estado', + 'te.timestamp', + 'te.evento', + 'te.utimestamp', + 'te.event_type', + 'te.id_alert_am', + 'te.criticity', + 'te.user_comment', + 'te.tags', + 'te.source', + 'te.id_extra', + 'te.critical_instructions', + 'te.warning_instructions', + 'te.unknown_instructions', + 'te.owner_user', + 'if(te.ack_utimestamp > 0, from_unixtime(te.ack_utimestamp),"") as ack_utimestamp', + 'te.custom_data', + 'te.data', + 'te.module_status', + 'ta.alias as agent_name', + 'tg.nombre as group_name', + ]; + if ((bool) \is_metaconsole() === false) { + $fields[] = 'am.nombre as module_name'; + $fields[] = 'am.id_agente_modulo as id_agentmodule'; + $fields[] = 'am.custom_id as module_custom_id'; + $fields[] = 'ta.server_name as server_name'; + } else { + $fields[] = 'ts.server_name as server_name'; + $fields[] = 'te.id_agentmodule'; + $fields[] = 'te.server_id'; } - if (empty($this->values['tagsId']) === false) { - foreach ($this->values['tagsId'] as $tag) { - $tag_name[$tag] = \tags_get_name($tag); - } - - $filter['tags'] = $tag_name; - } - - $events = \events_get_events($filter); + $events = \events_get_all( + // Fields. + $fields, + // Filter. + $filter, + // Offset. + null, + // Limit. + $this->values['limit'], + // Order. + $order['direction'], + // Sort field. + $order['field'], + // History. + false, + // SQL. + false, + // Having. + '', + // ValidatedEvents. + false, + // Recursive Groups. + (bool) $this->values['groupRecursion'] + ); if ($events === false) { $events = []; @@ -542,9 +605,9 @@ class EventsListWidget extends Widget && is_array($events) === true && empty($events) === false ) { - $output .= html_print_input_hidden( + $output .= \html_print_input_hidden( 'ajax_file', - ui_get_full_url('ajax.php', false, false, false), + \ui_get_full_url('ajax.php', false, false, false), true ); @@ -558,15 +621,10 @@ class EventsListWidget extends Widget foreach ($events as $event) { $data = []; - $event['evento'] = io_safe_output($event['evento']); - if ($event['estado'] === 0) { - $img = 'images/pixel_red.png'; - } else { - $img = 'images/pixel_green.png'; - } + $event['evento'] = \io_safe_output($event['evento']); - $data[0] = events_print_type_img($event['event_type'], true); - $agent_alias = agents_get_alias($event['id_agente']); + $data[0] = \events_print_type_img($event['event_type'], true); + $agent_alias = \agents_get_alias($event['id_agente']); if ($agent_alias !== '') { $data[1] = '
'; + $data[4] = ''; } - $data[2] .= substr(io_safe_output($event['evento']), 0, 150); + $data[4] .= substr(\io_safe_output($event['evento']), 0, 150); if (strlen($event['evento']) > 150) { - $data[2] .= '...'; + $data[4] .= '...'; } if ($this->publicLink === false) { - $data[2] .= ''; + $data[4] .= ''; } - $data[3] = ui_print_timestamp($event['timestamp'], true); + $data[5] = \ui_print_timestamp($event['timestamp'], true); $table->data[$i] = $data; $table->cellstyle[$i][0] = 'background: #E8E8E8;'; - $rowclass = get_priority_class($event['criticity']); + $rowclass = \events_get_criticity_class($event['criticity']); $table->cellclass[$i][1] = $rowclass; $table->cellclass[$i][2] = $rowclass; $table->cellclass[$i][3] = $rowclass; + $table->cellclass[$i][4] = $rowclass; + $table->cellclass[$i][5] = $rowclass; $i++; } - $output .= html_print_table($table, true); + $output .= \html_print_table($table, true); $output .= "
"; $output .= "
"; - $output .= "
"; - $output .= ui_require_javascript_file( + $output .= "
"; + $output .= \ui_require_javascript_file( 'pandora_events', 'include/javascript/', true @@ -632,7 +701,7 @@ class EventsListWidget extends Widget } else { $output .= '
'; $output .= \ui_print_info_message( - __('There are no events matching selected search filters'), + \__('There are no events matching selected search filters'), '', true ); @@ -650,7 +719,7 @@ class EventsListWidget extends Widget */ public static function getDescription() { - return __('List of latest events'); + return \__('List of latest events'); } diff --git a/pandora_console/views/dashboard/header.php b/pandora_console/views/dashboard/header.php index 0449e4dfb6..561196cc20 100644 --- a/pandora_console/views/dashboard/header.php +++ b/pandora_console/views/dashboard/header.php @@ -120,7 +120,9 @@ $publiclink['text'] .= html_print_image( $publiclink['text'] .= ''; // Refresh selector time dashboards. -if ($config['public_dashboard'] === true) { +if (isset($config['public_dashboard']) === true + && (bool) $config['public_dashboard'] === true +) { $urlRefresh = $publicUrl; } else { $queryRefresh = [ @@ -188,7 +190,9 @@ $newWidget['text'] .= html_print_image( ); $newWidget['text'] .= ''; -if ($config['public_dashboard'] === true) { +if (isset($config['public_dashboard']) === true + && (bool) $config['public_dashboard'] === true +) { $buttons = [ 'combo_refresh_one_dashboard' => $comboRefresh, 'combo_refresh_countdown' => $comboRefreshCountdown, From 20dc58a1400c527a055ed5ad84ed9dfc123f4dd1 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 10 Feb 2021 18:41:53 +0100 Subject: [PATCH 033/112] Improved event widget, added custom filters --- .../include/javascript/pandora_events.js | 8 ++ .../include/lib/Dashboard/Manager.php | 2 + .../include/lib/Dashboard/Widget.php | 11 ++ .../lib/Dashboard/Widgets/events_list.php | 121 ++++++++++++------ .../views/dashboard/configurationWidgets.php | 1 + 5 files changed, 107 insertions(+), 36 deletions(-) diff --git a/pandora_console/include/javascript/pandora_events.js b/pandora_console/include/javascript/pandora_events.js index c1b604b4e2..1a957cd4a5 100644 --- a/pandora_console/include/javascript/pandora_events.js +++ b/pandora_console/include/javascript/pandora_events.js @@ -1002,3 +1002,11 @@ function check_massive_response_event( counter++; }); } + +function event_widget_options() { + if ($("#customFilter").val() != "-1") { + $(".event-widget-input").disable(); + } else { + $(".event-widget-input").enable(); + } +} diff --git a/pandora_console/include/lib/Dashboard/Manager.php b/pandora_console/include/lib/Dashboard/Manager.php index 337027d426..a9a1f5051e 100644 --- a/pandora_console/include/lib/Dashboard/Manager.php +++ b/pandora_console/include/lib/Dashboard/Manager.php @@ -1362,6 +1362,7 @@ class Manager $instance = $this->instanceWidget(); $htmlInputs = $instance->getFormInputs([]); + $js = $instance->getFormJS(); View::render( 'dashboard/configurationWidgets', @@ -1369,6 +1370,7 @@ class Manager 'dashboardId' => $this->dashboardId, 'cellId' => $this->cellId, 'htmlInputs' => $htmlInputs, + 'js' => $js, ] ); diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php index 6e843803d5..8d57ce1e86 100644 --- a/pandora_console/include/lib/Dashboard/Widget.php +++ b/pandora_console/include/lib/Dashboard/Widget.php @@ -622,4 +622,15 @@ class Widget } + /** + * Return aux javascript code for forms. + * + * @return string + */ + public function getFormJS() + { + return ''; + } + + } diff --git a/pandora_console/include/lib/Dashboard/Widgets/events_list.php b/pandora_console/include/lib/Dashboard/Widgets/events_list.php index b00fb7cde6..904cd2cdb8 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/events_list.php +++ b/pandora_console/include/lib/Dashboard/Widgets/events_list.php @@ -246,6 +246,10 @@ class EventsListWidget extends Widget $values['groupRecursion'] = $decoder['groupRecursion']; } + if (isset($decoder['customFilter']) === true) { + $values['customFilter'] = $decoder['customFilter']; + } + if (isset($decoder['groupId']) === true) { $values['groupId'] = $decoder['groupId']; } @@ -258,6 +262,17 @@ class EventsListWidget extends Widget } + /** + * Aux javascript to be run after form load. + * + * @return string + */ + public function getFormJS(): string + { + return '$( document ).ready(function() {event_widget_options();});'; + } + + /** * Generates inputs for form (specific). * @@ -274,6 +289,21 @@ class EventsListWidget extends Widget // Retrieve global - common inputs. $inputs = parent::getFormInputs(); + // Select pre built filter. + $inputs[] = [ + 'label' => \__('Custom filters'), + 'arguments' => [ + 'type' => 'select', + 'id' => 'select-custom-filter', + 'fields' => \events_get_event_filter_select(false), + 'name' => 'customFilter', + 'script' => 'event_widget_options();', + 'nothing' => \__('None'), + 'nothing_value' => -1, + 'selected' => $this->values['customFilter'], + ], + ]; + $fields = \get_event_types(); $fields['not_normal'] = \__('Not normal'); @@ -292,6 +322,7 @@ class EventsListWidget extends Widget 'arguments' => [ 'type' => 'select', 'fields' => $fields, + 'class' => 'event-widget-input', 'name' => 'eventType', 'selected' => $values['eventType'], 'return' => true, @@ -306,6 +337,7 @@ class EventsListWidget extends Widget 'arguments' => [ 'name' => 'maxHours', 'type' => 'number', + 'class' => 'event-widget-input', 'value' => $values['maxHours'], 'return' => true, 'min' => 0, @@ -328,6 +360,7 @@ class EventsListWidget extends Widget 'arguments' => [ 'type' => 'select', 'fields' => $fields, + 'class' => 'event-widget-input', 'name' => 'limit', 'selected' => $values['limit'], 'return' => true, @@ -346,6 +379,7 @@ class EventsListWidget extends Widget 'arguments' => [ 'type' => 'select', 'fields' => $fields, + 'class' => 'event-widget-input', 'name' => 'eventStatus', 'selected' => $values['eventStatus'], 'return' => true, @@ -360,6 +394,7 @@ class EventsListWidget extends Widget 'arguments' => [ 'type' => 'select', 'fields' => $fields, + 'class' => 'event-widget-input', 'name' => 'severity', 'selected' => $values['severity'], 'return' => true, @@ -386,6 +421,7 @@ class EventsListWidget extends Widget 'arguments' => [ 'type' => 'select_groups', 'name' => 'groupId[]', + 'class' => 'event-widget-input', 'returnAllGroup' => true, 'privilege' => 'AR', 'selected' => $selected_groups_array, @@ -401,6 +437,7 @@ class EventsListWidget extends Widget 'arguments' => [ 'type' => 'switch', 'name' => 'groupRecursion', + 'class' => 'event-widget-input', 'value' => $values['groupRecursion'], 'return' => true, ], @@ -414,6 +451,7 @@ class EventsListWidget extends Widget 'arguments' => [ 'type' => 'select', 'fields' => $fields, + 'class' => 'event-widget-input', 'name' => 'tagsId[]', 'selected' => explode(',', $values['tagsId'][0]), 'return' => true, @@ -445,6 +483,7 @@ class EventsListWidget extends Widget $values['groupId'] = \get_parameter_switch('groupId', []); $values['tagsId'] = \get_parameter_switch('tagsId', []); $values['groupRecursion'] = \get_parameter_switch('groupRecursion', 0); + $values['customFilter'] = \get_parameter('customFilter', -1); return $values; } @@ -461,14 +500,6 @@ class EventsListWidget extends Widget $output = ''; - $return_all_group = false; - - if ((bool) \users_can_manage_group_all('RM') === true) { - $return_all_group = true; - } - - $user_groups = \users_get_groups(false, 'AR', $return_all_group); - \ui_require_css_file('events', 'include/styles/', true); \ui_require_css_file('tables', 'include/styles/', true); @@ -494,39 +525,51 @@ class EventsListWidget extends Widget $filter = []; $order = []; - // Filtering. - $filter['event_view_hr'] = $hours; - - // Group. - $filter['id_group_filter'] = $this->values['groupId']; - if (empty($filter['id_group_filter']) === true - || $filter['id_group_filter'][0] === '' - || $filter['id_group_filter'][0] === '0' - ) { - // No filter specified. Don't filter at all... - $filter['id_group_filter'] = null; - } - - // Tags. - if (empty($this->values['tagsId']) === false) { + $customFilter = \events_get_event_filter($this->values['customFilter']); + if ($customFilter !== false) { + $filter = $customFilter; $filter['tag_with'] = base64_encode( - json_encode($this->values['tagsId']) + json_encode($filter['tag_with']) ); - } - // Severity. - if (isset($this->values['severity']) === true) { - $filter['severity'] = $this->values['severity']; - } + $filter['tag_without'] = base64_encode( + json_encode($filter['tag_without']) + ); + } else { + // Filtering. + $filter['event_view_hr'] = $hours; - // Event types. - if (empty($this->values['eventType']) === false) { - $filter['event_type'] = $this->values['eventType']; - } + // Group. + $filter['id_group_filter'] = $this->values['groupId']; + if (empty($filter['id_group_filter']) === true + || $filter['id_group_filter'][0] === '' + || $filter['id_group_filter'][0] === '0' + ) { + // No filter specified. Don't filter at all... + $filter['id_group_filter'] = null; + } - // Event status. - if ((int) $this->values['eventStatus'] !== -1) { - $filter['status'] = $this->values['eventStatus']; + // Tags. + if (empty($this->values['tagsId']) === false) { + $filter['tag_with'] = base64_encode( + json_encode($this->values['tagsId']) + ); + } + + // Severity. + if (isset($this->values['severity']) === true) { + $filter['severity'] = $this->values['severity']; + } + + // Event types. + if (empty($this->values['eventType']) === false) { + $filter['event_type'] = $this->values['eventType']; + } + + // Event status. + if ((int) $this->values['eventStatus'] !== -1) { + $filter['status'] = $this->values['eventStatus']; + } } // Order. @@ -638,6 +681,12 @@ class EventsListWidget extends Widget $data[1] = ' '; } + if (isset($event['event_rep']) === true + && $event['event_rep'] > 1 + ) { + $data[1] .= ' ('.$event['event_rep'].')'; + } + // Group. $data[2] = $event['group_name']; diff --git a/pandora_console/views/dashboard/configurationWidgets.php b/pandora_console/views/dashboard/configurationWidgets.php index 5cebd952d7..d912027d53 100644 --- a/pandora_console/views/dashboard/configurationWidgets.php +++ b/pandora_console/views/dashboard/configurationWidgets.php @@ -51,6 +51,7 @@ HTML::printForm( [ 'form' => $form, 'inputs' => $htmlInputs, + 'js' => $js, ] ); From 376a46a925623923a9f8cfe9a748c2b07e8b5589 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 11 Feb 2021 13:28:13 +0100 Subject: [PATCH 034/112] WIP extra modules for interfaces wizard --- .../include/class/AgentWizard.class.php | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/pandora_console/include/class/AgentWizard.class.php b/pandora_console/include/class/AgentWizard.class.php index d9a42b7cfa..6a852dd6af 100644 --- a/pandora_console/include/class/AgentWizard.class.php +++ b/pandora_console/include/class/AgentWizard.class.php @@ -972,6 +972,16 @@ class AgentWizard extends HTML if (isset($unicastIpReferences[$indexKey]) === true) { $interfaces[$indexKey]['ip'] = ''; } + + // Get interface alias. + $interfaces[$indexKey]['alias'] = $this->snmpgetValue( + '.1.3.6.1.2.1.31.1.1.1.18.'.$indexKey + ); + + // Get interface speed. + $interfaces[$indexKey]['speed'] = $this->snmpgetValue( + '.1.3.6.1.2.1.2.2.1.5.'.$indexKey + ); } // Save the interfaces found for process later. @@ -4291,6 +4301,12 @@ class AgentWizard extends HTML $moduleDescription .= ''; } + if (empty($data['alias']) === false) { + $moduleDescription .= 'Alias: '.$data['alias'].' - '; + } else { + $moduleDescription .= ''; + } + $name = $data['name'].'_'; $value = $data['index']; } @@ -4402,6 +4418,32 @@ class AgentWizard extends HTML $definition = array_merge($definition, $definition_temp); } + // LocIfInCRC. + $moduleName = $name.'locIfInCRC'; + $definition['locIfInCRC'] = [ + 'module_name' => $moduleName, + 'module_type' => MODULE_TYPE_REMOTE_SNMP_INC, + 'module_description' => sprintf( + '(%s%s)', + $moduleDescription, + $moduleName + ), + 'module_info' => 'Number of input packets which had cyclic redundancy checksum errors.', + 'execution_type' => 'network', + 'value' => '1.3.6.1.4.1.9.2.2.1.1.12.'.$value, + 'module_unit' => 'packets/s', + 'default_enabled' => true, + 'module_enabled' => false, + 'module_thresholds' => [ + 'min_warning' => '0', + 'max_warning' => '0', + 'inv_warning' => false, + 'min_critical' => '0', + 'max_critical' => '0', + 'inv_critical' => false, + ], + ]; + // Continue with common x86 and x84 modules. // IfAdminStatus. $moduleName = $name.'ifAdminStatus'; @@ -4559,6 +4601,12 @@ class AgentWizard extends HTML $moduleDescription .= ''; } + if (empty($data['alias']) === false) { + $moduleDescription .= 'Alias: '.$data['alias'].' - '; + } else { + $moduleDescription .= ''; + } + $name = $data['name'].'_'; $value = $data['index']; } @@ -4748,6 +4796,12 @@ class AgentWizard extends HTML $moduleDescription .= ''; } + if (empty($data['alias']) === false) { + $moduleDescription .= 'Alias: '.$data['alias'].' - '; + } else { + $moduleDescription .= ''; + } + $name = $data['name'].'_'; $value = $data['index']; } From 24ed77b5a11bb383c6f2b0fedcf0312f7a547e10 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 12 Feb 2021 15:25:41 +0100 Subject: [PATCH 035/112] Pandora bandwidth server plugin --- .../include/class/AgentWizard.class.php | 165 +++++- pandora_server/lib/PandoraFMS/PluginTools.pm | 25 +- .../util/plugin/pandora_snmp_bandwidth.pl | 508 ++++++++++++++++++ 3 files changed, 656 insertions(+), 42 deletions(-) create mode 100644 pandora_server/util/plugin/pandora_snmp_bandwidth.pl diff --git a/pandora_console/include/class/AgentWizard.class.php b/pandora_console/include/class/AgentWizard.class.php index 6a852dd6af..35e8d676f7 100644 --- a/pandora_console/include/class/AgentWizard.class.php +++ b/pandora_console/include/class/AgentWizard.class.php @@ -937,8 +937,8 @@ class AgentWizard extends HTML $ipsResult = []; // In this case we need the full information provided by snmpwalk. - $ipsResult = $this->snmpwalkValues($snmpIpDiscover, false, true); - $indexes = $this->snmpwalkValues($snmpIpIndexes, false, true); + $ipsResult = $this->snmpWalkValues($snmpIpDiscover, false, true); + $indexes = $this->snmpWalkValues($snmpIpIndexes, false, true); $unicastIpReferences = []; foreach ($indexes as $k => $v) { @@ -960,11 +960,11 @@ class AgentWizard extends HTML // Set the name of interface. $interfaces[$indexKey]['name'] = $name; // Get the description. - $interfaces[$indexKey]['descr'] = $this->snmpgetValue( + $interfaces[$indexKey]['descr'] = $this->snmpGetValue( '.1.3.6.1.2.1.2.2.1.2.'.$indexKey ); // Get the MAC address. - $interfaces[$indexKey]['mac'] = $this->snmpgetValue( + $interfaces[$indexKey]['mac'] = $this->snmpGetValue( '.1.3.6.1.2.1.2.2.1.6.'.$indexKey ); // Get unicast IP address. @@ -974,12 +974,12 @@ class AgentWizard extends HTML } // Get interface alias. - $interfaces[$indexKey]['alias'] = $this->snmpgetValue( + $interfaces[$indexKey]['alias'] = $this->snmpGetValue( '.1.3.6.1.2.1.31.1.1.1.18.'.$indexKey ); // Get interface speed. - $interfaces[$indexKey]['speed'] = $this->snmpgetValue( + $interfaces[$indexKey]['speed'] = $this->snmpGetValue( '.1.3.6.1.2.1.2.2.1.5.'.$indexKey ); } @@ -1045,7 +1045,7 @@ class AgentWizard extends HTML if ($this->wizardSection === 'snmp_interfaces_explorer') { // Check if thereis x64 counters. $snmp_tmp = '.1.3.6.1.2.1.31.1.1.1.6'; - $check_x64 = $this->snmpwalkValues( + $check_x64 = $this->snmpWalkValues( $snmp_tmp, false, true @@ -1061,7 +1061,7 @@ class AgentWizard extends HTML // Explore interface names. $oidExplore = '.1.3.6.1.2.1.31.1.1.1.1'; - $receivedOid = $this->snmpwalkValues( + $receivedOid = $this->snmpWalkValues( $oidExplore, false, true @@ -1072,7 +1072,7 @@ class AgentWizard extends HTML } // Doc Interfaces de red. - $receivedOid = $this->snmpwalkValues( + $receivedOid = $this->snmpWalkValues( $oidExplore, false, false @@ -1083,7 +1083,7 @@ class AgentWizard extends HTML $oidExplore = '1.3.6.1.2.1.2.2.1.2'; // Doc Interfaces de red. - $receivedOid = $this->snmpwalkValues( + $receivedOid = $this->snmpWalkValues( $oidExplore, false, true @@ -2403,7 +2403,7 @@ class AgentWizard extends HTML } // Get current value. - $currentValue = $this->snmpgetValue($moduleData['value']); + $currentValue = $this->snmpGetValue($moduleData['value']); // It unit of measure have data, attach to current value. if (empty($moduleData['module_unit']) === false) { @@ -2556,7 +2556,7 @@ class AgentWizard extends HTML } // Get current value. - $currentValue = $this->snmpgetValue($moduleData['value']); + $currentValue = $this->snmpGetValue($moduleData['value']); // Format current value with thousands and decimals. if (is_numeric($currentValue) === true) { @@ -2927,7 +2927,7 @@ class AgentWizard extends HTML // Common for FIXED Scan types. // If _nameOID_ macro exists, stablish the name getted. if (empty($module['name_oid']) === false) { - $nameValue = $this->snmpgetValue($module['name_oid']); + $nameValue = $this->snmpGetValue($module['name_oid']); $moduleBlocks[$k]['name'] = str_replace( '_nameOID_', $nameValue, @@ -2941,7 +2941,7 @@ class AgentWizard extends HTML $module['value'] = 0; } - $value = $this->snmpgetValue($module['value']); + $value = $this->snmpGetValue($module['value']); // If the value is missing, we must not show this module. if (empty($value) === true) { unset($moduleBlocks[$k]); @@ -2963,7 +2963,7 @@ class AgentWizard extends HTML // OIDs and get his values. foreach ($macros as $key => $oid) { if (preg_match('/extra_field_/', $key) !== 0) { - $value = (float) $this->snmpgetValue($oid); + $value = (float) $this->snmpGetValue($oid); // If the value not exists, // we must not create a module. @@ -2999,20 +2999,20 @@ class AgentWizard extends HTML } else { if ($module['execution_type'] == EXECUTION_TYPE_NETWORK) { // Get the values of snmpwalk. - $snmpwalkNames = $this->snmpwalkValues($module['name_oid']); - $snmpwalkValues = $this->snmpwalkValues($module['value']); + $snmpwalkNames = $this->snmpWalkValues($module['name_oid']); + $snmpWalkValues = $this->snmpWalkValues($module['value']); $snmpwalkCombined = []; foreach ($snmpwalkNames as $index => $name) { if (isset($name) !== true - || isset($snmpwalkValues[$index]) !== true + || isset($snmpWalkValues[$index]) !== true ) { continue; } $snmpwalkCombined[$index] = [ 'name' => $name, - 'value' => $snmpwalkValues[$index], + 'value' => $snmpWalkValues[$index], ]; } @@ -3062,7 +3062,7 @@ class AgentWizard extends HTML $snmpwalkNamesTmp = []; // Is needed the index and the values of snmpwalk. - $snmpwalkNamesTmp = $this->snmpwalkValues( + $snmpwalkNamesTmp = $this->snmpWalkValues( $module['name_oid'], true ); @@ -3082,7 +3082,7 @@ class AgentWizard extends HTML foreach ($oids as $oidName => $oid) { $currentOid = $oid.'.'.$tmpSecond[0]; $macros['macros'][$oidName] = $currentOid; - $currentOidValue = $this->snmpgetValue($currentOid); + $currentOidValue = $this->snmpGetValue($currentOid); // If for any reason the value comes empty, add 1. if ($currentOidValue == '') { $currentOidValue = 1; @@ -3240,6 +3240,58 @@ class AgentWizard extends HTML } + /** + * Returns associated PEN code of this device. + * + * @return integer|null PEN oid or null if not found. + */ + private function getPEN() + { + $oid = '.1.3.6.1.2.1.1.2.0'; + $output = $this->snmpWalkValues($oid, false, true, true); + + static $pen; + + if (isset($pen) === true) { + return $pen; + } + + if (is_array($output) === true + && isset($output[$oid]) === true + ) { + // Output should be an array with only 1 element. + $pen = (int) explode('.', $output[$oid])[7]; + } + + if ($pen === 0) { + return null; + } + + return $pen; + } + + + /** + * Returns the index oid matching selected expected value. + * + * @param string $oidTree Tree to search in. + * @param string $expectedValue Expected value. + * + * @return string|false Index where expected value is stored or false if not + * found. + */ + private function snmpGetValueInverse($oidTree, $expectedValue) + { + $oidTree = $this->snmpWalkValues($oidTree); + + if (is_array($oidTree) === false) { + return false; + } + + return array_search($expectedValue, $oidTree); + } + + /** * Perform a snmpget for get a value from provided oid. * @@ -3248,13 +3300,13 @@ class AgentWizard extends HTML * * @return mixed String when response, null if error. */ - private function snmpgetValue(string $oid, ?bool $full_output=false) + private function snmpGetValue(string $oid, ?bool $full_output=false) { if ($oid[0] !== '.') { $oid = '.'.$oid; } - $output = $this->snmpwalkValues($oid, false, true, true); + $output = $this->snmpWalkValues($oid, false, true, true); if (is_array($output) === true) { foreach ($output as $k => $v) { @@ -3287,7 +3339,7 @@ class AgentWizard extends HTML * * @return array */ - private function snmpwalkValues( + private function snmpWalkValues( string $oid, bool $full_output=false, bool $pure=false, @@ -4286,7 +4338,7 @@ class AgentWizard extends HTML { $moduleDescription = ''; $name = ''; - $value = '1'; + $value = '_generic_'; // Unpack the array with data. if (empty($data) === false) { if (empty($data['mac']) === false) { @@ -4320,7 +4372,7 @@ class AgentWizard extends HTML // IfOperStatus. $adminStatusValue = 1; if (empty($data) === false) { - $adminStatusValue = $this->snmpgetValue( + $adminStatusValue = $this->snmpGetValue( '1.3.6.1.2.1.2.2.1.7.'.$value ); @@ -4331,7 +4383,7 @@ class AgentWizard extends HTML // IfOperStatus. $operStatusValue = 1; if (empty($data) === false) { - $operStatusValue = $this->snmpgetValue( + $operStatusValue = $this->snmpGetValue( '1.3.6.1.2.1.2.2.1.8.'.$value ); @@ -4408,9 +4460,11 @@ class AgentWizard extends HTML 'ifOutNUcastPkts / ifHCOutNUcastPkts', ]; - if ($name == '') { + if ($name === '') { foreach ($definition_temp as $module => $module_def) { - $definition_temp[$module]['module_name'] = array_shift($general_module_names); + $definition_temp[$module]['module_name'] = array_shift( + $general_module_names + ); } } @@ -4444,6 +4498,59 @@ class AgentWizard extends HTML ], ]; + // Manufacturer specific modules. + $pen = $this->getPEN(); + switch ($pen) { + case 9: + // CISCO. + $valueTranslated = $this->snmpGetValueInverse( + '.1.3.6.1.4.1.9.5.1.4.1.1.11.1', + $value + ); + if ($valueTranslated === false && $value !== '_generic_') { + $duplexMismatchOID = null; + } else { + $duplexMismatchOID = '.1.3.6.1.4.1.9.5.1.4.1.1.10.1'; + $duplexMismatchOID .= $valueTranslated; + $minc = 2.5; + $maxc = 3.5; + } + break; + + // TODO: Add here extra manufacturers. + default: + // Unknown. + $duplexMismatchOID = null; + break; + } + + if (isset($duplexMismatchOID) === true) { + // Duplex mismatch. + $moduleName = $name.'DuplexMismatch'; + $definition['DuplexMismatch'] = [ + 'module_name' => $moduleName, + 'module_type' => MODULE_TYPE_REMOTE_SNMP, + 'module_description' => sprintf( + '(%s%s)', + $moduleDescription, + $moduleName + ), + 'module_info' => 'Indicates whether the port is operating in half-duplex, full-duplex, disagree or auto negotiation mode. If the port could not agree with the far end on port duplex, the port will be in disagree(3) mode.', + 'execution_type' => 'network', + 'value' => $duplexMismatchOID, + 'default_enabled' => true, + 'module_enabled' => false, + 'module_thresholds' => [ + 'min_warning' => '0', + 'max_warning' => '0', + 'inv_warning' => false, + 'min_critical' => $minc, + 'max_critical' => $maxc, + 'inv_critical' => false, + ], + ]; + } + // Continue with common x86 and x84 modules. // IfAdminStatus. $moduleName = $name.'ifAdminStatus'; diff --git a/pandora_server/lib/PandoraFMS/PluginTools.pm b/pandora_server/lib/PandoraFMS/PluginTools.pm index ded2156f6a..fd6afcdac2 100644 --- a/pandora_server/lib/PandoraFMS/PluginTools.pm +++ b/pandora_server/lib/PandoraFMS/PluginTools.pm @@ -2042,19 +2042,18 @@ sub api_create_group { # -> means $context (v3) # # Configuration hash -# -# $snmp{version} -# $snmp{community} -# $snmp{host} -# $snmp{oid} -# $snmp{port} -# $snmp{securityName} -# $snmp{context -# $snmp{securityLevel} -# $snmp{authProtocol} -# $snmp{authKey} -# $snmp{privProtocol} -# $snmp{privKey} +# $snmp{version} +# $snmp{community} +# $snmp{host} +# $snmp{oid} +# $snmp{port} +# $snmp{securityName} +# $snmp{context +# $snmp{securityLevel} +# $snmp{authProtocol} +# $snmp{authKey} +# $snmp{privProtocol} +# $snmp{privKey} ################################################################################ sub snmp_walk { my $snmp = shift; diff --git a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl new file mode 100644 index 0000000000..ff5bbf2af2 --- /dev/null +++ b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl @@ -0,0 +1,508 @@ +#!/usr/bin/perl +# +################################################################################ +# +# Bandwith plugin +# +# Requirements: +# snmpget +# snmpwalk +# +# (c) Fco de Borja Sanchez +# +# 2018/06/27 +# Changes: +# First version +# +################################################################################ + +use strict; +use warnings; + +use POSIX qw(strftime); + +use lib '/usr/lib/perl5'; +use PandoraFMS::PluginTools; + +use Data::Dumper; +$Data::Dumper::Sortkeys = 1; + +# version: Defines actual version of Pandora FMS +my $pandora_version = "7.0NG.752"; +my $pandora_build = "210212"; +our $VERSION = $pandora_version." ".$pandora_build; + +my $HELP=< 0, + HALF_DUPLEX => 2, + FULL_DUPLEX => 3, +}; + +################################################################################ +# Translate argument to config hash key +################################################################################ +sub update_config_key ($) { + my $arg = shift; + if ($arg eq "c"){ + return "community"; + } + if ($arg eq "v"){ + return "version"; + } + if ($arg eq "h"){ + return "host"; + } + if ($arg eq "p"){ + return "port"; + } + if ($arg eq "o"){ + return "oid_base"; + } + if ($arg eq "d"){ + return "datatype"; + } + if ($arg eq "u"){ + return "securityName"; + } + if ($arg eq "n"){ + return "context"; + } + if ($arg eq "l"){ + return "securityLevel"; + } + if ($arg eq "a"){ + return "authProtocol"; + } + if ($arg eq "A"){ + return "authKey"; + } + if ($arg eq "x"){ + return "privProtocol"; + } + if ($arg eq "X"){ + return "privKey"; + } + if ($arg eq "agent") { + return "agent_name"; + } + if ($arg eq "names") { + return "names"; + } + if ($arg eq "branches") { + return "branches"; + } + if ($arg eq 'ifIndex') { + return "ifIndex"; + } +} + +################################################################################ +# Prepare analysis tree +################################################################################ +sub prepare_tree { + my ($config) = @_; + my $tree; + + my %snmp_call = %{$config}; + my $ifIndex = $config->{'ifIndex'}; + $ifIndex = '' if empty($ifIndex); + if (!empty($ifIndex) && $ifIndex !~ /^\./) { + $ifIndex = '.'.$ifIndex; + } + + if (is_enabled($config->{'use_x64'})) { + $snmp_call{'oid'} = $config->{'oid_base'} . $config->{'x64_indexes'}{'__idx__'}.$ifIndex; + } else { + $snmp_call{'oid'} = $config->{'oid_base'} . $config->{'x86_indexes'}{'__idx__'}.$ifIndex; + } + + my $raw = snmp_walk(\%snmp_call); + return $raw if (ref($raw) eq "HASH"); + + my @data = split /\n/, $raw; + foreach my $it (@data) { + my ($key, $value) = split /=/, $it; + $value = trim($value); + $key = trim($key); + $value =~ s/^.*:\ {0,1}//; + + if ($value =~ /No such instance/i) { + return {}; + } + + $ifIndex = $value; + if ($ifIndex !~ /^\./) { + $ifIndex = '.'.$ifIndex; + } + + my %inOctets_call = %{$config}; + if (is_enabled($config->{'use_x64'})) { + $inOctets_call{'oid'} = $config->{'oid_base'}; + $inOctets_call{'oid'} .= $config->{'x64_indexes'}{'inOctets'}.$ifIndex; + } else { + $inOctets_call{'oid'} = $config->{'oid_base'}; + $inOctets_call{'oid'} .= $config->{'x86_indexes'}{'inOctets'}.$ifIndex; + } + + my $inOctets = snmp_get(\%inOctets_call); + if (ref($inOctets) eq "HASH") { + $inOctets = $inOctets->{'data'}; + } else { + # Ignore, cannot retrieve inOctets. + next; + } + + my %outOctets_call = %{$config}; + if (is_enabled($config->{'use_x64'})) { + $outOctets_call{'oid'} = $config->{'oid_base'}; + $outOctets_call{'oid'} .= $config->{'x64_indexes'}{'outOctets'}.$ifIndex; + } else { + $outOctets_call{'oid'} = $config->{'oid_base'}; + $outOctets_call{'oid'} .= $config->{'x86_indexes'}{'outOctets'}.$ifIndex; + } + + my $outOctets = snmp_get(\%outOctets_call); + if (ref($outOctets) eq "HASH") { + $outOctets = $outOctets->{'data'}; + } else { + # Ignore, cannot retrieve inOctets. + next; + } + + my %duplex_call = %{$config}; + if (is_enabled($config->{'use_x64'})) { + $duplex_call{'oid'} = $config->{'oid_base'}; + $duplex_call{'oid'} .= $config->{'x64_indexes'}{'duplex'}.$ifIndex; + } else { + $duplex_call{'oid'} = $config->{'oid_base'}; + $duplex_call{'oid'} .= $config->{'x86_indexes'}{'duplex'}.$ifIndex; + } + + my $duplex = snmp_get(\%duplex_call); + if (ref($duplex) eq "HASH") { + $duplex = $duplex->{'data'}; + } else { + # Ignore, cannot retrieve inOctets. + next; + } + + my %speed = %{$config}; + if (is_enabled($config->{'use_x64'})) { + $speed{'oid'} = $config->{'oid_base'}; + $speed{'oid'} .= $config->{'x64_indexes'}{'ifSpeed'}.$ifIndex; + } else { + $speed{'oid'} = $config->{'oid_base'}; + $speed{'oid'} .= $config->{'x86_indexes'}{'ifSpeed'}.$ifIndex; + } + + my $speed = snmp_get(\%speed); + if (ref($speed) eq "HASH") { + $speed = $speed->{'data'}; + } else { + # Ignore, cannot retrieve inOctets. + next; + } + + $tree->{$value} = { + 'duplex' => int $duplex, + 'speed' => int $speed, + 'now' => { + 'timestamp' => time(), + 'inOctets' => int $inOctets, + 'outOctets' => int $outOctets, + }, + } + } + + load_data($config, $tree); + save_data($config, $tree); + + return $tree; +} + +################################################################################ +# Load previous metrics from temporal file. +################################################################################ +sub load_data { + my ($config, $tree) = @_; + + my $_f; + eval { + open($_f, "<$config->{'tmp_file'}") or die('Cannot open ' . $config->{'tmp_file'}); + }; + if( $@ ) { + foreach my $iface (keys %{$tree}) { + $tree->{$iface}{'old'} = { + 'timestamp' => int $tree->{$iface}{'now'}{'timestamp'}, + 'inOctets' => int $tree->{$iface}{'now'}{'inOctets'}, + 'outOctets' => int $tree->{$iface}{'now'}{'outOctets'}, + }; + } + return; + } + + # File opened, load previous values. + while (my $line =<$_f>) { + $line = trim($line); + my ($timestamp, $iface, $inOctets, $outOctets) = split /$config->{'tmp_separator'}/, $line; + + next if (!defined($tree->{trim($iface)})); + + $tree->{trim($iface)}{'old'} = { + 'timestamp' => int trim($timestamp), + 'inOctets' => int trim($inOctets), + 'outOctets' => int trim($outOctets), + }; + } + + close($_f); + + foreach my $iface (keys %{$tree}) { + if (empty($tree->{trim($iface)}{'old'}{'timestamp'})) { + $tree->{$iface}{'old'} = { + 'timestamp' => int $tree->{$iface}{'now'}{'timestamp'}, + 'inOctets' => int $tree->{$iface}{'now'}{'inOctets'}, + 'outOctets' => int $tree->{$iface}{'now'}{'outOctets'}, + }; + } + } +} + +################################################################################ +# Save metrics to temporal file. +################################################################################ +sub save_data { + my ($config, $tree) = @_; + + my $_f; + eval { + open($_f, ">$config->{'tmp_file'}") or die('Cannot open ' . $config->{'tmp_file'}); + }; + if( $@ ) { + logger($config, 'info', "Cannot save stats, please check writting permissions on [" . $config->{'tmp_file'} . "]"); + return; + } + + # File not available, reset old data. + my $target_oids = 'x86_indexes'; + $target_oids = 'x64_indexes' if is_enabled($config->{'use_x64'}); + + foreach my $iface (keys %{$tree}) { + # Timestamp. + print $_f $tree->{$iface}{'now'}{'timestamp'} . $config->{'tmp_separator'}; + + # Iface. + print $_f $iface . $config->{'tmp_separator'}; + + # InOctets. + print $_f $tree->{$iface}{'now'}{'inOctets'} . $config->{'tmp_separator'}; + + # OutOctets. + print $_f $tree->{$iface}{'now'}{'outOctets'} . $config->{'tmp_separator'}; + + # End. + print $_f "\n"; + } + + close($_f); + +} + +################################################################################ +# Calculate bandwidth +################################################################################ +sub get_bandwidth { + my ($config, $tree) = @_; + + foreach my $iface (keys %{$tree}) { + my $ifIndex = $iface; + if ($ifIndex !~ /^\./) { + $ifIndex = '.'.$ifIndex; + } + + my $speed = $tree->{$iface}{'speed'}; + my $input = $tree->{$iface}{'now'}{'inOctets'} - $tree->{$iface}{'old'}{'inOctets'}; + my $output = $tree->{$iface}{'now'}{'outOctets'} - $tree->{$iface}{'old'}{'outOctets'}; + my $delta = $tree->{$iface}{'now'}{'timestamp'} - $tree->{$iface}{'old'}{'timestamp'}; + my $bandwidth = 0; + + $tree->{$iface}->{'delta'} = { + 'inOctets' => $input, + 'outOctets' => $output, + 'seconds' => $delta, + }; + + $tree->{$iface}->{'speed'} = $speed; + + if (($speed > 0) && ($delta > 0)) { + # Information about bandwidth calculation: https://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/8141-calculate-bandwidth-snmp.html + if ($tree->{$iface}{'duplex'} == HALF_DUPLEX + || $tree->{$iface}{'duplex'} == UNKNOWN_DUPLEX + ) { + $bandwidth = (($input + $output) * 8) / ($delta * $speed); + } + elsif ($tree->{$iface}{'duplex'} == FULL_DUPLEX) { + my $input_bandwidth = ($input * 8) / ($delta * $speed); + my $output_bandwidth = ($output * 8) / ($delta * $speed); + $bandwidth = ($input_bandwidth + $output_bandwidth) / 2; + } + else { + logger($config, 'info', "Failed to calculate bandwidth, unknown duplex mode: [" . $tree->{$iface}{'duplex_mode'} . "]"); + } + } + else { + logger($config, 'info', "Failed to calculate bandwidth, interface [" . $iface . "] speed is 0"); + } + + $tree->{$iface}->{'bandwidth'} = 100 * $bandwidth; + } + +} + + + +################################################################################ +# +# MAIN +# +################################################################################ + +if ($#ARGV < 0) { + print $HELP; + exit 0; +} + +# Base config definition +my $_config = { + 'oid_base' => ".1.3.6.1.2.1", + 'as_agent_plugin' => 1, + 'use_x64' => 0, + 'x86_indexes' => { + '__idx__' => ".2.2.1.1", + 'duplex' => ".10.7.2.1.19", + 'inOctets' => ".2.2.1.16", + 'outOctets' => ".2.2.1.10", + 'ifSpeed' => ".2.2.1.5", + }, + 'x64_indexes' => { + # In x64 there is no 'index' branch. Uses latest 'id' in OID as ID. + '__idx__' => ".2.2.1.1", + 'duplex' => ".10.7.2.1.19", + 'inOctets' => ".31.1.1.1.6", + 'outOctets' => ".31.1.1.1.10", + 'ifSpeed' => ".2.2.1.5", + }, +}; + +$_config = read_configuration($_config); + +if (check_lib_version($pandora_version) == 0){ + print_stderror($_config, "Incorrect PluginTools library version " . get_lib_version() . " != " . $VERSION . " functionality could be affected."); +} + +my $config; + +foreach my $pk (keys %{$_config}) { + my $k = update_config_key($pk); + if (!empty($k)) { + $config->{$k} = $_config->{$pk}; + } + else { + $config->{$pk} = $_config->{$pk}; + } +} + +$config->{'host'} = '127.0.0.1' if empty($config->{'host'}); +$config->{'port'} = '161' if empty($config->{'port'}); +$config->{'tmp_separator'} = ';' if empty($config->{'tmp_separator'}); +$config->{'tmp'} = (($^O =~ /win/)?$ENV{'TMP'}:'/tmp') if empty($config->{'tmp'}); + +# Create unique name for tmp and log file for host +my $filename = $config->{'tmp'}.'/pandora_bandwith_'.$config->{'host'}; + +# Replace every dot for underscore +$filename =~ tr/./_/; +$config->{'tmp_file'} = $filename.'.idx' if empty($config->{'tmp_file'}); +$config->{'log'} = $filename.'.log' if empty($config->{'log'}); + +my @int_exc = split /,/, trim($config->{'interface_exceptions'}) if (!empty($config->{'interface_exceptions'})); +if ($#int_exc >= 0) { + $config->{'interface_exceptions'} = \@int_exc; +} +my @only_int = split /,/, trim($config->{'only_interfaces'}) if (!empty($config->{'only_interfaces'})); +if ($#only_int >= 0) { + $config->{'only_interfaces'} = \@only_int; +} + +logger($config, 'info', "Plugin starts"); +if (is_enabled($config->{'debug'})) { + eval { + eval "use Data::Dumper;1;";if($@) {} + logger($config, Dumper($config)); + }; + if($@) {} +} + +my $analysis_tree = prepare_tree($config); + +if (!empty($analysis_tree->{'error'})) { + logger($config, 'info', "Failed: " . $analysis_tree->{'error'}); + exit 0; +} +else { + get_bandwidth($config, $analysis_tree); +} + +# Report data +my @modules; +my $bandwidth = 0; +my $i = 0; +foreach my $iface (keys %{$analysis_tree}) { + # Calculate summary; + if (is_enabled($analysis_tree->{$iface}{'bandwidth'})) { + $bandwidth = $analysis_tree->{$iface}{'bandwidth'}; + $i++; + } + +} + +if ($i > 0) { + $bandwidth /= $i; + print sprintf("%.9f\n", $bandwidth); +} + +logger($config, 'info', "Plugin ends"); + From 09b5400023c415e5e557afc9fa414ed892269e58 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 15 Feb 2021 18:56:42 +0100 Subject: [PATCH 036/112] MR info + bandwidth analysis in wizards --- pandora_console/extras/mr/45.sql | 9 + .../pandoradb_migrate_6.0_to_7.0.mysql.sql | 6 + .../include/class/AgentWizard.class.php | 229 +++++++++++++++--- pandora_console/pandoradb_data.sql | 6 + .../util/plugin/pandora_snmp_bandwidth.pl | 59 +++-- 5 files changed, 258 insertions(+), 51 deletions(-) create mode 100644 pandora_console/extras/mr/45.sql diff --git a/pandora_console/extras/mr/45.sql b/pandora_console/extras/mr/45.sql new file mode 100644 index 0000000000..27957b1ef3 --- /dev/null +++ b/pandora_console/extras/mr/45.sql @@ -0,0 +1,9 @@ +START TRANSACTION; + +SET @plugin_name = 'Network bandwidth SNMP'; +SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; +SET @plugin_id = ''; +SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; +INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_''); + +COMMIT; 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 2131b619a4..22f06fcdf6 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 @@ -2874,6 +2874,12 @@ SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,20,0,'/usr/share/pandora_server/util/plugin/wizard_wmi_module',NULL,NULL,NULL,NULL,0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Namespace (Optional)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"User\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"1\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"WMI Class\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"Fields list\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"Query filter (Optional)\",\"help\":\"Use single quotes for query conditions\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"Operation\",\"help\":\"Aritmetic operation to get data. Macros _fN_ will be changed by fields in list. Example: ((_f1_ - _f2_) * 100) / _f1_\",\"value\":\"\",\"hide\":\"\"}}','-host '_field1_' -namespace '_field2_' -user '_field3_' -pass '_field4_' -wmiClass '_field5_' -fieldsList '_field6_' -queryFilter "_field7_" -operation '_field8_' -wmicPath /usr/bin/wmic'); +SET @plugin_name = 'Network bandwidth SNMP'; +SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; +SET @plugin_id = ''; +SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; +INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_''); + SET @main_component_group_name = 'Wizard'; SET @component_id = ''; SELECT @component_id := `id_sg` FROM `tnetwork_component_group` WHERE `name` = @main_component_group_name; diff --git a/pandora_console/include/class/AgentWizard.class.php b/pandora_console/include/class/AgentWizard.class.php index 35e8d676f7..7c273bf621 100644 --- a/pandora_console/include/class/AgentWizard.class.php +++ b/pandora_console/include/class/AgentWizard.class.php @@ -1337,7 +1337,6 @@ class AgentWizard extends HTML $content .= html_print_table($table, true); echo $content; - return; } @@ -1431,6 +1430,15 @@ class AgentWizard extends HTML $result[$value]['description'] = $data['module-default_description-'.$key]; } else if (empty(preg_match('/module-value/', $k)) === false) { $result[$value]['value'] = $data['module-value-'.$key]; + } else if (empty(preg_match('/module-macros/', $k)) === false) { + $result[$value]['macros'] = $data['module-macros-'.$key]; + continue; + } else if (empty(preg_match('/module-id_plugin/', $k)) === false) { + $result[$value]['id_plugin'] = $data['module-id_plugin-'.$key]; + continue; + } else if (empty(preg_match('/module-id_modulo/', $k)) === false) { + $result[$value]['id_modulo'] = $data['module-id_modulo-'.$key]; + continue; } preg_match('/^(.*)-.*?_(\d+-\d+)$/', $k, $matches); @@ -2062,35 +2070,42 @@ class AgentWizard extends HTML } else { $tmp->ip_target($this->targetIp); $tmp->id_modulo(MODULE_PLUGIN); - $fieldsPlugin = db_get_value_sql( - sprintf( - 'SELECT macros FROM tplugin WHERE id=%d', - (int) $infoMacros['server_plugin'] - ) - ); - if ($fieldsPlugin !== false) { - $fieldsPlugin = json_decode($fieldsPlugin, true); - $i = 1; - foreach ($infoMacros as $key => $value) { - if (empty(preg_match('/_snmp_field/', $key)) === false) { - $new_macros = []; - foreach ($fieldsPlugin as $k => $v) { - if ($v['macro'] === preg_replace('/_snmp_field/', '', $key)) { - $fieldsPlugin[$k]['value'] = $this->replacementMacrosPlugin( - $value, - $infoMacros['macros'] - ); - $i++; - continue; + if (empty($candidate['macros']) === true) { + $fieldsPlugin = db_get_value_sql( + sprintf( + 'SELECT macros FROM tplugin WHERE id=%d', + (int) $infoMacros['server_plugin'] + ) + ); + + if ($fieldsPlugin !== false) { + $fieldsPlugin = json_decode($fieldsPlugin, true); + $i = 1; + foreach ($infoMacros as $key => $value) { + if (empty(preg_match('/_snmp_field/', $key)) === false) { + $new_macros = []; + foreach ($fieldsPlugin as $k => $v) { + if ($v['macro'] === preg_replace('/_snmp_field/', '', $key)) { + $fieldsPlugin[$k]['value'] = $this->replacementMacrosPlugin( + $value, + $infoMacros['macros'] + ); + $i++; + continue; + } } } } } - } - $tmp->id_plugin($infoMacros['server_plugin']); - $tmp->macros(json_encode($fieldsPlugin)); + $tmp->id_plugin($infoMacros['server_plugin']); + $tmp->macros(json_encode($fieldsPlugin)); + } else { + // Use definition provided. + $tmp->id_plugin($candidate['id_plugin']); + $tmp->macros(base64_decode($candidate['macros'])); + } } } } else if ($this->protocol === 'wmi') { @@ -2403,7 +2418,18 @@ class AgentWizard extends HTML } // Get current value. - $currentValue = $this->snmpGetValue($moduleData['value']); + if (in_array( + $moduleData['module_type'], + [ + MODULE_TYPE_REMOTE_SNMP, + MODULE_TYPE_REMOTE_SNMP_INC, + MODULE_TYPE_REMOTE_SNMP_STRING, + MODULE_TYPE_REMOTE_SNMP_PROC, + ] + ) === true + ) { + $currentValue = $this->snmpGetValue($moduleData['value']); + } // It unit of measure have data, attach to current value. if (empty($moduleData['module_unit']) === false) { @@ -2413,6 +2439,7 @@ class AgentWizard extends HTML // Stablish the data for show. $generalInterfaceModulesUpdated[] = [ 'component_id' => $component_id_number++, + 'execution_type' => $moduleData['execution_type'], 'name' => $moduleData['module_name'], 'type' => $moduleData['module_type'], 'description' => $moduleData['module_info'], @@ -2425,6 +2452,9 @@ class AgentWizard extends HTML 'module_enabled' => $moduleData['default_enabled'], 'name_oid' => $moduleData['value'], 'value' => $moduleData['value'], + 'id_plugin' => $moduleData['id_plugin'], + 'macros' => $moduleData['macros'], + 'id_modulo' => $moduleData['id_modulo'], ]; } @@ -2556,7 +2586,20 @@ class AgentWizard extends HTML } // Get current value. - $currentValue = $this->snmpGetValue($moduleData['value']); + $currentValue = ''; + + if (in_array( + $moduleData['module_type'], + [ + MODULE_TYPE_REMOTE_SNMP, + MODULE_TYPE_REMOTE_SNMP_INC, + MODULE_TYPE_REMOTE_SNMP_STRING, + MODULE_TYPE_REMOTE_SNMP_PROC, + ] + ) === true + ) { + $currentValue = $this->snmpGetValue($moduleData['value']); + } // Format current value with thousands and decimals. if (is_numeric($currentValue) === true) { @@ -2572,6 +2615,7 @@ class AgentWizard extends HTML // Stablish the data for show. $interfaceModulesUpdated[] = [ 'component_id' => $component_id_number++, + 'execution_type' => $moduleData['execution_type'], 'name' => $moduleData['module_name'], 'type' => $moduleData['module_type'], 'description' => $moduleData['module_description'], @@ -2585,6 +2629,9 @@ class AgentWizard extends HTML 'current_value' => $currentValue, 'name_oid' => $moduleData['value'], 'value' => $moduleData['value'], + 'id_plugin' => $moduleData['id_plugin'], + 'macros' => $moduleData['macros'], + 'id_modulo' => $moduleData['id_modulo'], ]; } @@ -4189,14 +4236,49 @@ class AgentWizard extends HTML 'form="form-create-modules"' ); - // Macro module. - $data[6] .= html_print_input_hidden( - 'module-macros-'.$uniqueId, - base64_encode($module['macros']), - true, - $md5IdBlock, - 'form="form-create-modules"' - ); + if (empty($module['macros']) === false) { + // Macro module. + $data[6] .= html_print_input_hidden( + 'module-macros-'.$uniqueId, + base64_encode($module['macros']), + true, + $md5IdBlock, + 'form="form-create-modules"' + ); + } + + if (empty($module['execution_type']) === false) { + // Id plugin. + $data[6] .= html_print_input_hidden( + 'module-execution_type-'.$uniqueId, + $module['execution_type'], + true, + $md5IdBlock, + 'form="form-create-modules"' + ); + } + + if (empty($module['id_modulo']) === false) { + // Id module. + $data[6] .= html_print_input_hidden( + 'module-id_modulo-'.$uniqueId, + $module['id_modulo'], + true, + $md5IdBlock, + 'form="form-create-modules"' + ); + } + + if (empty($module['id_plugin']) === false) { + // Id plugin. + $data[6] .= html_print_input_hidden( + 'module-id_plugin-'.$uniqueId, + $module['id_plugin'], + true, + $md5IdBlock, + 'form="form-create-modules"' + ); + } // Macro module. $data[6] .= html_print_input_hidden( @@ -4551,6 +4633,85 @@ class AgentWizard extends HTML ]; } + // Bandwidth plugin. + static $plugin; + if ($plugin === null) { + $plugin = \db_get_row_filter( + 'tplugin', + [ 'name' => 'Network bandwidth SNMP' ] + ); + } + + if ($plugin !== false) { + // Network Bandwidth is installed. + $plugin_id = $plugin['id']; + $macros = json_decode($plugin['macros'], 1); + if (json_last_error() === JSON_ERROR_NONE) { + // SNMP Version. + $macros[1]['value'] = $this->version; + + // Community. + $macros[2]['value'] = $this->community; + + // Host. + $macros[3]['value'] = $this->targetIp; + + // Port. + $macros[4]['value'] = $this->targetPort; + + // Interface index filter. + $macros[5]['value'] = $value; + + // SecurityName. + $macros[6]['value'] = $this->authUserV3; + + // SecurityContext. + $macros[7]['value'] = $this->community; + + // SecurityLevel. + $macros[8]['value'] = $this->securityLevelV3; + + // AuthProtocol. + $macros[9]['value'] = $this->authMethodV3; + + // AuthKey. + $macros[10]['value'] = $this->authPassV3; + + // PrivProtocol. + $macros[11]['value'] = $this->privacyMethodV3; + + // PrivKey. + $macros[11]['value'] = $this->privacyPassV3; + + $moduleName = $name.'Bandwidth'; + $definition['Bandwidth'] = [ + 'module_name' => $moduleName, + 'module_type' => MODULE_TYPE_NUMERIC, + 'module_description' => sprintf( + '(%s%s)', + $moduleDescription, + $moduleName + ), + 'module_info' => 'Amount of digital information sent and received from this inteerface over a particular time (see interval).', + 'execution_type' => EXECUTION_TYPE_PLUGIN, + 'id_plugin' => $plugin_id, + 'id_modulo' => MODULE_PLUGIN, + 'macros' => json_encode($macros), + 'default_enabled' => true, + 'module_enabled' => false, + 'module_unit' => '%', + 'module_thresholds' => [ + 'min_warning' => '0', + 'max_warning' => '0', + 'inv_warning' => false, + 'min_critical' => '85', + 'max_critical' => '0', + 'inv_critical' => false, + ], + ]; + } + } + // Continue with common x86 and x84 modules. // IfAdminStatus. $moduleName = $name.'ifAdminStatus'; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 57f43c5085..f3f77b80c6 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -1739,6 +1739,12 @@ SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,20,0,'/usr/share/pandora_server/util/plugin/wizard_wmi_module',NULL,NULL,NULL,NULL,0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Namespace (Optional)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"User\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"1\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"WMI Class\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"Fields list\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"Query filter (Optional)\",\"help\":\"Use single quotes for query conditions\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"Operation\",\"help\":\"Aritmetic operation to get data. Macros _fN_ will be changed by fields in list. Example: ((_f1_ - _f2_) * 100) / _f1_\",\"value\":\"\",\"hide\":\"\"}}','-host '_field1_' -namespace '_field2_' -user '_field3_' -pass '_field4_' -wmiClass '_field5_' -fieldsList '_field6_' -queryFilter "_field7_" -operation '_field8_' -wmicPath /usr/bin/wmic'); +SET @plugin_name = 'Network bandwidth SNMP'; +SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; +SET @plugin_id = ''; +SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; +INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_''); + SET @main_component_group_name = 'Wizard'; SET @component_id = ''; SELECT @component_id := `id_sg` FROM `tnetwork_component_group` WHERE `name` = @main_component_group_name; diff --git a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl index ff5bbf2af2..100147a905 100644 --- a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl +++ b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl @@ -38,9 +38,6 @@ Pandora FMS Server plugin for bandwidth monitoring $VERSION Where OPTIONS could be: -[OIDS] - -use_x64 Use x64 counters (1) or not (0). - [SNMP] -community community -version SNMP version (1,2c,3) @@ -179,7 +176,11 @@ sub prepare_tree { my $inOctets = snmp_get(\%inOctets_call); if (ref($inOctets) eq "HASH") { - $inOctets = $inOctets->{'data'}; + if ($inOctets->{'data'} eq '') { + $inOctets = 0; + } else { + $inOctets = int $inOctets->{'data'}; + } } else { # Ignore, cannot retrieve inOctets. next; @@ -196,7 +197,11 @@ sub prepare_tree { my $outOctets = snmp_get(\%outOctets_call); if (ref($outOctets) eq "HASH") { - $outOctets = $outOctets->{'data'}; + if ($outOctets->{'data'} eq '') { + $outOctets = 0; + } else { + $outOctets = int $outOctets->{'data'}; + } } else { # Ignore, cannot retrieve inOctets. next; @@ -213,7 +218,12 @@ sub prepare_tree { my $duplex = snmp_get(\%duplex_call); if (ref($duplex) eq "HASH") { - $duplex = $duplex->{'data'}; + if ($duplex->{'data'} eq '') { + $duplex = 0; + } else { + $duplex = int $duplex->{'data'}; + } + } else { # Ignore, cannot retrieve inOctets. next; @@ -230,21 +240,24 @@ sub prepare_tree { my $speed = snmp_get(\%speed); if (ref($speed) eq "HASH") { - $speed = $speed->{'data'}; + $speed = int $speed->{'data'}; } else { # Ignore, cannot retrieve inOctets. next; } - $tree->{$value} = { - 'duplex' => int $duplex, - 'speed' => int $speed, - 'now' => { - 'timestamp' => time(), - 'inOctets' => int $inOctets, - 'outOctets' => int $outOctets, - }, - } + { + no warnings "uninitialized"; + $tree->{$value} = { + 'duplex' => int $duplex, + 'speed' => int $speed, + 'now' => { + 'timestamp' => time(), + 'inOctets' => int $inOctets, + 'outOctets' => int $outOctets, + }, + }; + }; } load_data($config, $tree); @@ -380,6 +393,7 @@ sub get_bandwidth { $bandwidth = ($input_bandwidth + $output_bandwidth) / 2; } else { + no warnings "uninitialized"; logger($config, 'info', "Failed to calculate bandwidth, unknown duplex mode: [" . $tree->{$iface}{'duplex_mode'} . "]"); } } @@ -409,7 +423,6 @@ if ($#ARGV < 0) { my $_config = { 'oid_base' => ".1.3.6.1.2.1", 'as_agent_plugin' => 1, - 'use_x64' => 0, 'x86_indexes' => { '__idx__' => ".2.2.1.1", 'duplex' => ".10.7.2.1.19", @@ -450,6 +463,18 @@ $config->{'port'} = '161' if empty($config->{'port'}); $config->{'tmp_separator'} = ';' if empty($config->{'tmp_separator'}); $config->{'tmp'} = (($^O =~ /win/)?$ENV{'TMP'}:'/tmp') if empty($config->{'tmp'}); +if(snmp_walk({ + %{$config}, + 'oid' => '.1.3.6.1.2.1.31.1.1.1.6' + }) +) { + # x64 counters available. + $config->{'use_x64'} = 1; +} else { + # x64 counters not available. + $config->{'use_x64'} = 1; +} + # Create unique name for tmp and log file for host my $filename = $config->{'tmp'}.'/pandora_bandwith_'.$config->{'host'}; From 2826f4fd89b813aee9b31edf935edf633098643a Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 15 Feb 2021 19:08:32 +0100 Subject: [PATCH 037/112] Fixes in MR, added uniqid macro to pandora_snmp_bandwidth --- pandora_console/extras/mr/45.sql | 2 +- pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql | 2 +- pandora_console/include/class/AgentWizard.class.php | 3 +++ pandora_console/pandoradb_data.sql | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pandora_console/extras/mr/45.sql b/pandora_console/extras/mr/45.sql index 27957b1ef3..13ce742a8a 100644 --- a/pandora_console/extras/mr/45.sql +++ b/pandora_console/extras/mr/45.sql @@ -4,6 +4,6 @@ SET @plugin_name = 'Network bandwidth SNMP'; SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; -INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_''); +INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_''); COMMIT; 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 22f06fcdf6..912d7e9ed5 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 @@ -2878,7 +2878,7 @@ SET @plugin_name = 'Network bandwidth SNMP'; SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; -INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_''); +INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_''); SET @main_component_group_name = 'Wizard'; SET @component_id = ''; diff --git a/pandora_console/include/class/AgentWizard.class.php b/pandora_console/include/class/AgentWizard.class.php index 7c273bf621..ebb95cc608 100644 --- a/pandora_console/include/class/AgentWizard.class.php +++ b/pandora_console/include/class/AgentWizard.class.php @@ -4683,6 +4683,9 @@ class AgentWizard extends HTML // PrivKey. $macros[11]['value'] = $this->privacyPassV3; + // Hash identifier. + $macros[12]['value'] = uniqid(); + $moduleName = $name.'Bandwidth'; $definition['Bandwidth'] = [ 'module_name' => $moduleName, diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index f3f77b80c6..a377d4a72d 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -1743,7 +1743,7 @@ SET @plugin_name = 'Network bandwidth SNMP'; SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; -INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_''); +INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_''); SET @main_component_group_name = 'Wizard'; SET @component_id = ''; From aca9814e0f3a538d15ba8dc9ec81c63886cbf367 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 15 Feb 2021 19:10:49 +0100 Subject: [PATCH 038/112] uniqid pandora_snmp_bandwidth --- pandora_server/util/plugin/pandora_snmp_bandwidth.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl index 100147a905..d6edf5d897 100644 --- a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl +++ b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl @@ -56,6 +56,7 @@ Where OPTIONS could be: [EXTRA] -ifIndex Target interface to retrieve, if not specified, total bandwith will be reported. + -uniqid Use custom temporary file name. Note: You can also use snmpget/snmpwalk argument notation, e.g. -v is equal to -version, -c to -community, etc. @@ -124,6 +125,9 @@ sub update_config_key ($) { if ($arg eq 'ifIndex') { return "ifIndex"; } +if ($arg eq 'uniqid') { + return "uniqid"; +} } ################################################################################ @@ -478,6 +482,10 @@ if(snmp_walk({ # Create unique name for tmp and log file for host my $filename = $config->{'tmp'}.'/pandora_bandwith_'.$config->{'host'}; +if (!empty($config->{'uniqid'})) { + $filename = $config->{'tmp'}.'/pandora_bandwith_'.$config->{'uniqid'}; +} + # Replace every dot for underscore $filename =~ tr/./_/; $config->{'tmp_file'} = $filename.'.idx' if empty($config->{'tmp_file'}); From 30755ba256a2ee56597a5a922e37ed576ddcc283 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 15 Feb 2021 19:12:06 +0100 Subject: [PATCH 039/112] minor fixes --- pandora_console/include/class/AgentWizard.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/class/AgentWizard.class.php b/pandora_console/include/class/AgentWizard.class.php index ebb95cc608..860f8f89f6 100644 --- a/pandora_console/include/class/AgentWizard.class.php +++ b/pandora_console/include/class/AgentWizard.class.php @@ -4681,10 +4681,10 @@ class AgentWizard extends HTML $macros[11]['value'] = $this->privacyMethodV3; // PrivKey. - $macros[11]['value'] = $this->privacyPassV3; + $macros[12]['value'] = $this->privacyPassV3; // Hash identifier. - $macros[12]['value'] = uniqid(); + $macros[13]['value'] = uniqid(); $moduleName = $name.'Bandwidth'; $definition['Bandwidth'] = [ From 74ee4971d0ff6387cf8152ac0849c2e3207fce87 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 16 Feb 2021 12:14:56 +0100 Subject: [PATCH 040/112] Added inUsage and outUsage, added units --- pandora_console/extras/mr/45.sql | 2 +- .../pandoradb_migrate_6.0_to_7.0.mysql.sql | 2 +- .../include/class/AgentWizard.class.php | 87 +++++++++++++- pandora_console/pandoradb_data.sql | 2 +- .../util/plugin/pandora_snmp_bandwidth.pl | 111 +++++++++++++----- 5 files changed, 167 insertions(+), 37 deletions(-) diff --git a/pandora_console/extras/mr/45.sql b/pandora_console/extras/mr/45.sql index 13ce742a8a..50b853ac64 100644 --- a/pandora_console/extras/mr/45.sql +++ b/pandora_console/extras/mr/45.sql @@ -4,6 +4,6 @@ SET @plugin_name = 'Network bandwidth SNMP'; SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; -INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_''); +INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"},\"14\":{\"macro\":\"_field14_\",\"desc\":\"inUsage\",\"help\":\"Retrieve input usage (%)\",\"value\":\"\",\"hide\":\"\"},\"15\":{\"macro\":\"_field15_\",\"desc\":\"outUsage\",\"help\":\"Retrieve output usage (%)\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_'; -inUsage '_field14_' -outUsage '_field15_''); COMMIT; 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 912d7e9ed5..c59867ee31 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 @@ -2878,7 +2878,7 @@ SET @plugin_name = 'Network bandwidth SNMP'; SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; -INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_''); +INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"},\"14\":{\"macro\":\"_field14_\",\"desc\":\"inUsage\",\"help\":\"Retrieve input usage (%)\",\"value\":\"\",\"hide\":\"\"},\"15\":{\"macro\":\"_field15_\",\"desc\":\"outUsage\",\"help\":\"Retrieve output usage (%)\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_'; -inUsage '_field14_' -outUsage '_field15_''); SET @main_component_group_name = 'Wizard'; SET @component_id = ''; diff --git a/pandora_console/include/class/AgentWizard.class.php b/pandora_console/include/class/AgentWizard.class.php index 860f8f89f6..6810244320 100644 --- a/pandora_console/include/class/AgentWizard.class.php +++ b/pandora_console/include/class/AgentWizard.class.php @@ -1439,6 +1439,9 @@ class AgentWizard extends HTML } else if (empty(preg_match('/module-id_modulo/', $k)) === false) { $result[$value]['id_modulo'] = $data['module-id_modulo-'.$key]; continue; + } else if (empty(preg_match('/module-unit/', $k)) === false) { + $result[$value]['unit'] = $data['module-unit-'.$key]; + continue; } preg_match('/^(.*)-.*?_(\d+-\d+)$/', $k, $matches); @@ -1899,6 +1902,7 @@ class AgentWizard extends HTML { $modules = []; $errorflag = false; + foreach ($modulesCandidates as $candidate) { $tmp = Module::search( [ @@ -2632,6 +2636,7 @@ class AgentWizard extends HTML 'id_plugin' => $moduleData['id_plugin'], 'macros' => $moduleData['macros'], 'id_modulo' => $moduleData['id_modulo'], + 'unit' => ($moduleData['unit'] ?? $moduleData['module_unit']), ]; } @@ -4221,7 +4226,7 @@ class AgentWizard extends HTML // Unit module. $data[6] .= html_print_input_hidden( 'module-unit-'.$uniqueId, - $module['unit'], + ($module['unit'] ?? $module['module_unit']), true, $md5IdBlock, 'form="form-create-modules"' @@ -4686,6 +4691,12 @@ class AgentWizard extends HTML // Hash identifier. $macros[13]['value'] = uniqid(); + // Get input usage. + $macros[14]['value'] = 0; + + // Get output usage. + $macros[15]['value'] = 0; + $moduleName = $name.'Bandwidth'; $definition['Bandwidth'] = [ 'module_name' => $moduleName, @@ -4695,7 +4706,7 @@ class AgentWizard extends HTML $moduleDescription, $moduleName ), - 'module_info' => 'Amount of digital information sent and received from this inteerface over a particular time (see interval).', + 'module_info' => 'Amount of digital information sent and received from this interface over a particular time (see interval).', 'execution_type' => EXECUTION_TYPE_PLUGIN, 'id_plugin' => $plugin_id, 'id_modulo' => MODULE_PLUGIN, @@ -4712,6 +4723,78 @@ class AgentWizard extends HTML 'inv_critical' => false, ], ]; + + // Hash identifier. + $macros[13]['value'] = uniqid(); + + // Get input usage. + $macros[14]['value'] = 1; + + // Get output usage. + $macros[15]['value'] = 0; + + $moduleName = $name.'inUsage'; + $definition['inUsage'] = [ + 'module_name' => $moduleName, + 'module_type' => MODULE_TYPE_NUMERIC, + 'module_description' => sprintf( + '(%s%s)', + $moduleDescription, + $moduleName + ), + 'module_info' => 'Bandwidth usage received into this interface over a particular time (see interval).', + 'execution_type' => EXECUTION_TYPE_PLUGIN, + 'id_plugin' => $plugin_id, + 'id_modulo' => MODULE_PLUGIN, + 'macros' => json_encode($macros), + 'default_enabled' => true, + 'module_enabled' => false, + 'module_unit' => '%', + 'module_thresholds' => [ + 'min_warning' => '0', + 'max_warning' => '0', + 'inv_warning' => false, + 'min_critical' => '0', + 'max_critical' => '0', + 'inv_critical' => false, + ], + ]; + + // Hash identifier. + $macros[13]['value'] = uniqid(); + + // Get input usage. + $macros[14]['value'] = 0; + + // Get output usage. + $macros[15]['value'] = 1; + + $moduleName = $name.'outUsage'; + $definition['outUsage'] = [ + 'module_name' => $moduleName, + 'module_type' => MODULE_TYPE_NUMERIC, + 'module_description' => sprintf( + '(%s%s)', + $moduleDescription, + $moduleName + ), + 'module_info' => 'Bandwidth usage sent from this interface over a particular time (see interval).', + 'execution_type' => EXECUTION_TYPE_PLUGIN, + 'id_plugin' => $plugin_id, + 'id_modulo' => MODULE_PLUGIN, + 'macros' => json_encode($macros), + 'default_enabled' => true, + 'module_enabled' => false, + 'module_unit' => '%', + 'module_thresholds' => [ + 'min_warning' => '0', + 'max_warning' => '0', + 'inv_warning' => false, + 'min_critical' => '0', + 'max_critical' => '0', + 'inv_critical' => false, + ], + ]; } } diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index a377d4a72d..b178702bc0 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -1743,7 +1743,7 @@ SET @plugin_name = 'Network bandwidth SNMP'; SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; -INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_''); +INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"},\"14\":{\"macro\":\"_field14_\",\"desc\":\"inUsage\",\"help\":\"Retrieve input usage (%)\",\"value\":\"\",\"hide\":\"\"},\"15\":{\"macro\":\"_field15_\",\"desc\":\"outUsage\",\"help\":\"Retrieve output usage (%)\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_'; -inUsage '_field14_' -outUsage '_field15_''); SET @main_component_group_name = 'Wizard'; SET @component_id = ''; diff --git a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl index d6edf5d897..ad0f6c8899 100644 --- a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl +++ b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl @@ -2,12 +2,12 @@ # ################################################################################ # -# Bandwith plugin -# +# Bandwith usage plugin +# # Requirements: # snmpget # snmpwalk -# +# # (c) Fco de Borja Sanchez # # 2018/06/27 @@ -45,18 +45,20 @@ Where OPTIONS could be: -port target port (161) [SNMPv3] - -securityName - -context - -securityLevel - -authProtocol - -authKey - -privProtocol + -securityName + -context + -securityLevel + -authProtocol + -authKey + -privProtocol -privKey [EXTRA] -ifIndex Target interface to retrieve, if not specified, total bandwith will be reported. -uniqid Use custom temporary file name. + -inUsage Show only input usage (in percentage) - 1, or not 0. + -outUsage Show only output usage (in percentage) - 1, or not 0. Note: You can also use snmpget/snmpwalk argument notation, e.g. -v is equal to -version, -c to -community, etc. @@ -125,9 +127,15 @@ sub update_config_key ($) { if ($arg eq 'ifIndex') { return "ifIndex"; } -if ($arg eq 'uniqid') { - return "uniqid"; -} + if ($arg eq 'uniqid') { + return "uniqid"; + } + if ($arg eq 'inUsage') { + return "inUsage"; + } + if ($arg eq 'outUsage') { + return "outUsage"; + } } ################################################################################ @@ -152,7 +160,7 @@ sub prepare_tree { my $raw = snmp_walk(\%snmp_call); return $raw if (ref($raw) eq "HASH"); - + my @data = split /\n/, $raw; foreach my $it (@data) { my ($key, $value) = split /=/, $it; @@ -227,7 +235,7 @@ sub prepare_tree { } else { $duplex = int $duplex->{'data'}; } - + } else { # Ignore, cannot retrieve inOctets. next; @@ -329,7 +337,7 @@ sub save_data { open($_f, ">$config->{'tmp_file'}") or die('Cannot open ' . $config->{'tmp_file'}); }; if( $@ ) { - logger($config, 'info', "Cannot save stats, please check writting permissions on [" . $config->{'tmp_file'} . "]"); + logger($config, 'info', "Cannot save stats, please check writting permissions on [" . $config->{'tmp_file'} . "]") if (is_enabled($config->{'debug'})); return; } @@ -343,7 +351,7 @@ sub save_data { # Iface. print $_f $iface . $config->{'tmp_separator'}; - + # InOctets. print $_f $tree->{$iface}{'now'}{'inOctets'} . $config->{'tmp_separator'}; @@ -359,9 +367,9 @@ sub save_data { } ################################################################################ -# Calculate bandwidth +# Calculate bandwidth usage ################################################################################ -sub get_bandwidth { +sub get_bandwidth_usage { my ($config, $tree) = @_; foreach my $iface (keys %{$tree}) { @@ -375,6 +383,8 @@ sub get_bandwidth { my $output = $tree->{$iface}{'now'}{'outOctets'} - $tree->{$iface}{'old'}{'outOctets'}; my $delta = $tree->{$iface}{'now'}{'timestamp'} - $tree->{$iface}{'old'}{'timestamp'}; my $bandwidth = 0; + my $inUsage = 0; + my $outUsage = 0; $tree->{$iface}->{'delta'} = { 'inOctets' => $input, @@ -385,7 +395,7 @@ sub get_bandwidth { $tree->{$iface}->{'speed'} = $speed; if (($speed > 0) && ($delta > 0)) { - # Information about bandwidth calculation: https://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/8141-calculate-bandwidth-snmp.html + # Information about bandwidth usage calculation: https://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/8141-calculate-bandwidth-snmp.html if ($tree->{$iface}{'duplex'} == HALF_DUPLEX || $tree->{$iface}{'duplex'} == UNKNOWN_DUPLEX ) { @@ -398,26 +408,40 @@ sub get_bandwidth { } else { no warnings "uninitialized"; - logger($config, 'info', "Failed to calculate bandwidth, unknown duplex mode: [" . $tree->{$iface}{'duplex_mode'} . "]"); + logger($config, 'info', "Failed to calculate bandwidth usage, unknown duplex mode: [" . $tree->{$iface}{'duplex_mode'} . "]") if (is_enabled($config->{'debug'})); } + + $inUsage = ($input * 8) / ($delta * $speed); + $outUsage = ($output * 8) / ($delta * $speed); + + if ($inUsage > 1) { + $inUsage = 1; + logger($config, 'info', "Max input usage exceeded: $inUsage") if (is_enabled($config->{'debug'})); + } + if ($outUsage > 1) { + $outUsage = 1; + logger($config, 'info', "Max output usage exceeded: $outUsage") if (is_enabled($config->{'debug'})); + } + } else { - logger($config, 'info', "Failed to calculate bandwidth, interface [" . $iface . "] speed is 0"); + logger($config, 'info', "Failed to calculate bandwidth usage, interface [" . $iface . "] speed is 0") if (is_enabled($config->{'debug'})); } - $tree->{$iface}->{'bandwidth'} = 100 * $bandwidth; + $tree->{$iface}->{'bandwidth'} = 100 * $bandwidth; + $tree->{$iface}->{'inUsage'} = 100 * $inUsage; + $tree->{$iface}->{'outUsage'} = 100 * $outUsage; + } } - ################################################################################ # # MAIN # ################################################################################ - if ($#ARGV < 0) { print $HELP; exit 0; @@ -500,11 +524,11 @@ if ($#only_int >= 0) { $config->{'only_interfaces'} = \@only_int; } -logger($config, 'info', "Plugin starts"); +logger($config, 'info', "Plugin starts") if (is_enabled($config->{'debug'})); if (is_enabled($config->{'debug'})) { eval { eval "use Data::Dumper;1;";if($@) {} - logger($config, Dumper($config)); + logger($config, Dumper($config)) if (is_enabled($config->{'debug'})); }; if($@) {} } @@ -512,30 +536,53 @@ if (is_enabled($config->{'debug'})) { my $analysis_tree = prepare_tree($config); if (!empty($analysis_tree->{'error'})) { - logger($config, 'info', "Failed: " . $analysis_tree->{'error'}); + logger($config, 'info', "Failed: " . $analysis_tree->{'error'}) if (is_enabled($config->{'debug'})); exit 0; } else { - get_bandwidth($config, $analysis_tree); + get_bandwidth_usage($config, $analysis_tree); } # Report data my @modules; my $bandwidth = 0; +my $inUsage = 0; +my $outUsage = 0; my $i = 0; +my $j = 0; +my $k = 0; foreach my $iface (keys %{$analysis_tree}) { # Calculate summary; if (is_enabled($analysis_tree->{$iface}{'bandwidth'})) { $bandwidth = $analysis_tree->{$iface}{'bandwidth'}; $i++; } + if (is_enabled($analysis_tree->{$iface}{'inUsage'})) { + $inUsage = $analysis_tree->{$iface}{'inUsage'}; + $j++; + } + if (is_enabled($analysis_tree->{$iface}{'outUsage'})) { + $outUsage = $analysis_tree->{$iface}{'outUsage'}; + $k++; + } } -if ($i > 0) { - $bandwidth /= $i; - print sprintf("%.9f\n", $bandwidth); +if ($j > 0 && is_enabled($config->{'inUsage'})) { + $inUsage /= $j; + print sprintf("%.9f\n", $inUsage); +} elsif ($k > 0 && is_enabled($config->{'outUsage'})) { + $outUsage /= $k; + print sprintf("%.9f\n", $outUsage); } -logger($config, 'info', "Plugin ends"); +if ($i > 0 + && !is_enabled($config->{'inUsage'}) + && !is_enabled($config->{'outUsage'}) +) { + $bandwidth /= $i; + print sprintf("%.9f\n", $bandwidth); +} + +logger($config, 'info', "Plugin ends") if (is_enabled($config->{'debug'})); From 416bc8cad49f612a0dcd9331161323be06e6aba7 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 16 Feb 2021 12:33:15 +0100 Subject: [PATCH 041/112] Minor fixes and speed out of control --- pandora_console/extras/mr/45.sql | 2 +- .../pandoradb_migrate_6.0_to_7.0.mysql.sql | 2 +- .../include/class/AgentWizard.class.php | 20 +++++++++++++------ pandora_console/pandoradb_data.sql | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/pandora_console/extras/mr/45.sql b/pandora_console/extras/mr/45.sql index 50b853ac64..e8c2e1c39b 100644 --- a/pandora_console/extras/mr/45.sql +++ b/pandora_console/extras/mr/45.sql @@ -4,6 +4,6 @@ SET @plugin_name = 'Network bandwidth SNMP'; SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; -INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"},\"14\":{\"macro\":\"_field14_\",\"desc\":\"inUsage\",\"help\":\"Retrieve input usage (%)\",\"value\":\"\",\"hide\":\"\"},\"15\":{\"macro\":\"_field15_\",\"desc\":\"outUsage\",\"help\":\"Retrieve output usage (%)\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_'; -inUsage '_field14_' -outUsage '_field15_''); +INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"},\"14\":{\"macro\":\"_field14_\",\"desc\":\"inUsage\",\"help\":\"Retrieve input usage (%)\",\"value\":\"\",\"hide\":\"\"},\"15\":{\"macro\":\"_field15_\",\"desc\":\"outUsage\",\"help\":\"Retrieve output usage (%)\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_' -inUsage '_field14_' -outUsage '_field15_''); COMMIT; 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 c59867ee31..7c7d7b3d22 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 @@ -2878,7 +2878,7 @@ SET @plugin_name = 'Network bandwidth SNMP'; SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; -INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"},\"14\":{\"macro\":\"_field14_\",\"desc\":\"inUsage\",\"help\":\"Retrieve input usage (%)\",\"value\":\"\",\"hide\":\"\"},\"15\":{\"macro\":\"_field15_\",\"desc\":\"outUsage\",\"help\":\"Retrieve output usage (%)\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_'; -inUsage '_field14_' -outUsage '_field15_''); +INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"},\"14\":{\"macro\":\"_field14_\",\"desc\":\"inUsage\",\"help\":\"Retrieve input usage (%)\",\"value\":\"\",\"hide\":\"\"},\"15\":{\"macro\":\"_field15_\",\"desc\":\"outUsage\",\"help\":\"Retrieve output usage (%)\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_' -inUsage '_field14_' -outUsage '_field15_''); SET @main_component_group_name = 'Wizard'; SET @component_id = ''; diff --git a/pandora_console/include/class/AgentWizard.class.php b/pandora_console/include/class/AgentWizard.class.php index 6810244320..9ba6f4e0f1 100644 --- a/pandora_console/include/class/AgentWizard.class.php +++ b/pandora_console/include/class/AgentWizard.class.php @@ -4458,11 +4458,16 @@ class AgentWizard extends HTML // IfOperStatus. $adminStatusValue = 1; + $speed = 0; if (empty($data) === false) { $adminStatusValue = $this->snmpGetValue( '1.3.6.1.2.1.2.2.1.7.'.$value ); + $speed = $this->snmpGetValue( + '.1.3.6.1.2.1.2.2.1.5.'.$value + ); + preg_match('/\((\d+?)\)/', $adminStatusValue, $match); $adminStatusValue = (int) $match[1]; } @@ -4702,9 +4707,10 @@ class AgentWizard extends HTML 'module_name' => $moduleName, 'module_type' => MODULE_TYPE_NUMERIC, 'module_description' => sprintf( - '(%s%s)', + '(%s%s - Speed:%d)', $moduleDescription, - $moduleName + $moduleName, + $speed ), 'module_info' => 'Amount of digital information sent and received from this interface over a particular time (see interval).', 'execution_type' => EXECUTION_TYPE_PLUGIN, @@ -4738,9 +4744,10 @@ class AgentWizard extends HTML 'module_name' => $moduleName, 'module_type' => MODULE_TYPE_NUMERIC, 'module_description' => sprintf( - '(%s%s)', + '(%s%s - Speed:%d)', $moduleDescription, - $moduleName + $moduleName, + $speed ), 'module_info' => 'Bandwidth usage received into this interface over a particular time (see interval).', 'execution_type' => EXECUTION_TYPE_PLUGIN, @@ -4774,9 +4781,10 @@ class AgentWizard extends HTML 'module_name' => $moduleName, 'module_type' => MODULE_TYPE_NUMERIC, 'module_description' => sprintf( - '(%s%s)', + '(%s%s - Speed:%d)', $moduleDescription, - $moduleName + $moduleName, + $speed ), 'module_info' => 'Bandwidth usage sent from this interface over a particular time (see interval).', 'execution_type' => EXECUTION_TYPE_PLUGIN, diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index b178702bc0..bb67048661 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -1743,7 +1743,7 @@ SET @plugin_name = 'Network bandwidth SNMP'; SET @plugin_description = 'Retrieves amount of digital information sent and received from device or filtered interface index over a particular time (agent/module interval).'; SET @plugin_id = ''; SELECT @plugin_id := `id` FROM `tplugin` WHERE `name` = @plugin_name; -INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"},\"14\":{\"macro\":\"_field14_\",\"desc\":\"inUsage\",\"help\":\"Retrieve input usage (%)\",\"value\":\"\",\"hide\":\"\"},\"15\":{\"macro\":\"_field15_\",\"desc\":\"outUsage\",\"help\":\"Retrieve output usage (%)\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_'; -inUsage '_field14_' -outUsage '_field15_''); +INSERT IGNORE INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`) VALUES (@plugin_id,@plugin_name,@plugin_description,300,0,'perl /usr/share/pandora_server/util/plugin/pandora_snmp_bandwidth.pl','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"SNMP Version(1,2c,3)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Community\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Host\",\"help\":\"\",\"value\":\"_address_\",\"hide\":\"\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Port\",\"help\":\"\",\"value\":\"161\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Interface Index (filter)\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"6\":{\"macro\":\"_field6_\",\"desc\":\"securityName\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"7\":{\"macro\":\"_field7_\",\"desc\":\"context\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"8\":{\"macro\":\"_field8_\",\"desc\":\"securityLevel\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"9\":{\"macro\":\"_field9_\",\"desc\":\"authProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"10\":{\"macro\":\"_field10_\",\"desc\":\"authKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"11\":{\"macro\":\"_field11_\",\"desc\":\"privProtocol\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"12\":{\"macro\":\"_field12_\",\"desc\":\"privKey\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"13\":{\"macro\":\"_field13_\",\"desc\":\"UniqId\",\"help\":\"This plugin needs to store information in temporary directory to calculate bandwidth. Set here an unique identifier with no spaces or symbols.\",\"value\":\"\",\"hide\":\"\"},\"14\":{\"macro\":\"_field14_\",\"desc\":\"inUsage\",\"help\":\"Retrieve input usage (%)\",\"value\":\"\",\"hide\":\"\"},\"15\":{\"macro\":\"_field15_\",\"desc\":\"outUsage\",\"help\":\"Retrieve output usage (%)\",\"value\":\"\",\"hide\":\"\"}}','-version '_field1_' -community '_field2_' -host '_field3_' -port '_field4_' -ifIndex '_field5_' -securityName '_field6_' -context '_field7_' -securityLevel '_field8_' -authProtocol '_field9_' -authKey '_field10_' -privProtocol '_field11_' -privKey '_field12_' -uniqid '_field13_' -inUsage '_field14_' -outUsage '_field15_''); SET @main_component_group_name = 'Wizard'; SET @component_id = ''; From 4b0f96126bf2fba378b0d166cf73aca50f41f9bd Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 22 Feb 2021 12:25:24 +0100 Subject: [PATCH 042/112] minor fix --- pandora_console/include/functions_config.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index ac24435712..95265cebff 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -1469,7 +1469,11 @@ function config_update_config() ) { // Same definition for active and historical database! // This is a critical error. - $errors[] = __('Active and historical database cannot be the same.'); + $config['error_config_update_config']['correct'] = false; + $config['error_config_update_config']['message'] = __( + 'Active and historical database cannot be the same.' + ); + return; } else { if (!config_update_value('history_db_host', get_parameter('history_db_host'))) { $error_update[] = __('Host'); From f84d7a413e257f3e21890851305c9ac4c12ba9d1 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 25 Feb 2021 12:08:58 +0100 Subject: [PATCH 043/112] POST/GET reloaded if empty in ajax --- pandora_console/ajax.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pandora_console/ajax.php b/pandora_console/ajax.php index 9b59695555..eaeec43ed6 100644 --- a/pandora_console/ajax.php +++ b/pandora_console/ajax.php @@ -64,6 +64,15 @@ if (isset($config['console_log_enabled']) === true ini_set('error_log', 0); } +// Sometimes input is badly retrieved from caller... +if (empty($_REQUEST) === true) { + $data = explode('&', urldecode(file_get_contents('php://input'))); + foreach ($data as $d) { + $r = explode('=', $d, 2); + $_REQUEST[$r[0]] = $r[1]; + } +} + // Hash login process. if (isset($_GET['loginhash']) === true) { $loginhash_data = get_parameter('loginhash_data', ''); From 8fcac749f5954ad95dbc198bb9ed0d658ef9fca0 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 25 Feb 2021 12:09:41 +0100 Subject: [PATCH 044/112] POST/GET reloaded if empty in ajax --- pandora_console/ajax.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandora_console/ajax.php b/pandora_console/ajax.php index eaeec43ed6..b653fbd5c5 100644 --- a/pandora_console/ajax.php +++ b/pandora_console/ajax.php @@ -69,7 +69,8 @@ if (empty($_REQUEST) === true) { $data = explode('&', urldecode(file_get_contents('php://input'))); foreach ($data as $d) { $r = explode('=', $d, 2); - $_REQUEST[$r[0]] = $r[1]; + $_POST[$r[0]] = $r[1]; + $_GET[$r[0]] = $r[1]; } } From f445ddc9eaa011ccdfcd8507991da1356e6f8994 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Fri, 5 Mar 2021 14:11:08 +0100 Subject: [PATCH 045/112] Fixed refresh auto hide on visual c --- pandora_console/operation/visual_console/view.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandora_console/operation/visual_console/view.php b/pandora_console/operation/visual_console/view.php index 7e39f2c856..169238db6b 100644 --- a/pandora_console/operation/visual_console/view.php +++ b/pandora_console/operation/visual_console/view.php @@ -422,6 +422,8 @@ ui_require_css_file('form'); var props = ; var items = ; var baseUrl = ""; + var controls = document.getElementById('vc-controls'); + autoHideElement(controls, 1000); var handleUpdate = function (prevProps, newProps) { if (!newProps) return; From b63f1ad681b587e51d39ab0b707279714419541e Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 15 Mar 2021 10:07:36 +0100 Subject: [PATCH 046/112] Removed extra verbosity --- pandora_console/operation/events/events_rss.php | 2 +- pandora_console/ws.php | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/pandora_console/operation/events/events_rss.php b/pandora_console/operation/events/events_rss.php index f6a155e676..613b88b423 100644 --- a/pandora_console/operation/events/events_rss.php +++ b/pandora_console/operation/events/events_rss.php @@ -30,7 +30,7 @@ global $config; // Don't display other errors, messes up XML. -ini_set('display_errors', E_ALL); +ini_set('display_errors', 0); require_once '../../include/config.php'; require_once '../../include/functions.php'; diff --git a/pandora_console/ws.php b/pandora_console/ws.php index 0c9509720c..e873cdf7f2 100644 --- a/pandora_console/ws.php +++ b/pandora_console/ws.php @@ -91,10 +91,6 @@ if (isset($config['gotty']) === false) { config_update_value('gotty', '/usr/bin/gotty'); } - -ini_set('display_errors', 1); -error_reporting(E_ALL); - $os = strtolower(PHP_OS); if (substr($os, 0, 3) !== 'win') { if (empty($config['gotty']) === false) { From 1762e758fa6ee8eebcd8c2f5dd65b3d659da482f Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 15 Mar 2021 10:09:02 +0100 Subject: [PATCH 047/112] forced no display_errors --- pandora_console/include/config_process.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 1f0f644a72..83ddd741aa 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -52,6 +52,10 @@ if ((int) $develop_bypass === 1) { } ini_set('display_errors', 1); +} else { + // Leave user decide error_level, but limit errors to be displayed only in + // logs. + ini_set('display_errors', 0); } // Check if mysqli is available From 4c5f220264e5702f015a67d38b626ac8a529d62b Mon Sep 17 00:00:00 2001 From: marcos Date: Mon, 15 Mar 2021 17:55:54 +0100 Subject: [PATCH 048/112] fixed visual error --- pandora_console/include/class/AgentsAlerts.class.php | 2 +- pandora_console/include/functions_html.php | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/class/AgentsAlerts.class.php b/pandora_console/include/class/AgentsAlerts.class.php index 41a75ffa8a..b63860f84d 100644 --- a/pandora_console/include/class/AgentsAlerts.class.php +++ b/pandora_console/include/class/AgentsAlerts.class.php @@ -651,7 +651,7 @@ class AgentsAlerts extends HTML $alias = db_get_row('tagente', 'id_agente', $agent['id_agente']); echo ''; // Name of the agent. - echo ''.$alias['alias'].''; + echo ''.$alias['alias'].''; // Alerts of the agent. foreach ($templates as $tid => $tname) { $anyfired = 0; diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index adb1fd9b9d..cde4a9e867 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -467,10 +467,9 @@ function html_print_select_groups( $output = ''; global $config; + $select2_css = 'select2.min'; - if ($config['style'] === 'pandora') { - $select2_css = 'select2.min'; - } else { + if ($config['style'] === 'pandora_black') { $select2_css = 'select2_dark.min'; } From 38695482c067dd8851c9db5b6374107d1c8a0d10 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 18 Mar 2021 10:35:41 +0100 Subject: [PATCH 049/112] Validate custom text --- pandora_console/include/functions_html.php | 28 +++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index c2ec13be47..ae83820bd6 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -577,7 +577,7 @@ function html_print_select_groups( ); if ($required !== false) { - $require_message = __('Please select an item from this list.'); + $require_message = __('Please select an item from this list. Madafaka'); } if (empty($size) === true) { @@ -599,13 +599,6 @@ function html_print_select_groups( $(document).ready(function() { $('select[name=""]').each( function() { - - this.setCustomValidity(''); - $(this).select2({ multiple: , placeholder: "", @@ -640,6 +633,25 @@ function html_print_select_groups( } } }); + + + $(this).on('change', function(e) { + e.currentTarget.setCustomValidity(''); + }) + + $(this).on('invalid', function(e) { + if ($(e.currentTarget).val() == null) { + e.currentTarget.setCustomValidity( + '' + ); + } + }) + + } ); From 9040e832b847d3773bb7be7d75c49dc177c9df68 Mon Sep 17 00:00:00 2001 From: Marcos Alconada Date: Thu, 18 Mar 2021 10:00:34 +0000 Subject: [PATCH 050/112] fixed xss vulnerability --- .../include/functions_notifications.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pandora_console/include/functions_notifications.php b/pandora_console/include/functions_notifications.php index d7b2f8236a..ef30d852f0 100644 --- a/pandora_console/include/functions_notifications.php +++ b/pandora_console/include/functions_notifications.php @@ -1080,6 +1080,27 @@ function notifications_print_dropdown_element($message_info) break; } + $split_subject = explode(' ', io_safe_output($message_info['subject'])); + $is_image = false; + $img = ''; + foreach ($split_subject as $item) { + if ($is_image) { + if (preg_match('/src/', $item)) { + $img .= $item.' >'; + $is_image = false; + } + } + + if (preg_match('/img/', $item)) { + $img = ' Date: Thu, 18 Mar 2021 10:01:21 +0000 Subject: [PATCH 051/112] Fixed api agent delete and show correct message when called by meta wizard --- pandora_console/include/functions_api.php | 26 +++++++++++++++++------ 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index cfccd66a9c..aebef6c06b 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -1864,10 +1864,14 @@ function api_get_custom_field_id($t1, $t2, $other, $returnType) * @param $thrast2 Don't use. * @param $thrash3 Don't use. */ -function api_set_delete_agent($id, $thrash1, $other, $thrash3) +function api_set_delete_agent($id, $thrash1, $other, $returnType) { global $config; + if (empty($returnType)) { + $returnType = 'string'; + } + $agent_by_alias = false; if ($other['data'][0] === '1') { @@ -1910,7 +1914,7 @@ function api_set_delete_agent($id, $thrash1, $other, $thrash3) } else { // Delete only if the centralised mode is disabled. $headers = getallheaders(); - if (isset($headers['idk']) === false || is_management_allowed($headers['idk']) === false) { + if (isset($headers['idk']) === false && is_management_allowed($headers['idk']) === false) { returnError('centralized'); exit; } @@ -1934,19 +1938,27 @@ function api_set_delete_agent($id, $thrash1, $other, $thrash3) } } } else { - $idAgent = agents_get_agent_id($id, true); + $idAgent = agents_get_agent_id($id, false); if (!util_api_check_agent_and_print_error($idAgent, 'string', 'AD')) { return; } - $result = agents_delete_agent($idAgent, true); + $result = agents_delete_agent($idAgent, false); } } - if (!$result) { - returnError('The agent could not be deleted'); + if ($result === false) { + if ($returnType !== 'string') { + return false; + } + + returnError('The agent could not be deleted', $returnType); } else { - returnData('string', ['type' => 'string', 'data' => __('The agent was successfully deleted')]); + if ($returnType !== 'string') { + return true; + } + + returnData($returnType, ['type' => 'string', 'data' => __('The agent was successfully deleted')]); } } From ddb58f56e97b6beb75221577d8aba2982f41be2c Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 18 Mar 2021 11:48:52 +0100 Subject: [PATCH 052/112] errata fix --- pandora_console/include/functions_html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index ae83820bd6..e7b8e246c4 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -577,7 +577,7 @@ function html_print_select_groups( ); if ($required !== false) { - $require_message = __('Please select an item from this list. Madafaka'); + $require_message = __('Please select an item from this list.'); } if (empty($size) === true) { From bfaaba9dbd1ea17683a39d8212c5632d5e298eb6 Mon Sep 17 00:00:00 2001 From: marcos Date: Thu, 18 Mar 2021 12:08:02 +0100 Subject: [PATCH 053/112] fixed spinner bug --- pandora_console/include/functions_snmp_browser.php | 6 +++--- pandora_console/include/styles/pandora.css | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/functions_snmp_browser.php b/pandora_console/include/functions_snmp_browser.php index 5c55dd4e69..54bc1a5ce6 100644 --- a/pandora_console/include/functions_snmp_browser.php +++ b/pandora_console/include/functions_snmp_browser.php @@ -1065,16 +1065,16 @@ function snmp_browser_print_container( ); $output .= '
'; - $output .= '
'.html_print_image('images/spinner.gif', true).'
'; + $output .= ''; $output .= '
'; $output .= '
'; - $output .= '
'; + $output .= '
'; $output .= '
'; $output .= '
'; $output .= '
'; if ($show_massive_buttons) { - $output .= '