From dec77331486cf75aa82337f41ee5d9c9be11956f Mon Sep 17 00:00:00 2001 From: marcos Date: Wed, 12 Feb 2020 11:47:43 +0100 Subject: [PATCH 001/296] 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/296] 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/296] 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 a90aeb14ff1bb9f3c330c44e21330a648e0eaac9 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Wed, 2 Dec 2020 11:45:54 +0100 Subject: [PATCH 004/296] Fixed services ACL on services treeview --- .../include/class/TreeService.class.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/class/TreeService.class.php b/pandora_console/include/class/TreeService.class.php index 0afa46af73..286540b8c4 100644 --- a/pandora_console/include/class/TreeService.class.php +++ b/pandora_console/include/class/TreeService.class.php @@ -342,6 +342,8 @@ class TreeService extends Tree */ protected function getSecondLevel() { + global $config; + $service = new Service($this->id, true); $output = []; @@ -422,7 +424,13 @@ class TreeService extends Tree } $tmp['children'] = []; - $tmp['searchChildren'] = 1; + + if (check_acl($config['id_user'], $item->agent()->id_grupo(), 'AR')) { + $tmp['searchChildren'] = 1; + } else { + $tmp['searchChildren'] = 0; + } + $tmp['showEventsBtn'] = 1; $tmp['eventAgent'] = $item->agent()->id_agente(); break; @@ -532,7 +540,9 @@ class TreeService extends Tree ); } - $grandchildren = $item->service()->children(); + if (check_acl($config['id_user'], $item->service()->id_group(), 'AR')) { + $grandchildren = $item->service()->children(); + } if ($this->connectedToNode === false && is_metaconsole() === true From d3a3a74cebf334508c8c1e4c7a4f31d7c4c560bb Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Thu, 3 Dec 2020 10:31:25 +0100 Subject: [PATCH 005/296] Fix item sql query remove fields --- .../godmode/reporting/reporting_builder.item_editor.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index 1a3249a306..85728d9031 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -5403,11 +5403,9 @@ function chooseType() { case 'sql': $("#row_description").show(); $("#row_query").show(); - $("#row_max_items").show(); $("#row_header").show(); $("#row_custom").show(); $("#row_custom_example").show(); - $("#row_dyn_height").show(); $("#row_servers").show(); $("#row_historical_db_check").show(); break; From 244c4d56d6f0b51926483094a3b17a7990373b02 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Fri, 4 Dec 2020 12:32:38 +0100 Subject: [PATCH 006/296] Fixed unit --- .../godmode/agentes/configurar_agente.php | 4 ++++ .../agentes/module_manager_editor_common.php | 22 +++++++++---------- pandora_console/include/functions_html.php | 1 - pandora_console/include/javascript/pandora.js | 6 +++-- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 422d4d0f13..81dfa9ffa6 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -1404,6 +1404,10 @@ if ($update_module || $create_module) { $each_ff = (int) get_parameter('each_ff', $module['each_ff']); $ff_timeout = (int) get_parameter('ff_timeout'); $unit = (string) get_parameter('unit'); + if ($unit === '0') { + $unit = ''; + } + $id_tag = (array) get_parameter('id_tag_selected'); $serialize_ops = (string) get_parameter('serialize_ops'); $critical_instructions = (string) get_parameter('critical_instructions'); diff --git a/pandora_console/godmode/agentes/module_manager_editor_common.php b/pandora_console/godmode/agentes/module_manager_editor_common.php index 64bb89a565..5fbe4343cb 100644 --- a/pandora_console/godmode/agentes/module_manager_editor_common.php +++ b/pandora_console/godmode/agentes/module_manager_editor_common.php @@ -548,17 +548,17 @@ $table_advanced->data[0][4] = html_print_input_text( $classdisabledBecauseInPolicy ); // $table_advanced->colspan[1][4] = 3; -// $table_advanced->data[0][4] = html_print_extended_select_for_unit( -// 'unit', -// $unit, -// '', -// '', -// '0', -// false, -// true, -// false, -// false -// ); +$table_advanced->data[0][4] = html_print_extended_select_for_unit( + 'unit', + $unit, + '', + 'none', + '0', + false, + true, + false, + false +); $table_advanced->colspan[0][4] = 3; $module_id_policy_module = 0; diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index 3edbea17d3..fadc9c4cc7 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -1481,7 +1481,6 @@ function html_print_extended_select_for_unit( // $fields = post_process_get_custom_values(); $fields['_timeticks_'] = 'Timeticks'; - $fields['none'] = __('none'); $default_module_custom_units = get_custom_module_units(); diff --git a/pandora_console/include/javascript/pandora.js b/pandora_console/include/javascript/pandora.js index 04a8f5336e..52cf12992d 100644 --- a/pandora_console/include/javascript/pandora.js +++ b/pandora_console/include/javascript/pandora.js @@ -724,12 +724,14 @@ function post_process_select_init_unit(name, selected) { ); $("#text-" + name + "_text").val(""); } else { - $("#" + name + "_select option[value=none]").attr("selected", true); + $("#" + name + "_select option[value=0]").attr("selected", true); $("#" + name + "_default").hide(); $("#" + name + "_manual").show(); } } else { - $("#" + name + "_select option[value=none]").attr("selected", true); + $("#" + name + "_select option[value=0]").attr("selected", true); + $("#" + name + "_default").hide(); + $("#" + name + "_manual").show(); } $("#" + name + "_select").change(function() { From 90b9ace749a3f4fcaabacf15e4c69de9988c96f3 Mon Sep 17 00:00:00 2001 From: alejandro-campos Date: Fri, 4 Dec 2020 13:41:06 +0100 Subject: [PATCH 007/296] added number limitation for operation of adding agents to policy in metaconsole --- pandora_console/include/constants.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index 66b784d712..a186e656cf 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -476,6 +476,8 @@ define('MODULE_LINKED', 1); define('MODULE_PENDING_UNLINK', 10); define('MODULE_PENDING_LINK', 11); +define('POLICY_ADD_MAX_AGENTS', 200); + // EVENTS. define('EVENTS_GOING_UNKNOWN', 'going_unknown'); define('EVENTS_UNKNOWN', 'unknown'); From 7ec1978f4191c419abd205812d87c00f97a44d90 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Wed, 9 Dec 2020 11:48:32 +0100 Subject: [PATCH 008/296] Fixed update_user --- pandora_console/include/functions.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index f79c56b764..4a7ca04ca7 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -424,16 +424,6 @@ function get_user_language($id_user=null) if ($quick_language) { $language = get_parameter('language', 0); - if (defined('METACONSOLE')) { - if ($id_user == null) { - $id_user = $config['id_user']; - } - - if ($language !== 0) { - update_user($id_user, ['language' => $language]); - } - } - if ($language === 'default') { return $config['language']; } From aa52ab01df9dd091ba56ea368516d4879392c638 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Wed, 9 Dec 2020 14:05:40 +0100 Subject: [PATCH 009/296] Fix loading charts modules and interfaces --- pandora_console/images/spinner_charts.gif | Bin 0 -> 55605 bytes pandora_console/include/ajax/module.php | 238 +++++++++++++++--- .../include/graphs/flot/pandora.flot.js | 13 - .../include/graphs/functions_flot.php | 19 +- .../lib/Dashboard/Widgets/custom_graph.php | 6 +- .../lib/Dashboard/Widgets/single_graph.php | 1 + pandora_console/include/styles/pandora.css | 14 ++ .../agentes/interface_traffic_graph_win.php | 67 +++-- .../operation/agentes/stat_win.php | 108 ++++---- 9 files changed, 341 insertions(+), 125 deletions(-) create mode 100644 pandora_console/images/spinner_charts.gif diff --git a/pandora_console/images/spinner_charts.gif b/pandora_console/images/spinner_charts.gif new file mode 100644 index 0000000000000000000000000000000000000000..e092d812896908cc485f7631a7578080a0361ad3 GIT binary patch literal 55605 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[0][1] = html_print_select($periods, 'period', $period, '', '', 0, true, false, false); + $formtable->data[0][1] = html_print_select( + $periods, + 'period', + $period, + '', + '', + 0, + true, + false, + false + ); $formtable->data[0][2] = ''; $formtable->data[0][3] = "".html_print_image('images/refresh.png', true, ['style' => 'vertical-align: middle;', 'border' => '0' ]).''; $formtable->rowspan[0][3] = 2; @@ -248,8 +290,20 @@ if (check_login()) { $freesearch_object = ''; if (preg_match('/_string/', $moduletype_name)) { $formtable->data[2][0] = __('Free search').' '; - $formtable->data[2][1] = html_print_input_text('freesearch', $freesearch, '', 20, null, true); - $formtable->data[2][2] = html_print_checkbox('free_checkbox', 1, $free_checkbox, true); + $formtable->data[2][1] = html_print_input_text( + 'freesearch', + $freesearch, + '', + 20, + null, + true + ); + $formtable->data[2][2] = html_print_checkbox( + 'free_checkbox', + 1, + $free_checkbox, + true + ); $formtable->data[2][2] .= ' '.__('Exact phrase'); $freesearch_object = json_encode( [ @@ -359,8 +413,16 @@ if (check_login()) { 'web_content_string' ); - $post_process = db_get_value_filter('post_process', 'tagente_modulo', ['id_agente_modulo' => $module_id]); - $unit = db_get_value_filter('unit', 'tagente_modulo', ['id_agente_modulo' => $module_id]); + $post_process = db_get_value_filter( + 'post_process', + 'tagente_modulo', + ['id_agente_modulo' => $module_id] + ); + $unit = db_get_value_filter( + 'unit', + 'tagente_modulo', + ['id_agente_modulo' => $module_id] + ); foreach ($result as $row) { $data = []; @@ -400,32 +462,65 @@ if (check_login()) { // Fixed the data from Selenium Plugin. if ($row[$attr[0]] != strip_tags($row[$attr[0]])) { $data[] = html_print_result_div($row[$attr[0]]); - } else if (is_numeric($row[$attr[0]]) && !modules_is_string_type($row['module_type'])) { + } else if (is_numeric($row[$attr[0]]) + && !modules_is_string_type($row['module_type']) + ) { switch ($row['module_type']) { case 15: - $value = db_get_value('snmp_oid', 'tagente_modulo', 'id_agente_modulo', $module_id); + $value = db_get_value( + 'snmp_oid', + 'tagente_modulo', + 'id_agente_modulo', + $module_id + ); // System Uptime: - // In case of System Uptime module, shows data in format "Days hours minutes seconds" if and only if + // In case of System Uptime module, + // shows data in format + // "Days hours minutes seconds" if and only if // selected module unit is "_timeticks_" - // Take notice that selected unit may not be postrocess unit - if ($value == '.1.3.6.1.2.1.1.3.0' || $value == '.1.3.6.1.2.1.25.1.1.0') { - $data_macro = modules_get_unit_macro($row[$attr[0]], $unit); + // Take notice that selected unit + // may not be postrocess unit. + if ($value == '.1.3.6.1.2.1.1.3.0' + || $value == '.1.3.6.1.2.1.25.1.1.0' + ) { + $data_macro = modules_get_unit_macro( + $row[$attr[0]], + $unit + ); if ($data_macro) { $data[] = $data_macro; } else { - $data[] = remove_right_zeros(number_format($row[$attr[0]], $config['graph_precision'])); + $data[] = remove_right_zeros( + number_format( + $row[$attr[0]], + $config['graph_precision'] + ) + ); } } else { - $data[] = remove_right_zeros(number_format($row[$attr[0]], $config['graph_precision'])); + $data[] = remove_right_zeros( + number_format( + $row[$attr[0]], + $config['graph_precision'] + ) + ); } break; default: - $data_macro = modules_get_unit_macro($row[$attr[0]], $unit); + $data_macro = modules_get_unit_macro( + $row[$attr[0]], + $unit + ); if ($data_macro) { $data[] = $data_macro; } else { - $data[] = remove_right_zeros(number_format($row[$attr[0]], $config['graph_precision'])); + $data[] = remove_right_zeros( + number_format( + $row[$attr[0]], + $config['graph_precision'] + ) + ); } break; } @@ -433,11 +528,16 @@ if (check_login()) { if ($row[$attr[0]] == '') { $data[] = 'No data'; } else { - $data_macro = modules_get_unit_macro($row[$attr[0]], $unit); + $data_macro = modules_get_unit_macro( + $row[$attr[0]], + $unit + ); if ($data_macro) { $data[] = $data_macro; } else { - $data[] = html_print_result_div($row[$attr[0]]); + $data[] = html_print_result_div( + $row[$attr[0]] + ); } } } @@ -453,7 +553,16 @@ if (check_login()) { if (empty($table->data)) { ui_print_error_message(__('No available data to show')); } else { - ui_pagination(count($count), false, $offset, 0, false, 'offset', true, 'binary_dialog'); + ui_pagination( + count($count), + false, + $offset, + 0, + false, + 'offset', + true, + 'binary_dialog' + ); html_print_table($table); } @@ -727,11 +836,17 @@ if (check_login()) { } } - $status_filter_monitor = (int) get_parameter('status_filter_monitor', -1); + $status_filter_monitor = (int) get_parameter( + 'status_filter_monitor', + -1 + ); $status_text_monitor = get_parameter('status_text_monitor', ''); $filter_monitors = (bool) get_parameter('filter_monitors', false); $status_module_group = get_parameter('status_module_group', -1); - $monitors_change_filter = (bool) get_parameter('monitors_change_filter', false); + $monitors_change_filter = (bool) get_parameter( + 'monitors_change_filter', + false + ); $status_filter_sql = '1 = 1'; if ($status_filter_monitor == AGENT_MODULE_STATUS_NOT_NORMAL) { @@ -787,7 +902,9 @@ if (check_login()) { AND tagente_estado.estado != $monitor_filter "; - $count_modules = db_get_all_rows_sql('SELECT COUNT(DISTINCT tagente_modulo.id_agente_modulo)'.$sql_condition); + $count_modules = db_get_all_rows_sql( + 'SELECT COUNT(DISTINCT tagente_modulo.id_agente_modulo)'.$sql_condition + ); if (isset($count_modules[0])) { $count_modules = reset($count_modules[0]); @@ -796,7 +913,7 @@ if (check_login()) { } // Get monitors/modules - // Get all module from agent + // Get all module from agent. $sql_modules_info = "SELECT tagente_estado.*, tagente_modulo.*, tmodule_group.* $sql_condition GROUP BY tagente_modulo.id_agente_modulo ORDER BY $order_sql"; @@ -1195,4 +1312,55 @@ if (check_login()) { echo $graph_type; return; } + + if ($get_graph_module === true) { + global $config; + $output = ''; + $graph_data = get_parameter('graph_data', ''); + $params = json_decode(base64_decode($graph_data), true); + $server_id = (int) get_parameter('server_id', 0); + include_once $config['homedir'].'/include/functions_graph.php'; + + // Metaconsole connection to the node. + if (is_metaconsole() === true && empty($server_id) === false) { + $server = metaconsole_get_connection_by_id($server_id); + metaconsole_connect($server); + } + + $output .= grafico_modulo_sparse($params); + echo $output; + + if (is_metaconsole() === true && empty($server_id) === false) { + metaconsole_restore_db(); + } + + return; + } + + if ($get_graph_module_interfaces === true) { + global $config; + include_once $config['homedir'].'/include/functions_graph.php'; + + $output = ''; + $graph_data = get_parameter('graph_data', ''); + $params = json_decode(base64_decode($graph_data), true); + + $modules = get_parameter('modules', ''); + $modules = json_decode(base64_decode($modules), true); + + $graph_data_combined = get_parameter('graph_data_combined', ''); + $params_combined = json_decode( + base64_decode($graph_data_combined), + true + ); + + $output .= graphic_combined_module( + $modules, + $params, + $params_combined + ); + echo $output; + + return; + } } diff --git a/pandora_console/include/graphs/flot/pandora.flot.js b/pandora_console/include/graphs/flot/pandora.flot.js index a35b5dd71b..b351637650 100644 --- a/pandora_console/include/graphs/flot/pandora.flot.js +++ b/pandora_console/include/graphs/flot/pandora.flot.js @@ -955,7 +955,6 @@ function pandoraFlotArea( legend, series_type, color, - water_mark, date_array, data_module_graph, params, @@ -972,7 +971,6 @@ function pandoraFlotArea( .shift(); var width = params.width; var vconsole = params.vconsole; - var dashboard = params.dashboard; var menu = params.menu; var min_x = date_array["start_date"] * 1000; var max_x = date_array["final_date"] * 1000; @@ -2794,17 +2792,6 @@ function pandoraFlotArea( ); adjust_menu(graph_id, plot, parent_height, width, show_legend); } - - if (!dashboard) { - if (water_mark) { - set_watermark( - graph_id, - plot, - $("#watermark_image_" + graph_id).attr("src") - ); - } - //adjust_menu(graph_id, plot, parent_height, width, show_legend); - } } function format_unit_yaxes(y) { diff --git a/pandora_console/include/graphs/functions_flot.php b/pandora_console/include/graphs/functions_flot.php index 81c9cc79cf..b682db2885 100644 --- a/pandora_console/include/graphs/functions_flot.php +++ b/pandora_console/include/graphs/functions_flot.php @@ -262,15 +262,17 @@ function flot_area_graph( $params['height'] = 1; } - if (!$vconsole) { - $return .= "
"; + if ((bool) $params['vconsole'] === false) { + $return .= '
'; + $legend_top = 10; + if (empty($params['show_legend']) === false) { + $legend_top = (20 + (count($legend) * 18)); + } - if ($water_mark != '') { - $return .= ""; - $watermark = 'true'; - } else { - $watermark = 'false'; + if ($water_mark != '' && (bool) $params['dashboard'] === false) { + $return .= '
'; + $return .= ''; + $return .= '
'; } } @@ -314,7 +316,6 @@ function flot_area_graph( $return .= $legend.", \n"; $return .= $series_type.", \n"; $return .= $color.", \n"; - $return .= $watermark.", \n"; $return .= $date_array.", \n"; $return .= $data_module_graph.", \n"; $return .= $params.", \n"; diff --git a/pandora_console/include/lib/Dashboard/Widgets/custom_graph.php b/pandora_console/include/lib/Dashboard/Widgets/custom_graph.php index b35ce233a1..3194e7b5da 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/custom_graph.php +++ b/pandora_console/include/lib/Dashboard/Widgets/custom_graph.php @@ -351,11 +351,10 @@ class CustomGraphWidget extends Widget ); $hackLegendHight = (30 * count($sources)); - if ($hackLegendHight < ($size['height'] - 10 - $hackLegendHight)) { - $height = ($size['height'] - 10 - $hackLegendHight); + if ($hackLegendHight > ($size['height'] - 10 - $hackLegendHight)) { + $height = ($size['height'] - $hackLegendHight); } else { $height = ($size['height'] - 10); - $this->values['showLegend'] = 0; } } else { $height = ($size['height'] - 10); @@ -392,6 +391,7 @@ class CustomGraphWidget extends Widget 'menu' => false, 'show_legend' => $this->values['showLegend'], 'vconsole' => true, + 'dashboard' => true, ]; $params_combined = [ diff --git a/pandora_console/include/lib/Dashboard/Widgets/single_graph.php b/pandora_console/include/lib/Dashboard/Widgets/single_graph.php index e4e3462024..431cc8fb87 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/single_graph.php +++ b/pandora_console/include/lib/Dashboard/Widgets/single_graph.php @@ -373,6 +373,7 @@ class SingleGraphWidget extends Widget 'show_legend' => $this->values['showLegend'], 'show_title' => $module_name, 'menu' => false, + 'dashboard' => true, ]; $output = '
'; diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 5e321b1a2e..00030c65d4 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -6087,3 +6087,17 @@ div.graph div.legend table { writing-mode: lr-tb; white-space: nowrap; } + +div.stat-win-spinner { + width: 100%; + height: 300px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +div.stat-win-spinner img { + width: 100px; + height: 100px; +} diff --git a/pandora_console/operation/agentes/interface_traffic_graph_win.php b/pandora_console/operation/agentes/interface_traffic_graph_win.php index fdd53c0bc3..a4912f63d6 100644 --- a/pandora_console/operation/agentes/interface_traffic_graph_win.php +++ b/pandora_console/operation/agentes/interface_traffic_graph_win.php @@ -31,8 +31,6 @@ require_once $config['homedir'].'/include/auth/mysql.php'; require_once $config['homedir'].'/include/functions.php'; require_once $config['homedir'].'/include/functions_db.php'; require_once $config['homedir'].'/include/functions_reporting.php'; -require_once $config['homedir'].'/include/functions_graph.php'; -require_once $config['homedir'].'/include/functions_custom_graphs.php'; require_once $config['homedir'].'/include/functions_modules.php'; require_once $config['homedir'].'/include/functions_agents.php'; require_once $config['homedir'].'/include/functions_tags.php'; @@ -45,7 +43,7 @@ $params = json_decode($params_json, true); // Metaconsole connection to the node. $server_id = (int) (isset($params['server']) ? $params['server'] : 0); -if ($config['metaconsole'] && empty($server_id) === false) { +if (is_metaconsole() === true && empty($server_id) === false) { $server = metaconsole_get_connection_by_id($server_id); // Error connecting. @@ -268,13 +266,15 @@ $table->data[] = $data; $table->rowclass[] = ''; $form_table = html_print_table($table, true); -$form_table .= '
'.html_print_submit_button( +$form_table .= '
'; +$form_table .= html_print_submit_button( __('Reload'), 'submit', false, 'class="sub upd"', true -).'
'; +); +$form_table .= '
'; // Menu. @@ -303,7 +303,7 @@ html_print_div( ); // Graph. -echo '
'; +$output = '
'; $height = 280; $width = '90%'; @@ -320,8 +320,8 @@ $params = [ 'zoom' => $zoom, ]; -if (is_metaconsole()) { - $params['id_server'] = $server_id; +if (is_metaconsole() === true) { + $params['server_id'] = $server_id; } if ($config['type_interface_charts'] == 'line') { @@ -340,13 +340,13 @@ $params_combined = [ 'stacked' => $stacked, ]; -graphic_combined_module( - array_values($interface_traffic_modules), - $params, - $params_combined -); +$modules = array_values($interface_traffic_modules); +$output .= '
'; +$output .= html_print_image('images/spinner_charts.gif', true); +$output .= '
'; -echo '
'; +$output .= '
'; +echo $output; ?> @@ -362,6 +362,10 @@ ui_require_jquery_file( true ); ui_include_time_picker(true); + +if (is_metaconsole() === true && empty($server_id) === false) { + metaconsole_restore_db(); +} ?> diff --git a/pandora_console/operation/agentes/stat_win.php b/pandora_console/operation/agentes/stat_win.php index fce948feb1..783b283fea 100644 --- a/pandora_console/operation/agentes/stat_win.php +++ b/pandora_console/operation/agentes/stat_win.php @@ -31,7 +31,6 @@ require_once $config['homedir'].'/include/auth/mysql.php'; require_once $config['homedir'].'/include/functions.php'; require_once $config['homedir'].'/include/functions_db.php'; require_once $config['homedir'].'/include/functions_reporting.php'; -require_once $config['homedir'].'/include/functions_graph.php'; require_once $config['homedir'].'/include/functions_modules.php'; require_once $config['homedir'].'/include/functions_agents.php'; require_once $config['homedir'].'/include/functions_tags.php'; @@ -41,7 +40,7 @@ enterprise_include_once('include/functions_agents.php'); check_login(); // Metaconsole connection to the node. -$server_id = (int) get_parameter('server'); +$server_id = (int) get_parameter('server', 0); if (is_metaconsole() === true && empty($server_id) === false) { $server = metaconsole_get_connection_by_id($server_id); // Error connecting. @@ -445,59 +444,39 @@ ui_print_message_dialog( ] ); + $params = [ + 'agent_module_id' => $id, + 'period' => $period, + 'show_events' => $draw_events, + 'title' => $label, + 'unit_name' => $unit, + 'show_alerts' => $draw_alerts, + 'date' => $date, + 'unit' => $unit, + 'baseline' => $baseline, + 'homeurl' => $urlImage, + 'adapt_key' => 'adapter_'.$graph_type, + 'compare' => $time_compare, + 'show_unknown' => $unknown_graph, + 'percentil' => (($show_percentil) ? $config['percentil'] : null), + 'type_graph' => $config['type_module_charts'], + 'fullscale' => $fullscale, + 'zoom' => $zoom, + 'height' => 300, + 'type_mode_graph' => $type_mode_graph, + ]; + // Graph. $output = '
'; - switch ($graph_type) { - case 'boolean': - case 'sparse': - case 'string': - $params = [ - 'agent_module_id' => $id, - 'period' => $period, - 'show_events' => $draw_events, - 'title' => $label, - 'unit_name' => $unit, - 'show_alerts' => $draw_alerts, - 'date' => $date, - 'unit' => $unit, - 'baseline' => $baseline, - 'homeurl' => $urlImage, - 'adapt_key' => 'adapter_'.$graph_type, - 'compare' => $time_compare, - 'show_unknown' => $unknown_graph, - 'percentil' => (($show_percentil) ? $config['percentil'] : null), - 'type_graph' => $config['type_module_charts'], - 'fullscale' => $fullscale, - 'zoom' => $zoom, - 'height' => 300, - 'type_mode_graph' => $type_mode_graph, - ]; - $output .= grafico_modulo_sparse($params); - $output .= '
'; - if ($show_events_graph) { - $width = '500'; - $height = '450'; - $output .= graphic_module_events( - $id, - $width, - $height, - $period, - $config['homeurl'], - $zoom, - 'adapted_'.$graph_type, - $date, - true - ); - } - break; - - default: - $output .= fs_error_image('../images'); - break; - } - + $output .= '
'; + $output .= html_print_image('images/spinner_charts.gif', true); + $output .= '
'; $output .= '
'; echo $output; + + if (is_metaconsole() === true && empty($server_id) === false) { + metaconsole_restore_db(); + } ?> @@ -580,5 +559,32 @@ ui_include_time_picker(true); arrow.attr('src',arrow.attr('src').replace(arrow_up, arrow_down)); } }); + + var graph_data = ""; + var url = ""; + var serverId = ""; + get_ajax_module(url, graph_data, serverId); }); + + + function get_ajax_module(url, graph_data, serverId) { + $.ajax({ + type: "POST", + url: url, + dataType: "html", + data: { + page: "include/ajax/module", + get_graph_module: true, + graph_data: graph_data, + server_id: serverId + }, + success: function (data) { + $("#stat-win-spinner").hide(); + $("#stat-win-module-graph").append(data); + }, + error: function (error) { + console.error(error); + } + }); + } From 631ebcbc2f4b3d991c3a3eb1c12ad814317aef34 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Wed, 9 Dec 2020 15:23:16 +0100 Subject: [PATCH 010/296] Added space in User ID --- pandora_console/godmode/users/configure_user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/users/configure_user.php b/pandora_console/godmode/users/configure_user.php index 2e0cdd8d7d..cfca6aa076 100644 --- a/pandora_console/godmode/users/configure_user.php +++ b/pandora_console/godmode/users/configure_user.php @@ -785,7 +785,7 @@ if (defined('METACONSOLE')) { } if (!$new_user) { - $user_id = '

'.__('User ID').'

'; + $user_id = '

'.__('User ID').':

'; $user_id .= ''.$id.''; $user_id .= html_print_input_hidden('id_user', $id, true); $user_id .= '
'; From 8fd46b390fb5515786fc97fb7b6b25df8e709893 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Wed, 9 Dec 2020 16:39:00 +0100 Subject: [PATCH 011/296] Removed metaconsole empty help links --- .../godmode/modules/manage_network_components_form_common.php | 4 +++- pandora_console/godmode/users/configure_user.php | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pandora_console/godmode/modules/manage_network_components_form_common.php b/pandora_console/godmode/modules/manage_network_components_form_common.php index d42e93c949..51e544a96d 100644 --- a/pandora_console/godmode/modules/manage_network_components_form_common.php +++ b/pandora_console/godmode/modules/manage_network_components_form_common.php @@ -48,7 +48,9 @@ if (enterprise_installed()) { 'basic' => __('Basic'), 'advanced' => __('Advanced'), ]; - $table->data[0][3] = html_print_select($wizard_levels, 'wizard_level', $wizard_level, '', '', -1, true, false, false).' '.ui_print_help_icon('meta_access', true); + // TODO review help tips on meta. + $table->data[0][3] = html_print_select($wizard_levels, 'wizard_level', $wizard_level, '', '', -1, true, false, false).' '; + // .ui_print_help_icon('meta_access', true) } else { $table->data[0][2] = ''; $table->data[0][3] = html_print_input_hidden('wizard_level', $wizard_level, true); diff --git a/pandora_console/godmode/users/configure_user.php b/pandora_console/godmode/users/configure_user.php index 2e0cdd8d7d..4a9707deb7 100644 --- a/pandora_console/godmode/users/configure_user.php +++ b/pandora_console/godmode/users/configure_user.php @@ -1065,7 +1065,8 @@ if (enterprise_installed() && defined('METACONSOLE')) { $user_info_metaconsole_access = $user_info['metaconsole_access']; } - $meta_access = '

'.__('Metaconsole access').' '.ui_print_help_icon('meta_access', true).'

'; + // TODO review help tips on meta. + $meta_access = '

'.__('Metaconsole access').' './* ui_print_help_icon('meta_access', true). */'

'; $metaconsole_accesses = [ 'basic' => __('Basic'), 'advanced' => __('Advanced'), From fd6aef1b37e41d2b3e7c1ce80b18b933ad1c0579 Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Wed, 9 Dec 2020 18:15:01 +0100 Subject: [PATCH 012/296] Added control for id_agent_module --- pandora_console/operation/events/events.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index f24aa98699..5efe5a538d 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -140,8 +140,11 @@ $text_module = get_parameter( $filter['module_search'] ); $id_agent_module = get_parameter( - 'filter[id_agent_module]', - $filter['id_agent_module'] + 'id_agent_module', + get_parameter( + 'filter[id_agent_module]', + $filter['id_agent_module'] + ) ); $pagination = get_parameter( 'filter[pagination]', From 888d702f6edd70901d5615c4a240b5df5d574d95 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Thu, 10 Dec 2020 09:32:20 +0100 Subject: [PATCH 013/296] Fixed api call set stop_downtime --- pandora_console/include/functions_api.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 96b3bc8cfa..490e96576e 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -6360,6 +6360,14 @@ function api_set_stop_downtime($id, $thrash1, $other, $thrash3) $date_time_stop = get_system_time(); + $sql = sprintf('SELECT date_to, type_execution, executed FROM tplanned_downtime WHERE id=%d', $id); + $data = db_get_row_sql($sql); + + if ($data['type_execution'] == 'periodically' && $data['executed'] == 1) { + returnError('error_stop_downtime', __('Error stopping downtime. Periodical and running planned downtime cannot be stopped.')); + return; + } + $values = []; $values['date_to'] = $date_time_stop; From dcbd310c8106167d402a4bf254fe070517255ae2 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Thu, 10 Dec 2020 10:36:55 +0100 Subject: [PATCH 014/296] SNMP trap filter colocado --- pandora_console/operation/snmpconsole/snmp_view.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/operation/snmpconsole/snmp_view.php b/pandora_console/operation/snmpconsole/snmp_view.php index e1a501ea1a..d345bd626b 100755 --- a/pandora_console/operation/snmpconsole/snmp_view.php +++ b/pandora_console/operation/snmpconsole/snmp_view.php @@ -616,7 +616,7 @@ $table->data[4][1] = html_print_input( ); // Type filter (ColdStart, WarmStart, LinkDown, LinkUp, authenticationFailure, Other). -$table->data[6][1] = ''.__('Trap type').''.ui_print_help_tip(__('Search by trap type'), true); +$table->data[4][3] = ''.__('Trap type').''.ui_print_help_tip(__('Search by trap type'), true); $trap_types = [ -1 => __('None'), 0 => __('Cold start (0)'), @@ -626,7 +626,7 @@ $trap_types = [ 4 => __('Authentication failure (4)'), 5 => __('Other'), ]; -$table->data[6][2] = html_print_select( +$table->data[4][4] = html_print_select( $trap_types, 'trap_type', $trap_type, From d0b119c05f712da25d50ca9b4b0aa4ebdd1c1e22 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Thu, 10 Dec 2020 10:49:13 +0100 Subject: [PATCH 015/296] Module library user pass let empty user/pass --- pandora_console/include/functions_config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index 4d3665db4d..fe148bfc1e 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -1619,12 +1619,12 @@ function config_update_config() case 'module_library': $module_library_user = get_parameter('module_library_user'); - if ($module_library_user == '' || !config_update_value('module_library_user', $module_library_user)) { + if (!config_update_value('module_library_user', $module_library_user)) { $error_update[] = __('User'); } $module_library_password = get_parameter('module_library_password'); - if ($module_library_password == '' || !config_update_value('module_library_password', $module_library_password)) { + if (!config_update_value('module_library_password', $module_library_password)) { $error_update[] = __('Password'); } break; From fcf4b6c239da63c7e5d6229ae45ab2eb046e5a2a Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Thu, 10 Dec 2020 12:06:56 +0100 Subject: [PATCH 016/296] Fixed Agent and module text size --- pandora_console/godmode/agentes/modificar_agente.php | 4 ++-- pandora_console/operation/agentes/estado_agente.php | 2 +- pandora_console/operation/agentes/estado_generalagente.php | 2 +- pandora_console/operation/agentes/status_monitor.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pandora_console/godmode/agentes/modificar_agente.php b/pandora_console/godmode/agentes/modificar_agente.php index 77d8f06b46..5c5658ac32 100644 --- a/pandora_console/godmode/agentes/modificar_agente.php +++ b/pandora_console/godmode/agentes/modificar_agente.php @@ -567,12 +567,12 @@ if ($agents !== false) { $url = ui_get_full_url( $url.'&op=update&id='.$cluster->id() ); - echo ''.$agent['alias'].''; + echo ''.ui_print_truncate_text($agent['alias'], 'agent_medium').''; } } else { echo '".''.$agent['alias'].''.''; + id_agente=".$agent['id_agente']."'>".''.ui_print_truncate_text($agent['alias'], 'agent_medium').''.''; } echo ''; diff --git a/pandora_console/operation/agentes/estado_agente.php b/pandora_console/operation/agentes/estado_agente.php index 9e01425198..00b306e158 100644 --- a/pandora_console/operation/agentes/estado_agente.php +++ b/pandora_console/operation/agentes/estado_agente.php @@ -784,7 +784,7 @@ foreach ($agents as $agent) { $data[0] = '
'; - $data[0] .= ''.$agent['alias'].''; + $data[0] .= ''.ui_print_truncate_text($agent['alias'], 'agent_medium', false, true, true).''; if ($agent['quiet']) { $data[0] .= ' '; diff --git a/pandora_console/operation/agentes/estado_generalagente.php b/pandora_console/operation/agentes/estado_generalagente.php index df788514a1..bae404dc2d 100755 --- a/pandora_console/operation/agentes/estado_generalagente.php +++ b/pandora_console/operation/agentes/estado_generalagente.php @@ -92,7 +92,7 @@ $alive_animation = agents_get_status_animation( $agent_name = ui_print_agent_name( $agent['id_agente'], true, - 500, + 'agent_medium', 'font-size: medium;font-weight:bold', true ); diff --git a/pandora_console/operation/agentes/status_monitor.php b/pandora_console/operation/agentes/status_monitor.php index db1e052ab9..c3e160bdda 100644 --- a/pandora_console/operation/agentes/status_monitor.php +++ b/pandora_console/operation/agentes/status_monitor.php @@ -1419,7 +1419,7 @@ if (!empty($result)) { } if (in_array('module_name', $show_fields) || is_metaconsole()) { - $data[3] = ui_print_truncate_text($row['module_name'], 'agent_small', false, true, true); + $data[3] = ui_print_truncate_text($row['module_name'], 'module_small', false, true, true); if ($row['extended_info'] != '') { $data[3] .= ui_print_help_tip($row['extended_info'], true, '/images/default_list.png'); } From 092011916be54b1ee8d51857844a039b95f85453 Mon Sep 17 00:00:00 2001 From: alejandro-campos Date: Thu, 10 Dec 2020 16:07:40 +0100 Subject: [PATCH 017/296] fix recursivity check --- .../include/javascript/jquery.pandora.controls.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/javascript/jquery.pandora.controls.js b/pandora_console/include/javascript/jquery.pandora.controls.js index aabc2b4cde..0158879c6b 100644 --- a/pandora_console/include/javascript/jquery.pandora.controls.js +++ b/pandora_console/include/javascript/jquery.pandora.controls.js @@ -35,11 +35,23 @@ $("option[value!=0]", $select).remove (); if (! config.callbackBefore (this)) return; + + if (typeof config.recursion === "function") { + // Perform this for those cases where recursion parameter is obtained through a function that returns a variable that is set in the lexical environment where this constructor is called. + var recursion_value = config.recursion(); + + if (typeof recursion_value === "boolean") { + recursion_value = recursion_value ? 1 : 0; + } + } else { + var recursion_value = config.recursion; + } + var opts = { "page" : "godmode/groups/group_list", "get_group_agents" : 1, "id_group" : this.value, - "recursion" : config.recursion, + "recursion" : recursion_value, "filter_agents_json" : config.filter_agents_json, "disabled" : (typeof config.disabled === "function") ? (config.disabled()) From 0e20c3d5476125988a5a99b6d47f652d48a9a33f Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Fri, 11 Dec 2020 09:38:37 +0100 Subject: [PATCH 018/296] Fixed --- pandora_console/operation/agentes/ver_agente.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index df5146711c..b22ff8ace5 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -1389,6 +1389,7 @@ if (isset($ehorus_tab) && !empty($ehorus_tab)) { $onheader['ehorus'] = $ehorus_tab; } +$id_extension = get_parameter('id_extension', ''); // Tabs for extensions. $tab_name_extensions = ''; foreach ($config['extensions'] as $extension) { @@ -1431,13 +1432,11 @@ foreach ($config['extensions'] as $extension) { } $image = $extension['extension_ope_tab']['icon']; - $name = $extension['extension_ope_tab']['name']; - $id = $extension['extension_ope_tab']['id']; - $tab_name_extensions = $name; + $name = $extension['extension_ope_tab']['name']; + $id = $extension['extension_ope_tab']['id']; - $id_extension = get_parameter('id_extension', ''); - - if ($id_extension == $id) { + if ($id_extension === $id) { + $tab_name_extensions = $name; $active = true; } else { $active = false; From 734efbf89284aa8ae1833b504a65145a61d897d8 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Fri, 11 Dec 2020 10:10:22 +0100 Subject: [PATCH 019/296] Added ACL check to custom view CSV donwload --- pandora_console/include/ajax/custom_fields.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pandora_console/include/ajax/custom_fields.php b/pandora_console/include/ajax/custom_fields.php index 85066675a1..d8982da1d4 100644 --- a/pandora_console/include/ajax/custom_fields.php +++ b/pandora_console/include/ajax/custom_fields.php @@ -54,6 +54,16 @@ if (check_login()) { $update_filter_cf = (bool) get_parameter('update_filter_cf', 0); $delete_filter_cf = (bool) get_parameter('delete_filter_cf', 0); $change_name_filter = (bool) get_parameter('change_name_filter', 0); + $check_csv_button = (bool) get_parameter('check_csv_button', 0); + + if ($check_csv_button) { + if (check_acl($config['id_user'], 0, 'PM')) { + echo json_encode($permission); + return; + } else { + exit; + } + } if ($get_custom_fields_data) { $name_custom_fields = get_parameter('name_custom_fields', 0); From 4d8a686ae7743ce6874c8994537d667a6f2aff90 Mon Sep 17 00:00:00 2001 From: alejandro-campos Date: Fri, 11 Dec 2020 11:40:01 +0100 Subject: [PATCH 020/296] fixed triggered alerts count --- pandora_console/include/functions_tactical.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/functions_tactical.php b/pandora_console/include/functions_tactical.php index 4e29dda423..26611e5b41 100644 --- a/pandora_console/include/functions_tactical.php +++ b/pandora_console/include/functions_tactical.php @@ -62,6 +62,7 @@ function tactical_get_data($id_user=false, $user_strict=false, $acltags, $return $list['_monitors_unknown_'] = 0; $list['_monitors_not_init_'] = 0; $list['_monitors_ok_'] = 0; + $list['_monitors_alerts_fired_'] = 0; if (empty($list_groups)) { $list_groups = []; @@ -142,7 +143,7 @@ function tactical_get_data($id_user=false, $user_strict=false, $acltags, $return $list['_monitors_warning_'] += (int) $value['monitors_warning']; $list['_monitors_unknown_'] += (int) $value['monitors_unknown']; $list['_monitors_not_init_'] += (int) $value['monitors_not_init']; - $list['_monitor_alerts_fire_count_'] += (int) $value['alerts_fired']; + $list['_monitors_alerts_fired_'] += (int) $value['alerts_fired']; } if (!empty($data_stats_unknown)) { From 125a5bffc603dc1f1fa0032217f05f620c95b774 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Fri, 11 Dec 2020 15:21:28 +0100 Subject: [PATCH 021/296] Fixed mobile events modal opening twice --- pandora_console/mobile/operation/events.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/mobile/operation/events.php b/pandora_console/mobile/operation/events.php index 41d078e1eb..676fed11fa 100644 --- a/pandora_console/mobile/operation/events.php +++ b/pandora_console/mobile/operation/events.php @@ -121,7 +121,7 @@ class Events $status_icon = html_print_image($img_st, true, false, false, false, false, true); $row = []; - $row[] = ''.__('Event Name').'
'.io_safe_output(str_replace([' ', ''], ' ', $event['evento'])).'
'; + $row[] = ''.__('Event Name').'
'.io_safe_output(str_replace([' ', ''], ' ', $event['evento'])).'
'; if ($event['id_agente'] == 0) { $agent_name = __('System'); From c4eb3dd088cd1d03c6b3cc486bc6d52cdcd8ebe6 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Mon, 14 Dec 2020 10:52:12 +0100 Subject: [PATCH 022/296] Added log on deleting tgraph_source data in pandora_db --- pandora_server/util/pandora_db.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index fc72c2f4ff..07498b6e2d 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -404,8 +404,10 @@ sub pandora_purgedb ($$) { } # Delete old tgraph_source data + log_message ('PURGE', 'Deleting old tgraph_source data.'); db_do ($dbh,"DELETE FROM tgraph_source WHERE id_graph NOT IN (SELECT id_graph FROM tgraph)"); + # Delete network traffic old data. log_message ('PURGE', 'Deleting old network matrix data.'); if ($conf->{'_delete_old_network_matrix'} > 0) { From dc5a0eb5b9bba3ad519152c8430b42169092a93f Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Mon, 14 Dec 2020 17:33:58 +0100 Subject: [PATCH 023/296] Fix issue with adding agents and modules --- .../agentes/planned_downtime.editor.php | 41 ++++------------ pandora_console/include/functions_agents.php | 48 +++++++++++++++++++ 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/pandora_console/godmode/agentes/planned_downtime.editor.php b/pandora_console/godmode/agentes/planned_downtime.editor.php index 40d3f3b1e3..08b114d28d 100644 --- a/pandora_console/godmode/agentes/planned_downtime.editor.php +++ b/pandora_console/godmode/agentes/planned_downtime.editor.php @@ -15,7 +15,7 @@ * |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______| * * ============================================================================ - * Copyright (c) 2005-2019 Artica Soluciones Tecnologicas + * Copyright (c) 2005-2021 Artica Soluciones Tecnologicas * Please see http://pandorafms.org for full contribution list * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -70,7 +70,6 @@ ui_print_page_header( // Recursion group filter. $recursion = get_parameter('recursion', $_POST['recursion']); - // Initialize data. $id_group = (int) get_parameter('id_group'); $name = (string) get_parameter('name'); @@ -181,9 +180,15 @@ if ($insert_downtime_agent === 1) { __('This elements cannot be modified while the downtime is being executed') ); } else { + // If is selected 'Any', get all the agents. + if (count($agents) === 1 && (int) $agents[0] === -2) { + $all_agents = get_parameter('all_agents'); + $agents = explode(',', $all_agents); + } + foreach ($agents as $agent_id) { // Check module belongs to the agent. - if ($modules_selection_mode == 'all') { + if ($modules_selection_mode == 'all' && $all_modules === false) { $check = false; foreach ($module_names as $module_name) { $check_module = modules_get_agentmodule_id( @@ -896,33 +901,7 @@ if ($id_downtime > 0) { } } - $sql = sprintf( - 'SELECT tagente.id_agente, tagente.alias - FROM tagente - WHERE tagente.id_agente NOT IN ( - SELECT tagente.id_agente - FROM tagente, tplanned_downtime_agents - WHERE tplanned_downtime_agents.id_agent = tagente.id_agente - AND tplanned_downtime_agents.id_downtime = %d - ) AND disabled = 0 %s - AND tagente.id_grupo IN (%s) - ORDER BY tagente.nombre', - $id_downtime, - $filter_cond, - $id_groups_str - ); - $agents = db_get_all_rows_sql($sql); - if (empty($agents)) { - $agents = []; - } - - $agent_ids = extract_column($agents, 'id_agente'); - $agent_names = extract_column($agents, 'alias'); - - $agents = array_combine($agent_ids, $agent_names); - if ($agents === false) { - $agents = []; - } + $agents = get_planned_downtime_agents_list($id_downtime, $filter_cond, $id_groups_str); $disabled_add_button = false; if (empty($agents) || $disabled_in_execution) { @@ -940,7 +919,7 @@ if ($id_downtime > 0) { // Show available agents to include into downtime echo '

'.__('Available agents').':

'; echo "
"; - + html_print_input_hidden('all_agents', implode(',', array_keys($agents))); echo html_print_select($agents, 'id_agents[]', -1, '', _('Any'), -2, false, true, true, '', false, 'width: 180px;'); if ($type_downtime != 'quiet') { diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index c9d93b6e36..dc67ccf998 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -3800,3 +3800,51 @@ function agents_get_last_status_change($id_agent) return $row['last_status_change']; } + + +/** + * Return the list of agents for a planned downtime + * + * @param integer $id_downtime Id of planned downtime. + * @param string $filter_cond String-based filters. + * @param string $id_groups_str String-based list of id group, separated with commas. + * + * @return array + */ +function get_planned_downtime_agents_list($id_downtime, $filter_cond, $id_groups_str) +{ + $agents = []; + + $sql = sprintf( + 'SELECT tagente.id_agente, tagente.alias + FROM tagente + WHERE tagente.id_agente NOT IN ( + SELECT tagente.id_agente + FROM tagente, tplanned_downtime_agents + WHERE tplanned_downtime_agents.id_agent = tagente.id_agente + AND tplanned_downtime_agents.id_downtime = %d + ) AND disabled = 0 %s + AND tagente.id_grupo IN (%s) + ORDER BY tagente.nombre', + $id_downtime, + $filter_cond, + $id_groups_str + ); + + $agents = db_get_all_rows_sql($sql); + + if (empty($agents)) { + $agents = []; + } + + $agent_ids = extract_column($agents, 'id_agente'); + $agent_names = extract_column($agents, 'alias'); + + $agents = array_combine($agent_ids, $agent_names); + + if ($agents === false) { + $agents = []; + } + + return $agents; +} From 430457b30a5fa73f29a957d5da364e1254079d1b Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Tue, 15 Dec 2020 13:12:00 +0100 Subject: [PATCH 024/296] 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 7a74ae4d206bb4c63cef139b381e6c64421bf045 Mon Sep 17 00:00:00 2001 From: alejandro-campos Date: Tue, 15 Dec 2020 17:40:15 +0100 Subject: [PATCH 025/296] changes in connected users view --- .../extensions/users_connected.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/pandora_console/extensions/users_connected.php b/pandora_console/extensions/users_connected.php index e26b0dab1e..22b030f602 100644 --- a/pandora_console/extensions/users_connected.php +++ b/pandora_console/extensions/users_connected.php @@ -76,20 +76,21 @@ function users_extension_main_god($god=true) $table->head[0] = __('User'); $table->head[1] = __('IP'); - $table->head[2] = __('Date'); + $table->head[2] = __('Last login'); + $table->head[3] = __('Last contact'); $rowPair = true; $iterator = 0; // Get data foreach ($rows as $row) { - // Get ip_origin of the last login of the user + // Get data of user's last login. switch ($config['dbtype']) { case 'mysql': case 'postgresql': - $ip_origin = db_get_value_sql( + $last_login_data = db_get_row_sql( sprintf( - "SELECT ip_origen + "SELECT ip_origen, utimestamp FROM tsesion WHERE id_usuario = '%s' AND descripcion = '".io_safe_input('Logged in')."' @@ -100,9 +101,9 @@ function users_extension_main_god($god=true) break; case 'oracle': - $ip_origin = db_get_value_sql( + $last_login_data = db_get_row_sql( sprintf( - "SELECT ip_origen + "SELECT ip_origen, utimestamp FROM tsesion WHERE id_usuario = '%s' AND to_char(descripcion) = '".io_safe_input('Logged in')."' @@ -124,8 +125,9 @@ function users_extension_main_god($god=true) $data = []; $data[0] = ''.$row['id_user'].''; - $data[1] = $ip_origin; - $data[2] = date($config['date_format'], $row['last_connect']); + $data[1] = $last_login_data['ip_origin']; + $data[2] = date($config['date_format'], $last_login_data['utimestamp']); + $data[3] = date($config['date_format'], $row['last_connect']); array_push($table->data, $data); } @@ -134,7 +136,6 @@ function users_extension_main_god($god=true) } -extensions_add_godmode_menu_option(__('Users connected'), 'UM', 'gusuarios', 'users/icon.png', 'v1r1'); extensions_add_operation_menu_option(__('Users connected'), 'workspace', 'users/icon.png', 'v1r1', '', 'UM'); extensions_add_godmode_function('users_extension_main_god'); From 010dc65dd4f1b89f1f982035f0c7b0bca2825ce1 Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Wed, 16 Dec 2020 14:09:54 +0100 Subject: [PATCH 026/296] WIP: Backup upload --- pandora_console/godmode/menu.php | 3 + pandora_console/godmode/setup/setup.php | 15 ++ .../godmode/setup/setup_net_tools.php | 36 +++++ .../include/class/NetTools.class.php | 147 ++++++++++++++++++ 4 files changed, 201 insertions(+) create mode 100644 pandora_console/godmode/setup/setup_net_tools.php create mode 100644 pandora_console/include/class/NetTools.class.php diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index ddea5fcafd..b71e44ea54 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -351,6 +351,9 @@ if (check_acl($config['id_user'], 0, 'PM')) { $sub2['godmode/setup/setup&section=websocket_engine']['text'] = __('Websocket Engine'); $sub2['godmode/setup/setup&section=websocket_engine']['refr'] = 0; + $sub2['godmode/setup/setup&section=nettools']['text'] = __('Network Tools'); + $sub2['godmode/setup/setup&section=nettools']['refr'] = 0; + if ($config['activate_gis']) { $sub2['godmode/setup/setup&section=gis']['text'] = __('Map conections GIS'); } diff --git a/pandora_console/godmode/setup/setup.php b/pandora_console/godmode/setup/setup.php index 9e4fb13a9c..7bfa1709f4 100644 --- a/pandora_console/godmode/setup/setup.php +++ b/pandora_console/godmode/setup/setup.php @@ -145,6 +145,11 @@ $buttons['websocket_engine'] = [ 'text' => ''.html_print_image('images/websocket_small.png', true, ['title' => __('Websocket engine')]).'', ]; +$buttons['nettools'] = [ + 'active' => false, + 'text' => ''.html_print_image('images/nettool.png', true, ['title' => __('Websocket engine')]).'', +]; + if ($config['activate_gis']) { $buttons['gis'] = [ 'active' => false, @@ -220,6 +225,12 @@ switch ($section) { $help_header = 'quickshell_settings'; break; + case 'nettools': + $buttons['nettools']['active'] = true; + $subpage = ' » '.__('Network Tools'); + $help_header = 'Network_Tools'; + break; + case 'enterprise': $buttons['enterprise']['active'] = true; $subpage = ' » '.__('Enterprise'); @@ -292,6 +303,10 @@ switch ($section) { include_once $config['homedir'].'/godmode/setup/setup_websocket_engine.php'; break; + case 'nettools': + include_once $config['homedir'].'/godmode/setup/setup_net_tools.php'; + break; + default: enterprise_hook('setup_enterprise_select_tab', [$section]); break; diff --git a/pandora_console/godmode/setup/setup_net_tools.php b/pandora_console/godmode/setup/setup_net_tools.php new file mode 100644 index 0000000000..9f5c88fb8a --- /dev/null +++ b/pandora_console/godmode/setup/setup_net_tools.php @@ -0,0 +1,36 @@ +width = '100%'; + + $table->data = []; + + $table->data[0][0] = __('Traceroute path'); + $table->data[0][1] = html_print_input_text('traceroute_path', $traceroute_path, '', 40, 255, true); + + $table->data[1][0] = __('Ping path'); + $table->data[1][1] = html_print_input_text('ping_path', $ping_path, '', 40, 255, true); + + $table->data[2][0] = __('Nmap path'); + $table->data[2][1] = html_print_input_text('nmap_path', $nmap_path, '', 40, 255, true); + + $table->data[3][0] = __('Dig path'); + $table->data[3][1] = html_print_input_text('dig_path', $dig_path, '', 40, 255, true); + + $table->data[4][0] = __('Snmpget path'); + $table->data[4][1] = html_print_input_text('snmpget_path', $snmpget_path, '', 40, 255, true); + + echo ''; + echo '
'; + echo ''.__('Options').''; + html_print_input_hidden('update_traceroute', 1); + html_print_table($table); + echo '
'; + + echo '
'; + html_print_submit_button(__('Update'), 'update_button', false, 'class="sub upd"'); + echo '
'; + echo ''; + } + + +} From 6da8f33e2010a1317ab2a25d6bfab3bcf63b844f Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Wed, 16 Dec 2020 14:26:32 +0100 Subject: [PATCH 027/296] WIP --- .../godmode/setup/setup_net_tools.php | 3 +- .../include/class/NetTools.class.php | 29 ++++++++++++------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/pandora_console/godmode/setup/setup_net_tools.php b/pandora_console/godmode/setup/setup_net_tools.php index 9f5c88fb8a..0f1b246626 100644 --- a/pandora_console/godmode/setup/setup_net_tools.php +++ b/pandora_console/godmode/setup/setup_net_tools.php @@ -32,5 +32,4 @@ global $config; require_once $config['homedir'].'/include/functions.php'; // Require needed class. -// require_once $config['homedir'].'/include/class/NetTools.class.php'; -hd('MIS HUEVOS EN VINAGRETA'); +require_once $config['homedir'].'/include/class/NetTools.class.php'; diff --git a/pandora_console/include/class/NetTools.class.php b/pandora_console/include/class/NetTools.class.php index 1bed9fc0bf..aeac561c7b 100644 --- a/pandora_console/include/class/NetTools.class.php +++ b/pandora_console/include/class/NetTools.class.php @@ -44,7 +44,7 @@ class NetTools extends HTML */ public function __construct() { - + echo 'Estoy funcionando'; } @@ -130,17 +130,24 @@ class NetTools extends HTML $table->data[4][0] = __('Snmpget path'); $table->data[4][1] = html_print_input_text('snmpget_path', $snmpget_path, '', 40, 255, true); - echo '
'; - echo '
'; - echo ''.__('Options').''; - html_print_input_hidden('update_traceroute', 1); - html_print_table($table); - echo '
'; + $form = ''; + $form .= '
'; + $form .= ''.__('Options').''; + $form .= html_print_input_hidden('update_traceroute', 1, true); + $form .= html_print_table($table); + $form .= '
'; + $form .= html_print_div( + [ + 'id' => '', + 'class' => 'action-buttons', + 'style' => 'width: 100%', + 'content' => html_print_submit_button(__('Update'), 'update_button', false, 'class="sub upd"'), + ] + ); - echo '
'; - html_print_submit_button(__('Update'), 'update_button', false, 'class="sub upd"'); - echo '
'; - echo '
'; + $form .= ''; + + echo $form; } From bb01a076b80507cc974fa4e214d1e8ca89da00d0 Mon Sep 17 00:00:00 2001 From: alejandro-campos Date: Wed, 16 Dec 2020 17:19:06 +0100 Subject: [PATCH 028/296] fixed omnishell errors --- pandora_console/include/functions_agents.php | 26 +++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index c9d93b6e36..ebdf494104 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -21,6 +21,8 @@ require_once $config['homedir'].'/include/functions.php'; require_once $config['homedir'].'/include/functions_modules.php'; require_once $config['homedir'].'/include/functions_users.php'; +use PandoraFMS\Enterprise\RCMDFile as RCMDFile; + /** * Return the agent if exists in the DB. @@ -2410,10 +2412,32 @@ function agents_delete_agent($id_agents, $disableACL=false) enterprise_include_once('include/functions_policies.php'); enterprise_hook('policies_delete_agent', [$id_agent]); - // Delete agent in networkmap enterprise if (enterprise_installed()) { + // Delete agent in networkmap. enterprise_include_once('include/functions_networkmap.php'); networkmap_delete_nodes_by_agent([$id_agent]); + + // Delete command targets with agent. + enterprise_include_once('include/lib/RCMDFile.class.php'); + + $target_filter = ['id_agent' => $id_agent]; + + // Retrieve all commands that have targets with specific agent id. + $commands = RCMDFile::getAll( + ['rct.rcmd_id'], + $target_filter + ); + + foreach ($commands as $command) { + hd($command, true); + $rcmd_id = $command['rcmd_id']; + $rcmd = new RCMDFile($rcmd_id); + + $command_targets = []; + + $command_targets = $rcmd->getTargets(false, $target_filter); + $rcmd->deleteTargets(array_keys($command_targets)); + } } // tagente_datos_inc From 6e9916a92546fe240f2f13a3dd4bc645d5a6175d Mon Sep 17 00:00:00 2001 From: alejandro-campos Date: Wed, 16 Dec 2020 17:20:25 +0100 Subject: [PATCH 029/296] fixed omnishell errors --- pandora_console/include/functions_agents.php | 1 - 1 file changed, 1 deletion(-) diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index ebdf494104..833cf090d0 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -2429,7 +2429,6 @@ function agents_delete_agent($id_agents, $disableACL=false) ); foreach ($commands as $command) { - hd($command, true); $rcmd_id = $command['rcmd_id']; $rcmd = new RCMDFile($rcmd_id); From 959fbd4764fed0fabb406312d5982284056b38cb Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Thu, 17 Dec 2020 13:04:21 +0100 Subject: [PATCH 030/296] WIP: Backup upload --- .../godmode/setup/setup_net_tools.php | 13 + .../include/class/NetTools.class.php | 557 ++++++++++++++++-- .../operation/agentes/net_tools.php | 48 ++ .../operation/agentes/ver_agente.php | 17 +- 4 files changed, 585 insertions(+), 50 deletions(-) create mode 100644 pandora_console/operation/agentes/net_tools.php diff --git a/pandora_console/godmode/setup/setup_net_tools.php b/pandora_console/godmode/setup/setup_net_tools.php index 0f1b246626..4dafb6e39c 100644 --- a/pandora_console/godmode/setup/setup_net_tools.php +++ b/pandora_console/godmode/setup/setup_net_tools.php @@ -33,3 +33,16 @@ require_once $config['homedir'].'/include/functions.php'; // Require needed class. require_once $config['homedir'].'/include/class/NetTools.class.php'; + +// Control call flow for debug window. +try { + // User access and validation is being processed on class constructor. + $obj = new NetTools('setup'); +} catch (Exception $e) { + echo '[NetTools]'.$e->getMessage(); + + // Stop this execution, but continue 'globally'. + return; +} + +$obj->run(); diff --git a/pandora_console/include/class/NetTools.class.php b/pandora_console/include/class/NetTools.class.php index aeac561c7b..1e3e3343dd 100644 --- a/pandora_console/include/class/NetTools.class.php +++ b/pandora_console/include/class/NetTools.class.php @@ -40,56 +40,98 @@ class NetTools extends HTML /** - * Class constructor + * Undocumented function + * + * @param string $origin Origin of the request. */ - public function __construct() + public function __construct(string $origin) { - echo 'Estoy funcionando'; + global $config; + + // Check if the user can access here. + check_login(); + // Setting the origin. + $this->origin = $origin; + + if ($this->origin === 'agent') { + if (check_acl($config['id_user'], 0, 'AR') === false) { + db_pandora_audit( + 'ACL Violation', + 'Trying to access Agent Management' + ); + include 'general/noaccess.php'; + return; + } + + // Capture needed parameter for agent form. + $this->operation = get_parameter('operation', 0); + $this->community = get_parameter('community', 'public'); + $this->ip = get_parameter('select_ips'); + $this->snmp_version = get_parameter('select_version'); + + // Show form. + $this->id_agente = get_parameter('id_agente', 0); + + // Capture needed parameters for agent executions. + } else if ($this->origin === 'setup') { + if (check_acl($config['id_user'], 0, 'PM') === false) { + db_pandora_audit( + 'ACL Violation', + 'Trying to access Profile Management' + ); + include 'general/noaccess.php'; + return; + } + + // Capture needed parameters for setup form. + $this->updatePaths = (bool) get_parameter('update_paths', 0); + // Capture paths. + $this->pathTraceroute = (string) get_parameter('traceroute_path'); + $this->pathPing = (string) get_parameter('ping_path'); + $this->pathNmap = (string) get_parameter('nmap_path'); + $this->pathDig = (string) get_parameter('dig_path'); + $this->pathSnmpget = (string) get_parameter('snmpget_path'); + } + + return $this; + } /** - * Add option. + * Undocumented function * * @return void */ - function godmode_net_tools() + public function run() { - global $config; - - check_login(); - - if (! check_acl($config['id_user'], 0, 'PM')) { - db_pandora_audit( - 'ACL Violation', - 'Trying to access Profile Management' - ); - include 'general/noaccess.php'; - return; + if ($this->origin === 'agent') { + // Print tool form. + $this->agentNetToolsForm(); + } else if ($this->origin === 'setup') { + // Print setup form. + $this->setupNetToolsForm(); } - ui_print_page_header( - __('Config Network Tools'), - '', - false, - 'network_tools_tab' - ); + // Anyway, load JS. + $this->loadJS(); + } - $update_traceroute = (bool) get_parameter('update_traceroute', 0); - $traceroute_path = (string) get_parameter('traceroute_path', ''); - $ping_path = (string) get_parameter('ping_path', ''); - $nmap_path = (string) get_parameter('nmap_path', ''); - $dig_path = (string) get_parameter('dig_path', ''); - $snmpget_path = (string) get_parameter('snmpget_path', ''); - - if ($update_traceroute) { + /** + * Print the form for setup the network tools. + * + * @return void + */ + private function setupNetToolsForm() + { + if ($this->updatePaths === true) { $network_tools_config = []; - $network_tools_config['traceroute_path'] = $traceroute_path; - $network_tools_config['ping_path'] = $ping_path; - $network_tools_config['nmap_path'] = $nmap_path; - $network_tools_config['dig_path'] = $dig_path; - $network_tools_config['snmpget_path'] = $snmpget_path; + $network_tools_config['traceroute_path'] = $this->pathTraceroute; + $network_tools_config['ping_path'] = $this->pathPing; + $network_tools_config['nmap_path'] = $this->pathNmap; + $network_tools_config['dig_path'] = $this->pathDig; + $network_tools_config['snmpget_path'] = $this->pathSnmpget; $result = config_update_value('network_tools_config', json_encode($network_tools_config)); @@ -102,47 +144,50 @@ class NetTools extends HTML if (isset($config['network_tools_config'])) { $network_tools_config_output = io_safe_output($config['network_tools_config']); $network_tools_config = json_decode($network_tools_config_output, true); - $traceroute_path = $network_tools_config['traceroute_path']; - $ping_path = $network_tools_config['ping_path']; - $nmap_path = $network_tools_config['nmap_path']; - $dig_path = $network_tools_config['dig_path']; - $snmpget_path = $network_tools_config['snmpget_path']; + // Setting paths. + $this->pathTraceroute = $network_tools_config['traceroute_path']; + $this->pathPing = $network_tools_config['ping_path']; + $this->pathNmap = $network_tools_config['nmap_path']; + $this->pathDig = $network_tools_config['dig_path']; + $this->pathSnmpget = $network_tools_config['snmpget_path']; } } + // Make the table for show the form. $table = new stdClass(); $table->width = '100%'; $table->data = []; $table->data[0][0] = __('Traceroute path'); - $table->data[0][1] = html_print_input_text('traceroute_path', $traceroute_path, '', 40, 255, true); + $table->data[0][1] = html_print_input_text('traceroute_path', $this->pathTraceroute, '', 40, 255, true); $table->data[1][0] = __('Ping path'); - $table->data[1][1] = html_print_input_text('ping_path', $ping_path, '', 40, 255, true); + $table->data[1][1] = html_print_input_text('ping_path', $this->pathPing, '', 40, 255, true); $table->data[2][0] = __('Nmap path'); - $table->data[2][1] = html_print_input_text('nmap_path', $nmap_path, '', 40, 255, true); + $table->data[2][1] = html_print_input_text('nmap_path', $this->pathNmap, '', 40, 255, true); $table->data[3][0] = __('Dig path'); - $table->data[3][1] = html_print_input_text('dig_path', $dig_path, '', 40, 255, true); + $table->data[3][1] = html_print_input_text('dig_path', $this->pathDig, '', 40, 255, true); $table->data[4][0] = __('Snmpget path'); - $table->data[4][1] = html_print_input_text('snmpget_path', $snmpget_path, '', 40, 255, true); + $table->data[4][1] = html_print_input_text('snmpget_path', $this->pathSnmpget, '', 40, 255, true); $form = '
'; $form .= '
'; $form .= ''.__('Options').''; - $form .= html_print_input_hidden('update_traceroute', 1, true); - $form .= html_print_table($table); + $form .= html_print_input_hidden('update_paths', 1, true); + $form .= html_print_table($table, true); $form .= '
'; $form .= html_print_div( [ 'id' => '', 'class' => 'action-buttons', 'style' => 'width: 100%', - 'content' => html_print_submit_button(__('Update'), 'update_button', false, 'class="sub upd"'), - ] + 'content' => html_print_submit_button(__('Update'), 'update_button', false, 'class="sub upd"', true), + ], + true ); $form .= '
'; @@ -151,4 +196,418 @@ class NetTools extends HTML } + /** + * Print the form for use the network tools. + * + * @return void + */ + private function agentNetToolsForm() + { + $principal_ip = db_get_sql( + sprintf( + 'SELECT direccion FROM tagente WHERE id_agente = %d', + $this->id_agente + ) + ); + + $list_address = db_get_all_rows_sql( + sprintf( + 'SELECT id_a FROM taddress_agent WHERE id_agent = %d', + $this->id_agente + ) + ); + foreach ($list_address as $address) { + $ids[] = join(',', $address); + } + + $ips = db_get_all_rows_sql( + sprintf( + 'SELECT ip FROM taddress WHERE id_a IN (%s)', + join(',', $ids) + ) + ); + + // Must be an a IP at least for work. + if (empty($ips) === true) { + html_print_div( + [ + 'class' => 'error', + 'style' => 'margin-top:5px', + 'content' => __('The agent hasn\'t got IP'), + ] + ); + return; + } + + // Make the data for show in table. + $ipsSelect = array_reduce( + $ips, + function ($carry, $item) { + $carry[$item['ip']] = $item['ip']; + return $carry; + } + ); + + // Form table. + $table = new StdClass(); + $table->class = 'databox filters w100p'; + $table->id = 'netToolTable'; + + $table->data = []; + + $table->data[0][0] = __('Operation'); + + $table->data[0][1] = html_print_select( + [ + 1 => __('Traceroute'), + 2 => __('Ping host & Latency'), + 3 => __('SNMP Interface status'), + 4 => __('Basic TCP Port Scan'), + 5 => __('DiG/Whois Lookup'), + ], + 'operation', + $this->operation, + 'mostrarColumns(this.value)', + __('Please select'), + 0, + true + ); + + $table->data[0][2] = __('IP Adress'); + $table->data[0][3] = html_print_select( + $ipsSelect, + 'select_ips', + $principal_ip, + '', + '', + 0, + true + ); + + $table->cellclass[0][4] = 'snmpcolumn'; + $table->data[0][4] = __('SNMP Version'); + $table->data[0][4] .= ' '; + $table->data[0][4] .= html_print_select( + [ + '1' => 'v1', + '2c' => 'v2c', + ], + 'select_version', + $this->snmp_version, + '', + '', + 0, + true + ); + + $table->cellclass[0][5] = 'snmpcolumn'; + $table->data[0][5] = __('SNMP Community'); + $table->data[0][5] .= ' '; + $table->data[0][5] .= html_print_input_text( + 'community', + $this->community, + '', + 50, + 255, + true + ); + + $table->data[0][6] = ""; + + // Output string. + $output = ''; + $output .= "
"; + $output .= html_print_table($table, true); + $output .= '
'; + + html_print_div( + [ + 'class' => '', + 'style' => 'width: 100%', + 'content' => $output, + ] + ); + + if ($this->operation === true) { + // Execute form. + $executionResult = $this->netToolsExecution($this->operation, $this->ip, $this->community, $this->snmp_version); + echo $executionResult; + } + + echo '
'; + + } + + + /** + * Searchs for command. + * + * @param string $command Command. + * + * @return string Path. + */ + private function whereIsTheCommand($command) + { + global $config; + + if (isset($config['network_tools_config'])) { + $network_tools_config = json_decode($config['network_tools_config'], true); + $traceroute_path = $network_tools_config['traceroute_path']; + $ping_path = $network_tools_config['ping_path']; + $nmap_path = $network_tools_config['nmap_path']; + $dig_path = $network_tools_config['dig_path']; + $snmpget_path = $network_tools_config['snmpget_path']; + + switch ($command) { + case 'traceroute': + if (!empty($traceroute_path)) { + return $traceroute_path; + } + break; + + case 'ping': + if (!empty($ping_path)) { + return $ping_path; + } + break; + + case 'nmap': + if (!empty($nmap_path)) { + return $nmap_path; + } + break; + + case 'dig': + if (!empty($dig_path)) { + return $dig_path; + } + break; + + case 'snmpget': + if (!empty($snmpget_path)) { + return $snmpget_path; + } + break; + + default: + return null; + } + } + + ob_start(); + system('whereis '.$command); + $output = ob_get_clean(); + $result = explode(':', $output); + $result = trim($result[1]); + + if (empty($result)) { + return null; + } + + $result = explode(' ', $result); + $fullpath = trim($result[0]); + + if (! file_exists($fullpath)) { + return null; + } + + return $fullpath; + } + + + /** + * Execute net tools action. + * + * @param integer $operation Operation. + * @param string $ip Ip. + * @param string $community Community. + * @param string $snmp_version SNMP version. + * + * @return string String formed result of execution. + */ + public function netToolsExecution(int $operation, string $ip, string $community, string $snmp_version) + { + $output = ''; + + if (!validate_address($ip)) { + $output .= ui_print_error_message( + __('The ip or dns name entered cannot be resolved'), + '', + true + ); + } else { + switch ($operation) { + case 1: + $traceroute = $this->whereIsTheCommand('traceroute'); + if (empty($traceroute)) { + ui_print_error_message(__('Traceroute executable does not exist.')); + } else { + echo '

