From a0dcdb88b09d118554b566cdeee218dbeb2f02a1 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Wed, 13 Sep 2023 15:19:42 +0200 Subject: [PATCH 01/79] #11391 Fixed ace editor and log viewer --- pandora_console/include/functions_config.php | 16 ++++++++++++++++ pandora_console/include/functions_ui.php | 3 ++- .../javascript/elasticsearch_queryResult.js | 5 ++++- pandora_console/include/styles/ace.css | 13 +++++++++++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index 1cc1b9d438..36ffedbb19 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -1707,6 +1707,14 @@ function config_update_config() if (config_update_value('Days_purge_old_information', (int) get_parameter('Days_purge_old_information'), true) === false) { $error_update[] = __('Days to purge old information'); } + + if (config_update_value('elasticsearch_user', get_parameter('elasticsearch_user'), true) === false) { + $error_update[] = __('User ElasticSearch server'); + } + + if (config_update_value('elasticsearch_pass', get_parameter('elasticsearch_pass'), true) === false) { + $error_update[] = __('Pass ElasticSearch server'); + } break; case 'hist_db': @@ -2480,6 +2488,14 @@ function config_process_config() config_update_value('Days_purge_old_information', 90); } + if (!isset($config['elasticsearch_user'])) { + config_update_value('elasticsearch_user', ''); + } + + if (!isset($config['elasticsearch_pass'])) { + config_update_value('elasticsearch_pass', ''); + } + if (!isset($config['font_size'])) { config_update_value('font_size', 8); } diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index e077e10c51..2431fb526d 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -7303,7 +7303,8 @@ function ui_query_result_editor($name='default') ] ); - html_print_submit_button(__('Execute query'), 'execute_query', false, ['icon' => 'update']); + $execute_button = html_print_submit_button(__('Execute query'), 'execute_query', false, ['icon' => 'update'], true); + html_print_action_buttons($execute_button); } diff --git a/pandora_console/include/javascript/elasticsearch_queryResult.js b/pandora_console/include/javascript/elasticsearch_queryResult.js index c50f8955b3..13352ef975 100644 --- a/pandora_console/include/javascript/elasticsearch_queryResult.js +++ b/pandora_console/include/javascript/elasticsearch_queryResult.js @@ -1,5 +1,8 @@ var editor = ace.edit("elasticsearch_editor"); -editor.setValue(`GET _search \n{\n "query": {\n "match_all": {}\n }\n}`); +editor.setValue(`GET _search\n{\n "query": {\n "match_all": {}\n }\n}`); +editor.session.setMode("ace/mode/json"); +editor.setTheme("ace/theme/textmate"); +editor.session.setUseWorker(false); editor.clearSelection(); var view = ace.edit("elasticsearch_view"); diff --git a/pandora_console/include/styles/ace.css b/pandora_console/include/styles/ace.css index 15aecb624b..b68f0c47ea 100644 --- a/pandora_console/include/styles/ace.css +++ b/pandora_console/include/styles/ace.css @@ -3,7 +3,7 @@ } .query_result_editor_container { - width: 30%; + width: 40%; } .query_result_editor_container p { @@ -26,7 +26,7 @@ } .query_result_view_container { - width: 70%; + width: 60%; margin-left: 30px; } @@ -51,3 +51,12 @@ margin-top: 10px; margin-bottom: 10px; } + +.ace_editor, +.ace_editor * { + font-family: "Monaco", "Menlo", "Ubuntu Mono", "Droid Sans Mono", "Consolas", + monospace !important; + font-size: 14px !important; + font-weight: 400 !important; + letter-spacing: 0 !important; +} From 7c201d28554ba02b96e4e181689aee8c4e7c1785 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Thu, 21 Sep 2023 17:58:18 +0200 Subject: [PATCH 02/79] #10194 new structure for general tactical view --- pandora_console/general/logon_ok.php | 6 + pandora_console/images/status_check@svg.svg | 26 ++ pandora_console/images/status_error@svg.svg | 26 ++ pandora_console/include/graphs/fgraph.php | 20 +- .../include/lib/TacticalView/Element.php | 56 +++++ .../lib/TacticalView/GeneralTacticalView.php | 115 +++++++++ .../elements/MonitoringElements.php | 41 +++ .../lib/TacticalView/elements/NewsBoard.php | 123 +++++++++ .../lib/TacticalView/elements/Overview.php | 233 ++++++++++++++++++ .../include/styles/general_tactical_view.css | 77 ++++++ pandora_console/include/styles/news.css | 8 +- pandora_console/views/tacticalView/view.php | 102 ++++++++ 12 files changed, 826 insertions(+), 7 deletions(-) create mode 100644 pandora_console/images/status_check@svg.svg create mode 100644 pandora_console/images/status_error@svg.svg create mode 100644 pandora_console/include/lib/TacticalView/Element.php create mode 100644 pandora_console/include/lib/TacticalView/GeneralTacticalView.php create mode 100644 pandora_console/include/lib/TacticalView/elements/MonitoringElements.php create mode 100644 pandora_console/include/lib/TacticalView/elements/NewsBoard.php create mode 100644 pandora_console/include/lib/TacticalView/elements/Overview.php create mode 100644 pandora_console/include/styles/general_tactical_view.css create mode 100644 pandora_console/views/tacticalView/view.php diff --git a/pandora_console/general/logon_ok.php b/pandora_console/general/logon_ok.php index 6567347999..059443eff6 100644 --- a/pandora_console/general/logon_ok.php +++ b/pandora_console/general/logon_ok.php @@ -26,6 +26,12 @@ * ============================================================================ */ +use PandoraFMS\TacticalView\GeneralTacticalView; + +$tacticalView = new GeneralTacticalView(); +$tacticalView->render(); +return; +// Temporal return for develop. // Config functions. require_once 'include/config.php'; diff --git a/pandora_console/images/status_check@svg.svg b/pandora_console/images/status_check@svg.svg new file mode 100644 index 0000000000..78e62ea848 --- /dev/null +++ b/pandora_console/images/status_check@svg.svg @@ -0,0 +1,26 @@ + + + AE320C3A-79E4-4E24-956A-B81125ACFA52@svg + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pandora_console/images/status_error@svg.svg b/pandora_console/images/status_error@svg.svg new file mode 100644 index 0000000000..e6502bff7e --- /dev/null +++ b/pandora_console/images/status_error@svg.svg @@ -0,0 +1,26 @@ + + + CD9D3D2F-E199-427F-BC6C-532C8382EE45@svg + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pandora_console/include/graphs/fgraph.php b/pandora_console/include/graphs/fgraph.php index 494ec9c010..f0980836b6 100644 --- a/pandora_console/include/graphs/fgraph.php +++ b/pandora_console/include/graphs/fgraph.php @@ -1019,7 +1019,9 @@ function get_build_setup_charts($type, $options, $data) ) { $scales = $chart->options()->getScales(); - if ($options['scales']['x'] !== false) { + if (isset($options['scales']['x']) === true + && $options['scales']['x'] !== false + ) { // Defaults scalesFont X. $scalesXFonts = $scales->getX()->ticks()->getFonts(); $scalesXFonts->setFamily((empty($config['fontpath']) === true) ? 'lato' : $config['fontpath']); @@ -1028,7 +1030,9 @@ function get_build_setup_charts($type, $options, $data) $scalesXFonts->setSize(((int) $config['font_size'] + 2)); } - if ($options['scales']['y'] !== false) { + if (isset($options['scales']['y']) === true + && $options['scales']['y'] !== false + ) { // Defaults scalesFont Y. $scalesYFonts = $scales->getY()->ticks()->getFonts(); $scalesYFonts->setFamily((empty($config['fontpath']) === true) ? 'lato' : $config['fontpath']); @@ -1037,7 +1041,9 @@ function get_build_setup_charts($type, $options, $data) $scalesYFonts->setSize(((int) $config['font_size'] + 2)); } - if ($options['scales']['r'] !== false) { + if (isset($options['scales']['r']) === true + && $options['scales']['r'] !== false + ) { // Defaults scalesFont R. $scalesRFonts = $scales->getR()->pointLabels()->getFonts(); $scalesRFonts->setStyle('normal'); @@ -1053,6 +1059,10 @@ function get_build_setup_charts($type, $options, $data) $scales->getX()->setBounds($options['scales']['x']['bounds']); } + if (isset($options['scales']['x']['display']) === true) { + $scales->getX()->setDisplay($options['scales']['x']['display']); + } + if (isset($options['scales']['x']['grid']) === true && empty($options['scales']['x']['grid']) === false && is_array($options['scales']['x']['grid']) === true @@ -1098,6 +1108,10 @@ function get_build_setup_charts($type, $options, $data) $scales->getY()->setBounds($options['scales']['y']['bounds']); } + if (isset($options['scales']['y']['display']) === true) { + $scales->getY()->setDisplay($options['scales']['y']['display']); + } + if (isset($options['scales']['y']['grid']) === true && empty($options['scales']['y']['grid']) === false && is_array($options['scales']['y']['grid']) === true diff --git a/pandora_console/include/lib/TacticalView/Element.php b/pandora_console/include/lib/TacticalView/Element.php new file mode 100644 index 0000000000..a97502e0e1 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/Element.php @@ -0,0 +1,56 @@ +interval = 0; + $this->title = __('Default element'); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/GeneralTacticalView.php b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php new file mode 100644 index 0000000000..82b042cf7c --- /dev/null +++ b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php @@ -0,0 +1,115 @@ +elements = $this->instanceElements(); + } + + + /** + * Instantiate all the elements that will build the dashboard + * + * @return array + */ + public function instanceElements():array + { + global $config; + $dir = $config['homedir'].'/include/lib/TacticalView/elements/'; + + $handle = opendir($dir); + if ($handle === false) { + return []; + } + + $ignores = [ + '.', + '..', + ]; + + $elements = []; + while (false !== ($file = readdir($handle))) { + try { + if (in_array($file, $ignores) === true) { + continue; + } + + $filepath = realpath($dir.'/'.$file); + if (is_readable($filepath) === false + || is_dir($filepath) === true + || preg_match('/.*\.php$/', $filepath) === false + ) { + continue; + } + + $className = preg_replace('/.php/', '', $file); + include_once $filepath; + if (class_exists($className) === true) { + $instance = new $className(); + $elements[$className] = $instance; + } + } catch (Exception $e) { + } + } + + return $elements; + } + + + /** + * Render funcion for print the html. + * + * @return void + */ + public function render():void + { + View::render( + 'tacticalView/view', + $this->elements + ); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php new file mode 100644 index 0000000000..4731d54b27 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php @@ -0,0 +1,41 @@ +title = __('Monitoring elements'); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/NewsBoard.php b/pandora_console/include/lib/TacticalView/elements/NewsBoard.php new file mode 100644 index 0000000000..4f7820b19c --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/NewsBoard.php @@ -0,0 +1,123 @@ +title = __('News Board'); + } + + + /** + * Returns the html of the latest news. + * + * @return string + */ + public function getNews():string + { + global $config; + $options = []; + $options['id_user'] = $config['id_user']; + $options['modal'] = false; + $options['limit'] = 7; + $news = get_news($options); + + if (!empty($news)) { + $output = '
'; + foreach ($news as $article) { + $default = false; + if ($article['text'] == '<p style="text-align: center; font-size: 13px;">Hello, congratulations, if you've arrived here you already have an operational monitoring console. Remember that our forums and online documentation are available 24x7 to get you out of any trouble. You can replace this message with a personalized one at Admin tools -> Site news.</p> ') { + $article['subject'] = __('Welcome to Pandora FMS Console'); + $default = true; + } + + $text_bbdd = io_safe_output($article['text']); + $text = html_entity_decode($text_bbdd); + + $output .= '
'; + $output .= '
'; + $output .= ''.$article['subject'].''; + $output .= ''.__('By').' '.$article['author'].' '.ui_print_timestamp($article['timestamp'], true).''; + $output .= '
'; + $output .= '
'; + + if ($default) { + $output .= '
'; + $output .= '
'; + $output .= 'img colabora con nosotros - Support'; + $output .= '
'; + + $output .= ' +

