diff --git a/pandora_console/images/widgets/service_view.png b/pandora_console/images/widgets/service_view.png new file mode 100644 index 0000000000..8043a1e453 Binary files /dev/null and b/pandora_console/images/widgets/service_view.png differ diff --git a/pandora_console/include/class/TreeService.class.php b/pandora_console/include/class/TreeService.class.php index 56ec13ac3a..9d9018665c 100644 --- a/pandora_console/include/class/TreeService.class.php +++ b/pandora_console/include/class/TreeService.class.php @@ -222,20 +222,20 @@ class TreeService extends Tree switch ($status) { case SERVICE_STATUS_NORMAL: - $processed_items[$row['id']]['statusImageHTML'] = 'NORMAL status.'; + $processed_items[$row['id']]['statusImageHTML'] = 'NORMAL status.'; break; case SERVICE_STATUS_CRITICAL: - $processed_items[$row['id']]['statusImageHTML'] = 'CRITICAL status.'; + $processed_items[$row['id']]['statusImageHTML'] = 'CRITICAL status.'; break; case SERVICE_STATUS_WARNING: - $processed_items[$row['id']]['statusImageHTML'] = 'WARNING status.'; + $processed_items[$row['id']]['statusImageHTML'] = 'WARNING status.'; break; case SERVICE_STATUS_UNKNOWN: default: - $processed_items[$row['id']]['statusImageHTML'] = 'UNKNOWN status.'; + $processed_items[$row['id']]['statusImageHTML'] = 'UNKNOWN status.'; break; } } @@ -406,21 +406,21 @@ class TreeService extends Tree switch ($item->agent()->lastStatus()) { case AGENT_STATUS_NORMAL: - $tmp['statusImageHTML'] = 'NORMAL status.'; + $tmp['statusImageHTML'] = 'NORMAL status.'; break; case AGENT_STATUS_CRITICAL: case AGENT_STATUS_ALERT_FIRED: - $tmp['statusImageHTML'] = 'CRITICAL status.'; + $tmp['statusImageHTML'] = 'CRITICAL status.'; break; case AGENT_STATUS_WARNING: - $tmp['statusImageHTML'] = 'WARNING status.'; + $tmp['statusImageHTML'] = 'WARNING status.'; break; case AGENT_STATUS_UNKNOWN: default: - $tmp['statusImageHTML'] = 'UNKNOWN status.'; + $tmp['statusImageHTML'] = 'UNKNOWN status.'; break; } diff --git a/pandora_console/include/javascript/pandora_dashboards.js b/pandora_console/include/javascript/pandora_dashboards.js index e1de0ba834..71893c1f62 100644 --- a/pandora_console/include/javascript/pandora_dashboards.js +++ b/pandora_console/include/javascript/pandora_dashboards.js @@ -948,6 +948,133 @@ function processTreeSearch(settings) { }); } +function processServiceTree(settings) { + var treeController = TreeController.getController(); + + if ( + typeof treeController.recipient != "undefined" && + treeController.recipient.length > 0 + ) + treeController.recipient.empty(); + + $(".loading_tree").show(); + + var parameters = {}; + parameters["page"] = "include/ajax/tree.ajax"; + parameters["getChildren"] = 1; + parameters["type"] = "services"; + parameters["filter"] = {}; + parameters["filter"]["searchGroup"] = ""; + parameters["filter"]["searchAgent"] = ""; + parameters["filter"]["statusAgent"] = ""; + parameters["filter"]["searchModule"] = ""; + parameters["filter"]["statusModule"] = ""; + parameters["filter"]["groupID"] = ""; + parameters["filter"]["tagID"] = ""; + parameters["filter"]["searchHirearchy"] = 1; + parameters["filter"]["show_not_init_agents"] = 1; + parameters["filter"]["show_not_init_modules"] = 1; + parameters["filter"]["is_favourite"] = 0; + parameters["filter"]["width"] = 100; + + $.ajax({ + type: "POST", + url: settings.ajaxURL, + data: parameters, + success: function(data) { + if (data.success) { + $(".loading_tree").hide(); + // Get the main values of the tree. + var rawTree = Object.values(data.tree); + // Sorting tree by description (TreeController.js). + rawTree.sort(function(a, b) { + var x = a.description.toLowerCase(); + var y = b.description.toLowerCase(); + if (x < y) { + return -1; + } + if (x > y) { + return 1; + } + return 0; + }); + treeController.init({ + recipient: $("div#container_servicemap_" + settings.cellId), + detailRecipient: { + render: function(element, data) { + return { + open: function() { + $("#module_details_window") + .hide() + .empty() + .append(data) + .dialog({ + resizable: true, + draggable: true, + modal: true, + title: "Info", + overlay: { + opacity: 0.5, + background: "black" + }, + width: 450, + height: 500 + }); + } + }; + } + }, + page: parameters["page"], + emptyMessage: "No data found", + foundMessage: "Found groups", + tree: rawTree, + baseURL: settings.baseURL, + ajaxURL: settings.ajaxURL, + filter: parameters["filter"], + counterTitles: { + total: { + agents: "Total agents", + modules: "Total modules", + none: "Total" + }, + alerts: { + agents: "Fired alerts", + modules: "Fired alerts", + none: "Fired alerts" + }, + critical: { + agents: "Critical agents", + modules: "Critical modules')", + none: "Critical" + }, + warning: { + agents: "Warning agents", + modules: "Warning modules", + none: "Warning" + }, + unknown: { + agents: "Unknown agents", + modules: "Unknown modules", + none: "Unknown" + }, + not_init: { + agents: "Not init agents", + modules: "Not init modules", + none: "Not init" + }, + ok: { + agents: " Normal agents ", + modules: " Normal modules ", + none: " Normal " + } + } + }); + } + }, + dataType: "json" + }); +} + function show_module_detail_dialog( module_id, id_agent, diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php index fa6c0a7711..617bd74cb8 100644 --- a/pandora_console/include/lib/Dashboard/Widget.php +++ b/pandora_console/include/lib/Dashboard/Widget.php @@ -352,6 +352,14 @@ class Widget $className .= '\ServiceMapWidget'; break; + case 'service_view': + if (\enterprise_installed() === false) { + $not_installed = true; + } + + $className .= '\ServiceViewWidget'; + break; + case 'single_graph': $className .= '\SingleGraphWidget'; break; diff --git a/pandora_console/include/lib/Dashboard/Widgets/service_view.php b/pandora_console/include/lib/Dashboard/Widgets/service_view.php new file mode 100644 index 0000000000..ec1749671a --- /dev/null +++ b/pandora_console/include/lib/Dashboard/Widgets/service_view.php @@ -0,0 +1,471 @@ +width = $width; + + // Height. + $this->height = $height; + + // Grid Width. + $this->gridWidth = $gridWidth; + + // Cell Id. + $this->cellId = $cellId; + + // Widget ID. + $this->widgetId = $widgetId; + + // Dashboard ID. + $this->dashboardId = $dashboardId; + + // 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 = __('Service View'); + + // Name. + if (empty($this->name) === true) { + $this->name = 'service_view'; + } + + // // This forces at least a first configuration. + // $this->configurationRequired = false; + // if (empty($this->values['serviceId']) === 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['type']) === true) { + $values['type'] = $decoder['type']; + } + + return $values; + } + + + /** + * Generates inputs for form (specific). + * + * @return array Of inputs. + * + * @throws Exception On error. + */ + public function getFormInputs(): array + { + // Retrieve global - common inputs. + $inputs = parent::getFormInputs(); + + $values = $this->values; + if (empty($values['type']) === true) { + $values['type'] = 'tree'; + } + + // Type services view. + $fields = [ + 'tree' => __('Tree'), + 'table' => __('Table'), + ]; + + $inputs[] = [ + 'label' => __('Type'), + 'arguments' => [ + 'type' => 'select', + 'fields' => $fields, + 'name' => 'type', + 'selected' => $values['type'], + 'return' => true, + ], + ]; + + return $inputs; + } + + + /** + * Get Post for widget. + * + * @return array + */ + public function getPost():array + { + // Retrieve global - common inputs. + $values = parent::getPost(); + $values['type'] = \get_parameter('type', 'tree'); + + return $values; + } + + + /** + * Draw widget. + * + * @return string; + */ + public function load() + { + global $config; + + $values = $this->values; + + $size = parent::getSize(); + $output = ''; + + if ($values['type'] === 'tree' || empty($values['type'])) { + if (check_acl($config['id_user'], 0, 'AR') === 0) { + $output .= '
'; + $output .= \ui_print_error_message( + __('The user doesn\'t have permission to read agents'), + '', + true + ); + $output .= '
'; + return $output; + } + + $containerId = 'container_servicemap_'.$this->cellId; + $output .= "
"; + $output .= '
'; + + $output .= \html_print_image( + 'images/spinner.gif', + true, + [ + 'class' => 'loading_tree', + 'style' => 'display: none;', + ] + ); + + // Css Files. + \ui_require_css_file('tree', 'include/styles/', true); + if ($config['style'] == 'pandora_black') { + \ui_require_css_file('pandora_black', 'include/styles/', true); + } + + \ui_require_javascript_file( + 'TreeController', + 'include/javascript/tree/', + true + ); + + \ui_require_javascript_file( + 'fixed-bottom-box', + 'include/javascript/', + true + ); + + $settings['cellId'] = $this->cellId; + $settings['baseURL'] = \ui_get_full_url('/', false, false, false); + $settings['ajaxURL'] = \ui_get_full_url('ajax.php', false, false, false); + + // Show the modal window of an module. + $output .= '
'; + $output .= '
'; + + // Script. + $output .= ''; + } else { + $own_info = \get_user_info($config['id_user']); + if ($own_info['is_admin'] || check_acl($config['id_user'], 0, 'PM')) { + $display_all_services = true; + } else { + $display_all_services = false; + } + + $order = [ + 'field' => 'name', + 'field2' => 'name', + 'order' => 'ASC', + ]; + + $filter['order'] = $order; + + $services = services_get_services( + $filter, + false, + $display_all_services, + 'AR' + ); + + $output .= '
'; + $output .= '
'; + foreach ($services as $service) { + switch ($service['status']) { + case SERVICE_STATUS_NORMAL: + $color = COL_NORMAL; + break; + + case SERVICE_STATUS_CRITICAL: + $color = COL_CRITICAL; + break; + + case SERVICE_STATUS_WARNING: + $color = COL_WARNING; + break; + + case SERVICE_STATUS_UNKNOWN: + default: + $color = COL_UNKNOWN; + break; + } + + $output .= ' +
+
'; + $output .= \ui_print_group_icon($service['id_group'], true, 'groups_small_white', '', false); + + $output .= '
+
'.$service['description'].' +
+
'; + $output .= \html_print_image('images/help_w.png', true, ['class' => 'img_help', 'title' => __($service['name']), 'id' => $service['id']]); + + $output .= '
+
+
'; + } + + $output .= '
'; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + + $output .= ''; + + $output .= ''; + $output .= ''; + $output .= ''; + $output .= ''; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= '
Unknown
'; + $output .= '
'; + $output .= '
Normal
'; + $output .= ''; + $output .= '
'; + $output .= '
Warning
'; + $output .= '
'; + $output .= '
Critical
'; + $output .= '
'; + $output .= '
'; + } + + return $output; + } + + + /** + * Get description. + * + * @return string. + */ + public static function getDescription() + { + return __('Services view'); + } + + + /** + * Get Name. + * + * @return string. + */ + public static function getName() + { + return 'service_view'; + } + + +} diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 365b393b1b..bb7743c37d 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -5814,6 +5814,18 @@ div#status_pie { margin-bottom: 30px; } +#table_services_dashboard { + display: grid; + grid-gap: 20px; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + grid-template-rows: 1fr; + margin-bottom: 30px; +} + +.services_table { + width: 97%; +} + .table_services_item_link { font-size: 16px; display: grid; @@ -5822,6 +5834,14 @@ div#status_pie { padding: 10px 10px 10px 0; } +.table_services_item_link_dashboard { + font-size: 16px; + display: grid; + min-height: 50px; + box-sizing: border-box; + padding: 10px 10px 10px 0; +} + .table_services_item { display: grid; align-items: center; diff --git a/pandora_console/include/styles/tree.css b/pandora_console/include/styles/tree.css index 6a0cc7b19f..c4cdf7d276 100644 --- a/pandora_console/include/styles/tree.css +++ b/pandora_console/include/styles/tree.css @@ -176,6 +176,12 @@ div#tree-controller-recipient { margin-top: 10px; } +.tree-controller-recipient { + text-align: left; + width: 98%; + margin-top: 10px; +} + .tree-node > .node-content > div + div:not(.tree-node-counters) { margin-left: 3px; }