'.__('Traceroute to ').$ip.'

'; + echo '
';
+                        echo system($traceroute.' '.$ip);
+                        echo '
'; + } + break; + + case 2: + $ping = $this->whereIsTheCommand('ping'); + if (empty($ping)) { + ui_print_error_message(__('Ping executable does not exist.')); + } else { + echo '

'.__('Ping to %s', $ip).'

'; + echo '
';
+                        echo system($ping.' -c 5 '.$ip);
+                        echo '
'; + } + break; + + case 4: + $nmap = $this->whereIsTheCommand('nmap'); + if (empty($nmap)) { + ui_print_error_message(__('Nmap executable does not exist.')); + } else { + echo '

'.__('Basic TCP Scan on ').$ip.'

'; + echo '
';
+                        echo system($nmap.' -F '.$ip);
+                        echo '
'; + } + break; + + case 5: + echo '

'.__('Domain and IP information for ').$ip.'

'; + + $dig = $this->whereIsTheCommand('dig'); + if (empty($dig)) { + ui_print_error_message(__('Dig executable does not exist.')); + } else { + echo '
';
+                        echo system('dig '.$ip);
+                        echo '
'; + } + + $whois = $this->whereIsTheCommand('whois'); + if (empty($whois)) { + ui_print_error_message(__('Whois executable does not exist.')); + } else { + echo '
';
+                        echo system('whois '.$ip);
+                        echo '
'; + } + break; + + case 3: + $snmp_obj = [ + 'ip_target' => $ip, + 'snmp_version' => $snmp_version, + 'snmp_community' => $community, + 'format' => '-Oqn', + ]; + + $snmp_obj['base_oid'] = '.1.3.6.1.2.1.1.3.0'; + $result = get_h_snmpwalk($snmp_obj); + echo '

