From a2d9aa81d0932ac601928ad2243a02826694899b Mon Sep 17 00:00:00 2001 From: Jonathan Date: Thu, 19 Jan 2023 14:44:30 +0100 Subject: [PATCH 01/25] #9895 Add description error login ldap --- pandora_console/index.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandora_console/index.php b/pandora_console/index.php index c712be0567..fed8053b4a 100755 --- a/pandora_console/index.php +++ b/pandora_console/index.php @@ -415,6 +415,7 @@ if (isset($config['id_user']) === false) { unset($_POST['auth_code'], $code); if (!$double_auth_success) { + $config['auth_error'] = __('Double auth error'); $login_failed = true; include_once 'general/login_page.php'; db_pandora_audit( @@ -440,6 +441,7 @@ if (isset($config['id_user']) === false) { } else if (($config['auth'] === 'saml') && ($login_button_saml)) { $saml_user_id = enterprise_hook('saml_process_user_login'); if (!$saml_user_id) { + $config['auth_error'] = __('saml error'); $login_failed = true; include_once 'general/login_page.php'; while (ob_get_length() > 0) { @@ -702,6 +704,7 @@ if (isset($config['id_user']) === false) { login_check_failed($nick); } + $config['auth_error'] = __('User is blocked'); $login_failed = true; } From 971fc84a470b2ebd536c970cfe7bd7f82d264ab6 Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Thu, 9 Feb 2023 10:12:59 +0100 Subject: [PATCH 02/25] 9680-Create widget ModulesByStatus --- .../images/widgets/ModulesByStatus.png | Bin 0 -> 5875 bytes pandora_console/include/ajax/module.php | 258 ++++++++ pandora_console/include/functions_html.php | 26 + .../include/lib/Dashboard/Widget.php | 1 + .../lib/Dashboard/Widgets/ModulesByStatus.php | 589 ++++++++++++++++++ 5 files changed, 874 insertions(+) create mode 100644 pandora_console/images/widgets/ModulesByStatus.png create mode 100644 pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php diff --git a/pandora_console/images/widgets/ModulesByStatus.png b/pandora_console/images/widgets/ModulesByStatus.png new file mode 100644 index 0000000000000000000000000000000000000000..796ff6382a7ae408cfa6e47897a50bf42f14a969 GIT binary patch literal 5875 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 + + $sql = sprintf( + 'SELECT + tagente_modulo.nombre, + tagente.alias, + tagente.id_agente, + tagente_estado.last_status_change, + tagente_estado.estado + FROM tagente_modulo + INNER JOIN tagente + ON tagente_modulo.id_agente = tagente.id_agente + INNER JOIN tagente_estado + ON tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo + WHERE %s', + $where + ); + + $res_sql = db_get_all_rows_sql($sql); + + foreach ($res_sql as $row_sql) { + $row_sql['server_name'] = $node->server_name(); + $row_sql['server_url'] = $node->server_url(); + array_push($data, $row_sql); + } + + $node->disconnect(); + } catch (\Exception $e) { + // Unexistent modules. + $node->disconnect(); + } + } + + // Drop temporary table if exist. + db_process_sql('DROP TEMPORARY TABLE IF EXISTS temp_modules_status;'); + + $table_temporary = 'CREATE TEMPORARY TABLE IF NOT EXISTS temp_modules_status ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + nombre VARCHAR(600), + alias VARCHAR(600), + id_agente INT, + last_status_change INT, + estado INT, + server_name VARCHAR(100), + server_url VARCHAR(200), + PRIMARY KEY (`id`), + KEY `nombre` (`nombre`(600)) + )'; + db_process_sql($table_temporary); + + $result = db_process_sql_insert_multiple('temp_modules_status', $data); + + if (empty($result) === false) { + $data = []; + $sql = ''; + $where = ''; + + if (empty($search) === false) { + $where = 'nombre LIKE "%%'.$search.'%%" AND '; + } + + $where .= sprintf( + 'estado IN (%s)', + $status + ); + + $order_by = $order['field'].' '.$order['direction']; + + $sql = sprintf( + 'SELECT + nombre, + alias, + id_agente, + last_status_change, + estado, + server_name, + server_url + FROM temp_modules_status + WHERE %s + ORDER BY %s + LIMIT %d, %d', + $where, + $order_by, + $start, + $length + ); + $data = db_get_all_rows_sql($sql); + + $sql_count = sprintf( + 'SELECT COUNT(*) AS "total" + FROM temp_modules_status' + ); + + $recordsTotal = db_get_value_sql($sql_count); + } + } + + if ($data === false) { + $data = []; + } + + foreach ($data as $key => $row) { + $data[$key]['nombre'] = html_ellipsis_characters($row['nombre'], 35, true); + + if (is_metaconsole() === false) { + $name_link = ''; + $name_link .= ''; + + $data[$key]['alias'] = $name_link; + + $data[$key]['last_status_change'] = ui_print_timestamp( + $row['last_status_change'], + true + ); + + switch ((int) $row['estado']) { + case 0: + $status_img = ui_print_status_image(STATUS_MODULE_OK, __('Normal'), true); + break; + + case 1: + case 6: + $status_img = ui_print_status_image(STATUS_MODULE_CRITICAL, __('Critical'), true); + break; + + case 2: + $status_img = ui_print_status_image(STATUS_MODULE_WARNING, __('Warning'), true); + break; + + case 3: + $status_img = ui_print_status_image(STATUS_MODULE_UNKNOWN, __('Unknown'), true); + break; + + case 5: + $status_img = ui_print_status_image(STATUS_MODULE_NO_DATA, __('Not init'), true); + break; + + default: + $status_img = ''; + break; + } + + $data[$key]['estado'] = $status_img; + } + + echo json_encode( + [ + 'data' => $data, + 'recordsTotal' => $recordsTotal, + 'recordsFiltered' => $recordsTotal, + ] + ); + } + if ($get_children_modules === true) { $parent_modules = get_parameter('parent_modulues', false); $children_selected = []; diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index 31c2e5214a..4ace0131ab 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -6361,3 +6361,29 @@ function html_print_extended_select_for_downtime_cron( echo $returnString; } } + + +/** + * Ellipse string to x characters. + * + * @param string $string String to ellipsis. + * @param integer $characters Characters size to show. + * @return string String ellipsed. + */ +function html_ellipsis_characters( + string $string, + int $characters, + bool $return=false +) { + $out = $string; + + if (strlen($string) > $characters) { + $out = substr($string, 0, $characters).'...'; + } + + if ($return === true) { + return $out; + } else { + echo $out; + } +} \ No newline at end of file diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php index 2753b8a55d..3b4e47cb35 100644 --- a/pandora_console/include/lib/Dashboard/Widget.php +++ b/pandora_console/include/lib/Dashboard/Widget.php @@ -420,6 +420,7 @@ class Widget case 'ColorModuleTabs': case 'BlockHistogram': case 'DataMatrix': + case 'ModulesByStatus': $className .= '\\'.$name; break; diff --git a/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php b/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php new file mode 100644 index 0000000000..8191607616 --- /dev/null +++ b/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php @@ -0,0 +1,589 @@ +width = $width; + + // Height. + $this->height = $height; + + // Grid Width. + $this->gridWidth = $gridWidth; + + // Cell Id. + $this->cellId = $cellId; + + // Options. + $this->values = $this->decoders($this->getOptionsWidget()); + + // Positions. + $this->position = $this->getPositionWidget(); + + // Page. + $this->page = basename(__FILE__); + + // ClassName. + $class = new \ReflectionClass($this); + $this->className = $class->getShortName(); + + // Title. + $this->title = __('Module status'); + + // Name. + if (empty($this->name) === true) { + $this->name = 'ModulesByStatus'; + } + + // This forces at least a first configuration. + // This forces at least a first configuration. + $this->configurationRequired = false; + if (empty($this->values['status']) === true) { + $this->configurationRequired = true; + } + + $this->overflow_scrollbars = false; + } + + + /** + * Decoders hack for retrocompability. + * + * @param array $decoder Values. + * + * @return array Returns the values ​​with the correct key. + */ + public function decoders(array $decoder): array + { + $values = []; + // Retrieve global - common inputs. + $values = parent::decoders($decoder); + + if (isset($decoder['search']) === true) { + $values['search'] = $decoder['search']; + } + + if (isset($decoder['status']) === true) { + $values['status'] = $decoder['status']; + } + + if (isset($decoder['limit']) === true) { + $values['limit'] = $decoder['limit']; + } + + if (isset($decoder['nodes']) === true) { + $values['nodes'] = $decoder['nodes']; + } + + return $values; + } + + + /** + * Generates inputs for form (specific). + * + * @return array Of inputs. + * + * @throws Exception On error. + */ + public function getFormInputs(): array + { + global $config; + + $values = $this->values; + + // Retrieve global - common inputs. + $inputs = parent::getFormInputs(); + + // Search. + $inputs[] = [ + 'label' => __('Free search').ui_print_help_tip(__('Search filter by Module name field content'), true), + 'arguments' => [ + 'name' => 'search', + 'type' => 'text', + 'value' => $values['search'], + 'return' => true, + 'size' => 0, + ], + ]; + + // Status fields. + $status_fields = []; + $status_fields[AGENT_MODULE_STATUS_NORMAL] = __('Normal'); + $status_fields[AGENT_MODULE_STATUS_CRITICAL_BAD] = __('Critical'); + $status_fields[AGENT_MODULE_STATUS_WARNING] = __('Warning'); + $status_fields[AGENT_MODULE_STATUS_UNKNOWN] = __('Unknown'); + $status_fields[AGENT_MODULE_STATUS_NOT_INIT] = __('Not init'); + $status_fields[AGENT_MODULE_STATUS_NOT_NORMAL] = __('Not normal'); + $status_selected = explode(',', $values['status']); + + (isset($values['status']) === false) ? $status_selected = AGENT_MODULE_STATUS_WARNING : ''; + + $inputs[] = [ + 'label' => __('Status'), + 'arguments' => [ + 'name' => 'status', + 'type' => 'select', + 'fields' => $status_fields, + 'selected' => $status_selected, + 'return' => true, + 'multiple' => true, + 'class' => 'overflow-hidden', + 'size' => count($status_fields), + 'select_all' => false, + 'required' => true, + ], + ]; + + // Limit fields. + $limit_fields = []; + $limit_fields[5] = 5; + $limit_fields[10] = 10; + $limit_fields[25] = 25; + $limit_fields[100] = 100; + $limit_fields[200] = 200; + $limit_fields[500] = 500; + $limit_fields[1000] = 1000; + $limit_selected = explode(',', $values['limit']); + + (isset($values['limit']) === false) ? $limit_selected = 5 : ''; + + $inputs[] = [ + 'label' => __('Limit'), + 'arguments' => [ + 'name' => 'limit', + 'type' => 'select', + 'fields' => $limit_fields, + 'selected' => $limit_selected, + 'return' => true, + 'required' => true, + 'select2_enable' => false, + ], + ]; + + if (is_metaconsole() === true) { + // Nodes fields. + $nodes_fields = []; + $servers_ids = array_column(metaconsole_get_servers(), 'id'); + foreach ($servers_ids as $server_id) { + $nodes_fields[$server_id] = $server_id; + } + + $nodes_selected = explode(',', $values['nodes']); + + (isset($values['nodes']) === false) ? $nodes_selected = '' : ''; + + $inputs[] = [ + 'label' => __('Nodes'), + 'arguments' => [ + 'name' => 'nodes', + 'type' => 'select', + 'fields' => $nodes_fields, + 'selected' => $nodes_selected, + 'return' => true, + 'multiple' => true, + 'class' => 'overflow-hidden', + 'size' => count($nodes_fields), + 'select_all' => false, + 'required' => true, + ], + ]; + } + + return $inputs; + } + + + /** + * Get Post for widget. + * + * @return array + */ + public function getPost():array + { + // Retrieve global - common inputs. + $values = parent::getPost(); + + $values['search'] = \get_parameter('search', ''); + $values['status'] = \get_parameter('status', ''); + $values['limit'] = \get_parameter('limit', ''); + $values['nodes'] = \get_parameter('nodes', ''); + + return $values; + } + + + /** + * Draw widget. + * + * @return string; + */ + public function load() + { + $this->size = parent::getSize(); + + $output = ''; + + if (is_metaconsole() === true) { + $modules = []; + + $servers_ids = array_column(metaconsole_get_servers(), 'id'); + + foreach ($servers_ids as $server_id) { + try { + $node = new Node((int) $server_id); + + $node->connect(); + $modules_tmp = $this->getInfoModules( + $this->values['search'], + $this->values['status'], + $this->values['nodes'] + ); + $modules[$node->id()] = $modules_tmp[0]; + $node->disconnect(); + } catch (\Exception $e) { + // Unexistent modules. + $node->disconnect(); + } + } + } else { + $modules = $this->getInfoModules( + $this->values['search'], + $this->values['status'] + ); + } + + if ($modules !== false && empty($modules) === false) { + // Datatables list. + try { + $info_columns = $this->columns(); + $column_names = $info_columns['column_names']; + $columns = $info_columns['columns']; + + $tableId = 'ModuleByStatus_'.$this->dashboardId.'_'.$this->cellId; + // Load datatables user interface. + ui_print_datatable( + [ + 'id' => $tableId, + 'class' => 'info_table align-left-important', + 'style' => 'width: 100%', + 'columns' => $columns, + 'column_names' => $column_names, + 'ajax_url' => 'include/ajax/module', + 'ajax_data' => [ + 'get_data_ModulesByStatus' => 1, + 'table_id' => $tableId, + 'search' => $this->values['search'], + 'status' => $this->values['status'], + 'nodes' => $this->values['nodes'], + ], + 'default_pagination' => $this->values['limit'], + 'order' => [ + 'field' => 'last_status_change', + 'direction' => 'desc', + ], + 'csv' => 0, + ] + ); + } catch (\Exception $e) { + echo $e->getMessage(); + } + } else { + $output = ''; + $output .= '
'; + $output .= \ui_print_info_message( + __('Not found modules'), + '', + true + ); + $output .= '
'; + + return $output; + } + } + + + /** + * Get info modules. + * + * @param string $search Free search. + * @param string $status Modules status. + * + * @return array Data. + */ + private function getInfoModules(string $search, string $status): array + { + if (empty($search) === false) { + $where = 'tagente_modulo.nombre LIKE "%%'.$search.'%%" AND '; + } + + $where .= sprintf( + 'tagente_estado.estado IN (%s) + AND tagente_modulo.delete_pending = 0', + $status + ); + + $sql = sprintf( + 'SELECT + COUNT(*) AS "modules" + FROM tagente_modulo + INNER JOIN tagente + ON tagente_modulo.id_agente = tagente.id_agente + INNER JOIN tagente_estado + ON tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo + WHERE %s', + $where + ); + + $modules = db_get_all_rows_sql($sql); + + if ($modules === false) { + $modules = []; + } + + return $modules; + } + + + /** + * Get columns. + * + * @return array + */ + private function columns() + { + $columns = []; + $column_names = []; + + if (is_metaconsole() === true) { + $column_names = [ + __('Module name'), + __('Agent'), + __('Node'), + __('Last status change'), + __('Status'), + ]; + + $columns = [ + 'nombre', + 'alias', + 'server_name', + 'last_status_change', + 'estado', + ]; + } else { + $column_names = [ + __('Module name'), + __('Agent'), + __('Last status change'), + __('Status'), + ]; + + $columns = [ + 'nombre', + 'alias', + 'last_status_change', + 'estado', + ]; + } + + $data = [ + 'columns' => $columns, + 'column_names' => $column_names, + ]; + + return $data; + } + + + /** + * Get description. + * + * @return string. + */ + public static function getDescription() + { + return __('Modules by status'); + } + + + /** + * Get Name. + * + * @return string. + */ + public static function getName() + { + return 'ModulesByStatus'; + } + + + /** + * Get size Modal Configuration. + * + * @return array + */ + public function getSizeModalConfiguration(): array + { + if (is_metaconsole() === true) { + $nodes_fields = array_column(metaconsole_get_servers(), 'id'); + + $height_counter = (((int) count($nodes_fields)) * 20); + + $size = [ + 'width' => 450, + 'height' => (520 + $height_counter), + ]; + } else { + $size = [ + 'width' => 450, + 'height' => 480, + ]; + } + + return $size; + } + + +} From f35acde8ebb822694f364843b7eb8ca9503019e0 Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Thu, 9 Feb 2023 10:37:12 +0100 Subject: [PATCH 03/25] 9680-Create widget ModulesByStatus --- .../include/lib/Dashboard/Widgets/ModulesByStatus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php b/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php index 8191607616..e2c83ca59d 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php +++ b/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php @@ -258,7 +258,7 @@ class ModulesByStatus extends Widget $status_fields[AGENT_MODULE_STATUS_NOT_NORMAL] = __('Not normal'); $status_selected = explode(',', $values['status']); - (isset($values['status']) === false) ? $status_selected = AGENT_MODULE_STATUS_WARNING : ''; + (isset($values['status']) === false) ? $status_selected = AGENT_MODULE_STATUS_CRITICAL_BAD : ''; $inputs[] = [ 'label' => __('Status'), From b439ed684ee04ea181a751aca841dfe864e4ae2b Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Fri, 10 Feb 2023 10:31:41 +0100 Subject: [PATCH 04/25] 9859-Widget AvgSumMaxMinModule --- .../images/widgets/AvgSumMaxMinModule.png | Bin 0 -> 5984 bytes .../include/lib/Dashboard/Widget.php | 1 + .../Dashboard/Widgets/AvgSumMaxMinModule.php | 701 ++++++++++++++++++ 3 files changed, 702 insertions(+) create mode 100644 pandora_console/images/widgets/AvgSumMaxMinModule.png create mode 100644 pandora_console/include/lib/Dashboard/Widgets/AvgSumMaxMinModule.php diff --git a/pandora_console/images/widgets/AvgSumMaxMinModule.png b/pandora_console/images/widgets/AvgSumMaxMinModule.png new file mode 100644 index 0000000000000000000000000000000000000000..19e980f38dda95f64625f15bcbda86269fb91cf0 GIT binary patch literal 5984 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 = $width; + + // Height. + $this->height = $height; + + // Grid Width. + $this->gridWidth = $gridWidth; + + // Cell Id. + $this->cellId = $cellId; + + // Options. + $this->values = $this->decoders($this->getOptionsWidget()); + + // Positions. + $this->position = $this->getPositionWidget(); + + // Page. + $this->page = basename(__FILE__); + + // ClassName. + $class = new \ReflectionClass($this); + $this->className = $class->getShortName(); + + // Title. + $this->title = __('Avg|Sum|Max|Min Module Data'); + + // Name. + if (empty($this->name) === true) { + $this->name = 'AvgSumMaxMinModule'; + } + + // This forces at least a first configuration. + $this->configurationRequired = false; + if (empty($this->values['moduleId']) === true) { + $this->configurationRequired = true; + } else { + try { + if (is_metaconsole() === true + && $this->values['metaconsoleId'] > 0 + ) { + $node = new Node($this->values['metaconsoleId']); + $node->connect(); + } + + $check_exist = db_get_sql( + sprintf( + 'SELECT id_agente_modulo + FROM tagente_modulo + WHERE id_agente_modulo = %s + AND delete_pending = 0', + $this->values['moduleId'] + ) + ); + } catch (\Exception $e) { + // Unexistent agent. + if (is_metaconsole() === true + && $this->values['metaconsoleId'] > 0 + ) { + $node->disconnect(); + } + + $check_exist = false; + } finally { + if (is_metaconsole() === true + && $this->values['metaconsoleId'] > 0 + ) { + $node->disconnect(); + } + } + + if ($check_exist === false) { + $this->loadError = true; + } + } + + $this->overflow_scrollbars = false; + } + + + /** + * Decoders hack for retrocompability. + * + * @param array $decoder Values. + * + * @return array Returns the values ​​with the correct key. + */ + public function decoders(array $decoder): array + { + $values = []; + // Retrieve global - common inputs. + $values = parent::decoders($decoder); + + if (isset($decoder['label_'.$this->cellId]) === true) { + $values['label'] = $decoder['label_'.$this->cellId]; + } + + if (isset($decoder['label']) === true) { + $values['label'] = $decoder['label']; + } + + if (isset($decoder['id_agent_'.$this->cellId]) === true) { + $values['agentId'] = $decoder['id_agent_'.$this->cellId]; + } + + if (isset($decoder['type_'.$this->cellId]) === true) { + $values['type'] = $decoder['type_'.$this->cellId]; + } + + if (isset($decoder['type']) === true) { + $values['type'] = $decoder['type']; + } + + if (isset($decoder['period_'.$this->cellId]) === true) { + $values['period'] = $decoder['period_'.$this->cellId]; + } + + if (isset($decoder['period']) === true) { + $values['period'] = $decoder['period']; + } + + if (isset($decoder['agentId']) === true) { + $values['agentId'] = $decoder['agentId']; + } + + if (isset($decoder['metaconsoleId']) === true) { + $values['metaconsoleId'] = $decoder['metaconsoleId']; + } + + if (isset($decoder['id_module_'.$this->cellId]) === true) { + $values['moduleId'] = $decoder['id_module_'.$this->cellId]; + } + + if (isset($decoder['moduleId']) === true) { + $values['moduleId'] = $decoder['moduleId']; + } + + if (isset($decoder['size_value_'.$this->cellId]) === true) { + $values['sizeValue'] = $decoder['size_value_'.$this->cellId]; + } + + if (isset($decoder['sizeValue']) === true) { + $values['sizeValue'] = $decoder['sizeValue']; + } + + if (isset($decoder['size_label_'.$this->cellId]) === true) { + $values['sizeLabel'] = $decoder['size_label_'.$this->cellId]; + } + + if (isset($decoder['sizeLabel']) === true) { + $values['sizeLabel'] = $decoder['sizeLabel']; + } + + if (isset($decoder['text_color_'.$this->cellId]) === true) { + $values['text_color'] = $decoder['text_color_'.$this->cellId]; + } + + if (isset($decoder['text_color']) === true) { + $values['text_color'] = $decoder['text_color']; + } + + if (isset($decoder['unit_'.$this->cellId]) === true) { + $values['unit'] = $decoder['unit_'.$this->cellId]; + } + + if (isset($decoder['unit']) === true) { + $values['unit'] = $decoder['unit']; + } + + return $values; + } + + + /** + * Generates inputs for form (specific). + * + * @return array Of inputs. + * + * @throws Exception On error. + */ + public function getFormInputs(): array + { + global $config; + + $values = $this->values; + + // Default values. + if (isset($values['sizeLabel']) === false) { + $values['sizeLabel'] = 20; + } + + if (isset($values['sizeValue']) === false) { + $values['sizeValue'] = 20; + } + + // Retrieve global - common inputs. + $inputs = parent::getFormInputs(); + + // Label. + $inputs[] = [ + 'label' => __('Label'), + 'arguments' => [ + 'name' => 'label', + 'type' => 'text', + 'value' => $values['label'], + 'return' => true, + 'size' => 0, + ], + ]; + + // Type. + $type_fields = []; + $type_fields[0] = 'AVG'; + $type_fields[1] = 'SUM'; + $type_fields[2] = 'MAX'; + $type_fields[3] = 'MIN'; + $type_selected = explode(',', $values['type']); + + (isset($values['type']) === false) ? $type_selected = 0 : ''; + + $inputs[] = [ + 'label' => __('Type'), + 'arguments' => [ + 'name' => 'type', + 'type' => 'select', + 'fields' => $type_fields, + 'selected' => $type_selected, + 'return' => true, + 'required' => true, + 'select2_enable' => false, + 'sort' => false, + ], + ]; + + // Period. + $period_fields = []; + $period_fields[0] = __('Last 30 days'); + $period_fields[1] = __('This month'); + $period_fields[2] = __('Last 7 days'); + $period_fields[3] = __('This week'); + $period_fields[4] = __('Last 24 hrs'); + $period_fields[5] = __('Today'); + $period_selected = explode(',', $values['period']); + + (isset($values['period']) === false) ? $period_selected = 0 : ''; + + $inputs[] = [ + 'label' => __('Time period'), + 'arguments' => [ + 'name' => 'period', + 'type' => 'select', + 'fields' => $period_fields, + 'selected' => $period_selected, + 'return' => true, + 'required' => true, + 'select2_enable' => false, + 'sort' => false, + ], + ]; + + // Autocomplete agents. + $inputs[] = [ + 'label' => __('Agent'), + 'arguments' => [ + 'type' => 'autocomplete_agent', + 'name' => 'agentAlias', + 'id_agent_hidden' => $values['agentId'], + 'name_agent_hidden' => 'agentId', + 'server_id_hidden' => $values['metaconsoleId'], + 'name_server_hidden' => 'metaconsoleId', + 'return' => true, + 'module_input' => true, + 'module_name' => 'moduleId', + 'module_none' => false, + 'size' => 0, + ], + ]; + + // Autocomplete module. + $inputs[] = [ + 'label' => __('Module'), + 'arguments' => [ + 'type' => 'autocomplete_module', + 'name' => 'moduleId', + 'selected' => $values['moduleId'], + 'return' => true, + 'sort' => false, + 'agent_id' => $values['agentId'], + 'metaconsole_id' => $values['metaconsoleId'], + 'style' => 'width: inherit;', + 'filter_modules' => (users_access_to_agent($values['agentId']) === false) ? [$values['moduleId']] : [], + 'nothing' => __('None'), + 'nothing_value' => 0, + ], + ]; + + // Text size of value in px. + $inputs[] = [ + 'label' => __('Text size of value in px'), + 'arguments' => [ + 'name' => 'sizeValue', + 'type' => 'number', + 'value' => $values['sizeValue'], + 'return' => true, + 'min' => 0, + ], + ]; + + // Text size of label in px. + $inputs[] = [ + 'label' => __('Text size of label in px'), + 'arguments' => [ + 'name' => 'sizeLabel', + 'type' => 'number', + 'value' => $values['sizeLabel'], + 'return' => true, + 'min' => 0, + ], + ]; + + // Text color. + if (empty($values['text_color']) === true) { + $values['text_color'] = '#000000'; + + if ($config['style'] === 'pandora_black' + && is_metaconsole() === false + ) { + $values['text_color'] = '#eeeeee'; + } + } + + $inputs[] = [ + 'label' => __('Text color'), + 'arguments' => [ + 'wrapper' => 'div', + 'name' => 'text_color', + 'type' => 'color', + 'value' => $values['text_color'], + 'return' => true, + ], + ]; + + // Unit. + $inputs[] = [ + 'label' => __('Unit'), + 'arguments' => [ + 'wrapper' => 'div', + 'name' => 'unit', + 'type' => 'switch', + 'value' => $values['unit'], + 'return' => true, + ], + ]; + + return $inputs; + } + + + /** + * Get Post for widget. + * + * @return array + */ + public function getPost():array + { + // Retrieve global - common inputs. + $values = parent::getPost(); + + $values['label'] = \get_parameter('label', ''); + $values['type'] = \get_parameter('type', 0); + $values['period'] = \get_parameter('period', 0); + $values['agentId'] = \get_parameter('agentId', 0); + $values['metaconsoleId'] = \get_parameter('metaconsoleId', 0); + $values['moduleId'] = \get_parameter('moduleId', 0); + $values['sizeValue'] = \get_parameter('sizeValue', 0); + $values['sizeLabel'] = \get_parameter_switch('sizeLabel'); + $values['text_color'] = \get_parameter('text_color', 0); + $values['unit'] = \get_parameter_switch('unit'); + + return $values; + } + + + /** + * Draw widget. + * + * @return string; + */ + public function load() + { + global $config; + + $output = ''; + $text_color = 'color:'.$this->values['text_color'].' !important;'; + + $id_module = $this->values['moduleId']; + + $to = 0; + $now = time(); + + switch ((int) $this->values['period']) { + case 0: + $to = strtotime('-30 days'); + break; + + case 1: + $to = strtotime(date('Y-m-01 00:00:00')); + break; + + case 2: + $to = strtotime('-7 days'); + break; + + case 3: + $to = strtotime('last Monday'); + break; + + case 4: + $to = strtotime('-1 days'); + break; + + case 5: + $to = strtotime(date('Y-m-d 00:00:00')); + break; + + default: + $to = 0; + break; + } + + $data = 0; + switch ((int) $this->values['type']) { + case 0: + $rows = modules_get_raw_data($id_module, $to, $now); + $count = (int) count($rows); + $sum = 0; + foreach ($rows as $row) { + $sum += (int) $row['datos']; + } + + $data = ($sum / $count); + break; + + case 1: + $rows = modules_get_raw_data($id_module, $to, $now); + $sum = 0; + foreach ($rows as $row) { + $sum += (int) $row['datos']; + } + + $data = $sum; + break; + + case 2: + $rows = modules_get_min_max_data($id_module, $to); + + $data = $rows[0]['max']; + break; + + case 3: + $rows = modules_get_min_max_data($id_module, $to); + + $data = $rows[0]['min']; + break; + + default: + $data = 0; + break; + } + + $label = $this->values['label']; + $sizeLabel = (isset($this->values['sizeLabel']) === true) ? $this->values['sizeLabel'] : 40; + $sizeValue = (isset($this->values['sizeValue']) === true) ? $this->values['sizeValue'] : 40; + + $output .= '
'; + // General div. + $output .= '
'; + // Div value. + $output .= '
'; + + if (is_numeric($data) === true) { + $dataDatos = remove_right_zeros( + number_format( + $data, + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] + ) + ); + } else { + $dataDatos = trim($data); + } + + $unit = ''; + if (empty($this->values['unit']) === false) { + $unit = modules_get_unit($id_module); + } + + $output .= $dataDatos.' '.$unit; + + $output .= '
'; + + if (empty($label) === false) { + // Div Label. + $output .= '
'.$label.'
'; + } + + $output .= '
'; + $output .= '
'; + return $output; + } + + + /** + * Get description. + * + * @return string. + */ + public static function getDescription() + { + return __('Avg|Sum|Max|Min Module Data'); + } + + + /** + * Get Name. + * + * @return string. + */ + public static function getName() + { + return 'AvgSumMaxMinModule'; + } + + + /** + * Get size Modal Configuration. + * + * @return array + */ + public function getSizeModalConfiguration(): array + { + $size = [ + 'width' => 550, + 'height' => 710, + ]; + + return $size; + } + + +} From 0125ba742b53269d879f7e3ca295662dc277acef Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Wed, 15 Feb 2023 11:42:50 +0100 Subject: [PATCH 05/25] 9680-Create widget ModulesByStatus --- .../lib/Dashboard/Widgets/ModulesByStatus.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php b/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php index e2c83ca59d..21fa53d21c 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php +++ b/pandora_console/include/lib/Dashboard/Widgets/ModulesByStatus.php @@ -302,17 +302,23 @@ class ModulesByStatus extends Widget ], ]; + // Nodes. if (is_metaconsole() === true) { - // Nodes fields. $nodes_fields = []; - $servers_ids = array_column(metaconsole_get_servers(), 'id'); - foreach ($servers_ids as $server_id) { - $nodes_fields[$server_id] = $server_id; + $servers_ids = metaconsole_get_servers(); + + foreach ($servers_ids as $server) { + $nodes_fields[$server['id']] = $server['server_name']; } $nodes_selected = explode(',', $values['nodes']); - (isset($values['nodes']) === false) ? $nodes_selected = '' : ''; + (isset($values['nodes']) === false) ? $nodes_selected = $servers_ids : ''; + + $nodes_height = count($nodes_fields); + if (count($nodes_fields) > 5) { + $nodes_height = 5; + } $inputs[] = [ 'label' => __('Nodes'), @@ -324,7 +330,7 @@ class ModulesByStatus extends Widget 'return' => true, 'multiple' => true, 'class' => 'overflow-hidden', - 'size' => count($nodes_fields), + 'size' => $nodes_height, 'select_all' => false, 'required' => true, ], From 5fb43198eabaac3819ea147b511a2cefc7951971 Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 3 Mar 2023 11:22:39 +0100 Subject: [PATCH 06/25] Fix quores error --- pandora_server/lib/PandoraFMS/Core.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 234229b5c1..40196329d1 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -5630,7 +5630,7 @@ sub pandora_server_statistics ($$) { $lag_row = get_db_single_row ($dbh, "SELECT COUNT(tam.id_agente_modulo) AS module_lag, - AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS "lag" + AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS lag FROM ( SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo FROM tagente_estado @@ -5652,7 +5652,7 @@ sub pandora_server_statistics ($$) { # Dataserver LAG calculation: else { $lag_row = get_db_single_row ($dbh, "SELECT COUNT(tam.id_agente_modulo) AS module_lag, - AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS "lag" + AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS lag FROM ( SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo FROM tagente_estado From 2386b87c1d2cb43a2c7eea9e13c6a12f69bc8b2b Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 3 Mar 2023 11:34:01 +0100 Subject: [PATCH 07/25] Functions servers lag query updated --- pandora_console/include/functions_servers.php | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/pandora_console/include/functions_servers.php b/pandora_console/include/functions_servers.php index 3f9fe1a6b2..14c8d31813 100644 --- a/pandora_console/include/functions_servers.php +++ b/pandora_console/include/functions_servers.php @@ -1017,40 +1017,58 @@ function servers_get_info($id_server=-1) // Remote servers LAG Calculation (server_type != 0). if ($server['server_type'] != 0) { // MySQL 8.0 has function lag(). So, lag must be enclosed in quotations. - $result = db_get_row_sql( - 'SELECT COUNT(tagente_modulo.id_agente_modulo) AS module_lag, - AVG(UNIX_TIMESTAMP() - utimestamp - current_interval) AS "lag" - FROM tagente_estado, tagente_modulo, tagente - WHERE utimestamp > 0 - AND tagente.disabled = 0 - AND tagente.id_agente = tagente_estado.id_agente - AND tagente_modulo.disabled = 0 - AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo - AND current_interval > 0 - AND running_by = '.$server['id_server'].' - AND (UNIX_TIMESTAMP() - utimestamp) < ( current_interval * 10) - AND (UNIX_TIMESTAMP() - utimestamp) > current_interval' + $sql = sprintf( + 'SELECT COUNT(tam.id_agente_modulo) AS module_lag, + AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS "lag" + FROM ( + SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo + FROM tagente_estado + WHERE tagente_estado.current_interval > 0 + AND tagente_estado.last_execution_try > 0 + AND tagente_estado.running_by = %d + ) tae + JOIN ( + SELECT tagente_modulo.id_agente_modulo + FROM tagente_modulo LEFT JOIN tagente + ON tagente_modulo.id_agente = tagente.id_agente + WHERE tagente.disabled = 0 + AND tagente_modulo.disabled = 0 + ) tam + ON tae.id_agente_modulo = tam.id_agente_modulo + WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval) + AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)', + $server['id_server'] ); } else { // Local/Dataserver server LAG calculation. // MySQL 8.0 has function lag(). So, lag must be enclosed in quotations. - $result = db_get_row_sql( - 'SELECT COUNT(tagente_modulo.id_agente_modulo) AS module_lag, - AVG(UNIX_TIMESTAMP() - utimestamp - current_interval) AS "lag" - FROM tagente_estado, tagente_modulo, tagente - WHERE utimestamp > 0 - AND tagente.disabled = 0 - AND tagente.id_agente = tagente_estado.id_agente - AND tagente_modulo.disabled = 0 - AND tagente_modulo.id_tipo_modulo < 5 - AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo - AND current_interval > 0 - AND (UNIX_TIMESTAMP() - utimestamp) < ( current_interval * 10) - AND running_by = '.$server['id_server'].' - AND (UNIX_TIMESTAMP() - utimestamp) > (current_interval * 1.1)' + $sql = sprintf( + 'SELECT COUNT(tam.id_agente_modulo) AS module_lag, + AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS "lag" + FROM ( + SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo + FROM tagente_estado + WHERE tagente_estado.current_interval > 0 + AND tagente_estado.last_execution_try > 0 + AND tagente_estado.running_by = %d + ) tae + JOIN ( + SELECT tagente_modulo.id_agente_modulo + FROM tagente_modulo LEFT JOIN tagente + ON tagente_modulo.id_agente = tagente.id_agente + WHERE tagente.disabled = 0 + AND tagente_modulo.disabled = 0 + AND tagente_modulo.id_tipo_modulo < 5 + ) tam + ON tae.id_agente_modulo = tam.id_agente_modulo + WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval * 1.1) + AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)', + $server['id_server'] ); } + $result = db_get_row_sql($sql); + // Lag over current_interval * 2 is not lag, // it's a timed out module. if (!empty($result['lag'])) { From 4b31bc340e86e23828f20eb29aece2dbc368d8ac Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 3 Mar 2023 11:50:21 +0100 Subject: [PATCH 08/25] Fix code style --- pandora_console/include/functions_servers.php | 56 ++++++------ pandora_server/lib/PandoraFMS/Core.pm | 90 ++++++++++--------- 2 files changed, 76 insertions(+), 70 deletions(-) diff --git a/pandora_console/include/functions_servers.php b/pandora_console/include/functions_servers.php index 14c8d31813..3f4071ccf2 100644 --- a/pandora_console/include/functions_servers.php +++ b/pandora_console/include/functions_servers.php @@ -1021,22 +1021,22 @@ function servers_get_info($id_server=-1) 'SELECT COUNT(tam.id_agente_modulo) AS module_lag, AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS "lag" FROM ( - SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo - FROM tagente_estado - WHERE tagente_estado.current_interval > 0 - AND tagente_estado.last_execution_try > 0 - AND tagente_estado.running_by = %d + SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo + FROM tagente_estado + WHERE tagente_estado.current_interval > 0 + AND tagente_estado.last_execution_try > 0 + AND tagente_estado.running_by = %d ) tae - JOIN ( + JOIN ( SELECT tagente_modulo.id_agente_modulo - FROM tagente_modulo LEFT JOIN tagente - ON tagente_modulo.id_agente = tagente.id_agente - WHERE tagente.disabled = 0 - AND tagente_modulo.disabled = 0 + FROM tagente_modulo LEFT JOIN tagente + ON tagente_modulo.id_agente = tagente.id_agente + WHERE tagente.disabled = 0 + AND tagente_modulo.disabled = 0 ) tam - ON tae.id_agente_modulo = tam.id_agente_modulo - WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval) - AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)', + ON tae.id_agente_modulo = tam.id_agente_modulo + WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval) + AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)', $server['id_server'] ); } else { @@ -1044,25 +1044,25 @@ function servers_get_info($id_server=-1) // MySQL 8.0 has function lag(). So, lag must be enclosed in quotations. $sql = sprintf( 'SELECT COUNT(tam.id_agente_modulo) AS module_lag, - AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS "lag" + AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS "lag" FROM ( SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo - FROM tagente_estado - WHERE tagente_estado.current_interval > 0 - AND tagente_estado.last_execution_try > 0 - AND tagente_estado.running_by = %d + FROM tagente_estado + WHERE tagente_estado.current_interval > 0 + AND tagente_estado.last_execution_try > 0 + AND tagente_estado.running_by = %d ) tae - JOIN ( + JOIN ( SELECT tagente_modulo.id_agente_modulo - FROM tagente_modulo LEFT JOIN tagente - ON tagente_modulo.id_agente = tagente.id_agente - WHERE tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND tagente_modulo.id_tipo_modulo < 5 - ) tam - ON tae.id_agente_modulo = tam.id_agente_modulo - WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval * 1.1) - AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)', + FROM tagente_modulo LEFT JOIN tagente + ON tagente_modulo.id_agente = tagente.id_agente + WHERE tagente.disabled = 0 + AND tagente_modulo.disabled = 0 + AND tagente_modulo.id_tipo_modulo < 5 + ) tam + ON tae.id_agente_modulo = tam.id_agente_modulo + WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval * 1.1) + AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)', $server['id_server'] ); } diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 40196329d1..b911f05b50 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -5627,50 +5627,56 @@ sub pandora_server_statistics ($$) { # Non-dataserver LAG calculation: if ($server->{"server_type"} != DATASERVER){ - - $lag_row = get_db_single_row ($dbh, - "SELECT COUNT(tam.id_agente_modulo) AS module_lag, - AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS lag - FROM ( - SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo - FROM tagente_estado - WHERE tagente_estado.current_interval > 0 - AND tagente_estado.last_execution_try > 0 - AND tagente_estado.running_by = ? - ) tae - JOIN ( - SELECT tagente_modulo.id_agente_modulo - FROM tagente_modulo LEFT JOIN tagente - ON tagente_modulo.id_agente = tagente.id_agente - WHERE tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - ) tam - ON tae.id_agente_modulo = tam.id_agente_modulo - WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval) - AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)", $server->{"id_server"}); - } + $lag_row = get_db_single_row ( + $dbh, + "SELECT COUNT(tam.id_agente_modulo) AS module_lag, + AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS lag + FROM ( + SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo + FROM tagente_estado + WHERE tagente_estado.current_interval > 0 + AND tagente_estado.last_execution_try > 0 + AND tagente_estado.running_by = ? + ) tae + JOIN ( + SELECT tagente_modulo.id_agente_modulo + FROM tagente_modulo LEFT JOIN tagente + ON tagente_modulo.id_agente = tagente.id_agente + WHERE tagente.disabled = 0 + AND tagente_modulo.disabled = 0 + ) tam + ON tae.id_agente_modulo = tam.id_agente_modulo + WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval) + AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)", + $server->{"id_server"} + ); +} # Dataserver LAG calculation: else { - $lag_row = get_db_single_row ($dbh, "SELECT COUNT(tam.id_agente_modulo) AS module_lag, - AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS lag - FROM ( - SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo - FROM tagente_estado - WHERE tagente_estado.current_interval > 0 - AND tagente_estado.last_execution_try > 0 - AND tagente_estado.running_by = ? - ) tae - JOIN ( - SELECT tagente_modulo.id_agente_modulo - FROM tagente_modulo LEFT JOIN tagente - ON tagente_modulo.id_agente = tagente.id_agente - WHERE tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND tagente_modulo.id_tipo_modulo < 5 - ) tam - ON tae.id_agente_modulo = tam.id_agente_modulo - WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval * 1.1) - AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)", $server->{"id_server"}); + $lag_row = get_db_single_row ( + $dbh, + "SELECT COUNT(tam.id_agente_modulo) AS module_lag, + AVG(UNIX_TIMESTAMP() - tae.last_execution_try - tae.current_interval) AS lag + FROM ( + SELECT tagente_estado.last_execution_try, tagente_estado.current_interval, tagente_estado.id_agente_modulo + FROM tagente_estado + WHERE tagente_estado.current_interval > 0 + AND tagente_estado.last_execution_try > 0 + AND tagente_estado.running_by = ? + ) tae + JOIN ( + SELECT tagente_modulo.id_agente_modulo + FROM tagente_modulo LEFT JOIN tagente + ON tagente_modulo.id_agente = tagente.id_agente + WHERE tagente.disabled = 0 + AND tagente_modulo.disabled = 0 + AND tagente_modulo.id_tipo_modulo < 5 + ) tam + ON tae.id_agente_modulo = tam.id_agente_modulo + WHERE (UNIX_TIMESTAMP() - tae.last_execution_try) > (tae.current_interval * 1.1) + AND (UNIX_TIMESTAMP() - tae.last_execution_try) < ( tae.current_interval * 10)", + $server->{"id_server"} + ); } $server->{"module_lag"} = $lag_row->{'module_lag'}; From 6cee279de7823dc460ff0b1da902fa1367500628 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Fri, 3 Mar 2023 12:49:54 +0100 Subject: [PATCH 09/25] fixed entities --- pandora_console/godmode/reporting/map_builder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_console/godmode/reporting/map_builder.php b/pandora_console/godmode/reporting/map_builder.php index f85849a4ea..e7aecf917d 100644 --- a/pandora_console/godmode/reporting/map_builder.php +++ b/pandora_console/godmode/reporting/map_builder.php @@ -487,9 +487,9 @@ if (!$maps && !is_metaconsole()) { $data = []; if (!is_metaconsole()) { - $data[0] = ''.$map['name'].''; + $data[0] = ''.io_safe_output($map['name']).''; } else { - $data[0] = ''.$map['name'].''; + $data[0] = ''.io_safe_output($map['name']).''; } $data[1] = ui_print_group_icon($map['id_group'], true); From 4c926f1e046d4bcff8c1f5ff894a58e7c243a7da Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Thu, 9 Mar 2023 09:07:04 +0100 Subject: [PATCH 10/25] fixed entities --- pandora_console/godmode/reporting/map_builder.php | 4 ++-- pandora_console/godmode/reporting/visual_console_builder.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pandora_console/godmode/reporting/map_builder.php b/pandora_console/godmode/reporting/map_builder.php index 42610ff4c5..898c3becda 100644 --- a/pandora_console/godmode/reporting/map_builder.php +++ b/pandora_console/godmode/reporting/map_builder.php @@ -511,9 +511,9 @@ if (!$maps && is_metaconsole() === false) { $data = []; if (is_metaconsole() === false) { - $data[0] = ''.io_safe_output($map['name']).''; + $data[0] = ''.$map['name'].''; } else { - $data[0] = ''.io_safe_output($map['name']).''; + $data[0] = ''.$map['name'].''; } $data[1] = ui_print_group_icon($map['id_group'], true); diff --git a/pandora_console/godmode/reporting/visual_console_builder.php b/pandora_console/godmode/reporting/visual_console_builder.php index ca1e0386bf..dfc73b8f67 100755 --- a/pandora_console/godmode/reporting/visual_console_builder.php +++ b/pandora_console/godmode/reporting/visual_console_builder.php @@ -165,7 +165,7 @@ switch ($activeTab) { $background_color = (string) get_parameter('background_color'); $width = (int) get_parameter('width'); $height = (int) get_parameter('height'); - $visualConsoleName = io_safe_input((string) get_parameter('name')); + $visualConsoleName = (string) get_parameter('name'); $is_favourite = (int) get_parameter('is_favourite_sent'); $auto_adjust = (int) get_parameter('auto_adjust_sent'); From edbc9d8f6b224c1d9da4418aa0b8027d70c4a9b0 Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Thu, 9 Mar 2023 23:31:40 +0100 Subject: [PATCH 11/25] Icons review --- pandora_console/extensions/files_repo.php | 8 +- .../extensions/files_repo/files_repo_list.php | 11 ++- .../godmode/agentes/inventory_manager.php | 8 +- .../agentes/module_manager_editor_common.php | 33 +++++---- .../godmode/alerts/alert_commands.php | 4 +- .../godmode/alerts/alert_list.list.php | 2 +- pandora_console/godmode/alerts/alert_list.php | 8 +- .../godmode/alerts/alert_templates.php | 2 +- pandora_console/godmode/extensions.php | 3 +- .../module_library/module_library_view.php | 6 +- .../godmode/reporting/reporting_builder.php | 14 ++-- .../godmode/setup/setup_general.php | 8 +- .../godmode/setup/setup_visuals.php | 10 +-- .../godmode/snmpconsole/snmp_alert.php | 6 +- .../wizards/DiscoveryTaskList.class.php | 74 +++++++++---------- .../include/class/CalendarManager.class.php | 10 +-- .../include/class/Diagnostics.class.php | 4 +- .../include/class/EventSound.class.php | 10 +-- pandora_console/include/functions_cron.php | 50 ++++++------- .../include/functions_integriaims.php | 10 +-- .../include/functions_notifications.php | 18 +++-- .../include/functions_snmp_browser.php | 2 +- .../lib/ClusterViewer/ClusterManager.php | 12 +-- .../rest-api/models/VisualConsole/View.php | 54 ++++++++------ .../operation/netflow/nf_live_view.php | 6 +- .../operation/reporting/reporting_viewer.php | 18 ++--- pandora_console/operation/users/user_edit.php | 4 +- pandora_console/views/cluster/edit.php | 8 +- pandora_console/views/cluster/view.php | 22 +++--- 29 files changed, 222 insertions(+), 203 deletions(-) diff --git a/pandora_console/extensions/files_repo.php b/pandora_console/extensions/files_repo.php index 0313af90b2..656c3377c7 100644 --- a/pandora_console/extensions/files_repo.php +++ b/pandora_console/extensions/files_repo.php @@ -115,11 +115,11 @@ function pandora_files_repo_godmode() } // Header tabs. - $godmode['text'] = ''.html_print_image('images/setup.png', true, ['title' => __('Administration view'), 'class' => 'invert_filter']).''; + $godmode['text'] = ''.html_print_image('images/configuration@svg.svg', true, ['title' => __('Administration view'), 'class' => 'main_menu_icon invert_filter']).''; $godmode['godmode'] = 1; $godmode['active'] = 1; - $operation['text'] = ''.html_print_image('images/eye_show.png', true, ['title' => __('Operation view'), 'class' => 'invert_filter']).''; + $operation['text'] = ''.html_print_image('images/see-details@svg.svg', true, ['title' => __('Operation view'), 'class' => 'main_menu_icon invert_filter']).''; $operation['operation'] = 1; $onheader = [ @@ -226,10 +226,10 @@ function pandora_files_repo_operation() // Header tabs. $onheader = []; if (check_acl($config['id_user'], 0, 'PM')) { - $godmode['text'] = ''.html_print_image('images/setup.png', true, ['title' => __('Administration view'), 'class' => 'invert_filter']).''; + $godmode['text'] = ''.html_print_image('images/configuration@svg.svg', true, ['title' => __('Administration view'), 'class' => 'main_menu_icon invert_filter']).''; $godmode['godmode'] = 1; - $operation['text'] = ''.html_print_image('images/eye_show.png', true, ['title' => __('Operation view'), 'class' => 'invert_filter']).''; + $operation['text'] = ''.html_print_image('images/see-details@svg.svg', true, ['title' => __('Operation view'), 'class' => 'main_menu_icon invert_filter']).''; $operation['operation'] = 1; $operation['active'] = 1; diff --git a/pandora_console/extensions/files_repo/files_repo_list.php b/pandora_console/extensions/files_repo/files_repo_list.php index 6c75218d18..2cb464eec3 100644 --- a/pandora_console/extensions/files_repo/files_repo_list.php +++ b/pandora_console/extensions/files_repo/files_repo_list.php @@ -133,9 +133,12 @@ if (!empty($files)) { ); $data[4] .= ""; $data[4] .= html_print_image( - 'images/config.png', + 'images/edit.svg', true, - ['title' => __('Edit')] + [ + 'title' => __('Edit'), + 'class' => 'main_menu_icon invert_filter', + ] ); // Edit image $data[4] .= ''; @@ -145,11 +148,11 @@ if (!empty($files)) { ); $data[4] .= " "; $data[4] .= html_print_image( - 'images/cross.png', + 'images/delete.svg', true, [ 'title' => __('Delete'), - 'class' => 'invert_filter', + 'class' => 'main_menu_icon invert_filter', ] ); // Delete image diff --git a/pandora_console/godmode/agentes/inventory_manager.php b/pandora_console/godmode/agentes/inventory_manager.php index b8d8014545..42984caeda 100644 --- a/pandora_console/godmode/agentes/inventory_manager.php +++ b/pandora_console/godmode/agentes/inventory_manager.php @@ -235,7 +235,7 @@ if (db_get_num_rows($sql) == 0) { if ($id_policy) { $policy = policies_get_policy($id_policy); $data[0] = ''; - $data[0] .= html_print_image('images/policies_mc.png', true, ['border' => '0', 'title' => $policy['name']]); + $data[0] .= html_print_image('images/policy@svg.svg', true, ['border' => '0', 'title' => $policy['name'], 'class' => 'main_menu_icon invert_filter']); $data[0] .= ''; } else { $data[0] = ''; @@ -247,15 +247,15 @@ if (db_get_num_rows($sql) == 0) { $data[4] = human_time_description_raw($row['interval']); // Delete module $data[5] = ''; - $data[5] .= html_print_image('images/cross.png', true, ['border' => '0', 'title' => __('Delete'), 'class' => 'invert_filter']); + $data[5] .= html_print_image('images/delete.svg', true, ['border' => '0', 'title' => __('Delete'), 'class' => 'main_menu_icon invert_filter']); $data[5] .= '  '; // Update module $data[5] .= ''; - $data[5] .= html_print_image('images/config.png', true, ['border' => '0', 'title' => __('Update'), 'class' => 'invert_filter']); + $data[5] .= html_print_image('images/edit.svg', true, ['border' => '0', 'title' => __('Update'), 'class' => 'main_menu_icon invert_filter']); $data[5] .= '  '; // Force refresh module $data[5] .= ''; - $data[5] .= html_print_image('images/target.png', true, ['border' => '0', 'title' => __('Force'), 'class' => 'invert_filter']).''; + $data[5] .= html_print_image('images/change-active.svg', true, ['border' => '0', 'title' => __('Force'), 'class' => 'main_menu_icon invert_filter']).''; array_push($table->data, $data); } diff --git a/pandora_console/godmode/agentes/module_manager_editor_common.php b/pandora_console/godmode/agentes/module_manager_editor_common.php index 085afcb455..2cceb5fa34 100644 --- a/pandora_console/godmode/agentes/module_manager_editor_common.php +++ b/pandora_console/godmode/agentes/module_manager_editor_common.php @@ -290,7 +290,7 @@ $table_simple->rowclass['captions_module_n_type'] = 'field_half_width pdd_t_10px $table_simple->rowclass['module_n_type'] = 'field_half_width'; $table_simple->data['captions_module_n_type'][0] = html_print_input_hidden('id_module_type_hidden', $id_module_type, true); $table_simple->data['captions_module_n_type'][0] .= __('Module group'); -$table_simple->data['captions_module_n_type'][1] = __('Type').ui_print_help_icon($help_type, true, '', 'images/help_green.png', '', 'module_type_help'); +$table_simple->data['captions_module_n_type'][1] = __('Type').ui_print_help_icon($help_type, true, '', '', '', 'module_type_help'); // Module group and Type. $table_simple->rowclass['module_n_type'] = 'field_half_width'; $table_simple->data['module_n_type'][0] .= html_print_select_from_sql( @@ -1437,7 +1437,7 @@ if (isset($module_macros)) { $table_macros->data[$macro_count][2] = __('Value'); $table_macros->data[$macro_count][3] = html_print_input_text('module_macro_values[]', $macro_value, '', 50, 60, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy); if (!$disabledBecauseInPolicy) { - $table_macros->data[$macro_count][4] = ''.html_print_image('images/cross.png', true, ['class' => 'invert_filter']).''; + $table_macros->data[$macro_count][4] = ''.html_print_image('images/delete.svg', true, ['class' => 'main_menu_icon invert_filter']).''; } $macro_count++; @@ -1446,7 +1446,7 @@ if (isset($module_macros)) { } if (!$disabledBecauseInPolicy) { - $table_macros->data[$macro_count][0] = ''.__('Custom macros').' '.html_print_image('images/add.png', true, ['class' => 'invert_filter']).''; + $table_macros->data[$macro_count][0] = ''.__('Custom macros').' '.html_print_image('images/fail@svg.svg', true, ['style' => 'rotate:45deg', 'class' => 'main_menu_icon invert_filter']).''; $table_macros->colspan[$macro_count][0] = 5; } @@ -1535,14 +1535,15 @@ $table_relations->data[-1][1] = ''; $table_relations->data[-1][2] = ''; $table_relations->data[-1][3] = ''; $table_relations->data[-1][3] .= html_print_image( - 'images/lock_mc.png', - true + 'images/policy@svg.svg', + true, + ['class' => 'main_menu_icon invert_filter'] ).''; $table_relations->data[-1][4] = ''; $table_relations->data[-1][4] .= html_print_image( - 'images/cross.png', + 'images/delete.svg', true, - ['class' => 'invert_filter'] + ['class' => 'main_menu_icon invert_filter'] ).''; @@ -1598,15 +1599,15 @@ if ($id_agent_module) { $table_relations->data[$relations_count][2] = ($module_relation['type'] === 'direct') ? __('Direct') : __('Failover'); // Lock relationship updates. $table_relations->data[$relations_count][3] = ''.html_print_image( - 'images/lock_mc.png', + 'images/policy@svg.svg', true, - ['class' => 'invert_filter'] + ['class' => 'main_menu_icon invert_filter'] ).''; // Delete relationship. $table_relations->data[$relations_count][4] = ''.html_print_image( - 'images/cross.png', + 'images/delete.svg', true, - ['class' => 'invert_filter'] + ['class' => 'main_menu_icon invert_filter'] ).''; $relations_count++; } @@ -2035,7 +2036,7 @@ function change_modules_autocomplete_input () { var id_agent = parseInt($("#hidden-autocomplete_id_agent").val()); var module_autocomplete = $("#module_autocomplete"); var load_icon = ''; - var error_icon = ''; + var error_icon = ' 'main_menu_icon invert_filter']); ?>'; if (!module_autocomplete.hasClass('working')) { module_autocomplete.addClass('working'); module_autocomplete.html(load_icon); @@ -2086,8 +2087,8 @@ function add_new_relation () { var button = $("#button-add_relation"); var iconPlaceholder = $("#add_relation_status"); var load_icon = ' 'vertical-align:middle;']); ?>'; - var suc_icon = ' 'vertical-align:middle;']); ?>'; - var error_icon = ' 'vertical-align:middle;']); ?>'; + var suc_icon = ' 'main_menu_icon invert_filter', 'style' => 'vertical-align:middle;']); ?>'; + var error_icon = ' 'main_menu_icon invert_filter', 'style' => 'vertical-align:middle;']); ?>'; if (!button.hasClass('working')) { button.addClass('working'); @@ -2129,12 +2130,12 @@ function add_new_relation () { '' + relation_type + '' + '' + '' + - ' 'invert_filter']); ?>' + + ' 'main_menu_icon invert_filter']); ?>' + '' + '' + '' + '' + - ' 'invert_filter']); ?>' + + ' 'main_menu_icon invert_filter']); ?>' + '' + '' + ''; diff --git a/pandora_console/godmode/alerts/alert_commands.php b/pandora_console/godmode/alerts/alert_commands.php index 696882e133..9b22483f5c 100644 --- a/pandora_console/godmode/alerts/alert_commands.php +++ b/pandora_console/godmode/alerts/alert_commands.php @@ -809,10 +809,10 @@ foreach ($commands as $command) { if (is_user_admin($config['id_user']) === true) { $data['action'] = ''; $data['action'] .= ''.html_print_image('images/copy.png', true, ['class' => 'invert_filter']).''; + onClick="if (!confirm(\''.__('Are you sure?').'\')) return false;">'.html_print_image('images/copy.svg', true, ['class' => 'main_menu_icon invert_filter']).''; $data['action'] .= ''.html_print_image('images/cross.png', true, ['class' => 'invert_filter']).''; + onClick="if (!confirm(\''.__('Are you sure?').'\')) return false;">'.html_print_image('images/delete.svg', true, ['class' => 'main_menu_icon invert_filter']).''; $data['action'] .= ''; } } diff --git a/pandora_console/godmode/alerts/alert_list.list.php b/pandora_console/godmode/alerts/alert_list.list.php index 854905343a..f844d2c18d 100644 --- a/pandora_console/godmode/alerts/alert_list.list.php +++ b/pandora_console/godmode/alerts/alert_list.list.php @@ -1053,7 +1053,7 @@ foreach ($simple_alerts as $alert) { $data[4] .= '
'; $data[4] .= html_print_input_image( 'view_alert', - 'images/operation.png', + 'images/details.svg', 1, '', true, diff --git a/pandora_console/godmode/alerts/alert_list.php b/pandora_console/godmode/alerts/alert_list.php index 4d23bb8d6f..55f786c3c2 100644 --- a/pandora_console/godmode/alerts/alert_list.php +++ b/pandora_console/godmode/alerts/alert_list.php @@ -478,17 +478,17 @@ if ($standbyoff_alert) { $searchFlag = true; -if (!is_metaconsole()) { +if (is_metaconsole() === false) { // The tabs will be shown only with manage alerts permissions if (check_acl($config['id_user'], 0, 'LW') || check_acl($config['id_user'], 0, 'LM')) { $buttons = [ 'list' => [ 'active' => false, - 'text' => ''.html_print_image('images/list.png', true, ['title' => __('List alerts'), 'class' => 'invert_filter']).'', + 'text' => ''.html_print_image('images/load@svg.svg', true, ['title' => __('List alerts'), 'class' => 'main_menu_icon invert_filter']).'', ], 'builder' => [ 'active' => false, - 'text' => ''.html_print_image('images/pencil.png', true, ['title' => __('Builder alert'), 'class' => 'invert_filter']).'', + 'text' => ''.html_print_image('images/edit.svg', true, ['title' => __('Builder alert'), 'class' => 'main_menu_icon invert_filter']).'', ], ]; @@ -497,7 +497,7 @@ if (!is_metaconsole()) { $buttons = ''; } - if ($tab == 'list') { + if ($tab === 'list') { ui_print_standard_header( __('Alerts'), 'images/gm_alerts.png', diff --git a/pandora_console/godmode/alerts/alert_templates.php b/pandora_console/godmode/alerts/alert_templates.php index fbe2835354..23d94b094d 100644 --- a/pandora_console/godmode/alerts/alert_templates.php +++ b/pandora_console/godmode/alerts/alert_templates.php @@ -450,7 +450,7 @@ foreach ($templates as $template) { $data[4] .= html_print_input_hidden('source_id', $template['id'], true); $data[4] .= html_print_input_image( 'dup', - 'images/copy.png', + 'images/copy.svg', 1, '', true, diff --git a/pandora_console/godmode/extensions.php b/pandora_console/godmode/extensions.php index 8faef70d3e..69c5e59b8b 100644 --- a/pandora_console/godmode/extensions.php +++ b/pandora_console/godmode/extensions.php @@ -295,7 +295,8 @@ foreach ($extensions as $file => $extension) { $data[] = html_print_menu_button( [ 'href' => 'index.php?sec=godmode/extensions&sec2=godmode/extensions&enterprise='.(int) $extension['enterprise'].'&delete='.$file, - 'image' => 'images/cross.png', + 'image' => 'images/delete.svg', + 'class' => 'main_menu_icon invert_filter', 'title' => __('Delete'), 'onClick' => 'if (!confirm(\''.__('Are you sure?').'\')) return false;', ], diff --git a/pandora_console/godmode/module_library/module_library_view.php b/pandora_console/godmode/module_library/module_library_view.php index aeab26be20..aea7681f3b 100644 --- a/pandora_console/godmode/module_library/module_library_view.php +++ b/pandora_console/godmode/module_library/module_library_view.php @@ -45,18 +45,18 @@ if (! check_acl($config['id_user'], 0, 'AR')) { if (check_acl($config['id_user'], 0, 'PM') && enterprise_installed()) { $buttons['setup'] = [ 'active' => false, - 'text' => ''.html_print_image('images/gm_setup.png', true, ['title' => __('Setup'), 'class' => 'invert_filter']).'', + 'text' => ''.html_print_image('images/configuration@svg.svg', true, ['title' => __('Setup'), 'class' => 'main_menu_icon invert_filter']).'', ]; } $buttons['categories'] = [ 'active' => false, - 'text' => ''.html_print_image('images/list.png', true, ['title' => __('Categories'), 'class' => 'invert_filter']).'', + 'text' => ''.html_print_image('images/logs@svg.svg', true, ['title' => __('Categories'), 'class' => 'main_menu_icon invert_filter']).'', ]; $buttons['view'] = [ 'active' => false, - 'text' => ''.html_print_image('images/eye_show.png', true, ['title' => __('View'), 'class' => 'invert_filter']).'', + 'text' => ''.html_print_image('images/see-details@svg.svg', true, ['title' => __('View'), 'class' => 'main_menu_icon invert_filter']).'', ]; diff --git a/pandora_console/godmode/reporting/reporting_builder.php b/pandora_console/godmode/reporting/reporting_builder.php index a4f688ab05..a0e25d0e04 100755 --- a/pandora_console/godmode/reporting/reporting_builder.php +++ b/pandora_console/godmode/reporting/reporting_builder.php @@ -3680,21 +3680,21 @@ $buttons = [ true, [ 'title' => __('Reports list'), - 'class' => 'invert_filter', + 'class' => 'main_menu_icon invert_filter', ] ).'', ], 'main' => [ 'active' => false, - 'text' => ''.html_print_image('images/op_reporting.png', true, ['title' => __('Main data'), 'class' => 'invert_filter']).'', + 'text' => ''.html_print_image('images/op_reporting.png', true, ['title' => __('Main data'), 'class' => 'main_menu_icon invert_filter']).'', ], 'list_items' => [ 'active' => false, - 'text' => ''.html_print_image('images/list.png', true, ['title' => __('List items'), 'class' => 'invert_filter']).'', + 'text' => ''.html_print_image('images/logs@svg.svg', true, ['title' => __('List items'), 'class' => 'main_menu_icon invert_filter']).'', ], 'item_editor' => [ 'active' => false, - 'text' => ''.html_print_image('images/pencil.png', true, ['title' => __('Item editor'), 'class' => 'invert_filter']).'', + 'text' => ''.html_print_image('images/edit.svg', true, ['title' => __('Item editor'), 'class' => 'main_menu_icon invert_filter']).'', ], ]; @@ -3708,11 +3708,11 @@ if ($enterpriseEnable) { $buttons['view'] = [ 'active' => false, 'text' => ''.html_print_image( - 'images/eye.png', + 'images/see-details@svg.svg', true, [ 'title' => __('View report'), - 'class' => 'invert_filter', + 'class' => 'main_menu_icon invert_filter', ] ).'', ]; @@ -3727,7 +3727,7 @@ if ($idReport != 0) { $buttons = [ 'main' => [ 'active' => true, - 'text' => ''.html_print_image('images/report_list.png', true, ['title' => __('Reports list'), 'class' => 'invert_filter']).'', + 'text' => ''.html_print_image('images/report_list.png', true, ['title' => __('Reports list'), 'class' => 'main_menu_icon invert_filter']).'', ], ]; $textReportName = __('Create Custom Report'); diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index fc169f91a2..d19d3587c6 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -292,11 +292,11 @@ $table->data[$i][1] = html_print_input_text_extended( true ); $table->data[$i][1] .= ''.html_print_image( - 'images/pencil.png', + 'images/edit.svg', true, [ 'title' => __('Change timezone'), - 'class' => 'invert_filter', + 'class' => 'main_menu_icon invert_filter', ] ).''; $table->data[$i][1] .= '  '.html_print_select( @@ -423,9 +423,9 @@ $table_ichanges = ' diff --git a/pandora_console/godmode/setup/setup_visuals.php b/pandora_console/godmode/setup/setup_visuals.php index 73b2511b2b..5fb042fe66 100755 --- a/pandora_console/godmode/setup/setup_visuals.php +++ b/pandora_console/godmode/setup/setup_visuals.php @@ -1626,11 +1626,11 @@ if ($config['csv_divider'] != ';' && $config['csv_divider'] != ',' && $config['c true ); $table_other->data[$row][1] .= ''.html_print_image( - 'images/list.png', + 'images/logs@svg.svg', true, [ 'id' => 'select', - 'class' => 'invert_filter', + 'class' => 'main_menu_icon invert_filter', ] ).''; } else { @@ -1646,11 +1646,11 @@ if ($config['csv_divider'] != ';' && $config['csv_divider'] != ',' && $config['c false ); $table_other->data[$row][1] .= ''.html_print_image( - 'images/pencil.png', + 'images/edit.svg', true, [ 'id' => 'pencil', - 'class' => 'invert_filter', + 'class' => 'main_menu_icon invert_filter', ] ).''; } @@ -1777,7 +1777,7 @@ function edit_csv_divider () { $("#text-csv_divider").val(value); } else { - $("#csv_divider_custom img").attr("src", "images/pencil.png"); + $("#csv_divider_custom img").attr("src", "images/edit.svg"); $("#csv_divider_custom img").attr("id", "pencil"); $("#text-csv_divider").replaceWith("'; echo ''; @@ -545,14 +545,14 @@ if (is_metaconsole()) {
'.$select_out.' - '.html_print_image('images/darrowright.png', true, ['id' => 'right_iblacklist', 'alt' => __('Push selected modules into blacklist'), 'title' => __('Push selected modules into blacklist'), 'class' => 'invert_filter']).' + '.html_print_image('images/arrow@svg.svg', true, ['style' => 'rotate: 180deg;', 'id' => 'right_iblacklist', 'alt' => __('Push selected modules into blacklist'), 'title' => __('Push selected modules into blacklist'), 'class' => 'main_menu_icon invert_filter']).'

- '.html_print_image('images/darrowleft.png', true, ['id' => 'left_iblacklist', 'alt' => __('Pop selected modules out of blacklist'), 'title' => __('Pop selected modules out of blacklist'), 'class' => 'invert_filter']).' + '.html_print_image('images/arrow@svg.svg', true, ['style' => 'rotate: 0', 'id' => 'left_iblacklist', 'alt' => __('Pop selected modules out of blacklist'), 'title' => __('Pop selected modules out of blacklist'), 'class' => 'main_menu_icon invert_filter']).'
'.$select_in.'
'.html_print_select($max_values, 'max_aggregates', $max_aggregates, '', '', 0, true).''.html_print_image('images/pencil.png', true, ['id' => 'pencil']).''; + echo ''.html_print_select($max_values, 'max_aggregates', $max_aggregates, '', '', 0, true).''.html_print_image('images/edit.svg', true, ['id' => 'pencil', 'class' => 'main_menu_icon invert_filter']).''; echo ''.__('Aggregate by').'