From 971fc84a470b2ebd536c970cfe7bd7f82d264ab6 Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Thu, 9 Feb 2023 10:12:59 +0100 Subject: [PATCH] 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; + } + + +}