'.__('SNMP information for ').$ip.'

'; + echo '

'.__('Uptime').'

'; + echo '
';
+                    if (empty($result)) {
+                        ui_print_error_message(__('Target unreachable.'));
+                        break;
+                    } else {
+                        echo array_pop($result);
+                    }
+
+                    echo '
'; + echo '

'.__('Device info').'

'; + echo '
';
+                    $snmp_obj['base_oid'] = '.1.3.6.1.2.1.1.1.0';
+                    $result = get_h_snmpwalk($snmp_obj);
+                    if (empty($result)) {
+                        ui_print_error_message(__('Target unreachable.'));
+                        break;
+                    } else {
+                        echo array_pop($result);
+                    }
+
+                    echo '
'; + + echo '

Interface Information

'; + + $table = new StdClass(); + $table->class = 'databox'; + $table->head = []; + $table->head[] = __('Interface'); + $table->head[] = __('Status'); + + $i = 0; + + $base_oid = '.1.3.6.1.2.1.2.2.1'; + $idx_oids = '.1'; + $names_oids = '.2'; + $status_oids = '.8'; + + $snmp_obj['base_oid'] = $base_oid.$idx_oids; + $idx = get_h_snmpwalk($snmp_obj); + + $snmp_obj['base_oid'] = $base_oid.$names_oids; + $names = get_h_snmpwalk($snmp_obj); + + $snmp_obj['base_oid'] = $base_oid.$status_oids; + $statuses = get_h_snmpwalk($snmp_obj); + + foreach ($idx as $k => $v) { + $index = str_replace($base_oid.$idx_oids, '', $k); + $name = $names[$base_oid.$names_oids.$index]; + + $status = $statuses[$base_oid.$status_oids.$index]; + + $table->data[$i][0] = $name; + $table->data[$i++][1] = $status; + } + + html_print_table($table); + break; + + default: + // Ignore. + break; + } + } + + return $output; + + } + + + /** + * Load the JS and attach + * + * @return string Formed script string. + */ + private function loadJS() + { + $str = ''; + ob_start(); + ?> + + getMessage(); + + // Stop this execution, but continue 'globally'. + return; +} + +$obj->run(); diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index df5146711c..72b4ee4389 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -1351,6 +1351,13 @@ if ($is_sap) { $saptab = ''; } +// Network Tools tab. +$nettools['text'] = ''.html_print_image('images/nettool.png', true, ['title' => __('Network Tools')]).''; +if ($tab == 'nettools') { + $nettools['active'] = true; +} else { + $nettools['active'] = false; +} $onheader = [ 'manage' => $managetab, @@ -1366,7 +1373,7 @@ $onheader = [ 'wux_console' => $wux_console_tab, 'url_route_analyzer' => $url_route_analyzer_tab, 'sap_view' => $saptab, - + 'nettools' => $nettools, ]; // Added after it exists @@ -1536,6 +1543,10 @@ switch ($tab) { $tab_name = 'SAP View'; break; + case 'nettools': + $tab_name = 'Net Tools'; + break; + default: $tab_name = ''; $help_header = ''; @@ -1656,6 +1667,10 @@ switch ($tab) { include 'general/sap_view.php'; break; + case 'nettools': + include 'net_tools.php'; + break; + case 'extension': $found = false; foreach ($config['extensions'] as $extension) { From 7d5f4f8f65471067158ecee39de787f4f3f14c9c Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Thu, 17 Dec 2020 16:51:05 +0100 Subject: [PATCH 031/296] WIP: Backup upload --- pandora_console/godmode/setup/setup.php | 2 +- .../include/class/NetTools.class.php | 330 ++++++++++-------- pandora_console/include/constants.php | 7 + 3 files changed, 189 insertions(+), 150 deletions(-) diff --git a/pandora_console/godmode/setup/setup.php b/pandora_console/godmode/setup/setup.php index 7bfa1709f4..7fae0afa3b 100644 --- a/pandora_console/godmode/setup/setup.php +++ b/pandora_console/godmode/setup/setup.php @@ -147,7 +147,7 @@ $buttons['websocket_engine'] = [ $buttons['nettools'] = [ 'active' => false, - 'text' => ''.html_print_image('images/nettool.png', true, ['title' => __('Websocket engine')]).'', + 'text' => ''.html_print_image('images/nettool.png', true, ['title' => __('Network Tools')]).'', ]; if ($config['activate_gis']) { diff --git a/pandora_console/include/class/NetTools.class.php b/pandora_console/include/class/NetTools.class.php index 1e3e3343dd..779ddca25e 100644 --- a/pandora_console/include/class/NetTools.class.php +++ b/pandora_console/include/class/NetTools.class.php @@ -40,7 +40,7 @@ class NetTools extends HTML /** - * Undocumented function + * Constructor. * * @param string $origin Origin of the request. */ @@ -64,15 +64,11 @@ class NetTools extends HTML } // Capture needed parameter for agent form. - $this->operation = get_parameter('operation', 0); - $this->community = get_parameter('community', 'public'); - $this->ip = get_parameter('select_ips'); - $this->snmp_version = get_parameter('select_version'); - - // Show form. - $this->id_agente = get_parameter('id_agente', 0); - - // Capture needed parameters for agent executions. + $this->id_agente = (int) get_parameter('id_agente', 0); + $this->operation = (int) get_parameter('operation', 0); + $this->community = (string) get_parameter('community', 'public'); + $this->ip = (string) get_parameter('select_ips'); + $this->snmp_version = (string) get_parameter('select_version'); } else if ($this->origin === 'setup') { if (check_acl($config['id_user'], 0, 'PM') === false) { db_pandora_audit( @@ -99,7 +95,7 @@ class NetTools extends HTML /** - * Undocumented function + * Run action. * * @return void */ @@ -133,7 +129,10 @@ class NetTools extends HTML $network_tools_config['dig_path'] = $this->pathDig; $network_tools_config['snmpget_path'] = $this->pathSnmpget; - $result = config_update_value('network_tools_config', json_encode($network_tools_config)); + $result = config_update_value( + 'network_tools_config', + json_encode($network_tools_config) + ); ui_print_result_message( $result, @@ -259,11 +258,11 @@ class NetTools extends HTML $table->data[0][1] = html_print_select( [ - 1 => __('Traceroute'), - 2 => __('Ping host & Latency'), - 3 => __('SNMP Interface status'), - 4 => __('Basic TCP Port Scan'), - 5 => __('DiG/Whois Lookup'), + COMMAND_TRACEROUTE => __('Traceroute'), + COMMAND_PING => __('Ping host & Latency'), + COMMAND_SNMP => __('SNMP Interface status'), + COMMAND_NMAP => __('Basic TCP Port Scan'), + COMMAND_DIGWHOIS => __('DiG/Whois Lookup'), ], 'operation', $this->operation, @@ -316,7 +315,7 @@ class NetTools extends HTML // Output string. $output = ''; - $output .= "
"; + $output .= ''; $output .= html_print_table($table, true); $output .= '
'; @@ -328,14 +327,10 @@ class NetTools extends HTML ] ); - if ($this->operation === true) { + if ($this->operation !== 0) { // Execute form. - $executionResult = $this->netToolsExecution($this->operation, $this->ip, $this->community, $this->snmp_version); - echo $executionResult; + echo $this->netToolsExecution($this->operation, $this->ip, $this->community, $this->snmp_version); } - - echo '
'; - } @@ -346,45 +341,45 @@ class NetTools extends HTML * * @return string Path. */ - private function whereIsTheCommand($command) + private function whereIsTheCommand(string $command) { global $config; if (isset($config['network_tools_config'])) { - $network_tools_config = json_decode($config['network_tools_config'], true); + $network_tools_config = json_decode(io_safe_output($config['network_tools_config']), true); $traceroute_path = $network_tools_config['traceroute_path']; - $ping_path = $network_tools_config['ping_path']; - $nmap_path = $network_tools_config['nmap_path']; - $dig_path = $network_tools_config['dig_path']; - $snmpget_path = $network_tools_config['snmpget_path']; + $ping_path = $network_tools_config['ping_path']; + $nmap_path = $network_tools_config['nmap_path']; + $dig_path = $network_tools_config['dig_path']; + $snmpget_path = $network_tools_config['snmpget_path']; switch ($command) { case 'traceroute': - if (!empty($traceroute_path)) { + if (empty($traceroute_path) === false) { return $traceroute_path; } break; case 'ping': - if (!empty($ping_path)) { + if (empty($ping_path) === false) { return $ping_path; } break; case 'nmap': - if (!empty($nmap_path)) { + if (empty($nmap_path) === false) { return $nmap_path; } break; case 'dig': - if (!empty($dig_path)) { + if (empty($dig_path) === false) { return $dig_path; } break; case 'snmpget': - if (!empty($snmpget_path)) { + if (empty($snmpget_path) === false) { return $snmpget_path; } break; @@ -415,6 +410,44 @@ class NetTools extends HTML } + /** + * Create the output for show. + * + * @param string $command Command for execute. + * @param string $caption Description of the execution. + * + * @return void + */ + private function performExecution(string $command='', string $caption='') + { + $output = ''; + + try { + // If caption is not added, don't show anything. + if (empty($caption) === false) { + $output .= sprintf('

%s

', $caption); + } + + $output .= '
';
+
+            // Only perform an execution if command is passed. Avoid errors.
+            if (empty($command) === false) {
+                ob_start();
+                system($command);
+                $output .= ob_get_clean();
+            } else {
+                $output .= __('No command for perform');
+            }
+
+            $output .= '
'; + } catch (\Throwable $th) { + $output = __('Something went wrong while perform the execution. Please check the configuration.'); + } + + echo $output; + } + + /** * Execute net tools action. * @@ -429,146 +462,145 @@ class NetTools extends HTML { $output = ''; - if (!validate_address($ip)) { + if (validate_address($ip) === false) { $output .= ui_print_error_message( __('The ip or dns name entered cannot be resolved'), '', true ); } else { - switch ($operation) { - case 1: - $traceroute = $this->whereIsTheCommand('traceroute'); - if (empty($traceroute)) { - ui_print_error_message(__('Traceroute executable does not exist.')); - } else { - echo '

'.__('Traceroute to ').$ip.'

'; - echo '
';
-                        echo system($traceroute.' '.$ip);
-                        echo '
'; - } - break; + if ($operation === COMMAND_SNMP) { + $snmp_obj = [ + 'ip_target' => $ip, + 'snmp_version' => $snmp_version, + 'snmp_community' => $community, + 'format' => '-Oqn', + ]; - case 2: - $ping = $this->whereIsTheCommand('ping'); - if (empty($ping)) { - ui_print_error_message(__('Ping executable does not exist.')); - } else { - echo '

'.__('Ping to %s', $ip).'

'; - echo '
';
-                        echo system($ping.' -c 5 '.$ip);
-                        echo '
'; - } - break; + echo '

'.__('SNMP information for ').$ip.'

'; - case 4: - $nmap = $this->whereIsTheCommand('nmap'); - if (empty($nmap)) { - ui_print_error_message(__('Nmap executable does not exist.')); - } else { - echo '

'.__('Basic TCP Scan on ').$ip.'

'; - echo '
';
-                        echo system($nmap.' -F '.$ip);
-                        echo '
'; - } - break; - - case 5: - echo '

'.__('Domain and IP information for ').$ip.'

'; - - $dig = $this->whereIsTheCommand('dig'); - if (empty($dig)) { - ui_print_error_message(__('Dig executable does not exist.')); - } else { - echo '
';
-                        echo system('dig '.$ip);
-                        echo '
'; - } - - $whois = $this->whereIsTheCommand('whois'); - if (empty($whois)) { - ui_print_error_message(__('Whois executable does not exist.')); - } else { - echo '
';
-                        echo system('whois '.$ip);
-                        echo '
'; - } - break; - - case 3: - $snmp_obj = [ - 'ip_target' => $ip, - 'snmp_version' => $snmp_version, - 'snmp_community' => $community, - 'format' => '-Oqn', - ]; - - $snmp_obj['base_oid'] = '.1.3.6.1.2.1.1.3.0'; - $result = get_h_snmpwalk($snmp_obj); - echo '

'.__('SNMP information for ').$ip.'

'; + $snmp_obj['base_oid'] = '.1.3.6.1.2.1.1.3.0'; + $result = get_h_snmpwalk($snmp_obj); + if (empty($result) === true) { + ui_print_error_message(__('Target unreachable.')); + return null; + } else { echo '

'.__('Uptime').'

'; echo '
';
-                    if (empty($result)) {
-                        ui_print_error_message(__('Target unreachable.'));
-                        break;
-                    } else {
-                        echo array_pop($result);
-                    }
-
+                    echo array_pop($result);
                     echo '
'; + } + + $snmp_obj['base_oid'] = '.1.3.6.1.2.1.1.1.0'; + $result = get_h_snmpwalk($snmp_obj); + if (empty($result) === true) { + ui_print_error_message(__('Target unreachable.')); + return null; + } else { echo '

'.__('Device info').'

'; echo '
';
-                    $snmp_obj['base_oid'] = '.1.3.6.1.2.1.1.1.0';
-                    $result = get_h_snmpwalk($snmp_obj);
-                    if (empty($result)) {
-                        ui_print_error_message(__('Target unreachable.'));
-                        break;
-                    } else {
-                        echo array_pop($result);
-                    }
-
+                    echo array_pop($result);
                     echo '
'; + } - echo '

Interface Information

'; + echo '

Interface Information

'; - $table = new StdClass(); - $table->class = 'databox'; - $table->head = []; - $table->head[] = __('Interface'); - $table->head[] = __('Status'); + $table = new StdClass(); + $table->class = 'databox'; + $table->head = []; + $table->head[] = __('Interface'); + $table->head[] = __('Status'); - $i = 0; + $i = 0; - $base_oid = '.1.3.6.1.2.1.2.2.1'; - $idx_oids = '.1'; - $names_oids = '.2'; - $status_oids = '.8'; + $base_oid = '.1.3.6.1.2.1.2.2.1'; + $idx_oids = '.1'; + $names_oids = '.2'; + $status_oids = '.8'; - $snmp_obj['base_oid'] = $base_oid.$idx_oids; - $idx = get_h_snmpwalk($snmp_obj); + $snmp_obj['base_oid'] = $base_oid.$idx_oids; + $idx = get_h_snmpwalk($snmp_obj); - $snmp_obj['base_oid'] = $base_oid.$names_oids; - $names = get_h_snmpwalk($snmp_obj); + $snmp_obj['base_oid'] = $base_oid.$names_oids; + $names = get_h_snmpwalk($snmp_obj); - $snmp_obj['base_oid'] = $base_oid.$status_oids; - $statuses = get_h_snmpwalk($snmp_obj); + $snmp_obj['base_oid'] = $base_oid.$status_oids; + $statuses = get_h_snmpwalk($snmp_obj); - foreach ($idx as $k => $v) { - $index = str_replace($base_oid.$idx_oids, '', $k); - $name = $names[$base_oid.$names_oids.$index]; + foreach ($idx as $k => $v) { + $index = str_replace($base_oid.$idx_oids, '', $k); + $name = $names[$base_oid.$names_oids.$index]; - $status = $statuses[$base_oid.$status_oids.$index]; + $status = $statuses[$base_oid.$status_oids.$index]; - $table->data[$i][0] = $name; - $table->data[$i++][1] = $status; - } + $table->data[$i][0] = $name; + $table->data[$i++][1] = $status; + } - html_print_table($table); - break; + html_print_table($table); + } else if ($operation === COMMAND_DIGWHOIS) { + echo '

'.__('Domain and IP information for ').$ip.'

'; - default: - // Ignore. - break; + // Dig execution. + $dig = $this->whereIsTheCommand('dig'); + if (empty($dig) === true) { + ui_print_error_message(__('Dig executable does not exist.')); + } else { + $this->performExecution($dig); + } + + // Whois execution. + $whois = $this->whereIsTheCommand('whois'); + if (empty($whois) === true) { + ui_print_error_message(__('Whois executable does not exist.')); + } else { + $this->performExecution($whois); + } + + return; + } else { + switch ($operation) { + case COMMAND_TRACEROUTE: + $command = $this->whereIsTheCommand('traceroute'); + if (empty($command) === true) { + ui_print_error_message(__('Traceroute executable does not exist.')); + return; + } else { + $stringCommand = __('Traceroute to %s', $ip); + $executeCommand = sprintf('%s %s', $command, $ip); + } + break; + + case COMMAND_PING: + $command = $this->whereIsTheCommand('ping'); + if (empty($command) === true) { + ui_print_error_message(__('Ping executable does not exist.')); + return; + } else { + $stringCommand = __('Ping to %s', $ip); + $executeCommand = sprintf('%s -c 5 %s', $command, $ip); + } + break; + + case COMMAND_NMAP: + $command = $this->whereIsTheCommand('nmap'); + if (empty($command) === true) { + ui_print_error_message(__('Nmap executable does not exist.')); + return; + } else { + $stringCommand = __('Basic TCP Scan on %s', $ip); + $executeCommand = sprintf('%s -F %s', $command, $ip); + } + break; + + default: + // Nothing to do. + $stringCommand = ''; + $executeCommand = ''; + break; + } + + $this->performExecution($executeCommand, $stringCommand); } } diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index 54f4c286f2..d8dfa770f2 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -747,3 +747,10 @@ define('MODULE_TYPE_REMOTE_CMD_PROC', 35); define('MODULE_TYPE_REMOTE_CMD_STRING', 36); define('MODULE_TYPE_REMOTE_CMD_INC', 37); define('MODULE_TYPE_KEEP_ALIVE', 100); + +// Commands for network tools. +define('COMMAND_TRACEROUTE', 1); +define('COMMAND_PING', 2); +define('COMMAND_SNMP', 3); +define('COMMAND_NMAP', 4); +define('COMMAND_DIGWHOIS', 5); From a8ab897d44058353a1a16097a256f32c4bc6ac77 Mon Sep 17 00:00:00 2001 From: Luis Calvo Date: Thu, 17 Dec 2020 17:42:53 +0100 Subject: [PATCH 032/296] Fixed tokens htpp_auth user,avoid repetiton --- .../godmode/agentes/configurar_agente.php | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 422d4d0f13..2fa17d754f 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -1570,24 +1570,43 @@ if ($update_module) { 'module_macros' => $module_macros, ]; - if ($id_module_type == 30 || $id_module_type == 31 || $id_module_type == 32 || $id_module_type == 33) { - $plugin_parameter_split = explode(' ', $values['plugin_parameter']); + if (preg_match('/http_auth_user/m', $values['plugin_parameter'])) { + $http_user_conf = true; + } - $values['plugin_parameter'] = ''; + if (preg_match('/http_auth_pass/m', $values['plugin_parameter'])) { + $http_pass_conf = true; + } - foreach ($plugin_parameter_split as $key => $value) { - if ($key == 1) { - if ($http_user) { - $values['plugin_parameter'] .= 'http_auth_user '.$http_user.' '; + + if (!$http_user_conf || !$http_pass_conf) { + if ($id_module_type == 30 || $id_module_type == 31 || $id_module_type == 32 || $id_module_type == 33) { + $plugin_parameter_split = explode(' ', $values['plugin_parameter']); + + $values['plugin_parameter'] = ''; + + foreach ($plugin_parameter_split as $key => $value) { + if ($key == 1) { + if ($http_user) { + if ($http_user_conf) { + continue; + } + + $values['plugin_parameter'] .= 'http_auth_user '.$http_user.' '; + } + + if ($http_pass) { + if ($http_user_pass) { + continue; + } + + $values['plugin_parameter'] .= 'http_auth_pass '.$http_pass.' '; + } + + $values['plugin_parameter'] .= $value.' '; + } else { + $values['plugin_parameter'] .= $value.' '; } - - if ($http_pass) { - $values['plugin_parameter'] .= 'http_auth_pass '.$http_pass.' '; - } - - $values['plugin_parameter'] .= $value.' '; - } else { - $values['plugin_parameter'] .= $value.' '; } } } From daa6e47768da779b257246719c0fe6183b631cc0 Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Thu, 17 Dec 2020 19:33:10 +0100 Subject: [PATCH 033/296] Changes ended --- pandora_console/include/class/NetTools.class.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/class/NetTools.class.php b/pandora_console/include/class/NetTools.class.php index 779ddca25e..e519019158 100644 --- a/pandora_console/include/class/NetTools.class.php +++ b/pandora_console/include/class/NetTools.class.php @@ -121,6 +121,8 @@ class NetTools extends HTML */ private function setupNetToolsForm() { + global $config; + if ($this->updatePaths === true) { $network_tools_config = []; $network_tools_config['traceroute_path'] = $this->pathTraceroute; @@ -140,7 +142,7 @@ class NetTools extends HTML __('Set the paths.') ); } else { - if (isset($config['network_tools_config'])) { + if (isset($config['network_tools_config']) === true) { $network_tools_config_output = io_safe_output($config['network_tools_config']); $network_tools_config = json_decode($network_tools_config_output, true); // Setting paths. @@ -345,7 +347,7 @@ class NetTools extends HTML { global $config; - if (isset($config['network_tools_config'])) { + if (isset($config['network_tools_config']) === true) { $network_tools_config = json_decode(io_safe_output($config['network_tools_config']), true); $traceroute_path = $network_tools_config['traceroute_path']; $ping_path = $network_tools_config['ping_path']; @@ -395,14 +397,14 @@ class NetTools extends HTML $result = explode(':', $output); $result = trim($result[1]); - if (empty($result)) { + if (empty($result) === true) { return null; } $result = explode(' ', $result); $fullpath = trim($result[0]); - if (! file_exists($fullpath)) { + if (file_exists($fullpath) === false) { return null; } From 5f0d686034a7be45d5250910bbce7e8c243cfded Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Fri, 18 Dec 2020 12:31:44 +0100 Subject: [PATCH 034/296] Changed Network Tools for External Tools --- pandora_console/extensions/net_tools.php | 506 ------------------ ...net_tools.php => setup_external_tools.php} | 8 +- ...ools.class.php => ExternalTools.class.php} | 99 +++- pandora_console/include/constants.php | 2 +- pandora_console/include/styles/pandora.css | 7 + .../{net_tools.php => external_tools.php} | 10 +- .../operation/agentes/ver_agente.php | 20 +- 7 files changed, 113 insertions(+), 539 deletions(-) delete mode 100644 pandora_console/extensions/net_tools.php rename pandora_console/godmode/setup/{setup_net_tools.php => setup_external_tools.php} (89%) rename pandora_console/include/class/{NetTools.class.php => ExternalTools.class.php} (87%) rename pandora_console/operation/agentes/{net_tools.php => external_tools.php} (86%) diff --git a/pandora_console/extensions/net_tools.php b/pandora_console/extensions/net_tools.php deleted file mode 100644 index b23c5b1fe0..0000000000 --- a/pandora_console/extensions/net_tools.php +++ /dev/null @@ -1,506 +0,0 @@ -'.__('Traceroute to ').$ip.''; - echo '
';
-                    echo system($traceroute.' '.$ip);
-                    echo '
'; - } - break; - - case 2: - $ping = whereis_the_command('ping'); - if (empty($ping)) { - ui_print_error_message(__('Ping executable does not exist.')); - } else { - echo '

'.__('Ping to %s', $ip).'

'; - echo '
';
-                    echo system($ping.' -c 5 '.$ip);
-                    echo '
'; - } - break; - - case 4: - $nmap = whereis_the_command('nmap'); - if (empty($nmap)) { - ui_print_error_message(__('Nmap executable does not exist.')); - } else { - echo '

'.__('Basic TCP Scan on ').$ip.'

'; - echo '
';
-                    echo system($nmap.' -F '.$ip);
-                    echo '
'; - } - break; - - case 5: - echo '

'.__('Domain and IP information for ').$ip.'

'; - - $dig = whereis_the_command('dig'); - if (empty($dig)) { - ui_print_error_message(__('Dig executable does not exist.')); - } else { - echo '
';
-                    echo system('dig '.$ip);
-                    echo '
'; - } - - $whois = whereis_the_command('whois'); - if (empty($whois)) { - ui_print_error_message(__('Whois executable does not exist.')); - } else { - echo '
';
-                    echo system('whois '.$ip);
-                    echo '
'; - } - break; - - case 3: - $snmp_obj = [ - 'ip_target' => $ip, - 'snmp_version' => $snmp_version, - 'snmp_community' => $community, - 'format' => '-Oqn', - ]; - - $snmp_obj['base_oid'] = '.1.3.6.1.2.1.1.3.0'; - $result = get_h_snmpwalk($snmp_obj); - echo '

'.__('SNMP information for ').$ip.'

'; - echo '

'.__('Uptime').'

'; - echo '
';
-                if (empty($result)) {
-                    ui_print_error_message(__('Target unreachable.'));
-                    break;
-                } else {
-                    echo array_pop($result);
-                }
-
-                echo '
'; - echo '

'.__('Device info').'

'; - echo '
';
-                $snmp_obj['base_oid'] = '.1.3.6.1.2.1.1.1.0';
-                $result = get_h_snmpwalk($snmp_obj);
-                if (empty($result)) {
-                    ui_print_error_message(__('Target unreachable.'));
-                    break;
-                } else {
-                    echo array_pop($result);
-                }
-
-                echo '
'; - - echo '

Interface Information

'; - - $table = new StdClass(); - $table->class = 'databox'; - $table->head = []; - $table->head[] = __('Interface'); - $table->head[] = __('Status'); - - $i = 0; - - $base_oid = '.1.3.6.1.2.1.2.2.1'; - $idx_oids = '.1'; - $names_oids = '.2'; - $status_oids = '.8'; - - $snmp_obj['base_oid'] = $base_oid.$idx_oids; - $idx = get_h_snmpwalk($snmp_obj); - - $snmp_obj['base_oid'] = $base_oid.$names_oids; - $names = get_h_snmpwalk($snmp_obj); - - $snmp_obj['base_oid'] = $base_oid.$status_oids; - $statuses = get_h_snmpwalk($snmp_obj); - - foreach ($idx as $k => $v) { - $index = str_replace($base_oid.$idx_oids, '', $k); - $name = $names[$base_oid.$names_oids.$index]; - - $status = $statuses[$base_oid.$status_oids.$index]; - - $table->data[$i][0] = $name; - $table->data[$i++][1] = $status; - } - - html_print_table($table); - break; - - default: - // Ignore. - break; - } - } - -} - - -/** - * Main function. - * - * @return void - */ -function main_net_tools() -{ - $operation = get_parameter('operation', 0); - $community = get_parameter('community', 'public'); - $ip = get_parameter('select_ips'); - $snmp_version = get_parameter('select_version'); - - // Show form. - $id_agente = get_parameter('id_agente', 0); - $principal_ip = db_get_sql( - sprintf( - 'SELECT direccion FROM tagente WHERE id_agente = %d', - $id_agente - ) - ); - - $list_address = db_get_all_rows_sql( - sprintf( - 'SELECT id_a FROM taddress_agent WHERE id_agent = %d', - $id_agente - ) - ); - foreach ($list_address as $address) { - $ids[] = join(',', $address); - } - - $ips = db_get_all_rows_sql( - sprintf( - 'SELECT ip FROM taddress WHERE id_a IN (%s)', - join(',', $ids) - ) - ); - - if ($ips == '') { - echo "
".__('The agent hasn\'t got IP').'
'; - return; - } - - // Javascript. - ?> - - '; - echo "
"; - echo ""; - echo ''; - echo ''; - echo "'; - echo '
'; - echo __('Operation'); - echo ''; - - html_print_select( - [ - 1 => __('Traceroute'), - 2 => __('Ping host & Latency'), - 3 => __('SNMP Interface status'), - 4 => __('Basic TCP Port Scan'), - 5 => __('DiG/Whois Lookup'), - ], - 'operation', - $operation, - 'mostrarColumns(this.value)', - __('Please select') - ); - - echo ''; - echo __('IP address'); - echo ''; - - $ips_for_select = array_reduce( - $ips, - function ($carry, $item) { - $carry[$item['ip']] = $item['ip']; - return $carry; - } - ); - - html_print_select( - $ips_for_select, - 'select_ips', - $principal_ip - ); - echo '"; - echo __('SNMP Version'); - html_print_select( - [ - '1' => 'v1', - '2c' => 'v2c', - ], - 'select_version', - $snmp_version - ); - echo ''; - echo __('SNMP Community').' '; - html_print_input_text('community', $community); - echo ''; - echo ""; - echo '
'; - echo '
'; - - if ($operation) { - // Execute form. - net_tools_execute($operation, $ip, $community, $snmp_version); - } - - echo '
'; -} - - -/** - * Add option. - * - * @return void - */ -function godmode_net_tools() -{ - global $config; - - check_login(); - - if (! check_acl($config['id_user'], 0, 'PM')) { - db_pandora_audit( - 'ACL Violation', - 'Trying to access Profile Management' - ); - include 'general/noaccess.php'; - return; - } - - ui_print_page_header( - __('Config Network Tools'), - '', - false, - 'network_tools_tab' - ); - - $update_traceroute = (bool) get_parameter('update_traceroute', 0); - - $traceroute_path = (string) get_parameter('traceroute_path', ''); - $ping_path = (string) get_parameter('ping_path', ''); - $nmap_path = (string) get_parameter('nmap_path', ''); - $dig_path = (string) get_parameter('dig_path', ''); - $snmpget_path = (string) get_parameter('snmpget_path', ''); - - if ($update_traceroute) { - $network_tools_config = []; - $network_tools_config['traceroute_path'] = $traceroute_path; - $network_tools_config['ping_path'] = $ping_path; - $network_tools_config['nmap_path'] = $nmap_path; - $network_tools_config['dig_path'] = $dig_path; - $network_tools_config['snmpget_path'] = $snmpget_path; - - $result = config_update_value('network_tools_config', json_encode($network_tools_config)); - - ui_print_result_message( - $result, - __('Set the paths.'), - __('Set the paths.') - ); - } else { - if (isset($config['network_tools_config'])) { - $network_tools_config_output = io_safe_output($config['network_tools_config']); - $network_tools_config = json_decode($network_tools_config_output, true); - $traceroute_path = $network_tools_config['traceroute_path']; - $ping_path = $network_tools_config['ping_path']; - $nmap_path = $network_tools_config['nmap_path']; - $dig_path = $network_tools_config['dig_path']; - $snmpget_path = $network_tools_config['snmpget_path']; - } - } - - $table = null; - $table->width = '100%'; - - $table->data = []; - - $table->data[0][0] = __('Traceroute path'); - $table->data[0][1] = html_print_input_text('traceroute_path', $traceroute_path, '', 40, 255, true); - - $table->data[1][0] = __('Ping path'); - $table->data[1][1] = html_print_input_text('ping_path', $ping_path, '', 40, 255, true); - - $table->data[2][0] = __('Nmap path'); - $table->data[2][1] = html_print_input_text('nmap_path', $nmap_path, '', 40, 255, true); - - $table->data[3][0] = __('Dig path'); - $table->data[3][1] = html_print_input_text('dig_path', $dig_path, '', 40, 255, true); - - $table->data[4][0] = __('Snmpget path'); - $table->data[4][1] = html_print_input_text('snmpget_path', $snmpget_path, '', 40, 255, true); - - echo '
'; - echo '
'; - echo ''.__('Options').''; - html_print_input_hidden('update_traceroute', 1); - html_print_table($table); - echo '
'; - - echo '
'; - html_print_submit_button(__('Update'), 'update_button', false, 'class="sub upd"'); - echo '
'; - echo '
'; -} - - -extensions_add_godmode_menu_option(__('Config Network Tools'), 'PM'); -extensions_add_godmode_function('godmode_net_tools'); diff --git a/pandora_console/godmode/setup/setup_net_tools.php b/pandora_console/godmode/setup/setup_external_tools.php similarity index 89% rename from pandora_console/godmode/setup/setup_net_tools.php rename to pandora_console/godmode/setup/setup_external_tools.php index 4dafb6e39c..30bdd6b188 100644 --- a/pandora_console/godmode/setup/setup_net_tools.php +++ b/pandora_console/godmode/setup/setup_external_tools.php @@ -1,6 +1,6 @@ getMessage(); + echo '[ExternalTools]'.$e->getMessage(); // Stop this execution, but continue 'globally'. return; diff --git a/pandora_console/include/class/NetTools.class.php b/pandora_console/include/class/ExternalTools.class.php similarity index 87% rename from pandora_console/include/class/NetTools.class.php rename to pandora_console/include/class/ExternalTools.class.php index e519019158..97b644a11f 100644 --- a/pandora_console/include/class/NetTools.class.php +++ b/pandora_console/include/class/ExternalTools.class.php @@ -1,6 +1,6 @@ updatePaths = (bool) get_parameter('update_paths', 0); + // Capture paths. $this->pathTraceroute = (string) get_parameter('traceroute_path'); $this->pathPing = (string) get_parameter('ping_path'); @@ -103,10 +104,10 @@ class NetTools extends HTML { if ($this->origin === 'agent') { // Print tool form. - $this->agentNetToolsForm(); + $this->agentExternalToolsForm(); } else if ($this->origin === 'setup') { // Print setup form. - $this->setupNetToolsForm(); + $this->setupExternalToolsForm(); } // Anyway, load JS. @@ -115,11 +116,11 @@ class NetTools extends HTML /** - * Print the form for setup the network tools. + * Print the form for setup the external tools. * * @return void */ - private function setupNetToolsForm() + private function setupExternalToolsForm() { global $config; @@ -151,6 +152,7 @@ class NetTools extends HTML $this->pathNmap = $network_tools_config['nmap_path']; $this->pathDig = $network_tools_config['dig_path']; $this->pathSnmpget = $network_tools_config['snmpget_path']; + $this->pathCustomComm = ($network_tools_config['custom_command'] ?? ['a' => 'a']); } } @@ -175,6 +177,70 @@ class NetTools extends HTML $table->data[4][0] = __('Snmpget path'); $table->data[4][1] = html_print_input_text('snmpget_path', $this->pathSnmpget, '', 40, 255, true); + $table->data[5][0] = html_print_div( + [ + 'class' => 'title_custom_commands bolder float-left', + 'content' => __('Custom commands') + ], + true + ); + + $table->data[5][0] .= html_print_div( + [ + 'id' => 'add_button_custom_command', + 'content' => html_print_image( + 'images/add.png', + true, + ['title' => __('Add new custom command') ] + ) + ], + true + ); + + $table->data[6][0] = __('Command'); + $table->data[6][1] = __('Parameters'); + + $i = 0; + $iRow = 6; + foreach ($this->pathCustomComm as $command) { + $i++; + $iRow++; + + // Fill the fields. + $customCommand = ($command['custom_command'] ?? ''); + $customParams = ($command['custom_params'] ?? ''); + // Attach the fields. + $table->rowid[$iRow] = 'custom_row_'.$i; + $table->data[$iRow][0] = html_print_input_text( + 'command_custom_'.$i, + $customCommand, + '', + 40, + 255, + true + ); + $table->data[$iRow][1] = html_print_input_text( + 'params_custom_'.$i, + $customParams, + '', + 40, + 255, + true + ); + $table->data[$iRow][2] = html_print_div( + [ + 'id' => 'delete_custom_'.$i, + 'class' => '', + 'content' => html_print_image( + 'images/delete.png', + true, + ['title' => __('Delete this custom command') ] + ) + ], + true + ); + } + $form = '
'; $form .= '
'; $form .= ''.__('Options').''; @@ -198,11 +264,11 @@ class NetTools extends HTML /** - * Print the form for use the network tools. + * Print the form for use the external tools. * * @return void */ - private function agentNetToolsForm() + private function agentExternalToolsForm() { $principal_ip = db_get_sql( sprintf( @@ -252,7 +318,7 @@ class NetTools extends HTML // Form table. $table = new StdClass(); $table->class = 'databox filters w100p'; - $table->id = 'netToolTable'; + $table->id = 'externalToolTable'; $table->data = []; @@ -331,7 +397,7 @@ class NetTools extends HTML if ($this->operation !== 0) { // Execute form. - echo $this->netToolsExecution($this->operation, $this->ip, $this->community, $this->snmp_version); + echo $this->externalToolsExecution($this->operation, $this->ip, $this->community, $this->snmp_version); } } @@ -451,7 +517,7 @@ class NetTools extends HTML /** - * Execute net tools action. + * Execute external tools action. * * @param integer $operation Operation. * @param string $ip Ip. @@ -460,7 +526,7 @@ class NetTools extends HTML * * @return string String formed result of execution. */ - public function netToolsExecution(int $operation, string $ip, string $community, string $snmp_version) + public function externalToolsExecution(int $operation, string $ip, string $community, string $snmp_version) { $output = ''; @@ -623,6 +689,13 @@ class NetTools extends HTML ?> diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index d3005d5639..fcf9adce0d 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -6273,3 +6273,55 @@ function ui_print_reveal_password(string $name, bool $return=false) echo $output; } + + +/** + * Generate a spinner box for waiting times + * + * @param string $text Text for show in spinner. English Loading for default. + * @param boolean $return If true, return the string with the formed element. + * + * @return string + */ +function ui_print_spinner(string $text='Loading', bool $return=false) +{ + $output = ''; + + $output .= '
'; + + $output .= html_print_div( + [ + 'id' => 'loading_spinner', + 'class' => 'white_box invisible', + 'content' => ''.$text.'...'.html_print_image( + 'images/spinner.gif', + true, + [ + 'border' => '0', + 'width' => '25px', + 'heigth' => '25px', + ] + ), + ], + true + ); + + $output .= '
'; + + $output .= ' + + '; + + if ($return === true) { + return $output; + } else { + echo $output; + } +} diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 9a1ce23dca..c2cb379ea4 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -792,6 +792,7 @@ p.center { cursor: help; } +/* Legacy spinner */ #loading { position: fixed; width: 200px; @@ -802,6 +803,18 @@ p.center { padding: 20px; } +/* New standard spinner */ +#loading_spinner { + position: fixed; + margin-left: 30%; + text-align: center; + top: 50%; + background-color: #fff; + border: 2px solid #82b92e; + box-shadow: 2px 2px 2px #9dbba1; + padding: 20px; +} + .tactical_set legend { text-align: left; color: #3f3f3f; From 0be3e0ab90cddc49622817126f4089896dcb9999 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 10 Feb 2021 15:00:23 +0100 Subject: [PATCH 096/296] 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 097/296] 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 098/296] 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 e727f7c276a63d515f1fc89c040b4e732056d17b Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Fri, 12 Feb 2021 11:28:13 +0100 Subject: [PATCH 099/296] Added modals and fixed some bugs --- .../massive/massive_add_action_alerts.php | 67 ++++++------- .../godmode/massive/massive_add_alerts.php | 14 ++- .../godmode/massive/massive_add_profiles.php | 48 +++++---- .../godmode/massive/massive_copy_modules.php | 60 +++++++----- .../massive/massive_delete_action_alerts.php | 45 ++++++--- .../godmode/massive/massive_delete_agents.php | 64 ++++++------ .../godmode/massive/massive_delete_alerts.php | 49 ++++++---- .../massive/massive_delete_modules.php | 71 +++++++------- .../massive/massive_delete_profiles.php | 48 +++++---- .../godmode/massive/massive_edit_agents.php | 85 +++++++++------- .../godmode/massive/massive_edit_modules.php | 93 +++++++++--------- .../godmode/massive/massive_edit_plugins.php | 44 ++++++--- .../massive/massive_enable_disable_alerts.php | 39 +++++--- .../godmode/massive/massive_operations.php | 84 ++++++++++------ .../massive/massive_standby_alerts.php | 43 +++++--- .../include/functions_massive_operations.php | 97 +++++++++++++++++++ pandora_console/include/functions_ui.php | 3 +- .../include/javascript/massive_operations.js | 93 ++++++++++++++++++ pandora_console/include/styles/pandora.css | 1 + 19 files changed, 690 insertions(+), 358 deletions(-) create mode 100644 pandora_console/include/functions_massive_operations.php create mode 100644 pandora_console/include/javascript/massive_operations.js diff --git a/pandora_console/godmode/massive/massive_add_action_alerts.php b/pandora_console/godmode/massive/massive_add_action_alerts.php index 7bfbbee09f..f9a02c8545 100755 --- a/pandora_console/godmode/massive/massive_add_action_alerts.php +++ b/pandora_console/godmode/massive/massive_add_action_alerts.php @@ -1,17 +1,32 @@ data[1][0] .= ''; $table->data[1][1] = html_print_select([], 'id_agents[]', 0, false, __('Any'), '', true, true); $table->data[2][0] = __('Alert templates'); -$table->data[2][0] .= ''; $table->data[2][1] = html_print_select([], 'id_alert_templates[]', '', '', '', '', true, true, true, '', $alert_templates == 0); $table->data[2][2] = __('When select agents'); $table->data[2][2] .= '
'; @@ -251,10 +263,8 @@ $agents_with_templates_json = json_encode($agents_with_templates_json); echo ""; -echo '
'; -html_print_input_hidden('add', 1); -html_print_submit_button(__('Add'), 'go', false, 'class="sub add"'); -echo '
'; +attachActionButton('add', 'create', $table->width); + echo ''; echo ''; @@ -265,23 +275,8 @@ ui_require_jquery_file('pandora.controls'); ?> - - "+value+""; }); $("#id_alert_templates").append (options); - $("#template_loading").hide (); + hideSpinner(); $select_template.enable (); }, "json" diff --git a/pandora_console/include/functions_massive_operations.php b/pandora_console/include/functions_massive_operations.php new file mode 100644 index 0000000000..389d87ddcc --- /dev/null +++ b/pandora_console/include/functions_massive_operations.php @@ -0,0 +1,97 @@ + 'action-buttons', + 'style' => sprintf('width: %s', $tableWidth), + 'content' => html_print_input_hidden( + $action, + 1 + ).html_print_button( + __($caption), + 'go', + false, + '', + sprintf('class="sub %s"', $class), + true + ), + ], + $return + ); +} diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index fcf9adce0d..8cb234db8e 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -6277,8 +6277,9 @@ function ui_print_reveal_password(string $name, bool $return=false) /** * Generate a spinner box for waiting times + * TIP: It's made for Massive Operations, but it migth used in entire project. * - * @param string $text Text for show in spinner. English Loading for default. + * @param string $text Text for show in spinner. English term Loading for default. * @param boolean $return If true, return the string with the formed element. * * @return string diff --git a/pandora_console/include/javascript/massive_operations.js b/pandora_console/include/javascript/massive_operations.js new file mode 100644 index 0000000000..dd1c8acd13 --- /dev/null +++ b/pandora_console/include/javascript/massive_operations.js @@ -0,0 +1,93 @@ +/** global $ */ +function massiveOperationValidation(contents, totalCount, limit, thisForm) { + var output = false; + + // If the amount of changes exceed the limit, the operation stops. + if (totalCount > limit) { + // Set the content. + $("#massive_modal") + .empty() + .html(contents.html); + // Set the title. + $("#massive_modal").prop("title", contents.title); + // Build the dialog for show the mesage. + $("#massive_modal").dialog({ + resizable: true, + draggable: true, + modal: true, + width: 800, + buttons: [ + { + text: "OK", + click: function() { + hideSpinner(); + $(this).dialog("close"); + return false; + } + } + ], + overlay: { + opacity: 0.5, + background: "black" + }, + closeOnEscape: false, + open: function(event, ui) { + $(".ui-dialog-titlebar-close").hide(); + } + }); + + return false; + } else { + confirmDialog({ + title: contents.title, + message: contents.question, + ok: contents.ok, + cancel: contents.cancel, + onAccept: function() { + showSpinner(); + output = true; + $("#" + thisForm).submit(); + }, + onDeny: function() { + hideSpinner(); + return false; + } + }); + } + + return output; +} + +/* +function showMassiveOperationMessage(message) { + $("#massive_modal") + .empty() + .html(message); + + $("#massive_modal").prop("title", "Massive operations"); + + $("#massive_modal").dialog({ + resizable: true, + draggable: true, + modal: true, + width: 800, + buttons: [ + { + text: "OK", + click: function() { + $(this).dialog("close"); + hideSpinner(); + } + } + ], + overlay: { + opacity: 0.5, + background: "black" + }, + closeOnEscape: false, + open: function(event, ui) { + $(".ui-dialog-titlebar-close").hide(); + } + }); +} +*/ diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index c2cb379ea4..79e5572823 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -813,6 +813,7 @@ p.center { border: 2px solid #82b92e; box-shadow: 2px 2px 2px #9dbba1; padding: 20px; + z-index: 100; } .tactical_set legend { From 24ed77b5a11bb383c6f2b0fedcf0312f7a547e10 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 12 Feb 2021 15:25:41 +0100 Subject: [PATCH 100/296] 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 101/296] 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 102/296] 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 103/296] 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 104/296] 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 45f89ccb4f22230f0f88013e08c72fd25a4dc14e Mon Sep 17 00:00:00 2001 From: marcos Date: Tue, 16 Feb 2021 11:55:51 +0100 Subject: [PATCH 105/296] fixed select style --- .../godmode/gis_maps/configure_gis_map.php | 24 ++++++++++++++++++- .../godmode/netflow/nf_edit_form.php | 12 +++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/pandora_console/godmode/gis_maps/configure_gis_map.php b/pandora_console/godmode/gis_maps/configure_gis_map.php index 1a0625d030..fa1351082c 100644 --- a/pandora_console/godmode/gis_maps/configure_gis_map.php +++ b/pandora_console/godmode/gis_maps/configure_gis_map.php @@ -469,7 +469,29 @@ if (users_can_manage_group_all('MM') === true) { } $table->data[2][0] = __('Group'); -$table->data[2][1] = html_print_select_groups(false, 'IW', $return_all_group, 'map_group_id', $map_group_id, '', '', '', true); +$table->data[2][1] = html_print_select_groups( + false, + 'IW', + $return_all_group, + 'map_group_id', + $map_group_id, + '', + '', + '', + true, + false, + true, + '', + false, + false, + false, + false, + 'id_grupo', + false, + false, + false, + '250px' +); $table->data[3][0] = __('Default zoom'); $table->data[3][1] = html_print_input_text('map_zoom_level', $map_zoom_level, '', 2, 4, true).html_print_input_hidden('map_levels_zoom', $map_levels_zoom, true); diff --git a/pandora_console/godmode/netflow/nf_edit_form.php b/pandora_console/godmode/netflow/nf_edit_form.php index f9c607c894..5fc9b9d0af 100644 --- a/pandora_console/godmode/netflow/nf_edit_form.php +++ b/pandora_console/godmode/netflow/nf_edit_form.php @@ -212,7 +212,17 @@ $table->data[1][1] = html_print_select_groups( -1, true, false, - false + false, + '', + false, + false, + false, + false, + 'id_grupo', + false, + false, + false, + '250px' ); if ($advanced_filter != '') { From 74ee4971d0ff6387cf8152ac0849c2e3207fce87 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 16 Feb 2021 12:14:56 +0100 Subject: [PATCH 106/296] 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 107/296] 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 45a2b7141d327d79acadd97362a648d8346c9b69 Mon Sep 17 00:00:00 2001 From: marcos Date: Wed, 17 Feb 2021 14:07:18 +0100 Subject: [PATCH 108/296] fixed error with group cordinator profile with agent management meta --- pandora_console/godmode/groups/group_list.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/groups/group_list.php b/pandora_console/godmode/groups/group_list.php index ad6eb27adf..55f38b3e35 100644 --- a/pandora_console/godmode/groups/group_list.php +++ b/pandora_console/godmode/groups/group_list.php @@ -251,7 +251,16 @@ if (is_ajax()) { $tab = (string) get_parameter('tab', 'groups'); -if ($tab != 'credbox' && ! check_acl($config['id_user'], 0, 'PM')) { +if ($tab != 'credbox' && ! check_acl( + $config['id_user'], + 0, + 'PM' +) && ! check_acl( + $config['id_user'], + 0, + 'AW' +) +) { db_pandora_audit( 'ACL Violation', 'Trying to access Group Management' From 6e3a3a1d386550668c0bd7e80a5f9e8a03b4aab2 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Thu, 18 Feb 2021 14:09:23 +0100 Subject: [PATCH 109/296] Fixed error reports sla selected modules in metaconsole --- .../godmode/reporting/reporting_builder.item_editor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index 52d94006d7..ea18927a0c 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -3279,7 +3279,7 @@ function print_SLA_list($width, $action, $idItem=null) - + Date: Thu, 18 Feb 2021 17:34:42 +0100 Subject: [PATCH 110/296] Ent 7059 no existe el console log en nuevas instalaciones --- pandora_console/include/config_process.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 535de7b0d3..85f3afb094 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -40,6 +40,7 @@ if (!is_dir($config['homedir'])) { } + // Help to debug problems. Override global PHP configuration global $develop_bypass; if ((int) $develop_bypass === 1) { @@ -164,6 +165,10 @@ if (session_status() === PHP_SESSION_NONE) { config_process_config(); config_prepare_session(); +if ((bool) $config['console_log_enabled'] === true) { + error_reporting(E_ALL ^ E_NOTICE); +} + // Set a the system timezone default if ((!isset($config['timezone'])) or ($config['timezone'] == '')) { $config['timezone'] = 'Europe/Berlin'; From 0f4f9cd461998022a613a3472376f094af475fce Mon Sep 17 00:00:00 2001 From: artica Date: Fri, 19 Feb 2021 01:00:21 +0100 Subject: [PATCH 111/296] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 40864e4e7d..24733f7f34 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.752-210218 +Version: 7.0NG.752-210219 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index c7091d62c5..aeaa4a82f9 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210218" +pandora_version="7.0NG.752-210219" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index fc942dfa86..bf7104f901 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1016,7 +1016,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.752'; -use constant AGENT_BUILD => '210218'; +use constant AGENT_BUILD => '210219'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 016c1b893a..ee75ed2adc 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210218 +%define release 210219 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 66a44cc3a1..5cb11cf13a 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210218 +%define release 210219 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index d7c5108279..e93ed65725 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210218" +PI_BUILD="210219" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index fa798cde71..b547ddf4c2 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{210218} +{210219} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 7811371ddf..e16ac3e4bd 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.752(Build 210218)") +#define PANDORA_VERSION ("7.0NG.752(Build 210219)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 66f4ec6695..d7af86296d 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.752(Build 210218))" + VALUE "ProductVersion", "(7.0NG.752(Build 210219))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 3826a0e0de..c786a460f7 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.752-210218 +Version: 7.0NG.752-210219 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 462cd30346..7a3b422a9c 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210218" +pandora_version="7.0NG.752-210219" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 85f3afb094..93d1106a31 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC210218'; +$build_version = 'PC210219'; $pandora_version = 'v7.0NG.752'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index de0494b4cb..886dae5b8c 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 94592960fc..ffd6140fe1 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210218 +%define release 210219 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 6b6bc24d6d..dbb530241f 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210218 +%define release 210219 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index d6033e863c..1005f4f432 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210218" +PI_BUILD="210219" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 7e9e70583e..6ecf77f652 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -35,7 +35,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.752 PS210218"; +my $version = "7.0NG.752 PS210219"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 6268ea9daa..b5a06c5edb 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.752 PS210218"; +my $version = "7.0NG.752 PS210219"; # save program name for logging my $progname = basename($0); From 0fb3ba92326a196cd4347b3d1d5d92cf31043c7f Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 19 Feb 2021 13:36:29 +0100 Subject: [PATCH 112/296] System status notifications filtered by subtype --- .../pandoradb_migrate_6.0_to_7.0.mysql.sql | 1 + .../godmode/setup/setup_notifications.php | 36 ++++- .../include/class/ConsoleSupervisor.php | 34 ++--- .../include/functions_notifications.php | 130 +++++++++++++++++- pandora_console/include/functions_ui.php | 23 +++- pandora_console/include/styles/pandora.css | 14 ++ .../users/user_edit_notifications.php | 5 +- pandora_console/pandoradb.sql | 1 + 8 files changed, 216 insertions(+), 28 deletions(-) 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 946db364f7..64683c2096 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 @@ -2392,6 +2392,7 @@ CREATE TABLE `tnotification_source` ( `enabled` int(1) DEFAULT NULL, `user_editable` int(1) DEFAULT NULL, `also_mail` int(1) DEFAULT NULL, + `subtype_blacklist` TEXT, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/godmode/setup/setup_notifications.php b/pandora_console/godmode/setup/setup_notifications.php index 102f47b634..a03812ddc4 100644 --- a/pandora_console/godmode/setup/setup_notifications.php +++ b/pandora_console/godmode/setup/setup_notifications.php @@ -65,6 +65,7 @@ if (get_parameter('remove_source_on_database', 0)) { if (get_parameter('update_config', 0)) { $element = (string) get_parameter('element', ''); $value = (int) get_parameter('value', 0); + $source = (string) get_parameter('source'); // Update the label value. ob_clean(); @@ -75,6 +76,37 @@ if (get_parameter('update_config', 0)) { $res = ($value) ? notifications_add_group_to_source($source, [0]) : notifications_remove_group_from_source($source, [0]); break; + case 'subtype': + $data = explode('.', $source, 2); + $source_id = $data[0]; + $subtype = $data[1]; + $source = notifications_get_all_sources( + [ 'id' => $source_id ] + ); + + if ($source !== false && is_array($source[0]) === true) { + $source = $source[0]; + + $blacklist = json_decode($source['subtype_blacklist'], 1); + if (json_last_error() !== JSON_ERROR_NONE) { + $blacklist = []; + } + + if ((bool) $value === true) { + unset($blacklist[$subtype]); + } else { + $blacklist[$subtype] = 1; + } + + $source['subtype_blacklist'] = json_encode($blacklist, 1); + $res = (bool) db_process_sql_update( + 'tnotification_source', + ['subtype_blacklist' => $source['subtype_blacklist']], + ['id' => $source['id']] + ); + } + break; + default: $res = (bool) db_process_sql_update( 'tnotification_source', @@ -337,7 +369,7 @@ function remove_source_elements(id, source_id) { function notifications_handle_change_element(event) { event.preventDefault(); - var match = /nt-([0-9]+)-(.*)/.exec(event.target.id); + var match = /nt-(.+)-(.*)/.exec(event.target.id); if (!match) { console.error( "Cannot handle change element. Id not valid: ", event.target.id @@ -356,6 +388,7 @@ function notifications_handle_change_element(event) { var value; switch (action.bit) { case 'enabled': + case 'subtype': case 'also_mail': case 'user_editable': case 'all_users': @@ -383,6 +416,7 @@ function notifications_handle_change_element(event) { } else { switch (action.bit) { case 'enabled': + case 'subtype': case 'also_mail': case 'user_editable': case 'all_users': diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php index cc52f2062f..017d4a1a80 100644 --- a/pandora_console/include/class/ConsoleSupervisor.php +++ b/pandora_console/include/class/ConsoleSupervisor.php @@ -115,12 +115,6 @@ class ConsoleSupervisor } else { $this->enabled = (bool) $source['enabled']; $this->sourceId = $source['id']; - - // Assign targets. - $targets = get_notification_source_targets($this->sourceId); - $this->targetGroups = $targets['groups']; - $this->targetUsers = $targets['users']; - $this->targetUpdated = true; } return $this; @@ -620,20 +614,28 @@ class ConsoleSupervisor return; } - if ($this->targetUpdated === false) { - $targets = get_notification_source_targets($this->sourceId); - $this->targetGroups = $targets['groups']; - $this->targetUsers = $targets['users']; - $this->targetUpdated = false; - } - if ($source_id === 0) { $source_id = $this->sourceId; - // Assign targets. - $targets = get_notification_source_targets($source_id); + } + + static $_cache_targets; + $key = $source_id.'|'.$data['type']; + + if ($_cache_targets === null) { + $_cache_targets = []; + } + + if ($_cache_targets[$key] !== null) { + $targets = $_cache_targets[$key]; + } else { + $targets = get_notification_source_targets( + $source_id, + $data['type'] + ); $this->targetGroups = $targets['groups']; $this->targetUsers = $targets['users']; - $this->targetUpdated = false; + + $_cache_targets[$key] = $targets; } switch ($data['type']) { diff --git a/pandora_console/include/functions_notifications.php b/pandora_console/include/functions_notifications.php index 67e5c6e547..2765f2cee3 100644 --- a/pandora_console/include/functions_notifications.php +++ b/pandora_console/include/functions_notifications.php @@ -116,6 +116,70 @@ function get_notification_targets(int $id_message) } +/** + * Return subtypes. + * + * @param string|null $source Source filter or all. + * + * @return array + */ +function notifications_get_subtypes(?string $source=null) +{ + $subtypes = [ + 'System status' => [ + 'NOTIF.LICENSE.LIMITED', + 'NOTIF.LICENSE.EXPIRATION', + 'NOTIF.FILES.ATTACHMENT', + 'NOTIF.FILES.DATAIN', + 'NOTIF.FILES.DATAIN.BADXML', + 'NOTIF.PHP.SAFE_MODE', + 'NOTIF.PHP.INPUT_TIME', + 'NOTIF.PHP.EXECUTION_TIME', + 'NOTIF.PHP.UPLOAD_MAX_FILESIZE', + 'NOTIF.PHP.MEMORY_LIMIT', + 'NOTIF.PHP.DISABLE_FUNCTIONS', + 'NOTIF.PHP.PHANTOMJS', + 'NOTIF.PHP.VERSION', + 'NOTIF.HISTORYDB', + 'NOTIF.PANDORADB', + 'NOTIF.PANDORADB.HISTORICAL', + 'NOTIF.HISTORYDB.MR', + 'NOTIF.EXT.ELASTICSEARCH', + 'NOTIF.EXT.LOGSTASH', + 'NOTIF.METACONSOLE.DB_CONNECTION', + 'NOTIF.DOWNTIME', + 'NOTIF.UPDATEMANAGER.REGISTRATION', + 'NOTIF.MISC.EVENTSTORMPROTECTION', + 'NOTIF.MISC.DEVELOPBYPASS', + 'NOTIF.MISC.FONTPATH', + 'NOTIF.SECURITY.DEFAULT_PASSWORD', + 'NOTIF.UPDATEMANAGER.OPENSETUP', + 'NOTIF.UPDATEMANAGER.UPDATE', + 'NOTIF.UPDATEMANAGER.MINOR', + 'NOTIF.UPDATEMANAGER.MESSAGES', + 'NOTIF.CRON.CONFIGURED', + 'NOTIF.ALLOWOVERRIDE.MESSAGE', + 'NOTIF.HAMASTER.MESSAGE', + 'NOTIF.SERVER.STATUS', + 'NOTIF.SERVER.STATUS.ID_SERVER', + 'NOTIF.SERVER.QUEUE.ID_SERVER', + 'NOTIF.SERVER.MASTER', + 'NOTIF.SERVER.STATUS.ID_SERVER', + ], + ]; + + if ($source === null) { + return $subtypes; + } + + if (isset($subtypes[$source]) === true) { + return $subtypes[$source]; + } + + return []; +} + + /** * Check if current user has grants to read this notification * @@ -160,14 +224,22 @@ function check_notification_readable(int $id_message) * Returns the target users and groups assigned to be notified on * desired source. * - * @param integer $id_source Source identificator. + * @param integer $id_source Source identificator. + * @param string|null $subtype Subtype identification. * * @return array [users] and [groups] with the targets. */ -function get_notification_source_targets(int $id_source) +function get_notification_source_targets(int $id_source, ?string $subtype=null) { $ret = []; + if ($subtype !== null) { + $filter = sprintf( + ' AND ns.`subtype_blacklist` NOT LIKE "%s"', + $subtype + ); + } + $users = db_get_all_rows_sql( sprintf( 'SELECT @@ -178,8 +250,11 @@ function get_notification_source_targets(int $id_source) ON ns.id=nsu.id_source WHERE ns.id = %d AND ((ns.enabled is NULL OR ns.enabled != 0) - OR (nsu.enabled is NULL OR nsu.enabled != 0))', - $id_source + OR (nsu.enabled is NULL OR nsu.enabled != 0)) + %s + ', + $id_source, + $filter ) ); @@ -198,8 +273,10 @@ function get_notification_source_targets(int $id_source) INNER JOIN tnotification_source ns ON ns.id=nsg.id_source WHERE ns.id = %d - AND (ns.enabled is NULL OR ns.enabled != 0)', - $id_source + AND (ns.enabled is NULL OR ns.enabled != 0) + %s', + $id_source, + $filter ) ); @@ -700,8 +777,47 @@ function notifications_print_global_source_configuration($source) ); $html_selectors .= '
'; + $html_checkboxes = ''; + + $blacklist = json_decode($source['subtype_blacklist'], 1); + if (json_last_error() !== JSON_ERROR_NONE) { + $blacklist = []; + } + + if ($source['description'] === io_safe_input('System status')) { + $system_subtypes = notifications_get_subtypes('System status'); + + foreach ($system_subtypes as $type) { + $html_checkboxes .= html_print_input( + [ + 'input_class' => 'flex flex-row w290px margin-soft', + 'label' => $type, + 'name' => 'check-'.$type, + 'type' => 'switch', + 'id' => 'nt-'.$source['id'].'.'.$type.'-subtype', + 'class' => 'elem-clickable', + 'value' => (isset($blacklist[$type]) === false), + 'return' => true, + ] + ); + } + + $html_checkboxes = ui_print_toggle( + [ + 'content' => $html_checkboxes, + 'name' => __('Subtype customization'), + 'hidden_default' => false, + 'return' => true, + 'toggle_class' => '', + 'container_class' => 'flex flex-row flex-start w100p', + 'main_class' => '', + 'clean' => true, + ] + ); + } + // Return all html. - return $html_title.$html_selectors.$html_checkboxes.$html_select_pospone; + return $html_title.$html_selectors.$html_checkboxes; } diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index b9d75f69c6..27bcb1313e 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -3821,7 +3821,9 @@ function ui_toggle( $main_class = ''; } - $container_class = 'white-box-content-clean'; + if (empty($container_class) === true) { + $container_class = 'white-box-content-clean'; + } } // Link to toggle. @@ -3943,7 +3945,24 @@ 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' + * 'reverseImg' + * 'switch' + * 'attributes_switch' + * 'toggl_attr' + * 'switch_on'. * * @return string HTML code with toggle content. */ diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 31e7a60251..afb5b8ad5c 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; } +.w500px { + width: 500px; + max-width: 500px; +} .mw120px { min-width: 120px; } @@ -626,6 +630,13 @@ select:-internal-list-box { align-items: flex-start; } +.flex-row-reverse { + display: flex; + flex-direction: row-reverse; + flex-wrap: wrap; + align-items: flex-start; +} + .flex-space-around { justify-content: space-around; } @@ -652,6 +663,9 @@ select:-internal-list-box { .padding-right-2-imp { padding-right: 2em !important; } +.margin-soft { + margin: 0.3em 1em; +} .margin-right-1 { margin-right: 1em; } diff --git a/pandora_console/operation/users/user_edit_notifications.php b/pandora_console/operation/users/user_edit_notifications.php index 611530a3b4..6e227024fa 100644 --- a/pandora_console/operation/users/user_edit_notifications.php +++ b/pandora_console/operation/users/user_edit_notifications.php @@ -89,8 +89,9 @@ foreach ($sources as $source) { echo '
'; } -if ($disabled_flag) { - echo 'Disabled controls have been set by the system administrator'; +if ((bool) $disabled_flag === true) { + $s = __('Controls have been disabled by the system administrator'); + echo ''.$s.''; } echo '
'; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 090e87fd2e..32d025b128 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -1317,6 +1317,7 @@ CREATE TABLE `tnotification_source` ( `enabled` int(1) DEFAULT NULL, `user_editable` int(1) DEFAULT NULL, `also_mail` int(1) DEFAULT NULL, + `subtype_blacklist` TEXT, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; From 925f456ef77339eaf69532396bc9216291ec5ffc Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 19 Feb 2021 13:57:39 +0100 Subject: [PATCH 113/296] minor fixes --- .../include/functions_notifications.php | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/pandora_console/include/functions_notifications.php b/pandora_console/include/functions_notifications.php index 2765f2cee3..05371f6b3c 100644 --- a/pandora_console/include/functions_notifications.php +++ b/pandora_console/include/functions_notifications.php @@ -161,10 +161,8 @@ function notifications_get_subtypes(?string $source=null) 'NOTIF.ALLOWOVERRIDE.MESSAGE', 'NOTIF.HAMASTER.MESSAGE', 'NOTIF.SERVER.STATUS', - 'NOTIF.SERVER.STATUS.ID_SERVER', - 'NOTIF.SERVER.QUEUE.ID_SERVER', + 'NOTIF.SERVER.QUEUE', 'NOTIF.SERVER.MASTER', - 'NOTIF.SERVER.STATUS.ID_SERVER', ], ]; @@ -233,9 +231,15 @@ function get_notification_source_targets(int $id_source, ?string $subtype=null) { $ret = []; + $filter = ''; if ($subtype !== null) { + $matches = []; + if (preg_match('/(.*)\.\d+$/', $subtype, $matches) > 0) { + $subtype = $matches[1]; + } + $filter = sprintf( - ' AND ns.`subtype_blacklist` NOT LIKE "%s"', + ' AND ns.`subtype_blacklist` NOT LIKE "%%%s%%"', $subtype ); } @@ -248,13 +252,12 @@ function get_notification_source_targets(int $id_source, ?string $subtype=null) FROM tnotification_source_user nsu INNER JOIN tnotification_source ns ON ns.id=nsu.id_source + %s WHERE ns.id = %d AND ((ns.enabled is NULL OR ns.enabled != 0) - OR (nsu.enabled is NULL OR nsu.enabled != 0)) - %s - ', - $id_source, - $filter + OR (nsu.enabled is NULL OR nsu.enabled != 0))', + $filter, + $id_source ) ); @@ -272,11 +275,11 @@ function get_notification_source_targets(int $id_source, ?string $subtype=null) FROM tnotification_source_group nsg INNER JOIN tnotification_source ns ON ns.id=nsg.id_source + %s WHERE ns.id = %d - AND (ns.enabled is NULL OR ns.enabled != 0) - %s', - $id_source, - $filter + AND (ns.enabled is NULL OR ns.enabled != 0)', + $filter, + $id_source ) ); From 64ae9641911ce55923b36ada623f1242c069440a Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Fri, 19 Feb 2021 14:30:09 +0100 Subject: [PATCH 114/296] Fixed forced 2FA --- pandora_console/general/register.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pandora_console/general/register.php b/pandora_console/general/register.php index 9f90e7ad39..9147a0e016 100644 --- a/pandora_console/general/register.php +++ b/pandora_console/general/register.php @@ -234,8 +234,8 @@ if (!$double_auth_enabled && $config['2FA_all_users'] != '' } }); - $("div#doble_auth_window").dialog({ + $("div#doble_auth_window").dialog({ resizable: true, draggable: true, modal: true, @@ -247,12 +247,6 @@ if (!$double_auth_enabled && $config['2FA_all_users'] != '' width: 500, height: 400, close: function (event, ui) { - - // Abort the ajax request if (typeof request != 'undefined'){ request.abort(); From 396f67d57b3f7f2ab23585e627ac6d409c16205b Mon Sep 17 00:00:00 2001 From: artica Date: Sat, 20 Feb 2021 01:00:21 +0100 Subject: [PATCH 115/296] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 24733f7f34..85f5a2f5ce 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.752-210219 +Version: 7.0NG.752-210220 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index aeaa4a82f9..a64a917ce2 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210219" +pandora_version="7.0NG.752-210220" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index bf7104f901..76dbd4f27e 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1016,7 +1016,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.752'; -use constant AGENT_BUILD => '210219'; +use constant AGENT_BUILD => '210220'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index ee75ed2adc..b5e37c4209 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210219 +%define release 210220 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 5cb11cf13a..5b1ad940b2 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210219 +%define release 210220 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index e93ed65725..45fb676f4e 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210219" +PI_BUILD="210220" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index b547ddf4c2..23a1b31bf1 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{210219} +{210220} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index e16ac3e4bd..e69818a2d1 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.752(Build 210219)") +#define PANDORA_VERSION ("7.0NG.752(Build 210220)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index d7af86296d..6a74d3ddd9 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.752(Build 210219))" + VALUE "ProductVersion", "(7.0NG.752(Build 210220))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index c786a460f7..9462aebec0 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.752-210219 +Version: 7.0NG.752-210220 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 7a3b422a9c..5ee036fe74 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210219" +pandora_version="7.0NG.752-210220" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 93d1106a31..8a92622360 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC210219'; +$build_version = 'PC210220'; $pandora_version = 'v7.0NG.752'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 886dae5b8c..a53c377e55 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index ffd6140fe1..d2f2662bd0 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210219 +%define release 210220 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index dbb530241f..f6bcc37b66 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210219 +%define release 210220 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 1005f4f432..ab9701810e 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210219" +PI_BUILD="210220" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 6ecf77f652..3bc9fa417d 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -35,7 +35,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.752 PS210219"; +my $version = "7.0NG.752 PS210220"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index b5a06c5edb..0e3c604d6d 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.752 PS210219"; +my $version = "7.0NG.752 PS210220"; # save program name for logging my $progname = basename($0); From c70643203fe27478b0626392861ebe7556474427 Mon Sep 17 00:00:00 2001 From: artica Date: Sun, 21 Feb 2021 01:00:14 +0100 Subject: [PATCH 116/296] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 85f5a2f5ce..f14bee6ef8 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.752-210220 +Version: 7.0NG.752-210221 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index a64a917ce2..07058a75bd 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210220" +pandora_version="7.0NG.752-210221" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 76dbd4f27e..a3a757e37c 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1016,7 +1016,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.752'; -use constant AGENT_BUILD => '210220'; +use constant AGENT_BUILD => '210221'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index b5e37c4209..ed208307ed 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210220 +%define release 210221 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 5b1ad940b2..e147b4689e 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210220 +%define release 210221 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 45fb676f4e..191c925b72 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210220" +PI_BUILD="210221" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 23a1b31bf1..c430d8e646 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{210220} +{210221} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index e69818a2d1..6df1ab3e93 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.752(Build 210220)") +#define PANDORA_VERSION ("7.0NG.752(Build 210221)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 6a74d3ddd9..2094ee9e2d 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.752(Build 210220))" + VALUE "ProductVersion", "(7.0NG.752(Build 210221))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 9462aebec0..f56850dfa7 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.752-210220 +Version: 7.0NG.752-210221 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 5ee036fe74..535fc7322d 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210220" +pandora_version="7.0NG.752-210221" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 8a92622360..7c57f868e0 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC210220'; +$build_version = 'PC210221'; $pandora_version = 'v7.0NG.752'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index a53c377e55..6919c6e6e4 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index d2f2662bd0..9319c1afc7 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210220 +%define release 210221 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index f6bcc37b66..69a9ee0e27 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210220 +%define release 210221 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index ab9701810e..7c06a670de 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210220" +PI_BUILD="210221" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 3bc9fa417d..9b49fce500 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -35,7 +35,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.752 PS210220"; +my $version = "7.0NG.752 PS210221"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 0e3c604d6d..19eb8be391 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.752 PS210220"; +my $version = "7.0NG.752 PS210221"; # save program name for logging my $progname = basename($0); From cd9694f034c1f9b98b5d029af2b1aaacf00297d6 Mon Sep 17 00:00:00 2001 From: artica Date: Mon, 22 Feb 2021 01:00:09 +0100 Subject: [PATCH 117/296] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index f14bee6ef8..7a76392a62 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.752-210221 +Version: 7.0NG.752-210222 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 07058a75bd..1ecbc72ec5 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210221" +pandora_version="7.0NG.752-210222" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index a3a757e37c..8f4f0ca828 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1016,7 +1016,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.752'; -use constant AGENT_BUILD => '210221'; +use constant AGENT_BUILD => '210222'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index ed208307ed..b02acd170e 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210221 +%define release 210222 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index e147b4689e..95717d26e9 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210221 +%define release 210222 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 191c925b72..3525411abe 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210221" +PI_BUILD="210222" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index c430d8e646..e6aa49ccae 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{210221} +{210222} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 6df1ab3e93..4aa2e9873b 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.752(Build 210221)") +#define PANDORA_VERSION ("7.0NG.752(Build 210222)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 2094ee9e2d..f67d5b421f 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.752(Build 210221))" + VALUE "ProductVersion", "(7.0NG.752(Build 210222))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index f56850dfa7..2e824fbd26 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.752-210221 +Version: 7.0NG.752-210222 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 535fc7322d..0af0e48f4d 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210221" +pandora_version="7.0NG.752-210222" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 7c57f868e0..0b90f357a6 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC210221'; +$build_version = 'PC210222'; $pandora_version = 'v7.0NG.752'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 6919c6e6e4..12c9b0ccc0 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 9319c1afc7..920579d8e3 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210221 +%define release 210222 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 69a9ee0e27..2cb702c5e9 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210221 +%define release 210222 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 7c06a670de..4e3e2ac08c 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210221" +PI_BUILD="210222" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 9b49fce500..7512a3f87b 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -35,7 +35,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.752 PS210221"; +my $version = "7.0NG.752 PS210222"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 19eb8be391..58bd4d2bcc 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.752 PS210221"; +my $version = "7.0NG.752 PS210222"; # save program name for logging my $progname = basename($0); From 34a19b969c72ed57dd477286c2f86d288539722d Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 22 Feb 2021 12:04:12 +0100 Subject: [PATCH 118/296] missed mr file --- pandora_console/extras/mr/45.sql | 5 +++++ 1 file changed, 5 insertions(+) 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..e2e229eb36 --- /dev/null +++ b/pandora_console/extras/mr/45.sql @@ -0,0 +1,5 @@ +START TRANSACTION; + +ALTER TABLE `tnotification_sources` ADD COLUMN `subtype_blacklist` TEXT; + +COMMIT; \ No newline at end of file From 4b0f96126bf2fba378b0d166cf73aca50f41f9bd Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 22 Feb 2021 12:25:24 +0100 Subject: [PATCH 119/296] 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 a5b11280144b094fc4e364ade53e1bc250deffb1 Mon Sep 17 00:00:00 2001 From: artica Date: Tue, 23 Feb 2021 01:00:16 +0100 Subject: [PATCH 120/296] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 7a76392a62..9c8cfd644c 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.752-210222 +Version: 7.0NG.752-210223 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 1ecbc72ec5..64542e1736 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210222" +pandora_version="7.0NG.752-210223" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 8f4f0ca828..4127bd7cea 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1016,7 +1016,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.752'; -use constant AGENT_BUILD => '210222'; +use constant AGENT_BUILD => '210223'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index b02acd170e..1be5cdb778 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210222 +%define release 210223 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 95717d26e9..fb3ee1d880 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210222 +%define release 210223 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 3525411abe..46ed6fd2cb 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210222" +PI_BUILD="210223" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index e6aa49ccae..00f4875d92 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{210222} +{210223} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 4aa2e9873b..27ba38926a 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.752(Build 210222)") +#define PANDORA_VERSION ("7.0NG.752(Build 210223)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index f67d5b421f..51b3ba2bf6 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.752(Build 210222))" + VALUE "ProductVersion", "(7.0NG.752(Build 210223))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 2e824fbd26..b5823986e3 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.752-210222 +Version: 7.0NG.752-210223 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 0af0e48f4d..2891ef4729 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210222" +pandora_version="7.0NG.752-210223" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 0b90f357a6..987596e071 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC210222'; +$build_version = 'PC210223'; $pandora_version = 'v7.0NG.752'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index 12c9b0ccc0..c751c04642 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 920579d8e3..c24a1251d8 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210222 +%define release 210223 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 2cb702c5e9..360f660938 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210222 +%define release 210223 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 4e3e2ac08c..edf372ad33 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210222" +PI_BUILD="210223" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 7512a3f87b..455470a121 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -35,7 +35,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.752 PS210222"; +my $version = "7.0NG.752 PS210223"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 58bd4d2bcc..3cd9e46078 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.752 PS210222"; +my $version = "7.0NG.752 PS210223"; # save program name for logging my $progname = basename($0); From b13d5dc8d4be49d07e9ea102782f420cd485350b Mon Sep 17 00:00:00 2001 From: marcos Date: Tue, 23 Feb 2021 14:35:57 +0100 Subject: [PATCH 121/296] fixed error not show messages --- pandora_console/include/functions_messages.php | 6 +----- .../operation/messages/message_edit.php | 17 ----------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/pandora_console/include/functions_messages.php b/pandora_console/include/functions_messages.php index 9ebe703f94..f929eb9ed1 100644 --- a/pandora_console/include/functions_messages.php +++ b/pandora_console/include/functions_messages.php @@ -497,11 +497,7 @@ function messages_get_overview( if ($incl_source_info) { $source_fields = ', tns.*'; $source_join = 'INNER JOIN tnotification_source tns - ON tns.id=tm.id_source - INNER JOIN tnotification_source_user nsu - ON nsu.id_source=tns.id - AND nsu.enabled = 1 - OR tns.enabled = 1'; + ON tns.id=tm.id_source'; } // Using distinct because could be double assignment due group/user. diff --git a/pandora_console/operation/messages/message_edit.php b/pandora_console/operation/messages/message_edit.php index 6135c4b10b..9d72c262cb 100644 --- a/pandora_console/operation/messages/message_edit.php +++ b/pandora_console/operation/messages/message_edit.php @@ -209,23 +209,6 @@ if (($new_msg) && (!empty($dst_user)) && (!$reply)) { ); } -// Create message (destination group). -if (($new_msg) && ($dst_group != '') && (!$reply)) { - $return = messages_create_message( - $config['id_user'], - [], - [$dst_group], - $subject, - $message - ); - - ui_print_result_message( - $return, - __('Message successfully sent'), - __('Error sending message to group %s', groups_get_name($dst_group)) - ); -} - // Message creation form. // User info. $own_info = get_user_info($config['id_user']); From 793ca4ace7f762958be7637af8fc8542bcbc85e1 Mon Sep 17 00:00:00 2001 From: "rafael.ameijeiras" Date: Tue, 23 Feb 2021 15:05:08 +0100 Subject: [PATCH 122/296] change agent docker image to centos7 --- pandora_agents/Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pandora_agents/Dockerfile b/pandora_agents/Dockerfile index 0ee2515a75..79257b955c 100644 --- a/pandora_agents/Dockerfile +++ b/pandora_agents/Dockerfile @@ -1,15 +1,15 @@ -FROM centos:centos8 -MAINTAINER Pandora FMS Team +FROM centos:7 +LABEL maintainer="Pandora FMS Team " # Add Pandora FMS agent installer ADD unix /opt/pandora/pandora_agent/unix RUN export LC_ALL=C -RUN dnf install -y dnf-plugins-core; dnf config-manager --set-enabled PowerTools +RUN yum -y update # Install dependencies -RUN dnf -y install \ +RUN yum -y install \ epel-release \ unzip \ perl \ @@ -17,7 +17,7 @@ RUN dnf -y install \ sed \ perl-YAML-Tiny \ "perl(Sys::Syslog)" \ - && dnf clean all + && yum clean all # Install Pandora FMS agent From 508b953496fa928e81c3409d2ae6f3735aa0ae51 Mon Sep 17 00:00:00 2001 From: artica Date: Wed, 24 Feb 2021 01:00:21 +0100 Subject: [PATCH 123/296] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 9c8cfd644c..764f3828ce 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.752-210223 +Version: 7.0NG.752-210224 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 64542e1736..64cc04d8d1 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210223" +pandora_version="7.0NG.752-210224" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 4127bd7cea..d6e6ce7f48 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1016,7 +1016,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.752'; -use constant AGENT_BUILD => '210223'; +use constant AGENT_BUILD => '210224'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 1be5cdb778..f76ab40c09 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210223 +%define release 210224 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index fb3ee1d880..d12f7c7475 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210223 +%define release 210224 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 46ed6fd2cb..b87bc9f388 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210223" +PI_BUILD="210224" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 00f4875d92..c1e4bc2629 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{210223} +{210224} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 27ba38926a..c81e629d61 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.752(Build 210223)") +#define PANDORA_VERSION ("7.0NG.752(Build 210224)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 51b3ba2bf6..ae32cb4dad 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.752(Build 210223))" + VALUE "ProductVersion", "(7.0NG.752(Build 210224))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index b5823986e3..e98695d340 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.752-210223 +Version: 7.0NG.752-210224 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 2891ef4729..54d98dad6e 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210223" +pandora_version="7.0NG.752-210224" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index 987596e071..fa35bc05b9 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC210223'; +$build_version = 'PC210224'; $pandora_version = 'v7.0NG.752'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index c751c04642..dd1391a626 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index c24a1251d8..7d28796267 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210223 +%define release 210224 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 360f660938..39b93c7e05 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210223 +%define release 210224 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index edf372ad33..d2fcafcacf 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210223" +PI_BUILD="210224" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 455470a121..723208e2e7 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -35,7 +35,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.752 PS210223"; +my $version = "7.0NG.752 PS210224"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 3cd9e46078..8319d4a09b 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.752 PS210223"; +my $version = "7.0NG.752 PS210224"; # save program name for logging my $progname = basename($0); From 078ab1657f1ecb4a76e5cc903491c4b0bcfa3965 Mon Sep 17 00:00:00 2001 From: artica Date: Thu, 25 Feb 2021 01:00:25 +0100 Subject: [PATCH 124/296] Auto-updated build strings. --- pandora_agents/unix/DEBIAN/control | 2 +- pandora_agents/unix/DEBIAN/make_deb_package.sh | 2 +- pandora_agents/unix/pandora_agent | 2 +- pandora_agents/unix/pandora_agent.redhat.spec | 2 +- pandora_agents/unix/pandora_agent.spec | 2 +- pandora_agents/unix/pandora_agent_installer | 2 +- pandora_agents/win32/installer/pandora.mpi | 2 +- pandora_agents/win32/pandora.cc | 2 +- pandora_agents/win32/versioninfo.rc | 2 +- pandora_console/DEBIAN/control | 2 +- pandora_console/DEBIAN/make_deb_package.sh | 2 +- pandora_console/include/config_process.php | 2 +- pandora_console/install.php | 2 +- pandora_console/pandora_console.redhat.spec | 2 +- pandora_console/pandora_console.rhel7.spec | 2 +- pandora_console/pandora_console.spec | 2 +- pandora_server/DEBIAN/control | 2 +- pandora_server/DEBIAN/make_deb_package.sh | 2 +- pandora_server/lib/PandoraFMS/Config.pm | 2 +- pandora_server/lib/PandoraFMS/PluginTools.pm | 2 +- pandora_server/pandora_server.redhat.spec | 2 +- pandora_server/pandora_server.spec | 2 +- pandora_server/pandora_server_installer | 2 +- pandora_server/util/pandora_db.pl | 2 +- pandora_server/util/pandora_manage.pl | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 764f3828ce..dba64b4ca2 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.752-210224 +Version: 7.0NG.752-210225 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 64cc04d8d1..556e6e20f4 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210224" +pandora_version="7.0NG.752-210225" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index d6e6ce7f48..89b0b7fe25 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1016,7 +1016,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.752'; -use constant AGENT_BUILD => '210224'; +use constant AGENT_BUILD => '210225'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index f76ab40c09..7e157bcd94 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210224 +%define release 210225 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index d12f7c7475..bb0b7e9d89 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.752 -%define release 210224 +%define release 210225 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index b87bc9f388..366b5f73a9 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210224" +PI_BUILD="210225" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index c1e4bc2629..e105390f03 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{210224} +{210225} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index c81e629d61..fe4a5ac3ad 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.752(Build 210224)") +#define PANDORA_VERSION ("7.0NG.752(Build 210225)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index ae32cb4dad..d5a54e2871 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.752(Build 210224))" + VALUE "ProductVersion", "(7.0NG.752(Build 210225))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index e98695d340..6b40a3b87c 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.752-210224 +Version: 7.0NG.752-210225 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 54d98dad6e..d8e3ff24ee 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.752-210224" +pandora_version="7.0NG.752-210225" package_pear=0 package_pandora=1 diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index fa35bc05b9..0f7224b9d9 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC210224'; +$build_version = 'PC210225'; $pandora_version = 'v7.0NG.752'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/install.php b/pandora_console/install.php index dd1391a626..b798204cb3 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
[ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 7d28796267..2e405c0592 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210224 +%define release 210225 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 39b93c7e05..5adcb376f0 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.752 -%define release 210224 +%define release 210225 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index d2fcafcacf..c8078b30d0 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.752" -PI_BUILD="210224" +PI_BUILD="210225" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 723208e2e7..5d5b37c6e1 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -35,7 +35,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.752 PS210224"; +my $version = "7.0NG.752 PS210225"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 8319d4a09b..bd5cf72c44 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.752 PS210224"; +my $version = "7.0NG.752 PS210225"; # save program name for logging my $progname = basename($0); From f84d7a413e257f3e21890851305c9ac4c12ba9d1 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 25 Feb 2021 12:08:58 +0100 Subject: [PATCH 125/296] 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 126/296] 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 901d12fec02b31f6c5f28e825daa28aadf409f48 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Thu, 25 Feb 2021 13:18:04 +0100 Subject: [PATCH 127/296] Integration with Integria --- pandora_console/extras/mr/45.sql | 5 + .../pandoradb_migrate_6.0_to_7.0.mysql.sql | 2 + .../godmode/agentes/agent_incidents.php | 44 +- .../godmode/agentes/configurar_agente.php | 19 - .../godmode/alerts/alert_commands.php | 72 ++- .../godmode/alerts/alert_list.builder.php | 9 +- .../godmode/alerts/configure_alert_action.php | 248 +++++++- .../godmode/setup/setup_integria.php | 227 ++++++-- pandora_console/include/functions_alerts.php | 27 +- pandora_console/include/functions_config.php | 8 +- pandora_console/include/functions_graph.php | 204 ++----- .../include/functions_integriaims.php | 23 +- .../operation/agentes/ver_agente.php | 11 +- .../configure_integriaims_incident.php | 20 +- .../dashboard_detail_integriaims_incident.php | 2 +- .../operation/incidents/incident.php | 503 ----------------- .../operation/incidents/incident_detail.php | 532 ------------------ .../incidents/incident_statistics.php | 8 +- .../incidents/list_integriaims_incidents.php | 2 +- pandora_console/operation/menu.php | 5 +- pandora_server/lib/PandoraFMS/Core.pm | 172 ++++-- pandora_server/util/pandora_db.pl | 33 ++ pandora_server/util/pandora_manage.pl | 21 - .../util/recon_scripts/wmi-recon.pl | 8 - 24 files changed, 837 insertions(+), 1368 deletions(-) create mode 100644 pandora_console/extras/mr/45.sql delete mode 100755 pandora_console/operation/incidents/incident.php delete mode 100755 pandora_console/operation/incidents/incident_detail.php diff --git a/pandora_console/extras/mr/45.sql b/pandora_console/extras/mr/45.sql new file mode 100644 index 0000000000..c02109bd16 --- /dev/null +++ b/pandora_console/extras/mr/45.sql @@ -0,0 +1,5 @@ +START TRANSACTION; + +ALTER TABLE `talert_actions` ADD COLUMN `create_wu_integria` TINYINT(1) default NULL; + +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 bae705f725..4a279450f3 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 @@ -1378,6 +1378,8 @@ ALTER TABLE `talert_actions` MODIFY COLUMN `field11` text NOT NULL, MODIFY COLUMN `field14` text NOT NULL, MODIFY COLUMN `field15` text NOT NULL; +ALTER TABLE `talert_actions` ADD COLUMN `create_wu_integria` TINYINT(1) default NULL; + -- --------------------------------------------------------------------- -- Table `talert_commands` -- --------------------------------------------------------------------- diff --git a/pandora_console/godmode/agentes/agent_incidents.php b/pandora_console/godmode/agentes/agent_incidents.php index c144cdfdcd..c669af992e 100644 --- a/pandora_console/godmode/agentes/agent_incidents.php +++ b/pandora_console/godmode/agentes/agent_incidents.php @@ -18,6 +18,11 @@ require_once 'include/functions_incidents.php'; check_login(); +if (!$config['integria_enabled']) { + ui_print_error_message(__('In order to access ticket management system, integration with Integria IMS must be enabled and properly configured')); + return; +} + $group = $id_grupo; if (! check_acl($config['id_user'], $group, 'AW', $id_agente)) { @@ -38,24 +43,21 @@ $groups = users_get_groups($config['id_user'], 'IR'); $filter = ' AND id_agent = '.$id_agent; $url = 'index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=incident&id_agente='.$id_agent; -// Select incidencts where the user has access to ($groups from -// get_user_groups), array_keys for the id, implode to pass to SQL -switch ($config['dbtype']) { - case 'mysql': - $sql = 'SELECT * FROM tincidencia WHERE - id_grupo IN ('.implode(',', array_keys($groups)).')'.$filter.' - ORDER BY actualizacion DESC LIMIT '.$offset.','.$config['block_size']; - break; +$params = [ + '', + '-10', + '1', + '-1', + '0', + '', + '', + '', + agents_get_name($id_agent), +]; - case 'oracle': - $sql = 'SELECT * FROM tincidencia WHERE - id_grupo IN ('.implode(',', array_keys($groups)).')'.$filter.' - AND rownum <= '.$offset.','.$config['block_size'].' - ORDER BY actualizacion DESC'; - break; -} +$result = integria_api_call($config['integria_hostname'], $config['integria_user'], $config['integria_pass'], $config['integria_api_pass'], 'get_incidents', $params, false, 'json', ','); -$result = db_get_all_rows_sql($sql); +$result = json_decode($result, true); $count_sql = 'SELECT count(*) FROM tincidencia WHERE id_grupo IN ('.implode(',', array_keys($groups)).')'.$filter.' @@ -91,8 +93,6 @@ $table->head[2] = __('Incident'); $table->head[3] = __('Priority'); $table->head[4] = __('Group'); $table->head[5] = __('Updated'); -$table->head[6] = __('Source'); -$table->head[7] = __('Owner'); $table->size[0] = 43; $table->size[7] = 50; @@ -115,7 +115,7 @@ foreach ($result as $row) { $data = []; - $data[0] = ''.$row['id_incidencia'].''; + $data[0] = ''.$row['id_incidencia'].''; $attach = incidents_get_attach($row['id_incidencia']); if (!empty($attach)) { @@ -123,12 +123,10 @@ foreach ($result as $row) { } $data[1] = incidents_print_status_img($row['estado'], true); - $data[2] = ''.substr(io_safe_output($row['titulo']), 0, 45).''; + $data[2] = ''.substr(io_safe_output($row['titulo']), 0, 45).''; $data[3] = incidents_print_priority_img($row['prioridad'], true); - $data[4] = ui_print_group_icon($row['id_grupo'], true); + $data[4] = $row['id_grupo']; $data[5] = ui_print_timestamp($row['actualizacion'], true); - $data[6] = $row['origen']; - $data[7] = ui_print_username($row['id_usuario'], true); array_push($table->data, $data); } diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 72fc0ef125..1f765c7d86 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -486,20 +486,6 @@ if ($id_agente) { $agent_wizard['active'] = false; } - - $total_incidents = agents_get_count_incidents($id_agente); - - // Incident tab. - if ($total_incidents > 0) { - $incidenttab['text'] = ''.html_print_image('images/book_edit.png', true, ['title' => __('Incidents')]).''; - - if ($tab == 'incident') { - $incidenttab['active'] = true; - } else { - $incidenttab['active'] = false; - } - } - if (check_acl_one_of_groups($config['id_user'], $all_groups, 'AW')) { if ($has_remote_conf) { $agent_name = agents_get_name($id_agente); @@ -550,11 +536,6 @@ if ($id_agente) { ]; } - - // Only if the agent has incidents associated show incidents tab. - if ($total_incidents) { - $onheader['incident'] = $incidenttab; - } } else { $onheader = [ 'view' => $viewtab, diff --git a/pandora_console/godmode/alerts/alert_commands.php b/pandora_console/godmode/alerts/alert_commands.php index 53272f6273..2175c8f7b2 100644 --- a/pandora_console/godmode/alerts/alert_commands.php +++ b/pandora_console/godmode/alerts/alert_commands.php @@ -56,7 +56,7 @@ if (is_ajax()) { $command = alerts_get_alert_command($id); - // If is setted a description, we change the carriage return by
tags + // If a description is set, change the carriage return by
tags. if (isset($command['description'])) { $command['description'] = str_replace( [ @@ -265,6 +265,76 @@ if (is_ajax()) { $editor_type_chkbx .= '
'; $rfield = $editor_type_chkbx; // Select type. + } else if (preg_match('/^_integria_type_custom_field_$/i', $field_value)) { + $ffield = ''; + $rfield = ''; + + $ffield .= '
'.html_print_switch( + [ + 'name' => 'field'.$i.'_value[]', + 'value' => '', + ] + ).'
'; + $rfield .= '
'.html_print_switch( + [ + 'name' => 'field'.$i.'_recovery_value[]', + 'value' => '', + ] + ).'
'; + + $ffield .= html_print_select( + '', + 'field'.$i.'_value[]', + '', + '', + __('None'), + '', + true, + false, + false, + 'fields', + $is_central_policies_on_node + ); + + $rfield .= html_print_select( + '', + 'field'.$i.'_recovery_value[]', + '', + '', + __('None'), + '', + true, + false, + false, + 'fields', + $is_central_policies_on_node + ); + + $ffield .= html_print_input_text('field'.$i.'_value[]', '', '', 10, 10, true, false, false, '', 'datepicker'); + $rfield .= html_print_input_text('field'.$i.'_recovery_value[]', '', '', 10, 10, true, false, false, '', 'datepicker'); + + $ffield .= html_print_textarea( + 'field'.$i.'_value[]', + 1, + 1, + '', + 'style="min-height:40px; '.$style.'" class="fields"', + true, + '', + $is_central_policies_on_node + ); + + + $rfield .= html_print_textarea( + 'field'.$i.'_recovery_value[]', + 1, + 1, + '', + 'style="min-height:40px; '.$style.'" class="fields_recovery', + true, + '', + $is_central_policies_on_node + ); } else { $fields_value_select = []; $fv = explode(';', $field_value); diff --git a/pandora_console/godmode/alerts/alert_list.builder.php b/pandora_console/godmode/alerts/alert_list.builder.php index 4fa89805ce..e1c07778c3 100644 --- a/pandora_console/godmode/alerts/alert_list.builder.php +++ b/pandora_console/godmode/alerts/alert_list.builder.php @@ -97,7 +97,14 @@ $table->data[1][0] = __('Actions'); $groups_user = users_get_groups($config['id_user']); if (!empty($groups_user)) { $groups = implode(',', array_keys($groups_user)); - $sql = "SELECT id, name FROM talert_actions WHERE id_group IN ($groups)"; + + if ($config['integria_enabled'] == 0) { + $integria_command = 'Integria IMS Ticket'; + $sql = sprintf('SELECT taa.id, taa.name FROM talert_actions taa INNER JOIN talert_commands tac ON taa.id_alert_command = tac.id WHERE tac.name <> "%s" AND taa.id_group IN (%s)', $integria_command, $groups); + } else { + $sql = "SELECT id, name FROM talert_actions WHERE id_group IN ($groups)"; + } + $actions = db_get_all_rows_sql($sql); } diff --git a/pandora_console/godmode/alerts/configure_alert_action.php b/pandora_console/godmode/alerts/configure_alert_action.php index 67a2837955..f3dfc35250 100644 --- a/pandora_console/godmode/alerts/configure_alert_action.php +++ b/pandora_console/godmode/alerts/configure_alert_action.php @@ -16,6 +16,7 @@ global $config; require_once $config['homedir'].'/include/functions_alerts.php'; require_once $config['homedir'].'/include/functions_users.php'; +require_once $config['homedir'].'/include/functions_integriaims.php'; enterprise_include_once('meta/include/functions_alerts_meta.php'); check_login(); @@ -36,6 +37,19 @@ $id = (int) get_parameter('id'); $al_action = alerts_get_alert_action($id); $pure = get_parameter('pure', 0); +if (is_ajax()) { + $get_integria_ticket_custom_types = (bool) get_parameter('get_integria_ticket_custom_types'); + + if ($get_integria_ticket_custom_types) { + $ticket_type_id = get_parameter('ticket_type_id'); + + $api_call = integria_api_call($config['integria_hostname'], $config['integria_user'], $config['integria_pass'], $config['integria_api_pass'], 'get_incident_fields', $ticket_type_id, false, 'json'); + + echo $api_call; + return; + } +} + if (defined('METACONSOLE')) { $sec = 'advanced'; } else { @@ -101,6 +115,7 @@ if ($id) { $group = $action['id_group']; $action_threshold = $action['action_threshold']; + $create_wu_integria = $action['create_wu_integria']; } // Hidden div with help hint to fill with javascript. @@ -185,10 +200,18 @@ $table->data[1][1] = '
'.html_print_select_groups( ).'
'; $table->colspan[1][1] = 2; +$create_ticket_command_id = db_get_value('id', 'talert_commands', 'name', io_safe_input('Integria IMS Ticket')); + +$sql_exclude_command_id = ''; + +if ($config['integria_enabled'] == 0 && $create_ticket_command_id !== false) { + $sql_exclude_command_id = ' AND id <> '.$create_ticket_command_id; +} + $table->data[2][0] = __('Command'); $commands_sql = db_get_all_rows_filter( 'talert_commands', - ['id_group' => array_keys(users_get_groups(false, 'LW'))], + 'id_group IN ('.implode(',', array_keys(users_get_groups(false, 'LW'))).')'.$sql_exclude_command_id, [ 'id', 'name', @@ -266,6 +289,12 @@ $table->data[5][2] = html_print_textarea( true ); +$table->data[6][0] = __('Create workunit on recovery').ui_print_help_tip( + __('If closed status is set on recovery, a workunit will be added to the ticket in Integria IMS rather that closing the ticket.'), + true +); +$table->data[6][1] = html_print_checkbox_switch_extended('create_wu_integria', 1, $create_wu_integria, false, '', '', true); + for ($i = 1; $i <= $config['max_macro_fields']; $i++) { $table->data['field'.$i][0] = html_print_image( 'images/spinner.gif', @@ -356,6 +385,182 @@ $(document).ready (function () { render_command_description(command_description); } + function ajax_get_integria_custom_fields(ticket_type_id, values, recovery_values) { + var values = values || []; + var recovery_values = recovery_values || []; + + if (ticket_type_id === null || ticket_type_id === '' || (Array.isArray(values) && values.length === 0 && Array.isArray(recovery_values) && recovery_values.length === 0)) { + $('[name=field8_value\\[\\]').val(''); + $('[name=field9_value\\[\\]').val(''); + $('[name=field10_value\\[\\]').val(''); + $('[name=field8_recovery_value\\[\\]').val(''); + $('[name=field9_recovery_value\\[\\]').val(''); + $('[name=field10_recovery_value\\[\\]').val(''); + } + + // On ticket type change, hide all table rows and inputs corresponding to custom fields, regardless of what its type is. + $('[name=field8_value\\[\\]').hide(); + $('[name=field9_value\\[\\]').hide(); + $('[name=field10_value\\[\\]').hide(); + $('[name=field8_recovery_value\\[\\]').hide(); + $('[name=field9_recovery_value\\[\\]').hide(); + $('[name=field10_recovery_value\\[\\]').hide(); + $('#table_macros-field8').hide(); + $('#table_macros-field9').hide(); + $('#table_macros-field10').hide(); + $('[name=field8_value_container').hide(); + $('[name=field9_value_container').hide(); + $('[name=field10_value_container').hide(); + $('[name=field8_recovery_value_container').hide(); + $('[name=field9_recovery_value_container').hide(); + $('[name=field10_recovery_value_container').hide(); + + jQuery.post( + "ajax.php", + { + page: "godmode/alerts/configure_alert_action", + get_integria_ticket_custom_types: 1, + ticket_type_id: ticket_type_id + }, + function(data) { + var max_macro_fields = ; + + data.forEach(function(custom_field, key) { + var custom_field_key = key+8; // Custom fields start from field 8. + + if (custom_field_key > max_macro_fields) { + return; + } + + // Display field row for current input. + var custom_field_row = $('#table_macros-field'+custom_field_key); + custom_field_row.show(); + + // Replace label text of field row for current input. + var label_html = $('#table_macros-field'+custom_field_key+' td').first().html(); + var label_name = label_html.split('
')[0]; + var new_html_content = custom_field_row.html().replace(label_name, custom_field.label); + custom_field_row.html(new_html_content); + + switch (custom_field.type) { + case 'checkbox': + var checkbox_selector = $('input:not(.datepicker)[name=field'+custom_field_key+'_value\\[\\]]'); + var checkbox_recovery_selector = $('input:not(.datepicker)[name=field'+custom_field_key+'_recovery_value\\[\\]]'); + + checkbox_selector.on('change', function() { + if (checkbox_selector.prop('checked')) { + checkbox_selector.attr('value', "1"); + } else { + checkbox_selector.attr('value', "0"); + } + }); + + checkbox_recovery_selector.on('change', function() { + if (checkbox_recovery_selector.prop('checked')) { + checkbox_recovery_selector.attr('value', "1"); + } else { + checkbox_recovery_selector.attr('value', "0"); + } + }); + + if (typeof values[key] !== "undefined") { + if (values[key] == 1) { + checkbox_selector.prop('checked', true); + checkbox_selector.attr('value', "1"); + } else { + checkbox_selector.prop('checked', false); + checkbox_selector.attr('value', "0"); + } + } + + if (typeof recovery_values[key] !== "undefined") { + if (recovery_values[key] == 1) { + checkbox_recovery_selector.prop('checked', true); + checkbox_recovery_selector.attr('value', "1"); + } else { + checkbox_recovery_selector.prop('checked', false); + checkbox_recovery_selector.attr('value', "0"); + } + } + + $('[name=field'+custom_field_key+'_value_container]').show(); + $('[name=field'+custom_field_key+'_recovery_value_container]').show(); + $('input:not(.datepicker)[name=field'+custom_field_key+'_value\\[\\]]').show(); + $('input:not(.datepicker)[name=field'+custom_field_key+'_recovery_value\\[\\]]').show(); + break; + case 'combo': + var combo_input = $('select[name=field'+custom_field_key+'_value\\[\\]]'); + var combo_input_recovery = $('select[name=field'+custom_field_key+'_recovery_value\\[\\]]'); + + combo_input.find('option').remove(); + combo_input_recovery.find('option').remove(); + + var combo_values_array = custom_field.combo_value.split(','); + + combo_values_array.forEach(function(value) { + combo_input.append($('