From da7e903101f138b71f2544febdd82da46b76562d Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 17 Feb 2021 12:19:22 +0100 Subject: [PATCH 1/7] WIP dashboards meta --- .../include/lib/Dashboard/Manager.php | 11 +++++++++ pandora_console/include/lib/View.php | 1 - .../operation/dashboard/dashboard.php | 6 ++++- pandora_console/views/dashboard/header.php | 24 ++++++++++++------- pandora_console/views/dashboard/layout.php | 12 ++++++++-- pandora_console/views/dashboard/list.php | 19 +++++++++------ 6 files changed, 54 insertions(+), 19 deletions(-) diff --git a/pandora_console/include/lib/Dashboard/Manager.php b/pandora_console/include/lib/Dashboard/Manager.php index 891ef524df..050ff2576d 100644 --- a/pandora_console/include/lib/Dashboard/Manager.php +++ b/pandora_console/include/lib/Dashboard/Manager.php @@ -997,6 +997,10 @@ class Manager // Header. if ($this->slides === 0) { + if ((bool) \is_metaconsole() === true) { + open_meta_frame(); + } + View::render( 'dashboard/header', [ @@ -1077,6 +1081,13 @@ class Manager 'dashboard/jsLayout', ['dashboardId' => $this->dashboardId] ); + + if ((bool) \is_metaconsole() === true + && $this->slides === 0 + ) { + close_meta_frame(); + } + return null; } diff --git a/pandora_console/include/lib/View.php b/pandora_console/include/lib/View.php index e3c21066d1..7182b43e6a 100644 --- a/pandora_console/include/lib/View.php +++ b/pandora_console/include/lib/View.php @@ -32,7 +32,6 @@ namespace PandoraFMS; global $config; require_once $config['homedir'].'/include/class/HTML.class.php'; -use \HTML as HTML; /** * View class. diff --git a/pandora_console/operation/dashboard/dashboard.php b/pandora_console/operation/dashboard/dashboard.php index 5dc1292367..3f4a924ff8 100644 --- a/pandora_console/operation/dashboard/dashboard.php +++ b/pandora_console/operation/dashboard/dashboard.php @@ -29,10 +29,14 @@ global $config; -require 'vendor/autoload.php'; +require $config['homedir'].'/vendor/autoload.php'; use PandoraFMS\Dashboard\Manager; +if ((bool) is_metaconsole() === true) { + ui_require_css_file('meta_dashboards.css'); +} + $ajaxPage = 'operation/dashboard/dashboard'; // Control call flow. diff --git a/pandora_console/views/dashboard/header.php b/pandora_console/views/dashboard/header.php index 0449e4dfb6..d476dcff2d 100644 --- a/pandora_console/views/dashboard/header.php +++ b/pandora_console/views/dashboard/header.php @@ -245,14 +245,22 @@ if ($config['public_dashboard'] === true) { } if ($publicLink === false) { - ui_print_page_header( - $dashboardName, - '', - false, - '', - false, - $buttons - ); + if ((bool) is_metaconsole() === true) { + ui_meta_print_header( + __('Dashboards').' ยป '.__('List'), + false, + $buttons + ); + } else { + ui_print_page_header( + $dashboardName, + '', + false, + '', + false, + $buttons + ); + } } else { $output = '
'; foreach ($buttons as $key => $value) { diff --git a/pandora_console/views/dashboard/layout.php b/pandora_console/views/dashboard/layout.php index 57dd228898..1d33c974cc 100644 --- a/pandora_console/views/dashboard/layout.php +++ b/pandora_console/views/dashboard/layout.php @@ -27,10 +27,18 @@ */ // Css Files. -\ui_require_css_file('bootstrap.min'); +if ((bool) \is_metaconsole() !== true) { + \ui_require_css_file('bootstrap.min'); +} + \ui_require_css_file('gridstack.min'); \ui_require_css_file('gridstack-extra.min'); -\ui_require_css_file('pandora'); +if ((bool) \is_metaconsole() === true) { + \ui_require_css_file('meta_pandora'); +} else { + \ui_require_css_file('pandora'); +} + \ui_require_css_file('dashboards'); // Js Files. diff --git a/pandora_console/views/dashboard/list.php b/pandora_console/views/dashboard/list.php index be282e679b..bd956a578e 100644 --- a/pandora_console/views/dashboard/list.php +++ b/pandora_console/views/dashboard/list.php @@ -32,15 +32,20 @@ require_once $config['homedir'].'/include/class/HTML.class.php'; global $config; ui_require_css_file('dashboards'); +if ((bool) \is_metaconsole() === true) { + \ui_require_css_file('meta_dashboards'); +} // Header. -\ui_print_page_header( - __('Dashboards'), - '', - false, - '', - false -); +if ((bool) is_metaconsole() === false) { + \ui_print_page_header( + __('Dashboards'), + '', + false, + '', + false + ); +} if (isset($resultDelete) === true) { \ui_print_result_message( From 673f95e276adcc12fef913b8f555039404103f39 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 17 Feb 2021 12:57:13 +0100 Subject: [PATCH 2/7] Dashboards in meta --- .../include/lib/Dashboard/Widget.php | 71 +++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php index bfc640eaf0..9a8ae20dd3 100644 --- a/pandora_console/include/lib/Dashboard/Widget.php +++ b/pandora_console/include/lib/Dashboard/Widget.php @@ -37,6 +37,13 @@ class Widget */ private $values; + /** + * Target node Id. + * + * @var integer + */ + private $nodeId; + /** * Contructor widget. @@ -60,6 +67,9 @@ class Widget $cellClass = new Cell($this->cellId, $this->dashboardId); $this->dataCell = $cellClass->get(); $this->values = $this->decoders($this->getOptionsWidget()); + if (isset($this->values['node']) === true) { + $this->nodeId = $this->values['node']; + } } return $this; @@ -73,8 +83,6 @@ class Widget */ public function get() { - global $config; - $sql = sprintf( 'SELECT * FROM twidget @@ -99,8 +107,6 @@ class Widget */ public function getOptionsWidget():array { - global $config; - $result = []; if (empty($this->dataCell['options']) === false) { $result = \json_decode($this->dataCell['options'], true); @@ -419,6 +425,22 @@ class Widget $output = ''; + if ((bool) \is_metaconsole() === true) { + \enterprise_include_once('include/functions_metaconsole.php'); + if ($this->nodeId !== null) { + if (\metaconsole_connect(null, $this->nodeId) !== NOERR) { + $output .= '
'; + $output .= \ui_print_info_message( + __('Failed to connect to node %d', $this->nodeId), + '', + true + ); + $output .= '
'; + return $output; + } + } + } + if ($this->configurationRequired === true) { $output .= '
'; $output .= \ui_print_info_message( @@ -440,6 +462,12 @@ class Widget $output .= $this->load(); } + if ((bool) \is_metaconsole() === true) { + if ($this->nodeId !== null) { + \metaconsole_restore_db(); + } + } + return $output; } @@ -510,6 +538,34 @@ class Widget ], ]; + if ((bool) \is_metaconsole()) { + \enterprise_include_once('include/functions_metaconsole.php'); + $servers = \metaconsole_get_servers(); + if (is_array($servers) === true) { + $servers = array_reduce( + $servers, + function ($carry, $item) { + $carry[$item['id']] = $item['server_name']; + return $carry; + } + ); + } else { + $servers = []; + } + + $inputs[] = [ + 'label' => __('Node'), + 'arguments' => [ + 'wrapper' => 'div', + 'name' => 'node', + 'type' => 'select', + 'fields' => $servers, + 'selected' => $values['node'], + 'return' => true, + ], + ]; + } + return $inputs; } @@ -524,6 +580,9 @@ class Widget $values = []; $values['title'] = \get_parameter('title', ''); $values['background'] = \get_parameter('background', '#ffffff'); + if ((bool) \is_metaconsole() === true) { + $values['node'] = \get_parameter('node', null); + } return $values; @@ -553,6 +612,10 @@ class Widget $values['background'] = $decoder['background']; } + if (isset($decoder['node']) === true) { + $values['node'] = $decoder['node']; + } + return $values; } From ef16ef4281c120f4ea899bedb8b29dc18e6e6ed9 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 18 Feb 2021 12:47:42 +0100 Subject: [PATCH 3/7] Dashboards in metaconsole --- pandora_console/include/functions_events.php | 25 +-- pandora_console/include/functions_html.php | 1 + .../include/lib/Dashboard/Cell.php | 2 - .../include/lib/Dashboard/Manager.php | 22 +++ .../include/lib/Dashboard/Widget.php | 71 ++++++-- .../lib/Dashboard/Widgets/events_list.php | 9 +- .../include/lib/Dashboard/Widgets/reports.php | 160 ++++++++++++++---- .../include/styles/meta_dashboards.css | 4 + .../operation/dashboard/dashboard.php | 4 +- 9 files changed, 241 insertions(+), 57 deletions(-) create mode 100644 pandora_console/include/styles/meta_dashboards.css diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index ef361e0863..032ede4199 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -712,6 +712,7 @@ function events_update_status($id_evento, $status, $filter=null, $history=false) * @param boolean $validatedEvents If true, evaluate validated events. * @param boolean $recursiveGroups If true, filtered groups and their children * will be search. + * @param boolean $nodeConnected Already connected to node (uses tevento). * * @return array Events. * @throws Exception On error. @@ -727,7 +728,8 @@ function events_get_all( $return_sql=false, $having='', $validatedEvents=false, - $recursiveGroups=true + $recursiveGroups=true, + $nodeConnected=false ) { global $config; @@ -1017,7 +1019,10 @@ function events_get_all( ); } - $table = events_get_events_table(is_metaconsole(), $history); + $table = events_get_events_table( + (is_metaconsole() && $nodeConnected === false), + $history + ); $tevento = sprintf( ' %s te', $table @@ -1028,7 +1033,7 @@ function events_get_all( $tagente_table = 'tagente'; $tagente_field = 'id_agente'; $conditionMetaconsole = ''; - if (is_metaconsole()) { + if (is_metaconsole() && $nodeConnected === false) { $tagente_table = 'tmetaconsole_agent'; $tagente_field = 'id_tagente'; $conditionMetaconsole = ' AND ta.id_tmetaconsole_setup = te.server_id '; @@ -1075,7 +1080,7 @@ function events_get_all( ); } - if (is_metaconsole()) { + if (is_metaconsole() && $nodeConnected === false) { // Id source event. if (!empty($filter['id_source_event'])) { $sql_filters[] = sprintf( @@ -1239,7 +1244,7 @@ function events_get_all( // Query_table. '', // Meta. - is_metaconsole(), + is_metaconsole() && $nodeConnected === false, // Childrens_ids. [], // Force_group_and_tag. @@ -1265,7 +1270,7 @@ function events_get_all( // Query_table. '', // Meta. - is_metaconsole(), + is_metaconsole() && $nodeConnected === false, // Childrens_ids. [], // Force_group_and_tag. @@ -1291,7 +1296,7 @@ function events_get_all( // Query_table. '', // Meta. - is_metaconsole(), + is_metaconsole() && $nodeConnected === false, // Childrens_ids. [], // Force_group_and_tag. @@ -1312,7 +1317,7 @@ function events_get_all( // Module search. $agentmodule_join = 'LEFT JOIN tagente_modulo am ON te.id_agentmodule = am.id_agente_modulo'; - if (is_metaconsole()) { + if (is_metaconsole() && $nodeConnected === false) { $agentmodule_join = ''; } else if (!empty($filter['module_search'])) { $agentmodule_join = 'INNER JOIN tagente_modulo am ON te.id_agentmodule = am.id_agente_modulo'; @@ -1339,7 +1344,7 @@ function events_get_all( } $extra = ''; - if (is_metaconsole()) { + if (is_metaconsole() && $nodeConnected === false) { $extra = ', server_id'; } @@ -1405,7 +1410,7 @@ function events_get_all( } $server_join = ''; - if (is_metaconsole()) { + if (is_metaconsole() && $nodeConnected === false) { $server_join = ' LEFT JOIN tmetaconsole_setup ts ON ts.id = te.server_id'; if (!empty($filter['server_id'])) { diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index d00628000c..09bf5be7cd 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -4318,6 +4318,7 @@ function html_print_input($data, $wrapper='div', $input_only=false) return ''; } + enterprise_include_once('include/functions_metaconsole.php'); $output = ''; if ($data['label'] && $input_only === false) { diff --git a/pandora_console/include/lib/Dashboard/Cell.php b/pandora_console/include/lib/Dashboard/Cell.php index fdc6b3366d..964d43e668 100644 --- a/pandora_console/include/lib/Dashboard/Cell.php +++ b/pandora_console/include/lib/Dashboard/Cell.php @@ -216,8 +216,6 @@ class Cell */ public static function getCells(int $dashboardId):array { - global $config; - $cells = db_get_all_rows_filter( 'twidget_dashboard', [ diff --git a/pandora_console/include/lib/Dashboard/Manager.php b/pandora_console/include/lib/Dashboard/Manager.php index 63f276b6bf..be87ef8732 100644 --- a/pandora_console/include/lib/Dashboard/Manager.php +++ b/pandora_console/include/lib/Dashboard/Manager.php @@ -178,6 +178,7 @@ class Manager 'saveWidgetIntoCell', 'imageIconDashboardAjax', 'formSlides', + 'callWidgetMethod', ]; @@ -1501,4 +1502,25 @@ class Manager } + /** + * Call widget method (ajax only). + * + * @param string $method Method to be invoked. + * + * @return boolean Executed or not. + */ + public function callWidgetMethod(string $method):bool + { + $widget = $this->instanceWidget(); + + if (method_exists($widget, $method) === true) { + $widget->$method(); + return true; + } + + return false; + + } + + } diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php index 2ec76f5c40..cc2e560141 100644 --- a/pandora_console/include/lib/Dashboard/Widget.php +++ b/pandora_console/include/lib/Dashboard/Widget.php @@ -14,7 +14,7 @@ class Widget * * @var integer */ - private $dashboardId; + protected $dashboardId; /** * Cell ID. @@ -28,7 +28,7 @@ class Widget * * @var integer */ - private $widgetId; + protected $widgetId; /** * Values widget. @@ -42,7 +42,14 @@ class Widget * * @var integer */ - private $nodeId; + protected $nodeId; + + /** + * Should we show select node in metaconsole environments? + * + * @var boolean + */ + private $showSelectNodeMeta; /** @@ -63,6 +70,7 @@ class Widget $this->cellId = $cellId; $this->dashboardId = $dashboardId; $this->fields = $this->get(); + $this->className = $this->fields['class_name']; $cellClass = new Cell($this->cellId, $this->dashboardId); $this->dataCell = $cellClass->get(); @@ -427,7 +435,7 @@ class Widget if ((bool) \is_metaconsole() === true) { \enterprise_include_once('include/functions_metaconsole.php'); - if ($this->nodeId !== null) { + if ($this->nodeId > 0) { if (\metaconsole_connect(null, $this->nodeId) !== NOERR) { $output .= '
'; $output .= \ui_print_info_message( @@ -438,6 +446,8 @@ class Widget $output .= '
'; return $output; } + + $config['metaconsole'] = false; } } @@ -463,8 +473,9 @@ class Widget } if ((bool) \is_metaconsole() === true) { - if ($this->nodeId !== null) { + if ($this->nodeId > 0) { \metaconsole_restore_db(); + $config['metaconsole'] = true; } } @@ -538,7 +549,9 @@ class Widget ], ]; - if ((bool) \is_metaconsole()) { + if ((bool) \is_metaconsole() === true + && $this->shouldSelectNode() === true + ) { \enterprise_include_once('include/functions_metaconsole.php'); $servers = \metaconsole_get_servers(); if (is_array($servers) === true) { @@ -556,12 +569,14 @@ class Widget $inputs[] = [ 'label' => __('Node'), 'arguments' => [ - 'wrapper' => 'div', - 'name' => 'node', - 'type' => 'select', - 'fields' => $servers, - 'selected' => $values['node'], - 'return' => true, + 'wrapper' => 'div', + 'name' => 'node', + 'type' => 'select', + 'fields' => $servers, + 'selected' => $values['node'], + 'nothing' => __('This metaconsole'), + 'nothing_value' => -1, + 'return' => true, ], ]; } @@ -581,7 +596,11 @@ class Widget $values['title'] = \get_parameter('title', ''); $values['background'] = \get_parameter('background', '#ffffff'); if ((bool) \is_metaconsole() === true) { - $values['node'] = \get_parameter('node', null); + if ($this->shouldSelectNode() === true) { + $values['node'] = \get_parameter('node', null); + } else { + $values['node'] = \get_parameter('metaconsoleId', null); + } } return $values; @@ -654,6 +673,32 @@ class Widget } + /** + * Should select for nodes been shown while in metaconsole environment? + * + * @return boolean + */ + protected function shouldSelectNode():bool + { + if ($this->showSelectNodeMeta !== null) { + return (bool) $this->showSelectNodeMeta; + } + + switch ($this->className) { + case 'EventsListWidget': + case 'ReportsWidget': + $this->showSelectNodeMeta = true; + break; + + default: + $this->showSelectNodeMeta = false; + break; + } + + return (bool) $this->showSelectNodeMeta; + } + + /** * Get description should be implemented for each child. * diff --git a/pandora_console/include/lib/Dashboard/Widgets/events_list.php b/pandora_console/include/lib/Dashboard/Widgets/events_list.php index 904cd2cdb8..6216b5321c 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/events_list.php +++ b/pandora_console/include/lib/Dashboard/Widgets/events_list.php @@ -603,7 +603,10 @@ class EventsListWidget extends Widget 'ta.alias as agent_name', 'tg.nombre as group_name', ]; - if ((bool) \is_metaconsole() === false) { + + if ((bool) \is_metaconsole() === false + || $this->nodeId > 0 + ) { $fields[] = 'am.nombre as module_name'; $fields[] = 'am.id_agente_modulo as id_agentmodule'; $fields[] = 'am.custom_id as module_custom_id'; @@ -636,7 +639,9 @@ class EventsListWidget extends Widget // ValidatedEvents. false, // Recursive Groups. - (bool) $this->values['groupRecursion'] + (bool) $this->values['groupRecursion'], + // Already connected. + ($this->nodeId > 0) ); if ($events === false) { diff --git a/pandora_console/include/lib/Dashboard/Widgets/reports.php b/pandora_console/include/lib/Dashboard/Widgets/reports.php index 3da692bcb5..0a30f72287 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/reports.php +++ b/pandora_console/include/lib/Dashboard/Widgets/reports.php @@ -203,6 +203,90 @@ class ReportsWidget extends Widget } + /** + * Return report list. + * + * @return array + */ + protected function getReports(): array + { + $return_all_group = false; + + if ((bool) users_can_manage_group_all('RM') === true) { + $return_all_group = true; + } + + // Reports. + $reports = \reports_get_reports( + false, + [ + 'id_report', + 'name', + ], + $return_all_group + ); + + // If currently selected report is not included in fields array + // (it belongs to a group over which user has no permissions), then add + // it to fields array. + // This is aimed to avoid overriding this value when a user with + // narrower permissions edits widget configuration. + if ($this->values['reportId'] !== null + && in_array( + $this->values['reportId'], + array_column( + $reports, + 'id_report' + ) + ) === false + ) { + $selected_report = db_get_row( + 'treport', + 'id_report', + $this->values['reportId'] + ); + $reports[] = $selected_report; + } + + $fields = array_reduce( + $reports, + function ($carry, $item) { + $carry[$item['id_report']] = \io_safe_output($item['name']); + return $carry; + }, + [] + ); + return $fields; + } + + + /** + * Dumps report list in json to fullfill select for report. + * + * @return void + */ + public function getReportList(): void + { + $node_id = \get_parameter('nodeId', $this->nodeId); + if (\is_metaconsole() === true && $node_id > 0) { + if (\metaconsole_connect(null, $node_id) !== NOERR) { + echo json_encode( + ['error' => __('Failed to connect to node %d', $node_id) ] + ); + } + } + + echo json_encode( + $this->getReports(), + 1 + ); + + if (\is_metaconsole() === true && $node_id > 0) { + \metaconsole_restore_db(); + } + } + + /** * Generates inputs for form (specific). * @@ -217,31 +301,7 @@ class ReportsWidget extends Widget // Retrieve global - common inputs. $inputs = parent::getFormInputs(); - $return_all_group = false; - - if (users_can_manage_group_all('RM')) { - $return_all_group = true; - } - - // Reports. - $reports = \reports_get_reports(false, ['id_report', 'name'], $return_all_group); - - // If currently selected report is not included in fields array (it belongs to a group over which user has no permissions), then add it to fields array. - // This is aimed to avoid overriding this value when a user with narrower permissions edits widget configuration. - if ($values['reportId'] !== null && !in_array($values['reportId'], array_column($reports, 'id_report'))) { - $selected_report = db_get_row('treport', 'id_report', $values['reportId']); - - $reports[] = $selected_report; - } - - $fields = array_reduce( - $reports, - function ($carry, $item) { - $carry[$item['id_report']] = $item['name']; - return $carry; - }, - [] - ); + $fields = $this->getReports(); $inputs[] = [ 'label' => __('Report'), @@ -282,10 +342,6 @@ class ReportsWidget extends Widget */ public function load() { - global $config; - - $size = parent::getSize(); - $output = ''; ob_start(); if ($this->values['reportId'] !== 0) { @@ -397,4 +453,50 @@ class ReportsWidget extends Widget } + /** + * Return aux javascript code for forms. + * + * @return string + */ + public function getFormJS() + { + ob_start(); + ?> + $('#node').on('change', function() { + $.ajax({ + method: "POST", + url: '', + data: { + page: 'operation/dashboard/dashboard', + dashboardId: 'dashboardId; ?>', + widgetId: 'widgetId; ?>', + cellId: 'cellId; ?>', + class: '', + method: 'getReportList', + nodeId: $('#node').val() + }, + dataType: 'JSON', + success: function(data) { + $('#reportId').empty(); + Object.entries(data).forEach(e => { + key = e[0]; + value = e[1]; + $('#reportId').append($('