'.__('Welcome to our monitoring tool so grand,').' +
'.__('Where data insights are at your command.').' +
'.__('Sales, marketing, operations too,').' +
'.__("Customer support, we've got you.").' +

+ +

'.__('Our interface is user-friendly,').' +
'.__("Customize your dashboard, it's easy.").' +
'.__('Set up alerts and gain insights so keen,').' +
'.__("Optimize your data, like you've never seen.").' +

+ +

'.__('Unleash its power now, and join the pro league,').' +
'.__('Unlock the potential of your data to intrigue.').' +
'.__('Monitoring made simple, efficient and fun,').' +
'.__('Discover a whole new way to get things done.').' +

+ +

'.__('And take control of your IT once and for all.').'

+ + '.__('You can replace this message with a personalized one at Admin tools -> Site news.').' + '; + + $output .= '
'; + } else { + $text = str_replace('title = __('General overview'); + } + + + /** + * Return the html log size status. + * + * @return string + */ + public function getLogSizeStatus():string + { + // TODO connect to automonitorization. + $status = true; + + if ($status === true) { + $image_status = html_print_image('images/status_check@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Everything’s OK!'), + 'class' => 'status-text', + ], + true + ); + } else { + $image_status = html_print_image('images/status_error@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Something’s wrong'), + 'class' => 'status-text', + ], + true + ); + } + + $output = $image_status.$text; + + return html_print_div( + [ + 'content' => $output, + 'class' => 'flex_center margin-top-5', + ], + true + ); + + } + + + /** + * Return the html Wix server status. + * + * @return string + */ + public function getWuxServerStatus():string + { + // TODO connect to automonitorization. + $status = false; + + if ($status === true) { + $image_status = html_print_image('images/status_check@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Everything’s OK!'), + 'class' => 'status-text', + ], + true + ); + } else { + $image_status = html_print_image('images/status_error@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Something’s wrong'), + 'class' => 'status-text', + ], + true + ); + } + + $output = $image_status.$text; + + return html_print_div( + [ + 'content' => $output, + 'class' => 'flex_center margin-top-5', + ], + true + ); + + } + + + /** + * Returns the html of the used licenses. + * + * @return string + */ + public function getLicenseUsage():string + { + // TODO connect to automonitorization. + $options = [ + 'labels' => [ + 'Open Source', + 'Enterprise', + 'MaaS', + ], + 'colors' => [ + '#1C4E6B', + '#5C63A2', + '#EC7176', + ], + 'legend' => [ + 'position' => 'bottom', + 'align' => 'right', + ], + 'cutout' => 80, + ]; + $pie = ring_graph([2, 4, 6], $options); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 320px', + ], + true + ); + + return $output; + } + + + /** + * Returns the html of a graph with the processed xmls + * + * @return string + */ + public function getXmlProcessed():string + { + $sql = 'SELECT + utimestamp, + DATE_FORMAT(FROM_UNIXTIME(utimestamp), "%Y-%m-%d %H:00:00") AS hour, + COUNT(*) AS xml_proccessed + FROM tagent_access + WHERE FROM_UNIXTIME(utimestamp) >= NOW() - INTERVAL 24 HOUR + GROUP BY hour + ORDER BY hour;'; + + $rows = db_process_sql($sql); + + $dates = []; + $xml_proccessed = []; + $total = 0; + foreach ($rows as $key => $raw_data) { + $dates[] = date('H:i:s', $raw_data['utimestamp']); + $xml_proccessed[] = $raw_data['xml_proccessed']; + $total += $raw_data['xml_proccessed']; + } + + $options = [ + 'labels' => $dates, + 'legend' => [ 'display' => false ], + 'tooltips' => [ 'display' => false ], + 'scales' => [ + 'y' => [ + 'grid' => ['display' => false], + 'ticks' => ['display' => false], + ], + 'x' => [ + 'grid' => ['display' => false], + 'display' => false, + ], + ], + ]; + + $data = [['data' => $xml_proccessed]]; + + $graph_area = html_print_div( + [ + 'content' => line_graph($data, $options), + 'class' => 'margin-top-5 w100p h100p', + 'style' => 'max-height: 330px;', + ], + true + ); + + $total = html_print_div( + [ + 'content' => $total, + 'class' => 'text-xl', + ], + true + ); + + $output = $total.$graph_area; + + return $output; + } + + +} diff --git a/pandora_console/include/styles/general_tactical_view.css b/pandora_console/include/styles/general_tactical_view.css new file mode 100644 index 0000000000..27c8482cd3 --- /dev/null +++ b/pandora_console/include/styles/general_tactical_view.css @@ -0,0 +1,77 @@ +.row { + display: flex; + width: 100%; +} +.col-6 { + width: 49%; + display: flex; + flex-wrap: wrap; + flex-direction: column; +} +.col-7 { + width: 58%; +} +.col-5 { + width: 41%; +} +.container { + background-color: white; + border: 1px solid #e5e9ed; + border-radius: 10px; + margin: 5px; +} +.br-l { + border-left: 1px solid #e5e9ed; +} +.br-t { + border-top: 1px solid #e5e9ed; +} +.br-r { + border-right: 1px solid #e5e9ed; +} +.br-b { + border-bottom: 1px solid #e5e9ed; +} +.title { + font-size: 18px; + color: #161628; + text-align: center; + font-weight: bold; + padding: 15px 0px; +} +.subtitle { + font-size: 13px; + color: #161628; + padding-bottom: 10px; +} +.subtitle.link { + display: flex; + flex-direction: row; + justify-content: space-between; +} +.subtitle.link a { + color: #14524f; + font-size: 13px; +} +.absolute-link::after { + content: "→"; +} +.status-text { + color: #6e7079; + font-size: 13px; + margin-left: 6px; +} +.text-xl { + font-size: 40px; + color: #6c7587; + font-weight: bold; + padding-left: 8px; + margin-bottom: 8px; + line-height: initial; +} +#news-board { + min-width: 530px; + width: 100%; + max-height: 805px; + overflow-y: auto; +} diff --git a/pandora_console/include/styles/news.css b/pandora_console/include/styles/news.css index c9e66bd462..d25bcc322f 100644 --- a/pandora_console/include/styles/news.css +++ b/pandora_console/include/styles/news.css @@ -1,7 +1,7 @@ .new-board { background-color: #ffffff; - border: 1px solid #e5e9ed; - border-radius: 4px; + border-top: 1px solid #e5e9ed; + border-bottom: 1px solid #e5e9ed; margin-bottom: 15px; } @@ -36,12 +36,12 @@ display: flex; flex-direction: row; flex-wrap: nowrap; - align-items: center; + align-items: flex-start; } .default-new > div > img { width: 100%; - max-width: 430px; + max-width: 268px; height: auto; } diff --git a/pandora_console/views/tacticalView/view.php b/pandora_console/views/tacticalView/view.php new file mode 100644 index 0000000000..63c59c2790 --- /dev/null +++ b/pandora_console/views/tacticalView/view.php @@ -0,0 +1,102 @@ +
+
+
+
+
+ title; ?> +
+
+
+
+
+
+
+ + + + getLogSizeStatus(); ?> +
+
+
+
+ + + + getWuxServerStatus(); ?> +
+
+
+
+
+ + + + getLicenseUsage(); ?> +
+
+
+
+ + getXmlProcessed(); ?> +
+
+
+
+
+
+
+
+
+ title; ?> +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+
+
+
+ title; ?> +
+ getNews(); ?> +
+
+
+ +
+ +
+ +
+ +
\ No newline at end of file From 0fdbefa7eecbac24e61d5ffb42391520cd30a334 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Mon, 25 Sep 2023 13:52:28 +0200 Subject: [PATCH 03/79] #10194 first section drawed --- pandora_console/include/functions_graph.php | 7 +- .../include/lib/TacticalView/Element.php | 19 ++ .../lib/TacticalView/GeneralTacticalView.php | 32 ++ .../lib/TacticalView/elements/Database.php | 309 ++++++++++++++++++ .../lib/TacticalView/elements/Groups.php | 215 ++++++++++++ .../lib/TacticalView/elements/LogStorage.php | 141 ++++++++ .../elements/MonitoringElements.php | 149 +++++++++ .../lib/TacticalView/elements/Overview.php | 18 +- .../lib/TacticalView/elements/SnmpTraps.php | 79 +++++ .../include/styles/general_tactical_view.css | 50 ++- pandora_console/views/tacticalView/view.php | 175 ++++++++-- 11 files changed, 1161 insertions(+), 33 deletions(-) create mode 100644 pandora_console/include/lib/TacticalView/elements/Database.php create mode 100644 pandora_console/include/lib/TacticalView/elements/Groups.php create mode 100644 pandora_console/include/lib/TacticalView/elements/LogStorage.php create mode 100644 pandora_console/include/lib/TacticalView/elements/SnmpTraps.php diff --git a/pandora_console/include/functions_graph.php b/pandora_console/include/functions_graph.php index bb0fe8fd58..dae91c862c 100644 --- a/pandora_console/include/functions_graph.php +++ b/pandora_console/include/functions_graph.php @@ -4842,12 +4842,17 @@ function graph_nodata_image($options) return base64_encode($dataImg); } + $widthImage = '200px'; + if (isset($options['nodata_image']['width']) === true) { + $widthImage = $options['nodata_image']['width']; + } + return html_print_image( 'images/image_problem_area.png', true, [ 'title' => __('No data'), - 'style' => 'width: 200px;', + 'style' => 'width: '.$widthImage.';', ] ); } diff --git a/pandora_console/include/lib/TacticalView/Element.php b/pandora_console/include/lib/TacticalView/Element.php index a97502e0e1..cf0d6b517e 100644 --- a/pandora_console/include/lib/TacticalView/Element.php +++ b/pandora_console/include/lib/TacticalView/Element.php @@ -53,4 +53,23 @@ class Element } + /** + * Cut the text to display it on the labels. + * + * @param string $text Text for cut. + * @param integer $length Length max for text cutted. + * + * @return string + */ + protected function controlSizeText(string $text, int $length=14):string + { + if (mb_strlen($text) > $length) { + $newText = mb_substr($text, 0, $length).'...'; + return $newText; + } else { + return $text; + } + } + + } diff --git a/pandora_console/include/lib/TacticalView/GeneralTacticalView.php b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php index 82b042cf7c..275b82efbd 100644 --- a/pandora_console/include/lib/TacticalView/GeneralTacticalView.php +++ b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php @@ -70,6 +70,7 @@ class GeneralTacticalView ]; $elements = []; + $elements['welcome'] = $this->getWelcomeMessage(); while (false !== ($file = readdir($handle))) { try { if (in_array($file, $ignores) === true) { @@ -112,4 +113,35 @@ class GeneralTacticalView } + /** + * Return the welcome message. + * + * @return string + */ + private function getWelcomeMessage():string + { + global $config; + $profile = users_get_user_profile($config['id_user']); + if (is_array($profile) === true && count($profile) > 0) { + $name = $profile[0]['name']; + } else { + $name = ''; + } + + if (empty($name) === true) { + $message = __('Welcome back! 👋'); + } else { + $message = __('Welcome back %s! 👋', $name); + } + + return html_print_div( + [ + 'content' => $message, + 'class' => 'message-welcome', + ], + true + ); + } + + } diff --git a/pandora_console/include/lib/TacticalView/elements/Database.php b/pandora_console/include/lib/TacticalView/elements/Database.php new file mode 100644 index 0000000000..b7250fb390 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/Database.php @@ -0,0 +1,309 @@ +title = __('Database'); + } + + + /** + * Returns the html status of database. + * + * @return string + */ + public function getStatus():string + { + // TODO connect to automonitorization. + $status = true; + + if ($status === true) { + $image_status = html_print_image('images/status_check@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Everything’s OK!'), + 'class' => 'status-text', + ], + true + ); + } else { + $image_status = html_print_image('images/status_error@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Something’s wrong'), + 'class' => 'status-text', + ], + true + ); + } + + $output = $image_status.$text; + + return html_print_div( + [ + 'content' => $output, + 'class' => 'flex_center margin-top-5', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html records data of database. + * + * @return string + */ + public function getDataRecords():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total events. + * + * @return string + */ + public function getEvents():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total records. + * + * @return string + */ + public function getStringRecords():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total reads database in a graph. + * + * @return string + */ + public function getReadsGraph():string + { + // TODO connect to automonitorization. + $dates = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + ]; + $string_reads = [ + 1, + 0.5, + 2, + 1.5, + 3, + 2.5, + 4, + 3.5, + 5, + 4.5, + 6, + ]; + $total = '9.999.999'; + $options = [ + 'labels' => $dates, + 'legend' => [ 'display' => false ], + 'tooltips' => [ 'display' => false ], + 'scales' => [ + 'y' => [ + 'grid' => ['display' => false], + 'ticks' => ['display' => false], + 'display' => false, + ], + 'x' => [ + 'grid' => ['display' => false], + 'display' => false, + ], + ], + ]; + + $data = [ + [ + 'backgroundColor' => '#EC7176', + 'borderColor' => '#EC7176', + 'pointBackgroundColor' => '#EC7176', + 'pointHoverBorderColor' => '#EC7176', + 'data' => $string_reads, + ], + ]; + + $graph_area = html_print_div( + [ + 'content' => line_graph($data, $options), + 'class' => 'w100p h100p', + 'style' => 'max-height: 100px;', + ], + true + ); + + $total = html_print_div( + [ + 'content' => $total, + 'class' => 'text-xl', + ], + true + ); + + $output = $total.$graph_area; + + return $output; + } + + + /** + * Returns the html of total writes database in a graph. + * + * @return string + */ + public function getWritesGraph():string + { + // TODO connect to automonitorization. + $dates = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + ]; + $string_writes = [ + 1, + 0.5, + 2, + 1.5, + 3, + 2.5, + 4, + 3.5, + 5, + 4.5, + 6, + ]; + $total = '9.999.999'; + $options = [ + 'labels' => $dates, + 'legend' => [ 'display' => false ], + 'tooltips' => [ 'display' => false ], + 'scales' => [ + 'y' => [ + 'grid' => ['display' => false], + 'ticks' => ['display' => false], + 'display' => false, + ], + 'x' => [ + 'grid' => ['display' => false], + 'display' => false, + ], + ], + ]; + + $data = [ + [ + 'backgroundColor' => '#009D9E', + 'borderColor' => '#009D9E', + 'pointBackgroundColor' => '#009D9E', + 'pointHoverBorderColor' => '#009D9E', + 'data' => $string_writes, + ], + ]; + + $graph_area = html_print_div( + [ + 'content' => line_graph($data, $options), + 'class' => 'w100p h100p', + 'style' => 'max-height: 100px;', + ], + true + ); + + $total = html_print_div( + [ + 'content' => $total, + 'class' => 'text-xl', + ], + true + ); + + $output = $total.$graph_area; + + return $output; + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/Groups.php b/pandora_console/include/lib/TacticalView/elements/Groups.php new file mode 100644 index 0000000000..55bf2a2354 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/Groups.php @@ -0,0 +1,215 @@ +title = __('Groups'); + $this->total = $this->calculateTotalGroups(); + } + + + /** + * Return the total groups. + * + * @return integer + */ + public function calculateTotalGroups():int + { + $total = db_get_num_rows('SELECT * FROM tgrupo;'); + return $total; + } + + + /** + * Return the status groups in heat map. + * + * @return string + */ + public function getStatusHeatMap():string + { + ui_require_css_file('heatmap'); + $width = 350; + $height = 335; + $sql = 'SELECT * FROM tagente a + LEFT JOIN tagent_secondary_group g ON g.id_agent = a.id_agente'; + + $all_agents = db_get_all_rows_sql($sql); + if (empty($all_agents)) { + return null; + } + + $total_agents = count($all_agents); + + // Best square. + $high = (float) max($width, $height); + $low = 0.0; + + while (abs($high - $low) > 0.000001) { + $mid = (($high + $low) / 2.0); + $midval = (floor($width / $mid) * floor($height / $mid)); + if ($midval >= $total_agents) { + $low = $mid; + } else { + $high = $mid; + } + } + + $square_length = min(($width / floor($width / $low)), ($height / floor($height / $low))); + // Print starmap. + $heatmap = sprintf( + '', + $width, + $height + ); + + $heatmap .= ''; + $row = 0; + $column = 0; + $x = 0; + $y = 0; + $cont = 1; + + foreach ($all_agents as $key => $value) { + // Colour by status. + $status = agents_get_status_from_counts($value); + + switch ($status) { + case 5: + // Not init status. + $status = 'notinit'; + break; + + case 1: + // Critical status. + $status = 'critical'; + break; + + case 2: + // Warning status. + $status = 'warning'; + break; + + case 0: + // Normal status. + $status = 'normal'; + break; + + case 3: + case -1: + default: + // Unknown status. + $status = 'unknown'; + break; + } + + $heatmap .= sprintf( + '', + 'rect_'.$cont, + $x, + $y, + $row, + $column, + $square_length, + $square_length, + $status, + random_int(1, 10) + ); + + $y += $square_length; + $row++; + if ((int) ($y + $square_length) > (int) $height) { + $y = 0; + $x += $square_length; + $row = 0; + $column++; + } + + if ((int) ($x + $square_length) > (int) $width) { + $x = 0; + $y += $square_length; + $column = 0; + $row++; + } + + $cont++; + } + + $heatmap .= ''; + $heatmap .= ''; + $heatmap .= ''; + + return html_print_div( + [ + 'content' => $heatmap, + 'style' => 'margin: 0 auto; width: fit-content;', + ], + true + ); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/LogStorage.php b/pandora_console/include/lib/TacticalView/elements/LogStorage.php new file mode 100644 index 0000000000..fcde21a295 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/LogStorage.php @@ -0,0 +1,141 @@ +title = __('Log storage'); + } + + + /** + * Returns the html status of log storage. + * + * @return string + */ + public function getStatus():string + { + // TODO connect to automonitorization. + $status = true; + + if ($status === true) { + $image_status = html_print_image('images/status_check@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Everything’s OK!'), + 'class' => 'status-text', + ], + true + ); + } else { + $image_status = html_print_image('images/status_error@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Something’s wrong'), + 'class' => 'status-text', + ], + true + ); + } + + $output = $image_status.$text; + + return html_print_div( + [ + 'content' => $output, + 'class' => 'flex_center margin-top-5', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total sources in log storage. + * + * @return string + */ + public function getTotalSources():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 0px 10px;', + ], + true + ); + } + + + /** + * Returns the html of lines in log storage. + * + * @return string + */ + public function getStoredData():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 0px 10px;', + ], + true + ); + } + + + /** + * Returns the html of age of stored data. + * + * @return string + */ + public function getAgeOfStoredData():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 0px 10px;', + ], + true + ); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php index 4731d54b27..7a91348cf8 100644 --- a/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php +++ b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php @@ -38,4 +38,153 @@ class MonitoringElements extends Element } + /** + * Returns the html of the tags grouped by modules. + * + * @return string + */ + public function getTagsGraph():string + { + $sql = 'SELECT name, count(*) AS total + FROM ttag_module t + LEFT JOIN ttag ta ON ta.id_tag = t.id_tag + GROUP BY t.id_tag'; + $rows = db_process_sql($sql); + + $labels = []; + $data = []; + foreach ($rows as $key => $row) { + $labels[] = $this->controlSizeText($row['name']); + $data[] = $row['total']; + } + + $options = [ + 'labels' => $labels, + 'legend' => [ + 'position' => 'bottom', + 'align' => 'right', + ], + 'cutout' => 80, + 'nodata_image' => ['width' => '100%'], + ]; + $pie = ring_graph($data, $options); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 60%; max-height: 220px;', + ], + true + ); + + return $output; + } + + + /** + * Returns the html of the groups grouped by modules. + * + * @return string + */ + public function getModuleGroupGraph():string + { + $sql = 'SELECT name, count(*) AS total + FROM tagente_modulo m + LEFT JOIN tmodule_group g ON g.id_mg = m.id_module_group + WHERE name <> "" + GROUP BY m.id_module_group'; + $rows = db_process_sql($sql); + + $labels = []; + $data = []; + foreach ($rows as $key => $row) { + $labels[] = $this->controlSizeText($row['name']); + $data[] = $row['total']; + } + + $options = [ + 'labels' => $labels, + 'legend' => [ + 'position' => 'bottom', + 'align' => 'right', + ], + 'cutout' => 80, + 'nodata_image' => ['width' => '100%'], + ]; + $pie = ring_graph($data, $options); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 60%; max-height: 220px;', + ], + true + ); + + return $output; + } + + + /** + * Returns the html of the agent grouped by modules. + * + * @return string + */ + public function getAgentGroupsGraph():string + { + $sql = 'SELECT gr.nombre, count(*) AS total + FROM tagente a + LEFT JOIN tagent_secondary_group g ON g.id_agent = a.id_agente + LEFT JOIN tgrupo gr ON gr.id_grupo = a.id_grupo + GROUP BY a.id_grupo'; + $rows = db_process_sql($sql); + + $labels = []; + $data = []; + foreach ($rows as $key => $row) { + $labels[] = $this->controlSizeText($row['nombre']); + $data[] = $row['total']; + } + + $options = [ + 'labels' => $labels, + 'legend' => [ + 'position' => 'bottom', + 'align' => 'right', + ], + 'cutout' => 80, + 'nodata_image' => ['width' => '100%'], + ]; + $pie = ring_graph($data, $options); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 60%; max-height: 220px;', + ], + true + ); + + return $output; + } + + + /** + * Returns the html of monitoring by status. + * + * @return string + */ + public function getMonitoringStatusGraph():string + { + // TODO add labels. + $pie = graph_agent_status(false, '', '', true, true, false, true); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 60%; max-height: 220px;', + ], + true + ); + + return $output; + } + + } diff --git a/pandora_console/include/lib/TacticalView/elements/Overview.php b/pandora_console/include/lib/TacticalView/elements/Overview.php index ba82e00a60..8ab35336a9 100644 --- a/pandora_console/include/lib/TacticalView/elements/Overview.php +++ b/pandora_console/include/lib/TacticalView/elements/Overview.php @@ -129,7 +129,7 @@ class Overview extends Element * * @return string */ - public function getLicenseUsage():string + public function getLicenseUsageGraph():string { // TODO connect to automonitorization. $options = [ @@ -167,7 +167,7 @@ class Overview extends Element * * @return string */ - public function getXmlProcessed():string + public function getXmlProcessedGraph():string { $sql = 'SELECT utimestamp, @@ -184,9 +184,9 @@ class Overview extends Element $xml_proccessed = []; $total = 0; foreach ($rows as $key => $raw_data) { - $dates[] = date('H:i:s', $raw_data['utimestamp']); - $xml_proccessed[] = $raw_data['xml_proccessed']; + $dates[] = date('H:00:00', $raw_data['utimestamp']); $total += $raw_data['xml_proccessed']; + $xml_proccessed[] = $raw_data['xml_proccessed']; } $options = [ @@ -205,7 +205,15 @@ class Overview extends Element ], ]; - $data = [['data' => $xml_proccessed]]; + $data = [ + [ + 'backgroundColor' => '#009D9E', + 'borderColor' => '#009D9E', + 'pointBackgroundColor' => '#009D9E', + 'pointHoverBorderColor' => '#009D9E', + 'data' => $xml_proccessed, + ], + ]; $graph_area = html_print_div( [ diff --git a/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php b/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php new file mode 100644 index 0000000000..4068531c2d --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php @@ -0,0 +1,79 @@ +title = __('SNMP Traps'); + } + + + /** + * Returns the html of queues traps. + * + * @return string + */ + public function getQueues():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total sources traps. + * + * @return string + */ + public function getTotalSources():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + +} diff --git a/pandora_console/include/styles/general_tactical_view.css b/pandora_console/include/styles/general_tactical_view.css index 27c8482cd3..427667455e 100644 --- a/pandora_console/include/styles/general_tactical_view.css +++ b/pandora_console/include/styles/general_tactical_view.css @@ -1,3 +1,22 @@ +#welcome-message { + margin-bottom: 30px; +} + +.message-welcome { + color: #161628; + font-size: 32px; + line-height: 38px; + text-align: left; + font-weight: 700; +} + +.subtitle-welcome-message { + color: #8a96a6; + font-size: 15px; + line-height: 20px; + text-align: left; + margin-left: 5px; +} .row { display: flex; width: 100%; @@ -19,6 +38,7 @@ border: 1px solid #e5e9ed; border-radius: 10px; margin: 5px; + max-width: 100%; } .br-l { border-left: 1px solid #e5e9ed; @@ -33,11 +53,11 @@ border-bottom: 1px solid #e5e9ed; } .title { - font-size: 18px; + font-size: 18px !important; color: #161628; - text-align: center; - font-weight: bold; - padding: 15px 0px; + text-align: center !important; + font-weight: bold !important; + padding: 15px 0px !important; } .subtitle { font-size: 13px; @@ -52,6 +72,7 @@ .subtitle.link a { color: #14524f; font-size: 13px; + font-weight: 800; } .absolute-link::after { content: "→"; @@ -69,9 +90,30 @@ margin-bottom: 8px; line-height: initial; } +.text-l { + font-size: 27px; + color: #6c7587; + font-weight: bold; + margin-bottom: 8px; + line-height: initial; +} #news-board { min-width: 530px; width: 100%; max-height: 805px; overflow-y: auto; } + +#database .subtitle, +#logStorage .subtitle, +#SNMPTraps .subtitle { + padding: 10px 10px 5px 10px; +} + +.indicative-text { + color: #6e7079; + font-size: 12px; + line-height: 13px; + text-align: left; + padding: 0px 10px 10px 10px; +} diff --git a/pandora_console/views/tacticalView/view.php b/pandora_console/views/tacticalView/view.php index 63c59c2790..92a4d54f79 100644 --- a/pandora_console/views/tacticalView/view.php +++ b/pandora_console/views/tacticalView/view.php @@ -1,3 +1,8 @@ +
+ + +
+
@@ -31,7 +36,7 @@ - getLicenseUsage(); ?> + getLicenseUsageGraph(); ?>
@@ -39,7 +44,7 @@ - getXmlProcessed(); ?> + getXmlProcessedGraph(); ?>
@@ -51,27 +56,33 @@
title; ?>
-
-
-
-
+
title; ?> @@ -91,6 +91,7 @@
+ checkAcl() === true) : ?>
@@ -141,6 +142,7 @@
+
@@ -238,7 +240,7 @@
title; ?>
-
+
@@ -254,7 +256,7 @@
checkAclUserList() === true) : ?>
-