From b54ece2b70012d24142aeb6b100c03fae1bf3984 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Mon, 28 Oct 2019 10:46:25 +0100 Subject: [PATCH 01/66] Add menu omnishell --- pandora_console/godmode/menu.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 7175081912..c61405d66d 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -346,6 +346,9 @@ if (check_acl($config['id_user'], 0, 'PM') || check_acl($config['id_user'], 0, ' $sub['godmode/setup/links']['id'] = 'Links'; $sub['extras/pandora_diag']['text'] = __('Diagnostic info'); $sub['extras/pandora_diag']['id'] = 'Diagnostic info'; + + enterprise_hook('omnishell'); + $sub['godmode/setup/news']['text'] = __('Site news'); $sub['godmode/setup/news']['id'] = 'Site news'; $sub['godmode/setup/file_manager']['text'] = __('File manager'); From 3056c6741acc5bf52b785afe12b0aef0b78e59d1 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Mon, 28 Oct 2019 12:20:55 +0100 Subject: [PATCH 02/66] changes bbdd mr34 --- pandora_console/extras/mr/34.sql | 28 +++++++++++++++ .../pandoradb_migrate_6.0_to_7.0.mysql.sql | 35 +++++++++++++++++-- pandora_console/pandoradb.sql | 31 ++++++++++++++++ pandora_console/pandoradb_data.sql | 4 +-- 4 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 pandora_console/extras/mr/34.sql diff --git a/pandora_console/extras/mr/34.sql b/pandora_console/extras/mr/34.sql new file mode 100644 index 0000000000..1e28c01b69 --- /dev/null +++ b/pandora_console/extras/mr/34.sql @@ -0,0 +1,28 @@ +START TRANSACTION; + +CREATE TABLE `tremote_command` ( + `id` SERIAL, + `name` varchar(150) NOT NULL, + `timeout` int(10) unsigned NOT NULL default 30, + `retries` int(10) unsigned NOT NULL default 3, + `preconditions` text, + `script` text, + `postconditions` text, + `utimestamp` int(20) unsigned NOT NULL default 0, + `id_group` int(10) unsigned NOT NULL default 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `tremote_command_target` ( + `rcmd_id` SERIAL, + `id_agente` int(10) unsigned NOT NULL, + `utimestamp` int(20) unsigned NOT NULL default 0, + `stdout` text, + `stderr` text, + `errorlevel` int(10) unsigned NOT NULL default 0, + PRIMARY KEY (`rcmd_id`), + FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +COMMIT; \ No newline at end of file diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index 6476e79e2b..1cf541d6e5 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -1247,13 +1247,13 @@ ALTER TABLE titem MODIFY `source_data` int(10) unsigned; INSERT INTO `tconfig` (`token`, `value`) VALUES ('big_operation_step_datos_purge', '100'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('small_operation_step_datos_purge', '1000'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('days_autodisable_deletion', '30'); -INSERT INTO `tconfig` (`token`, `value`) VALUES ('MR', 32); +INSERT INTO `tconfig` (`token`, `value`) VALUES ('MR', 34); INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_docs_logo', 'default_docs.png'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_support_logo', 'default_support.png'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_logo_white_bg_preview', 'pandora_logo_head_white_bg.png'); UPDATE tconfig SET value = 'https://licensing.artica.es/pandoraupdate7/server.php' WHERE token='url_update_manager'; DELETE FROM `tconfig` WHERE `token` = 'current_package_enterprise'; -INSERT INTO `tconfig` (`token`, `value`) VALUES ('current_package_enterprise', '739'); +INSERT INTO `tconfig` (`token`, `value`) VALUES ('current_package_enterprise', '741'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('status_monitor_fields', 'policy,agent,data_type,module_name,server_type,interval,status,graph,warn,data,timestamp'); UPDATE `tconfig` SET `value` = 'mini_severity,evento,id_agente,estado,timestamp' WHERE `token` LIKE 'event_fields'; DELETE FROM `tconfig` WHERE `token` LIKE 'integria_api_password'; @@ -2293,3 +2293,34 @@ CREATE TABLE `tdeployment_hosts` ( FOREIGN KEY (`target_agent_version_id`) REFERENCES `tagent_repository`(`id`) ON UPDATE CASCADE ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tremote_command` +-- ---------------------------------------------------------------------- +CREATE TABLE `tremote_command` ( + `id` SERIAL, + `name` varchar(150) NOT NULL, + `timeout` int(10) unsigned NOT NULL default 30, + `retries` int(10) unsigned NOT NULL default 3, + `preconditions` text, + `script` text, + `postconditions` text, + `utimestamp` int(20) unsigned NOT NULL default 0, + `id_group` int(10) unsigned NOT NULL default 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tremote_command_target` +-- ---------------------------------------------------------------------- +CREATE TABLE `tremote_command_target` ( + `rcmd_id` SERIAL, + `id_agente` int(10) unsigned NOT NULL, + `utimestamp` int(20) unsigned NOT NULL default 0, + `stdout` text, + `stderr` text, + `errorlevel` int(10) unsigned NOT NULL default 0, + PRIMARY KEY (`rcmd_id`), + FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 3786c4dad3..59ee15dd62 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -3657,3 +3657,34 @@ CREATE TABLE `tdeployment_hosts` ( FOREIGN KEY (`target_agent_version_id`) REFERENCES `tagent_repository`(`id`) ON UPDATE CASCADE ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tremote_command` +-- ---------------------------------------------------------------------- +CREATE TABLE `tremote_command` ( + `id` SERIAL, + `name` varchar(150) NOT NULL, + `timeout` int(10) unsigned NOT NULL default 30, + `retries` int(10) unsigned NOT NULL default 3, + `preconditions` text, + `script` text, + `postconditions` text, + `utimestamp` int(20) unsigned NOT NULL default 0, + `id_group` int(10) unsigned NOT NULL default 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------------------------------------------------- +-- Table `tremote_command_target` +-- ---------------------------------------------------------------------- +CREATE TABLE `tremote_command_target` ( + `rcmd_id` SERIAL, + `id_agente` int(10) unsigned NOT NULL, + `utimestamp` int(20) unsigned NOT NULL default 0, + `stdout` text, + `stderr` text, + `errorlevel` int(10) unsigned NOT NULL default 0, + PRIMARY KEY (`rcmd_id`), + FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 686f4aa487..0a1be20b03 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -109,10 +109,10 @@ INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_report_front_logo', 'images/pandora_logo_white.jpg'), ('custom_report_front_header', ''), ('custom_report_front_footer', ''), -('MR', 32), +('MR', 34), ('identification_reminder', 1), ('identification_reminder_timestamp', 0), -('current_package_enterprise', '739'), +('current_package_enterprise', '741'), ('post_process_custom_values', '{"0.00000038580247":"Seconds to months","0.00000165343915":"Seconds to weeks","0.00001157407407":"Seconds to days","0.01666666666667":"Seconds to minutes","0.00000000093132":"Bytes to Gigabytes","0.00000095367432":"Bytes to Megabytes","0.0009765625":"Bytes to Kilobytes","0.00000001653439":"Timeticks to weeks","0.00000011574074":"Timeticks to days"}'), ('custom_docs_logo', 'default_docs.png'), ('custom_support_logo', 'default_support.png'), From 487da50d317adda89b4cac8b28f759079d497cfc Mon Sep 17 00:00:00 2001 From: marcos Date: Tue, 29 Oct 2019 16:56:11 +0100 Subject: [PATCH 03/66] add omnishell.css --- pandora_console/include/styles/omnishell.css | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 pandora_console/include/styles/omnishell.css diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css new file mode 100644 index 0000000000..8aae0bb3ff --- /dev/null +++ b/pandora_console/include/styles/omnishell.css @@ -0,0 +1,24 @@ +div.modal_form_omnishell { + max-width: 200px; + margin-left: 39px; + margin-top: 10px; + margin-bottom: 10px; + font-weight: bolder; +} +div.btn_section { + max-width: 200px; + margin-left: 39px; + margin-top: 10px; + margin-bottom: 10px; + font-weight: bolder; +} + +.darrow_style { + vertical-align: center; + text-align: center; + width: 100px; +} +.add_agent { + background-image: url("../../images/darrowright.png"); + background-repeat: no-repeat; +} From bb7ba67dab68a0427e009b4aa6afb7fba47d1569 Mon Sep 17 00:00:00 2001 From: marcos Date: Tue, 29 Oct 2019 17:49:04 +0100 Subject: [PATCH 04/66] changes in omnishell.css --- pandora_console/include/styles/omnishell.css | 27 +++++--------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css index 8aae0bb3ff..27a972425b 100644 --- a/pandora_console/include/styles/omnishell.css +++ b/pandora_console/include/styles/omnishell.css @@ -1,24 +1,11 @@ -div.modal_form_omnishell { - max-width: 200px; - margin-left: 39px; - margin-top: 10px; - margin-bottom: 10px; - font-weight: bolder; -} -div.btn_section { - max-width: 200px; - margin-left: 39px; - margin-top: 10px; - margin-bottom: 10px; - font-weight: bolder; -} - -.darrow_style { - vertical-align: center; - text-align: center; - width: 100px; -} .add_agent { background-image: url("../../images/darrowright.png"); background-repeat: no-repeat; + border: none; +} + +.edit_yaml { + margin-left: 39px; + margin-top: 10px; + margin-bottom: 10px; } From b7710a65622909f99a6741d014fffd6b9e719862 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Wed, 30 Oct 2019 08:04:13 +0100 Subject: [PATCH 05/66] fix remove mr34 to mr33 --- pandora_console/extras/mr/33.sql | 25 +++++++++++++++++ pandora_console/extras/mr/34.sql | 28 ------------------- .../pandoradb_migrate_6.0_to_7.0.mysql.sql | 2 +- pandora_console/pandoradb_data.sql | 2 +- 4 files changed, 27 insertions(+), 30 deletions(-) delete mode 100644 pandora_console/extras/mr/34.sql diff --git a/pandora_console/extras/mr/33.sql b/pandora_console/extras/mr/33.sql index eeca8ed5d7..61653a12ad 100644 --- a/pandora_console/extras/mr/33.sql +++ b/pandora_console/extras/mr/33.sql @@ -6,4 +6,29 @@ INSERT INTO `ttipo_modulo` VALUES (36,'remote_cmd_string', 10, 'Remote execution, alphanumeric data', 'mod_remote_cmd_string.png'), (37,'remote_cmd_inc', 10, 'Remote execution, incremental data', 'mod_remote_cmd_inc.png'); +CREATE TABLE `tremote_command` ( + `id` SERIAL, + `name` varchar(150) NOT NULL, + `timeout` int(10) unsigned NOT NULL default 30, + `retries` int(10) unsigned NOT NULL default 3, + `preconditions` text, + `script` text, + `postconditions` text, + `utimestamp` int(20) unsigned NOT NULL default 0, + `id_group` int(10) unsigned NOT NULL default 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `tremote_command_target` ( + `rcmd_id` SERIAL, + `id_agente` int(10) unsigned NOT NULL, + `utimestamp` int(20) unsigned NOT NULL default 0, + `stdout` text, + `stderr` text, + `errorlevel` int(10) unsigned NOT NULL default 0, + PRIMARY KEY (`rcmd_id`), + FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) + ON UPDATE CASCADE ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + COMMIT; \ No newline at end of file diff --git a/pandora_console/extras/mr/34.sql b/pandora_console/extras/mr/34.sql deleted file mode 100644 index 1e28c01b69..0000000000 --- a/pandora_console/extras/mr/34.sql +++ /dev/null @@ -1,28 +0,0 @@ -START TRANSACTION; - -CREATE TABLE `tremote_command` ( - `id` SERIAL, - `name` varchar(150) NOT NULL, - `timeout` int(10) unsigned NOT NULL default 30, - `retries` int(10) unsigned NOT NULL default 3, - `preconditions` text, - `script` text, - `postconditions` text, - `utimestamp` int(20) unsigned NOT NULL default 0, - `id_group` int(10) unsigned NOT NULL default 0, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `tremote_command_target` ( - `rcmd_id` SERIAL, - `id_agente` int(10) unsigned NOT NULL, - `utimestamp` int(20) unsigned NOT NULL default 0, - `stdout` text, - `stderr` text, - `errorlevel` int(10) unsigned NOT NULL default 0, - PRIMARY KEY (`rcmd_id`), - FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) - ON UPDATE CASCADE ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -COMMIT; \ No newline at end of file diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index 004611ca91..0a2cfdefb4 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -1247,7 +1247,7 @@ ALTER TABLE titem MODIFY `source_data` int(10) unsigned; INSERT INTO `tconfig` (`token`, `value`) VALUES ('big_operation_step_datos_purge', '100'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('small_operation_step_datos_purge', '1000'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('days_autodisable_deletion', '30'); -INSERT INTO `tconfig` (`token`, `value`) VALUES ('MR', 34); +INSERT INTO `tconfig` (`token`, `value`) VALUES ('MR', 33); INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_docs_logo', 'default_docs.png'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_support_logo', 'default_support.png'); INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_logo_white_bg_preview', 'pandora_logo_head_white_bg.png'); diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 98627a0e3f..c2868a214e 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -109,7 +109,7 @@ INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_report_front_logo', 'images/pandora_logo_white.jpg'), ('custom_report_front_header', ''), ('custom_report_front_footer', ''), -('MR', 34), +('MR', 33), ('identification_reminder', 1), ('identification_reminder_timestamp', 0), ('current_package_enterprise', '741'), From d37410ed8c6043364c30eb664acb82b5d9f0c27a Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Wed, 30 Oct 2019 14:43:10 +0100 Subject: [PATCH 06/66] fixed error bbdd --- pandora_console/extras/mr/33.sql | 5 +++-- .../extras/pandoradb_migrate_6.0_to_7.0.mysql.sql | 5 +++-- pandora_console/pandoradb.sql | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pandora_console/extras/mr/33.sql b/pandora_console/extras/mr/33.sql index 61653a12ad..9f9e857965 100644 --- a/pandora_console/extras/mr/33.sql +++ b/pandora_console/extras/mr/33.sql @@ -20,13 +20,14 @@ CREATE TABLE `tremote_command` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `tremote_command_target` ( - `rcmd_id` SERIAL, + `id` SERIAL, + `rcmd_id` bigint unsigned NOT NULL unique, `id_agente` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, `stdout` text, `stderr` text, `errorlevel` int(10) unsigned NOT NULL default 0, - PRIMARY KEY (`rcmd_id`), + PRIMARY KEY (`id`), FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index 0a2cfdefb4..d72c908400 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -2319,13 +2319,14 @@ CREATE TABLE `tremote_command` ( -- Table `tremote_command_target` -- ---------------------------------------------------------------------- CREATE TABLE `tremote_command_target` ( - `rcmd_id` SERIAL, + `id` SERIAL, + `rcmd_id` bigint unsigned NOT NULL unique, `id_agente` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, `stdout` text, `stderr` text, `errorlevel` int(10) unsigned NOT NULL default 0, - PRIMARY KEY (`rcmd_id`), + PRIMARY KEY (`id`), FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 59ee15dd62..61eab5f300 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -3678,13 +3678,14 @@ CREATE TABLE `tremote_command` ( -- Table `tremote_command_target` -- ---------------------------------------------------------------------- CREATE TABLE `tremote_command_target` ( - `rcmd_id` SERIAL, + `id` SERIAL, + `rcmd_id` bigint unsigned NOT NULL unique, `id_agente` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, `stdout` text, `stderr` text, `errorlevel` int(10) unsigned NOT NULL default 0, - PRIMARY KEY (`rcmd_id`), + PRIMARY KEY (`id`), FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file From 334cea472e9e4c45de3b8c22e40c8ea2726df7db Mon Sep 17 00:00:00 2001 From: marcos Date: Wed, 30 Oct 2019 14:47:28 +0100 Subject: [PATCH 07/66] add method ui_progress_extend(work in progress) --- pandora_console/include/functions_ui.php | 107 +++++++++++++++++++ pandora_console/include/styles/omnishell.css | 20 ++++ 2 files changed, 127 insertions(+) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index cc3b40ffbb..1d43cebe28 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -2911,6 +2911,113 @@ function ui_progress( } +/** + * Generates a progress bar CSS based. + * Requires css progress.css + * + * @param integer $progress Progress. + * @param string $width Width. + * @param integer $height Height in 'em'. + * @param string $color Color. + * @param boolean $return Return or paint (if false). + * @param boolean $text Text to be displayed,by default progress %. + * @param array $ajax Ajax: [ 'page' => 'page', 'data' => 'data' ] Sample: + * [ + * 'page' => 'operation/agentes/ver_agente', Target page. + * 'interval' => 100 / $agent["intervalo"], Ask every interval seconds. + * 'data' => [ Data to be sent to target page. + * 'id_agente' => $id_agente, + * 'refresh_contact' => 1, + * ], + * ]. + * + * @return string HTML code. + */ +function ui_progress_extend( + $progress, + $width='100%', + $height='2.5', + $color='#82b92e', + $return=true, + $text='', + $ajax=false +) { + if (!$progress) { + $progress = 0; + } + + if ($progress > 100) { + $progress = 100; + } + + if ($progress < 0) { + $progress = 0; + } + + if (empty($text)) { + $text = $progress.'%'; + } + + ui_require_css_file('progress'); + $output .= ''; + $output .= ''; + $output .= ''; + + if ($ajax !== false && is_array($ajax)) { + $output .= ''; + } + + if (!$return) { + echo $output; + } + + return $output; +} + + /** * Generate needed code to print a datatables jquery plugin. * diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css index 27a972425b..4d41cb3cd5 100644 --- a/pandora_console/include/styles/omnishell.css +++ b/pandora_console/include/styles/omnishell.css @@ -4,8 +4,28 @@ border: none; } +.remove_agent { + background-image: url("../../images/darrowleft.png"); + background-repeat: no-repeat; + border: none; +} + .edit_yaml { margin-left: 39px; margin-top: 10px; margin-bottom: 10px; } + +li > input[type="text"] { + border: 1px solid lightgrey; + border-radius: 0; + font-family: "lato-bolder", "Open Sans", sans-serif; + font-weight: lighter; + padding: 0px 0px 2px 0px; + box-sizing: border-box; + margin-bottom: 4px; +} + +.margin_button { + margin-right: 5px; +} From 7bfa0762635c73d056c1efb07c848e956293e0b6 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Wed, 30 Oct 2019 14:52:10 +0100 Subject: [PATCH 08/66] fixed error bbdd --- pandora_console/extras/mr/33.sql | 2 +- pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql | 2 +- pandora_console/pandoradb.sql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pandora_console/extras/mr/33.sql b/pandora_console/extras/mr/33.sql index 9f9e857965..c34209b867 100644 --- a/pandora_console/extras/mr/33.sql +++ b/pandora_console/extras/mr/33.sql @@ -21,7 +21,7 @@ CREATE TABLE `tremote_command` ( CREATE TABLE `tremote_command_target` ( `id` SERIAL, - `rcmd_id` bigint unsigned NOT NULL unique, + `rcmd_id` bigint unsigned NOT NULL, `id_agente` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, `stdout` text, diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index d72c908400..d195823d7b 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -2320,7 +2320,7 @@ CREATE TABLE `tremote_command` ( -- ---------------------------------------------------------------------- CREATE TABLE `tremote_command_target` ( `id` SERIAL, - `rcmd_id` bigint unsigned NOT NULL unique, + `rcmd_id` bigint unsigned NOT NULL, `id_agente` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, `stdout` text, diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 61eab5f300..1b235f6d01 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -3679,7 +3679,7 @@ CREATE TABLE `tremote_command` ( -- ---------------------------------------------------------------------- CREATE TABLE `tremote_command_target` ( `id` SERIAL, - `rcmd_id` bigint unsigned NOT NULL unique, + `rcmd_id` bigint unsigned NOT NULL, `id_agente` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, `stdout` text, From c72f792d4367cb0ef7a62eac408290306cdedd95 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 31 Oct 2019 18:18:38 +0100 Subject: [PATCH 09/66] SAP discovery task --- pandora_console/include/constants.php | 1 + 1 file changed, 1 insertion(+) diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index 893a4f6202..4c092bad52 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -590,6 +590,7 @@ define('DISCOVERY_CLOUD_AWS_EC2', 6); define('DISCOVERY_CLOUD_AWS_RDS', 7); define('DISCOVERY_CLOUD_AZURE_COMPUTE', 8); define('DISCOVERY_DEPLOY_AGENTS', 9); +define('DISCOVERY_APP_SAP', 10); // Discovery types matching definition. From 5a42e76650cc2f70e7073cea1d124d6258524311 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 31 Oct 2019 18:19:00 +0100 Subject: [PATCH 10/66] SAP discovery task --- pandora_console/include/constants.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index 4c092bad52..886c1f7c20 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -537,7 +537,7 @@ define('NODE_GENERIC', 3); define('STATUS_OK', 0); define('STATUS_ERROR', 1); -// Maps (new networkmaps and new visualmaps). +// Maps new networkmaps and new visualmaps. define('MAP_TYPE_NETWORKMAP', 0); define('MAP_TYPE_VISUALMAP', 1); From 115c884cd4d67c0e3f1d54ce96d24c65ea929962 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 31 Oct 2019 21:13:18 +0100 Subject: [PATCH 11/66] Discovery SAP --- pandora_console/extras/mr/33.sql | 2 ++ .../extras/pandoradb_migrate_6.0_to_7.0.mysql.sql | 2 +- .../godmode/wizards/DiscoveryTaskList.class.php | 3 +++ pandora_console/godmode/wizards/Wizard.main.php | 5 ++++- .../include/class/CredentialStore.class.php | 11 +++++++++-- pandora_console/pandoradb.sql | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pandora_console/extras/mr/33.sql b/pandora_console/extras/mr/33.sql index eeca8ed5d7..56357b388b 100644 --- a/pandora_console/extras/mr/33.sql +++ b/pandora_console/extras/mr/33.sql @@ -6,4 +6,6 @@ INSERT INTO `ttipo_modulo` VALUES (36,'remote_cmd_string', 10, 'Remote execution, alphanumeric data', 'mod_remote_cmd_string.png'), (37,'remote_cmd_inc', 10, 'Remote execution, incremental data', 'mod_remote_cmd_inc.png'); +ALTER TABLE `tcredential_store` MODIFY COLUMN `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE', 'SAP') default 'CUSTOM'; + COMMIT; \ No newline at end of file diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index 0b309cfd84..3075c64ddb 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -2245,7 +2245,7 @@ CREATE TABLE `tvisual_console_elements_cache` ( CREATE TABLE IF NOT EXISTS `tcredential_store` ( `identifier` varchar(100) NOT NULL, `id_group` mediumint(4) unsigned NOT NULL DEFAULT 0, - `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE') default 'CUSTOM', + `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE', 'SAP') default 'CUSTOM', `username` text, `password` text, `extra_1` text, diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index ed523d0b82..d1b98a716d 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -773,6 +773,9 @@ class DiscoveryTaskList extends Wizard case DISCOVERY_CLOUD_AWS_RDS: return 'wiz=cloud&mode=amazonws&ki='.$task['auth_strings'].'&sub=rds&page=0'; + case DISCOVERY_APP_SAP: + return 'wiz=app&mode=SAP&page=0'; + default: if ($task['description'] == 'console_task') { return 'wiz=ctask'; diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index 5ffeb716d9..71115b67ed 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -806,8 +806,11 @@ class Wizard $padding_left = isset($column['padding-left']) ? 'padding-left: '.$column['padding-left'].';' : 'padding-left: 0;'; $padding_right = isset($column['padding-right']) ? 'padding-right: '.$column['padding-right'].';' : 'padding-right: 0;'; $extra_styles = isset($column['style']) ? $column['style'] : ''; + $class = isset($column['class']) ? $column['class'] : ''; - $output .= '
'; + $output .= '
'; foreach ($column['inputs'] as $input) { if (is_array($input)) { diff --git a/pandora_console/include/class/CredentialStore.class.php b/pandora_console/include/class/CredentialStore.class.php index b453318c4b..cf315d4a5b 100644 --- a/pandora_console/include/class/CredentialStore.class.php +++ b/pandora_console/include/class/CredentialStore.class.php @@ -432,7 +432,7 @@ class CredentialStore extends Wizard return $return; } - return false; + return []; } @@ -866,6 +866,7 @@ class CredentialStore extends Wizard 'CUSTOM' => __('Custom'), 'AWS' => __('Aws'), 'AZURE' => __('Azure'), + 'SAP' => __('SAP'), // 'GOOGLE' => __('Google'), ], 'selected' => (isset($values['product']) ? $values['product'] : 'CUSTOM'), @@ -900,6 +901,7 @@ class CredentialStore extends Wizard case 'GOOGLE': // Need further investigation. case 'CUSTOM': + case 'SAP': $user_label = __('Account ID'); $pass_label = __('Password'); $extra1 = false; @@ -1038,7 +1040,12 @@ class CredentialStore extends Wizard $('#div-extra_2 label').text(''); $('#div-extra_1').show(); $('#div-extra_2').show(); - } + } else if ($('#product :selected').val() == "SAP") { + $('#div-username label').text(''); + $('#div-password label').text(''); + $('#div-extra_1').hide(); + $('#div-extra_2').hide(); + } } /** diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 3786c4dad3..1682da2ec7 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -699,7 +699,7 @@ CREATE TABLE IF NOT EXISTS `tgrupo` ( CREATE TABLE IF NOT EXISTS `tcredential_store` ( `identifier` varchar(100) NOT NULL, `id_group` mediumint(4) unsigned NOT NULL DEFAULT 0, - `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE') default 'CUSTOM', + `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE', 'SAP') default 'CUSTOM', `username` text, `password` text, `extra_1` text, From aa30a12f3172d7c9bbea71a86cc0026c14b86d1c Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 31 Oct 2019 21:15:18 +0100 Subject: [PATCH 12/66] wizard doc minor fix --- .../godmode/wizards/Wizard.main.php | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index 71115b67ed..6f1d59d56b 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -436,11 +436,15 @@ class Wizard * * @param array $input Definition of target block to be printed. * @param boolean $return Return as string or direct output. + * @param boolean $direct Avoid encapsulation if input print is direct. * * @return string HTML content. */ - public function printBlock(array $input, bool $return=false, bool $not_direct=false) - { + public function printBlock( + array $input, + bool $return=false, + bool $direct=false + ) { $output = ''; if ($input['hidden'] == 1) { $class = ' hidden'; @@ -453,7 +457,7 @@ class Wizard } if (is_array($input['block_content']) === true) { - $not_direct = (bool) $input['direct']; + $direct = (bool) $input['direct']; // Print independent block of inputs. $output .= '
  • '; @@ -462,17 +466,21 @@ class Wizard $output .= '<'.$input['wrapper'].' id="'.$input['block_id'].'" class="'.$class.'">'; } - if (!$not_direct) { + if (!$direct) { // Avoid encapsulation if input is direct => 1. $output .= '
      '; } foreach ($input['block_content'] as $input) { - $output .= $this->printBlock($input, $return, (bool) $not_direct); + $output .= $this->printBlock( + $input, + $return, + (bool) $direct + ); } // Close block. - if (!$not_direct) { + if (!$direct) { $output .= '
    '; } @@ -483,7 +491,7 @@ class Wizard $output .= '
  • '; } else { if ($input['arguments']['type'] != 'hidden') { - if (!$not_direct) { + if (!$direct) { $output .= '
  • '; } @@ -491,7 +499,7 @@ class Wizard $output .= $this->printInput($input['arguments']); // Allow dynamic content. $output .= $input['extra']; - if (!$not_direct) { + if (!$direct) { $output .= '
  • '; } } else { From a249132fb51700d89703c5829b60d4e872fc7261 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 31 Oct 2019 21:32:34 +0100 Subject: [PATCH 13/66] sap discovery - config --- pandora_console/include/functions_config.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index bab47d6926..4c46daf680 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -455,6 +455,10 @@ function config_update_config() $error_update[] = __('Ipam Ocuppied Manager Warning'); } + if (!config_update_value('sap_license', get_parameter('sap_license'))) { + $error_update[] = __('Deset SAP license'); + } + $inventory_changes_blacklist = get_parameter('inventory_changes_blacklist', []); if (!config_update_value('inventory_changes_blacklist', implode(',', $inventory_changes_blacklist))) { $error_update[] = __('Inventory changes blacklist'); From 84bdc8fc17c1d0763789fea7654ea04af60305b3 Mon Sep 17 00:00:00 2001 From: marcos Date: Mon, 4 Nov 2019 17:39:21 +0100 Subject: [PATCH 14/66] add progress extend --- pandora_console/include/functions_ui.php | 33 +++++++++++++++--------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 1d43cebe28..6122cd12c0 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -2915,10 +2915,10 @@ function ui_progress( * Generates a progress bar CSS based. * Requires css progress.css * - * @param integer $progress Progress. + * @param array $progress Progress. * @param string $width Width. * @param integer $height Height in 'em'. - * @param string $color Color. + * @param array $color status color. * @param boolean $return Return or paint (if false). * @param boolean $text Text to be displayed,by default progress %. * @param array $ajax Ajax: [ 'page' => 'page', 'data' => 'data' ] Sample: @@ -2942,27 +2942,36 @@ function ui_progress_extend( $text='', $ajax=false ) { - if (!$progress) { + if (!$progress['total']) { $progress = 0; } - if ($progress > 100) { - $progress = 100; + if ($progress['total'] > 100) { + $progress['total'] = 100; } - if ($progress < 0) { - $progress = 0; + if ($progress['total'] < 0) { + $progress['total'] = 0; } if (empty($text)) { - $text = $progress.'%'; + $text = $progress['total'].'%'; } + $totalW = ($progress['total'] * 10); + $badW = ($progress['bad'] * 10); + $goodW = ($progress['good'] * 10); + $unknownW = ($progress['unknown'] * 10); ui_require_css_file('progress'); - $output .= ''; - $output .= ''; - $output .= ''; + $output .= '
    '; + $output .= '
    '; + $output .= '
    '; + $output .= '
    '; + $output .= '
    '; if ($ajax !== false && is_array($ajax)) { $output .= ' + - - - From ca9d168e67b035611ecc4e4caf3594a2b615ec7f Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 11 Nov 2019 18:12:43 +0100 Subject: [PATCH 24/66] wip omnishell --- pandora_agents/unix/pandora_agent | 25 +++++++++++++++++---- pandora_server/lib/PandoraFMS/DataServer.pm | 6 ++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index c9315a31c8..cd2c293aef 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -281,6 +281,20 @@ sub error ($) { exit 1; } +################################################################################ +# Try to load extra libraries.c +################################################################################ +sub load_libraries() { + # Dynamic load. Avoid unwanted behaviour. + eval {eval 'require YAML::Tiny;1' or die('YAML::Tiny lib not found, commands feature won\'t be available');}; + if ($@) { + $YAML = 0; + print STDERR $@; + } else { + $YAML = 1; + } +} + ################################################################################ # Check a regular expression. Returns 1 if its valid, 0 otherwise. ################################################################################ @@ -1199,14 +1213,14 @@ sub recv_file { }; if ($@) { - log_message ('error', "Error retrieving file: File transfer command is not responding."); + log_message ('error', "Error retrieving file: '.$file.' File transfer command is not responding."); exit 1; } # Get the errorlevel my $rc = $? >> 8; if ($rc != 0) { - log_message ('error', "Error retrieving file: $output"); + log_message ('error', "Error retrieving file: '$file' $output"); } exit $rc; } @@ -1469,7 +1483,7 @@ sub prepare_remote_commands { }; if ($@) { # Failed. - log_message('error', 'Failed to decode command. ' . $@); + log_message('error', 'Failed to decode command. ' . "\n".$@); delete $Conf{'commands'}->{$ref}; next; } @@ -3206,6 +3220,8 @@ my $iter_base_time = time(); $LogFileIdx = -1; # Loop while (1) { + load_libraries(); + if (-e $Conf{'logfile'} && (stat($Conf{'logfile'}))[7] > $Conf{'logsize'}) { rotate_log(); } @@ -3376,9 +3392,10 @@ while (1) { $Xml .= "\n"; $Xml .= " \n"; $Xml .= " {'name'}."]]>\n"; + $Xml .= " \n"; $Xml .= " {'error_level'}."]]>\n"; $Xml .= " {'stdout'}."]]>\n"; - $Xml .= " {'stderr'}."]]>\n"; + $Xml .= " {'stderr'}."]]>\n"; $Xml .= " \n"; $Xml .= "\n"; } diff --git a/pandora_server/lib/PandoraFMS/DataServer.pm b/pandora_server/lib/PandoraFMS/DataServer.pm index df1cbbecfb..38a33fc263 100644 --- a/pandora_server/lib/PandoraFMS/DataServer.pm +++ b/pandora_server/lib/PandoraFMS/DataServer.pm @@ -602,8 +602,12 @@ sub process_xml_data ($$$$$) { # Process events process_events_dataserver($pa_config, $data, $agent_id, $group_id, $dbh); - # Process disovery modules + # Process discovery modules enterprise_hook('process_discovery_data', [$pa_config, $data, $server_id, $dbh]); + + # Process command responses + enterprise_hook('process_rcmd_report', [$pa_config, $data, $server_id, $dbh, $agent_id, $timestamp]); + } ########################################################################## From ec05b52fb4938b48c52f2b4a1fb5ba183c278108 Mon Sep 17 00:00:00 2001 From: marcos Date: Tue, 12 Nov 2019 10:08:35 +0100 Subject: [PATCH 25/66] update omnishell.css --- pandora_console/include/styles/omnishell.css | 44 ++++++++++++++------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css index c7379b8069..97dba30836 100644 --- a/pandora_console/include/styles/omnishell.css +++ b/pandora_console/include/styles/omnishell.css @@ -1,15 +1,3 @@ -.add_agent { - background-image: url("../../images/darrowright.png"); - background-repeat: no-repeat; - border: none; -} - -.remove_agent { - background-image: url("../../images/darrowleft.png"); - background-repeat: no-repeat; - border: none; -} - .edit_yaml { margin-left: 39px; margin-top: 10px; @@ -77,3 +65,35 @@ div.container-msg-target-modal pre { border: 3px dashed grey; border-radius: 10px; } + +ul.textarea_script, +.textarea_script { + max-height: 125px; +} + +.add_button { + height: 20%; + margin-bottom: 35px; +} + +.status_table { + margin-top: 20px; +} + +.gr_table { + margin-top: 20px; + margin-left: 75px; +} + +.btn_section { + width: 1px; + align-self: center; +} + +.btn_add_agent { + background-image: url(../../images/darrowright.png); +} + +.btn_del_agent { + background-image: url(../../images/darrowleft.png); +} From 7b06ceaafcbe289b2f8d79cefbcd8c98894c81b0 Mon Sep 17 00:00:00 2001 From: marcos Date: Tue, 12 Nov 2019 10:54:36 +0100 Subject: [PATCH 26/66] add sap menu --- pandora_console/godmode/menu.php | 1 + 1 file changed, 1 insertion(+) diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index edf7be1873..062df046b2 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -56,6 +56,7 @@ if (check_acl($config['id_user'], 0, 'AR') enterprise_hook('applications_menu'); enterprise_hook('cloud_menu'); enterprise_hook('console_task_menu'); + enterprise_hook('SAP_view'); } // Add to menu. From 9d3c9febad228cecf10bc07a24cd8d1fc3e94339 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Tue, 12 Nov 2019 13:16:25 +0100 Subject: [PATCH 27/66] Add alert correlation wizard --- pandora_console/include/functions_html.php | 121 ++++++++++++++++++- pandora_console/include/functions_menu.php | 2 +- pandora_console/include/styles/discovery.css | 1 + pandora_console/include/styles/pandora.css | 12 ++ 4 files changed, 134 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index 12a8ecfa88..e329af6013 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -1618,6 +1618,89 @@ function html_print_input_email(array $settings):string } +/** + * Render an input number element. + * + * @param array $settings Array with attributes input. + * only name is necessary. + * + * @return string + */ +function html_print_input_number(array $settings):string +{ + // TODO: const. + $valid_attrs = [ + 'accept', + 'disabled', + 'maxlength', + 'name', + 'readonly', + 'placeholder', + 'size', + 'value', + 'accesskey', + 'class', + 'dir', + 'id', + 'lang', + 'style', + 'tabindex', + 'title', + 'xml:lang', + 'onfocus', + 'onblur', + 'onselect', + 'onchange', + 'onclick', + 'ondblclick', + 'onmousedown', + 'onmouseup', + 'onmouseover', + 'onmousemove', + 'onmouseout', + 'onkeypress', + 'onkeydown', + 'onkeyup', + 'required', + 'pattern', + 'autocomplete', + ]; + + $output = ''; + if (isset($settings) === true && is_array($settings) === true) { + // Check Name is necessary. + if (isset($settings['name']) === true) { + $output = ' $attr_value) { + // Check valid attribute. + if (in_array($attribute, $valid_attrs) === false) { + continue; + } + + $output .= $attribute.'="'.$attr_value.'" '; + } + + $output .= $function.'/>'; + } + } + + return $output; +} + + /** * Render an input image element. * @@ -3309,6 +3392,10 @@ function html_print_input($data, $wrapper='div', $input_only=false) $output .= html_print_input_email($data); break; + case 'number': + $output .= html_print_input_number($data); + break; + case 'hidden': $output .= html_print_input_hidden( $data['name'], @@ -3413,7 +3500,8 @@ function html_print_input($data, $wrapper='div', $input_only=false) break; case 'submit': - $output .= '<'.$wrapper.' class="action-buttons" style="width: 100%">'.html_print_submit_button( + $width = (isset($data['width']) === true) ? 'width: '.$data['width'] : 'width: 100%'; + $output .= '<'.$wrapper.' class="action-buttons" style="'.$width.'">'.html_print_submit_button( ((isset($data['label']) === true) ? $data['label'] : 'OK'), ((isset($data['name']) === true) ? $data['name'] : ''), ((isset($data['disabled']) === true) ? $data['disabled'] : false), @@ -3498,6 +3586,10 @@ function html_print_input($data, $wrapper='div', $input_only=false) $output .= html_print_input_email($data); break; + case 'multicheck': + $output .= html_print_input_multicheck($data); + break; + default: // Ignore. break; @@ -3514,6 +3606,33 @@ function html_print_input($data, $wrapper='div', $input_only=false) } +/** + * Print all checkbox in the same row. + * + * @param array $data Array with attributes input. + * only name is necessary. + * + * @return string + */ +function html_print_input_multicheck(array $data):string +{ + $html = ''; + if (isset($data['data']) === true && is_array($data['data']) === true) { + foreach ($data['data'] as $key => $value) { + $html .= $value; + $html .= html_print_checkbox( + 'days_week_'.$key, + 1, + $data['checked'][$key], + true + ); + } + } + + return $html; +} + + /** * Print an autocomplete input filled out with Integria IMS users. * diff --git a/pandora_console/include/functions_menu.php b/pandora_console/include/functions_menu.php index 36785064ef..ee242a1624 100644 --- a/pandora_console/include/functions_menu.php +++ b/pandora_console/include/functions_menu.php @@ -536,7 +536,7 @@ function menu_add_extras(&$menu) $menu_extra['galertas']['sub']['godmode/alerts/configure_alert_action']['text'] = __('Manage alert actions'); $menu_extra['galertas']['sub']['godmode/alerts/configure_alert_command']['text'] = __('Manage commands'); - $menu_extra['galertas']['sub']['enterprise/godmode/alerts/alert_events']['text'] = __('Manage event alerts'); + $menu_extra['galertas']['sub']['enterprise/godmode/alerts/alert_correlation']['text'] = __('Manage event alerts'); $menu_extra['gservers']['sub']['enterprise/godmode/servers/manage_export_form']['text'] = __('Manage export targets'); diff --git a/pandora_console/include/styles/discovery.css b/pandora_console/include/styles/discovery.css index 2aee23f645..d191357511 100644 --- a/pandora_console/include/styles/discovery.css +++ b/pandora_console/include/styles/discovery.css @@ -204,6 +204,7 @@ label { width: 100%; } +li > input[type="number"], li > input[type="text"], li > input[type="email"], li > input[type="password"], diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index d6a1d97ecf..a7bf928bb5 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -551,6 +551,18 @@ select:-internal-list-box { align-items: center; } +.flex-space-around { + justify-content: space-around; +} + +.flex-end { + justify-content: flex-end; +} + +.flex-start { + justify-content: flex-start; +} + .nowrap { flex-wrap: nowrap; } From 02677849ced33f1ba969a3b1e376aaa09fd342ff Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Tue, 12 Nov 2019 13:17:00 +0100 Subject: [PATCH 28/66] add new css --- pandora_console/include/styles/alert.css | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 pandora_console/include/styles/alert.css diff --git a/pandora_console/include/styles/alert.css b/pandora_console/include/styles/alert.css new file mode 100644 index 0000000000..7ee5545e56 --- /dev/null +++ b/pandora_console/include/styles/alert.css @@ -0,0 +1,47 @@ +li#li-buttons-alert-list > div { + margin-left: 10px; +} + +li#li-buttons-alert-list > label, +li#li-filters-alert-list > label { + width: initial; +} + +form#general_filters_alert ul li label { + width: 150px; +} + +form#conditions_filters_alert ul li label:first-child { + width: 300px; +} + +li#li-name-group input { + margin-right: 50px; +} + +li#li-description textarea { + flex: 1 1 auto; +} + +li#li-from-to-threshold > label:not(:first-child), +li#li-time-from-to > label:not(:first-child) { + width: initial; + margin-right: 15px; +} + +li#li-from-to-threshold > input, +li#li-time-from-to > input { + margin-right: 15px; +} + +#threshold_manual, +#threshold_default { + /*TODO: UGLY*/ + width: initial !important; + margin-right: 10px; +} + +img.handle-alerts { + width: 20px; + cursor: move; +} From 25f879df00786378aa7d1064bcec38f0ae91f84c Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Tue, 12 Nov 2019 18:45:20 +0100 Subject: [PATCH 29/66] add step 3 --- pandora_console/include/styles/alert.css | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/pandora_console/include/styles/alert.css b/pandora_console/include/styles/alert.css index 7ee5545e56..b2d1c4f9ce 100644 --- a/pandora_console/include/styles/alert.css +++ b/pandora_console/include/styles/alert.css @@ -45,3 +45,71 @@ img.handle-alerts { width: 20px; cursor: move; } + +.content { + width: 80%; + min-height: 4em; + border: 1px solid #ddd; + padding-top: 1em; + padding-bottom: 1em; +} +ul.sample { + max-width: 50%; + flex-grow: 1; + justify-content: space-between; +} +ul.sample li { + padding-bottom: 1em; +} +ul.sample li:last-child { + padding-bottom: 0; +} +div.target { + flex-grow: 1; + margin-left: 3em; + border: 1px solid #ddd; +} + +.field { + display: inline-block; + border-radius: 10px; + padding: 5px; + padding-left: 8px; + padding-right: 8px; + margin: 3px; + color: #fff; + font-family: "lato-lighter", "Open Sans", sans-serif; + font-weight: 600; + background-color: #333; +} + +.log { + background-color: #638460; +} +.event { + background-color: #587cff; +} + +.operator { + background-color: #908787; +} + +.variable { + background-color: #82b92e; +} + +.modifier { + background-color: #cba9d2; +} + +.nexo { + background-color: #424242; +} + +.rules div { + display: inline-block; +} + +.inEdit { + background-color: #888; +} From d1fbd36a971a87a4ca6578c77b90b72c4f260f32 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Tue, 12 Nov 2019 19:31:38 +0100 Subject: [PATCH 30/66] WIP omnishell --- .../godmode/wizards/Wizard.main.php | 29 +- pandora_console/include/styles/discovery.css | 2 +- pandora_console/include/styles/omnishell.css | 430 ++++++++++++++++-- pandora_console/include/styles/pandora.css | 2 +- 4 files changed, 409 insertions(+), 54 deletions(-) diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index 5ffeb716d9..6f1d59d56b 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -436,11 +436,15 @@ class Wizard * * @param array $input Definition of target block to be printed. * @param boolean $return Return as string or direct output. + * @param boolean $direct Avoid encapsulation if input print is direct. * * @return string HTML content. */ - public function printBlock(array $input, bool $return=false, bool $not_direct=false) - { + public function printBlock( + array $input, + bool $return=false, + bool $direct=false + ) { $output = ''; if ($input['hidden'] == 1) { $class = ' hidden'; @@ -453,7 +457,7 @@ class Wizard } if (is_array($input['block_content']) === true) { - $not_direct = (bool) $input['direct']; + $direct = (bool) $input['direct']; // Print independent block of inputs. $output .= '
  • '; @@ -462,17 +466,21 @@ class Wizard $output .= '<'.$input['wrapper'].' id="'.$input['block_id'].'" class="'.$class.'">'; } - if (!$not_direct) { + if (!$direct) { // Avoid encapsulation if input is direct => 1. $output .= '
      '; } foreach ($input['block_content'] as $input) { - $output .= $this->printBlock($input, $return, (bool) $not_direct); + $output .= $this->printBlock( + $input, + $return, + (bool) $direct + ); } // Close block. - if (!$not_direct) { + if (!$direct) { $output .= '
    '; } @@ -483,7 +491,7 @@ class Wizard $output .= '
  • '; } else { if ($input['arguments']['type'] != 'hidden') { - if (!$not_direct) { + if (!$direct) { $output .= '
  • '; } @@ -491,7 +499,7 @@ class Wizard $output .= $this->printInput($input['arguments']); // Allow dynamic content. $output .= $input['extra']; - if (!$not_direct) { + if (!$direct) { $output .= '
  • '; } } else { @@ -806,8 +814,11 @@ class Wizard $padding_left = isset($column['padding-left']) ? 'padding-left: '.$column['padding-left'].';' : 'padding-left: 0;'; $padding_right = isset($column['padding-right']) ? 'padding-right: '.$column['padding-right'].';' : 'padding-right: 0;'; $extra_styles = isset($column['style']) ? $column['style'] : ''; + $class = isset($column['class']) ? $column['class'] : ''; - $output .= '
    '; + $output .= '
    '; foreach ($column['inputs'] as $input) { if (is_array($input)) { diff --git a/pandora_console/include/styles/discovery.css b/pandora_console/include/styles/discovery.css index 2aee23f645..82451e7a1e 100644 --- a/pandora_console/include/styles/discovery.css +++ b/pandora_console/include/styles/discovery.css @@ -31,7 +31,7 @@ li.discovery > a label { } div.data_container > label { - font-family: "lato-bolder", "Open Sans", sans-serif; + font-family: "lato", "Open Sans", sans-serif; font-weight: lighter; } diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css index 97dba30836..e082facc63 100644 --- a/pandora_console/include/styles/omnishell.css +++ b/pandora_console/include/styles/omnishell.css @@ -4,16 +4,6 @@ margin-bottom: 10px; } -li > input[type="text"] { - border: 1px solid lightgrey; - border-radius: 0; - font-family: "lato-bolder", "Open Sans", sans-serif; - font-weight: lighter; - padding: 0px 0px 2px 0px; - box-sizing: border-box; - margin-bottom: 4px; -} - .margin_button { margin-right: 5px; } @@ -41,59 +31,413 @@ li > input[type="text"] { background-color: #8bbbdd; } -h4 { - color: #343434; - font-family: "lato-bolder", "Open Sans", sans-serif; - line-height: 18pt; -} - .container-msg-target-modal { max-height: 400px; overflow: initial; } -div.container-msg-target-modal p { - font-size: 10pt; +ul.wizard li > textarea { + height: 5em; +} + +.label_select { + font-family: "lato-lighter", "Open Sans", sans-serif; font-weight: bolder; - text-align: center; } -div.container-msg-target-modal pre { - padding: 20px; - white-space: pre-wrap; - background-color: #e2e2e2; - border: 3px dashed grey; - border-radius: 10px; +.divided select { + width: 100%; } -ul.textarea_script, -.textarea_script { - max-height: 125px; +.inline { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-between; + align-content: center; + align-items: center; } -.add_button { - height: 20%; - margin-bottom: 35px; +.inline label:first-child { + width: 250px; + vertical-align: top; + display: inline-block; } -.status_table { - margin-top: 20px; +.inline label:nth-child(3) { + margin-right: 1em; + margin-left: 1em; } -.gr_table { - margin-top: 20px; - margin-left: 75px; +.inline select { + margin-right: 1em; } -.btn_section { - width: 1px; +.middle { align-self: center; } - -.btn_add_agent { - background-image: url(../../images/darrowright.png); +.edit_discovery_info { + padding-top: 0; } -.btn_del_agent { - background-image: url(../../images/darrowleft.png); +ul.wizard { + width: 100%; +} + +.filter_column { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-between; + align-content: center; +} + +.filter_column .edit_discovery_input { + flex-grow: 1; + width: 100%; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-between; + align-content: baseline; + margin-left: 2em; +} +.filter_column .edit_discovery_input .label_select { + display: inline; + margin: 0; +} + +.filter_column .edit_discovery_input select { + flex-grow: 1; + margin-left: 2em; +} + +.wizard li { + display: flex; +} + +/* + * Discovery css global + */ + +ul.bigbuttonlist { + min-height: 200px; +} + +li.discovery { + display: inline-block; + float: left; + width: 250px; + margin: 15px; + padding-bottom: 50px; +} + +li.discovery > a { + text-decoration: none; + color: #333; +} +li.discovery > a:hover { + color: #000; +} + +li.discovery img { + height: 90px; +} + +li.discovery > a label { + cursor: pointer; +} + +div.data_container > label { + font-family: "lato", "Open Sans", sans-serif; + font-weight: lighter; +} + +div.data_container { + width: 100%; + height: 100%; + text-align: center; + padding-top: 30px; + padding-bottom: 30px; +} + +div.data_container:hover { + box-shadow: 2px 2px 10px #ddd; +} + +/* + * TODO: This may be at hostdevices.css + */ +.texto { + height: auto; + text-align: center; +} +h1.wizard { + padding: 0; + margin: 0; +} +h1.wizard a { + margin-left: -20px; +} +h1.wizard a:hover { + color: #fff; +} +#text_wizard { + font-weight: bolder; + text-decoration: none; + font-size: 24px; +} +div.arrow_box { + display: inline-block; + position: relative; + color: #888; + padding: 1.3em; + margin-left: 20px; + margin-bottom: 10px; + padding-left: 3em; +} + +.arrow_box.selected { + background: #424242; + color: #ccc; +} + +.arrow_box:after { + left: 0%; + border-left-color: white; + border-width: 20px; + margin-top: -20px; +} + +div.arrow_box:before { + left: 100%; + border-left-color: #ccc; + border-width: 20px; + margin-top: -20px; +} +.arrow_box.selected:before { + border-left-color: #424242; +} + +.arrow_box.selected:hover { + color: #fff; +} +.arrow_box:hover { + color: #000; +} + +/* + * Breadcrum + */ + +#menu_tab_frame_view_bc { + display: flex; + justify-content: space-between; + border-bottom: 2px solid #82b92e; + max-height: 70px; + min-height: 55px; + width: 100%; + padding-right: 0px; + margin-left: 0px; + margin-bottom: 20px; + height: 55px; + box-sizing: border-box; + background-color: #fafafa; + border-top-right-radius: 7px; + border-top-left-radius: 7px; + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.1); +} + +#menu_tab_frame_view_bc .breadcrumbs_container { + align-self: flex-start; +} + +.breadcrumbs_container { + padding-top: 4px; + text-indent: 0.25em; + padding-left: 2.5em; +} + +.breadcrumb_link { + color: #848484; + font-size: 10pt; + font-family: "lato-bolder", "Open Sans", sans-serif; + text-decoration: none; +} + +span.breadcrumb_link { + color: #d0d0d0; + font-size: 12pt; +} + +.breadcrumb_link.selected { + color: #95b750; +} + +.breadcrumb_link.selected:hover { + color: #95b750; +} +.breadcrumb_link:hover { + color: #95b750; +} + +/* + * Discovery forms structure + */ + +form.discovery * { + font-size: 10pt; +} + +form.discovery .label_select b { + font-family: "lato", "Open Sans", sans-serif; + font-weight: bolder; +} + +.edit_discovery_info { + display: flex; + align-items: flex-start; + padding-top: 25px; +} + +.edit_discovery_input { + align-items: center; + margin-bottom: 25px; +} + +/* + * Discovery text inputs + */ + +.discovery_label_hint { + display: flex; +} + +label { + color: #343434; + font-weight: bold; +} + +.discovery_full_width_input { + width: 100%; +} + +li > input[type="text"], +li > input[type="email"], +li > input[type="password"], +li > input[type="email"], +.discovery_text_input > input[type="password"], +.discovery_text_input > input[type="text"], +#interval_manual > input[type="text"] { + background-color: transparent; + border: none; + border-radius: 0; + border-bottom: 1px solid #ccc; + font-family: "lato-bolder", "Open Sans", sans-serif; + font-weight: lighter; + padding: 0px 0px 2px 0px; + box-sizing: border-box; + margin-bottom: 4px; +} + +#interval_manual > input[type="text"] { + width: 50px; + margin-left: 10px; + margin-right: 10px; +} + +.discovery_list_input { + width: 100%; + border: 1px solid #cbcbcb; + overflow-y: auto; +} + +.discovery_list_input option { + text-align: left; +} + +.discovery_list_input option:checked { + background: #1aab8e -webkit-linear-gradient(bottom, #7db742 0%, #7db742 100%); + color: #fff; +} + +.discovery_textarea_input { + background-color: #fbfbfb; + padding-left: 10px; + width: 100%; + height: 100px; + max-height: 100px; + max-width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + resize: none; +} + +a.tip { + margin-left: 8px; +} + +.inline_switch > label { + float: right; +} + +.discovery_interval_select_width { + width: 90%; +} + +a.ext_link { + margin-left: 1em; + font-size: 8pt; +} + +div.ui-tooltip.ui-corner-all.ui-widget-shadow.ui-widget.ui-widget-content.uitooltip { + background: grey; + opacity: 0.9; + border-radius: 4px; + box-shadow: 6px 5px 9px -9px black; + padding: 6px; +} + +.ui-tooltip-content { + background: transparent; + color: #fff; + font-weight: bold; + font-family: "lato-lighter", "Open Sans", sans-serif; + letter-spacing: 0.03pt; + font-size: 8pt; +} + +.arrow { + width: 70px; + height: 16px; + overflow: hidden; + position: absolute; + left: 50%; + margin-left: -35px; + bottom: -16px; +} +.arrow.top { + top: -16px; + bottom: auto; +} +.arrow.left { + left: 50%; +} +.arrow:after { + background: grey; + content: ""; + position: absolute; + left: 20px; + top: -20px; + width: 25px; + height: 25px; + box-shadow: 6px 5px 9px -9px black; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); +} +.arrow.top:after { + bottom: -20px; + top: auto; } diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index d6a1d97ecf..4eaafa9d1b 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -5698,7 +5698,7 @@ div#status_pie { align-items: center; flex-wrap: wrap; padding: 1em; - min-width: fit-content; + min-width: 100%; } .white_table_graph_content { From e7dfd9b968ca187893b441827342e907399b5a27 Mon Sep 17 00:00:00 2001 From: marcos Date: Tue, 12 Nov 2019 19:53:46 +0100 Subject: [PATCH 31/66] Add sap view --- pandora_console/general/sap_view.php | 77 ++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 pandora_console/general/sap_view.php diff --git a/pandora_console/general/sap_view.php b/pandora_console/general/sap_view.php new file mode 100644 index 0000000000..58ee50e563 --- /dev/null +++ b/pandora_console/general/sap_view.php @@ -0,0 +1,77 @@ + '[sap_views]'.$e->getMessage() ]); + exit; + } else { + echo '[sap_views]'.$e->getMessage(); + } + + // Stop this execution, but continue 'globally'. + return; +} + +// Ajax controller. +if (is_ajax()) { + $method = get_parameter('method', ''); + + if (method_exists($sap_views, $method) === true) { + if ($sap_views->ajaxMethod($method) === true) { + $sap_views->{$method}(); + } else { + $sap_views->error('Unavailable method.'); + } + } else { + $sap_views->error('Method not found. ['.$method.']'); + } + + + // Stop any execution. + exit; +} else { + // Run. + $sap_views->run(); +} From 28c9718c265d68eaa9a77c48d1d73e4fd9d0d737 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Wed, 13 Nov 2019 12:07:23 +0100 Subject: [PATCH 32/66] WIP alerts-log --- pandora_console/include/styles/alert.css | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pandora_console/include/styles/alert.css b/pandora_console/include/styles/alert.css index b2d1c4f9ce..3368bf0796 100644 --- a/pandora_console/include/styles/alert.css +++ b/pandora_console/include/styles/alert.css @@ -7,6 +7,7 @@ li#li-filters-alert-list > label { width: initial; } +form#advanced_filters_alert ul li label, form#general_filters_alert ul li label { width: 150px; } @@ -34,6 +35,18 @@ li#li-time-from-to > input { margin-right: 15px; } +form#advanced_filters_alert textarea { + flex: 1 1 auto; + height: 5em; + min-height: 5em; +} + +form#advanced_filters_alert ul li label img { + margin-bottom: -2px; + margin-left: 5px; +} + +/*DRAG DROP*/ #threshold_manual, #threshold_default { /*TODO: UGLY*/ From 5f8ec8f89cd518ea3fdf6bbf245ca0ac2b3091b4 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Wed, 13 Nov 2019 13:29:09 +0100 Subject: [PATCH 33/66] fixed errors --- pandora_console/include/styles/omnishell.css | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css index e082facc63..8a572388d4 100644 --- a/pandora_console/include/styles/omnishell.css +++ b/pandora_console/include/styles/omnishell.css @@ -34,6 +34,24 @@ .container-msg-target-modal { max-height: 400px; overflow: initial; + padding-right: 20px; + padding-left: 20px; +} + +.container-msg-target-modal p { + font-family: "lato-lighter", "Open Sans", sans-serif; + text-align: center; + margin-bottom: 20px; + font-weight: bolder; +} + +.container-msg-target-modal pre { + font-family: "lato-lighter", "Open Sans", sans-serif; + padding: 15px; + white-space: pre-wrap; + background-color: #f2f6f7; + border: 3px dashed grey; + border-radius: 10px; } ul.wizard li > textarea { From c17328d39d45a386227eced20e9c0f2f9449603f Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 13 Nov 2019 14:21:09 +0100 Subject: [PATCH 34/66] Pandora Agent RCMD --- pandora_agents/unix/pandora_agent | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 7a84c47ce1..63cd9e8374 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -318,8 +318,7 @@ sub read_file { my $path = shift; my $_FILE; - if( !open($_FILE, "<".$path) ) { - print ">> Failed to open $path ".`whoami`."\n"; + if( !open($_FILE, "<", $path) ) { # failed to open, return undef return undef; } @@ -1535,15 +1534,20 @@ sub report_command { sub execute_command_block { my ($commands, $std_files) = @_; - $std_files = '' unless defined ($std_files); - return 0 if ref($commands) ne "ARRAY"; - my $err_level; + $std_files = '' unless defined ($std_files); - foreach my $comm (@{$commands}) { - `($comm) $std_files`; + if (ref($commands) ne "ARRAY") { + `($commands) $std_files`; + print "($commands) $std_files\n"; $err_level = $?>>8; - last unless ($err_level == 0); + } else { + foreach my $comm (@{$commands}) { + `($comm) $std_files`; + print $comm. '=> ' . ($?>>8)."\n"; + $err_level = $?>>8; + last unless ($err_level == 0); + } } return $err_level; From 9b1a3a9cd18d224227bd8174c83d4284996c53b4 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 13 Nov 2019 14:58:53 +0100 Subject: [PATCH 35/66] Firts_task => first_task --- pandora_console/extensions/plugin_registration.php | 4 ++-- .../HA_cluster_builder.php | 4 ++-- .../{firts_task => first_task}/cluster_builder.php | 4 ++-- .../{firts_task => first_task}/collections.php | 2 +- .../{firts_task => first_task}/custom_fields.php | 4 ++-- .../{firts_task => first_task}/custom_graphs.php | 4 ++-- .../{firts_task => first_task}/fields_manager.php | 4 ++-- .../{firts_task => first_task}/incidents.php | 4 ++-- .../{firts_task => first_task}/map_builder.php | 4 ++-- .../{firts_task => first_task}/network_map.php | 4 ++-- .../{firts_task => first_task}/planned_downtime.php | 4 ++-- .../{firts_task => first_task}/recon_view.php | 4 ++-- .../{firts_task => first_task}/service_list.php | 4 ++-- .../{firts_task => first_task}/snmp_filters.php | 4 ++-- .../general/{firts_task => first_task}/tags.php | 4 ++-- .../transactional_list.php | 4 ++-- pandora_console/godmode/agentes/fields_manager.php | 2 +- .../godmode/agentes/planned_downtime.list.php | 2 +- pandora_console/godmode/reporting/graphs.php | 2 +- pandora_console/godmode/reporting/map_builder.php | 2 +- .../godmode/servers/servers.build_table.php | 2 +- pandora_console/godmode/tag/tag.php | 2 +- .../godmode/wizards/DiscoveryTaskList.class.php | 2 +- .../icono-cluster-activo.png | Bin .../images/{firts_task => first_task}/icono_aws.png | Bin .../icono_grande_custom_reporting.png | Bin .../icono_grande_event_alerts.png | Bin .../icono_grande_export.png | Bin .../icono_grande_gestiondetags.png | Bin .../icono_grande_import.png | Bin .../icono_grande_incidencia.png | Bin .../icono_grande_inventario.png | Bin .../icono_grande_licencia.png | Bin .../icono_grande_reconserver.png | Bin .../icono_grande_registro_plugin.png | Bin .../icono_grande_servicios.png | Bin .../icono_grande_topology.png | Bin .../icono_grande_visualconsole.png | Bin .../icono_manage_agents.png | Bin .../op_workspace.menu.png | Bin .../{firts_task => first_task}/slave-mode.png | Bin pandora_console/operation/incidents/incident.php | 2 +- pandora_console/operation/servers/recon_view.php | 2 +- 43 files changed, 40 insertions(+), 40 deletions(-) rename pandora_console/general/{firts_task => first_task}/HA_cluster_builder.php (95%) rename pandora_console/general/{firts_task => first_task}/cluster_builder.php (96%) rename pandora_console/general/{firts_task => first_task}/collections.php (98%) rename pandora_console/general/{firts_task => first_task}/custom_fields.php (94%) rename pandora_console/general/{firts_task => first_task}/custom_graphs.php (94%) rename pandora_console/general/{firts_task => first_task}/fields_manager.php (94%) rename pandora_console/general/{firts_task => first_task}/incidents.php (95%) rename pandora_console/general/{firts_task => first_task}/map_builder.php (95%) rename pandora_console/general/{firts_task => first_task}/network_map.php (95%) rename pandora_console/general/{firts_task => first_task}/planned_downtime.php (94%) rename pandora_console/general/{firts_task => first_task}/recon_view.php (95%) rename pandora_console/general/{firts_task => first_task}/service_list.php (95%) rename pandora_console/general/{firts_task => first_task}/snmp_filters.php (95%) rename pandora_console/general/{firts_task => first_task}/tags.php (94%) rename pandora_console/general/{firts_task => first_task}/transactional_list.php (95%) rename pandora_console/images/{firts_task => first_task}/icono-cluster-activo.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_aws.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_custom_reporting.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_event_alerts.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_export.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_gestiondetags.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_import.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_incidencia.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_inventario.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_licencia.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_reconserver.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_registro_plugin.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_servicios.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_topology.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_grande_visualconsole.png (100%) rename pandora_console/images/{firts_task => first_task}/icono_manage_agents.png (100%) rename pandora_console/images/{firts_task => first_task}/op_workspace.menu.png (100%) rename pandora_console/images/{firts_task => first_task}/slave-mode.png (100%) diff --git a/pandora_console/extensions/plugin_registration.php b/pandora_console/extensions/plugin_registration.php index ef08e34bae..6cf20858ab 100644 --- a/pandora_console/extensions/plugin_registration.php +++ b/pandora_console/extensions/plugin_registration.php @@ -23,12 +23,12 @@ function pluginreg_extension_main() return; } - ui_require_css_file('firts_task'); + ui_require_css_file('first_task'); ui_print_page_header(__('Plugin registration'), 'images/extensions.png', false, '', true, ''); echo '
    '; - echo html_print_image('images/firts_task/icono_grande_import.png', true, ['title' => __('Plugin Registration') ]); + echo html_print_image('images/first_task/icono_grande_import.png', true, ['title' => __('Plugin Registration') ]); echo '
    '; echo '
    '; echo '

    '.__('Plugin registration').'

    '; diff --git a/pandora_console/general/firts_task/HA_cluster_builder.php b/pandora_console/general/first_task/HA_cluster_builder.php similarity index 95% rename from pandora_console/general/firts_task/HA_cluster_builder.php rename to pandora_console/general/first_task/HA_cluster_builder.php index 6d82d94ad0..7ae56a4287 100644 --- a/pandora_console/general/firts_task/HA_cluster_builder.php +++ b/pandora_console/general/first_task/HA_cluster_builder.php @@ -33,13 +33,13 @@ if (! check_acl($config['id_user'], 0, 'PM')) { exit; } -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ui_print_info_message(['no_close' => true, 'message' => __('There are no HA clusters defined yet.') ]); ?>
    - __('Clusters')]); ?> + __('Clusters')]); ?>

    diff --git a/pandora_console/general/firts_task/cluster_builder.php b/pandora_console/general/first_task/cluster_builder.php similarity index 96% rename from pandora_console/general/firts_task/cluster_builder.php rename to pandora_console/general/first_task/cluster_builder.php index ba9d8c311a..e80d4e4b15 100644 --- a/pandora_console/general/firts_task/cluster_builder.php +++ b/pandora_console/general/first_task/cluster_builder.php @@ -24,7 +24,7 @@ if (! check_acl($config['id_user'], 0, 'AR') && ! check_acl($config['id_user'], return; } -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no clusters defined yet.') ]); @@ -32,7 +32,7 @@ ui_print_info_message(['no_close' => true, 'message' => __('There are no cluster
    - __('Clusters')]); ?> + __('Clusters')]); ?>

    diff --git a/pandora_console/general/firts_task/collections.php b/pandora_console/general/first_task/collections.php similarity index 98% rename from pandora_console/general/firts_task/collections.php rename to pandora_console/general/first_task/collections.php index 8e27ce6ee3..2ca4583bb9 100755 --- a/pandora_console/general/firts_task/collections.php +++ b/pandora_console/general/first_task/collections.php @@ -13,7 +13,7 @@ // GNU General Public License for more details. global $config; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no collections defined yet.') ]); ?> diff --git a/pandora_console/general/firts_task/custom_fields.php b/pandora_console/general/first_task/custom_fields.php similarity index 94% rename from pandora_console/general/firts_task/custom_fields.php rename to pandora_console/general/first_task/custom_fields.php index 7d07ff9495..30f5b839c6 100644 --- a/pandora_console/general/firts_task/custom_fields.php +++ b/pandora_console/general/first_task/custom_fields.php @@ -13,7 +13,7 @@ // GNU General Public License for more details. global $config; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no custom fields defined yet.') ]); @@ -21,7 +21,7 @@ ui_print_info_message(['no_close' => true, 'message' => __('There are no custom
    - __('Custom Fields')]); ?> + __('Custom Fields')]); ?>

    diff --git a/pandora_console/general/firts_task/custom_graphs.php b/pandora_console/general/first_task/custom_graphs.php similarity index 94% rename from pandora_console/general/firts_task/custom_graphs.php rename to pandora_console/general/first_task/custom_graphs.php index e22187c6f5..d49001449a 100644 --- a/pandora_console/general/firts_task/custom_graphs.php +++ b/pandora_console/general/first_task/custom_graphs.php @@ -13,7 +13,7 @@ // GNU General Public License for more details. global $config; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no custom graphs defined yet.') ]); @@ -21,7 +21,7 @@ ui_print_info_message(['no_close' => true, 'message' => __('There are no custom

    - __('Custom Graphs')]); ?> + __('Custom Graphs')]); ?>

    diff --git a/pandora_console/general/firts_task/fields_manager.php b/pandora_console/general/first_task/fields_manager.php similarity index 94% rename from pandora_console/general/firts_task/fields_manager.php rename to pandora_console/general/first_task/fields_manager.php index f81de216db..2ef6e70f55 100755 --- a/pandora_console/general/firts_task/fields_manager.php +++ b/pandora_console/general/first_task/fields_manager.php @@ -13,13 +13,13 @@ // GNU General Public License for more details. global $config; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no custom fields defined yet.') ]); ?>

    - __('Fields Manager')]); ?> + __('Fields Manager')]); ?>

    diff --git a/pandora_console/general/firts_task/incidents.php b/pandora_console/general/first_task/incidents.php similarity index 95% rename from pandora_console/general/firts_task/incidents.php rename to pandora_console/general/first_task/incidents.php index daa83588e3..20630ff5e3 100644 --- a/pandora_console/general/firts_task/incidents.php +++ b/pandora_console/general/first_task/incidents.php @@ -15,7 +15,7 @@ global $config; global $incident_w; global $incident_m; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no incidents defined yet.') ]); @@ -25,7 +25,7 @@ if ($incident_w || $incident_m) {

    - __('Incidents')]); ?> + __('Incidents')]); ?>

    diff --git a/pandora_console/general/firts_task/map_builder.php b/pandora_console/general/first_task/map_builder.php similarity index 95% rename from pandora_console/general/firts_task/map_builder.php rename to pandora_console/general/first_task/map_builder.php index 352f7374e5..509f967195 100755 --- a/pandora_console/general/firts_task/map_builder.php +++ b/pandora_console/general/first_task/map_builder.php @@ -15,7 +15,7 @@ global $config; global $vconsoles_write; global $vconsoles_manage; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ui_print_info_message( [ @@ -28,7 +28,7 @@ if ($vconsoles_write || $vconsoles_manage) {

    - __('Visual Console')]); ?> + __('Visual Console')]); ?>

    diff --git a/pandora_console/general/firts_task/network_map.php b/pandora_console/general/first_task/network_map.php similarity index 95% rename from pandora_console/general/firts_task/network_map.php rename to pandora_console/general/first_task/network_map.php index 0526f936aa..f1de76c08b 100755 --- a/pandora_console/general/firts_task/network_map.php +++ b/pandora_console/general/first_task/network_map.php @@ -13,7 +13,7 @@ // GNU General Public License for more details. global $config; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no network map defined yet.') ]); @@ -23,7 +23,7 @@ $networkmap_types = networkmap_get_types($strict_user);

    - __('Network Map')]); ?> + __('Network Map')]); ?>

    diff --git a/pandora_console/general/firts_task/planned_downtime.php b/pandora_console/general/first_task/planned_downtime.php similarity index 94% rename from pandora_console/general/firts_task/planned_downtime.php rename to pandora_console/general/first_task/planned_downtime.php index 21bfb4b083..83c6cd9384 100644 --- a/pandora_console/general/firts_task/planned_downtime.php +++ b/pandora_console/general/first_task/planned_downtime.php @@ -13,13 +13,13 @@ // GNU General Public License for more details. global $config; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no planned downtime defined yet.') ]); ?>

    - __('Planned Downtime')]); ?> + __('Planned Downtime')]); ?>

    diff --git a/pandora_console/general/firts_task/recon_view.php b/pandora_console/general/first_task/recon_view.php similarity index 95% rename from pandora_console/general/firts_task/recon_view.php rename to pandora_console/general/first_task/recon_view.php index 8c59b23f64..9eee373dec 100755 --- a/pandora_console/general/firts_task/recon_view.php +++ b/pandora_console/general/first_task/recon_view.php @@ -13,13 +13,13 @@ // GNU General Public License for more details. global $config; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no discovery tasks defined yet.') ]); ?>

    - __('Discovery server')]); ?> + __('Discovery server')]); ?>

    diff --git a/pandora_console/general/firts_task/service_list.php b/pandora_console/general/first_task/service_list.php similarity index 95% rename from pandora_console/general/firts_task/service_list.php rename to pandora_console/general/first_task/service_list.php index 424bc60400..f4a56a826b 100755 --- a/pandora_console/general/firts_task/service_list.php +++ b/pandora_console/general/first_task/service_list.php @@ -15,14 +15,14 @@ global $config; global $agent_w; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no services defined yet.') ]); ?>

    - __('Services')]); ?> + __('Services')]); ?>

    diff --git a/pandora_console/general/firts_task/snmp_filters.php b/pandora_console/general/first_task/snmp_filters.php similarity index 95% rename from pandora_console/general/firts_task/snmp_filters.php rename to pandora_console/general/first_task/snmp_filters.php index 602702da69..724c9da31f 100755 --- a/pandora_console/general/firts_task/snmp_filters.php +++ b/pandora_console/general/first_task/snmp_filters.php @@ -13,13 +13,13 @@ // GNU General Public License for more details. global $config; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no SNMP filter defined yet.') ]); ?>

    - __('SNMP Filter')]); ?> + __('SNMP Filter')]); ?>

    diff --git a/pandora_console/general/firts_task/tags.php b/pandora_console/general/first_task/tags.php similarity index 94% rename from pandora_console/general/firts_task/tags.php rename to pandora_console/general/first_task/tags.php index 38c006d3b2..ea8086357c 100755 --- a/pandora_console/general/firts_task/tags.php +++ b/pandora_console/general/first_task/tags.php @@ -13,13 +13,13 @@ // GNU General Public License for more details. global $config; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no tags defined yet.') ]); ?>

    - __('Tags')]); ?> + __('Tags')]); ?>

    diff --git a/pandora_console/general/firts_task/transactional_list.php b/pandora_console/general/first_task/transactional_list.php similarity index 95% rename from pandora_console/general/firts_task/transactional_list.php rename to pandora_console/general/first_task/transactional_list.php index 6edc964ad7..40381f2da8 100644 --- a/pandora_console/general/firts_task/transactional_list.php +++ b/pandora_console/general/first_task/transactional_list.php @@ -15,7 +15,7 @@ global $config; global $networkmaps_write; global $networkmaps_manage; check_login(); -ui_require_css_file('firts_task'); +ui_require_css_file('first_task'); ?> true, 'message' => __('There are no transactions defined yet.') ]); @@ -25,7 +25,7 @@ if ($networkmaps_write || $networkmaps_manage) {

    - __('Transactions')]); ?> + __('Transactions')]); ?>

    diff --git a/pandora_console/godmode/agentes/fields_manager.php b/pandora_console/godmode/agentes/fields_manager.php index 20a9db547a..1536e5c278 100644 --- a/pandora_console/godmode/agentes/fields_manager.php +++ b/pandora_console/godmode/agentes/fields_manager.php @@ -126,7 +126,7 @@ if ($fields) { $table->size[3] = '8%'; $table->data = []; } else { - include_once $config['homedir'].'/general/firts_task/fields_manager.php'; + include_once $config['homedir'].'/general/first_task/fields_manager.php'; return; } diff --git a/pandora_console/godmode/agentes/planned_downtime.list.php b/pandora_console/godmode/agentes/planned_downtime.list.php index 01f30afba6..f116b2dcd8 100755 --- a/pandora_console/godmode/agentes/planned_downtime.list.php +++ b/pandora_console/godmode/agentes/planned_downtime.list.php @@ -352,7 +352,7 @@ if (!empty($groups)) { // No downtimes cause the user has not anyone. if (!$downtimes && !$filter_performed) { - include_once $config['homedir'].'/general/firts_task/planned_downtime.php'; + include_once $config['homedir'].'/general/first_task/planned_downtime.php'; } // No downtimes cause the user performed a search. else if (!$downtimes) { diff --git a/pandora_console/godmode/reporting/graphs.php b/pandora_console/godmode/reporting/graphs.php index e9f1aef011..155eb560db 100644 --- a/pandora_console/godmode/reporting/graphs.php +++ b/pandora_console/godmode/reporting/graphs.php @@ -337,7 +337,7 @@ $table_aux = new stdClass(); echo '

    '; } else { - include_once $config['homedir'].'/general/firts_task/custom_graphs.php'; + include_once $config['homedir'].'/general/first_task/custom_graphs.php'; } ?> diff --git a/pandora_console/godmode/reporting/map_builder.php b/pandora_console/godmode/reporting/map_builder.php index 8f5774b3a9..96f86191d7 100644 --- a/pandora_console/godmode/reporting/map_builder.php +++ b/pandora_console/godmode/reporting/map_builder.php @@ -395,7 +395,7 @@ if ($own_info['is_admin'] || $vconsoles_read) { if (!$maps && !is_metaconsole()) { $total = count(visual_map_get_user_layouts($config['id_user'], false, false, false)); if (!$total) { - include_once $config['homedir'].'/general/firts_task/map_builder.php'; + include_once $config['homedir'].'/general/first_task/map_builder.php'; } else { ui_print_info_message( [ diff --git a/pandora_console/godmode/servers/servers.build_table.php b/pandora_console/godmode/servers/servers.build_table.php index f0e2a4ad08..0006fc3e9b 100644 --- a/pandora_console/godmode/servers/servers.build_table.php +++ b/pandora_console/godmode/servers/servers.build_table.php @@ -154,7 +154,7 @@ foreach ($servers as $server) { if ($server['type'] == 'recon') { $data[8] .= ''; $data[8] .= html_print_image( - 'images/firts_task/icono_grande_reconserver.png', + 'images/first_task/icono_grande_reconserver.png', true, [ 'title' => __('Manage Discovery tasks'), diff --git a/pandora_console/godmode/tag/tag.php b/pandora_console/godmode/tag/tag.php index 680d0b7a45..cb5fb27ab1 100644 --- a/pandora_console/godmode/tag/tag.php +++ b/pandora_console/godmode/tag/tag.php @@ -304,7 +304,7 @@ if (!empty($result)) { } else if ($filter_performed) { echo $filter_form; } else { - include $config['homedir'].'/general/firts_task/tags.php'; + include $config['homedir'].'/general/first_task/tags.php'; return; } } diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index ed523d0b82..9b12f2ee36 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -145,7 +145,7 @@ class DiscoveryTaskList extends Wizard $ret2 = $this->showList(); if ($ret === false && $ret2 === false) { - include_once $config['homedir'].'/general/firts_task/recon_view.php'; + include_once $config['homedir'].'/general/first_task/recon_view.php'; } else { $form = [ 'form' => [ diff --git a/pandora_console/images/firts_task/icono-cluster-activo.png b/pandora_console/images/first_task/icono-cluster-activo.png similarity index 100% rename from pandora_console/images/firts_task/icono-cluster-activo.png rename to pandora_console/images/first_task/icono-cluster-activo.png diff --git a/pandora_console/images/firts_task/icono_aws.png b/pandora_console/images/first_task/icono_aws.png similarity index 100% rename from pandora_console/images/firts_task/icono_aws.png rename to pandora_console/images/first_task/icono_aws.png diff --git a/pandora_console/images/firts_task/icono_grande_custom_reporting.png b/pandora_console/images/first_task/icono_grande_custom_reporting.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_custom_reporting.png rename to pandora_console/images/first_task/icono_grande_custom_reporting.png diff --git a/pandora_console/images/firts_task/icono_grande_event_alerts.png b/pandora_console/images/first_task/icono_grande_event_alerts.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_event_alerts.png rename to pandora_console/images/first_task/icono_grande_event_alerts.png diff --git a/pandora_console/images/firts_task/icono_grande_export.png b/pandora_console/images/first_task/icono_grande_export.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_export.png rename to pandora_console/images/first_task/icono_grande_export.png diff --git a/pandora_console/images/firts_task/icono_grande_gestiondetags.png b/pandora_console/images/first_task/icono_grande_gestiondetags.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_gestiondetags.png rename to pandora_console/images/first_task/icono_grande_gestiondetags.png diff --git a/pandora_console/images/firts_task/icono_grande_import.png b/pandora_console/images/first_task/icono_grande_import.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_import.png rename to pandora_console/images/first_task/icono_grande_import.png diff --git a/pandora_console/images/firts_task/icono_grande_incidencia.png b/pandora_console/images/first_task/icono_grande_incidencia.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_incidencia.png rename to pandora_console/images/first_task/icono_grande_incidencia.png diff --git a/pandora_console/images/firts_task/icono_grande_inventario.png b/pandora_console/images/first_task/icono_grande_inventario.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_inventario.png rename to pandora_console/images/first_task/icono_grande_inventario.png diff --git a/pandora_console/images/firts_task/icono_grande_licencia.png b/pandora_console/images/first_task/icono_grande_licencia.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_licencia.png rename to pandora_console/images/first_task/icono_grande_licencia.png diff --git a/pandora_console/images/firts_task/icono_grande_reconserver.png b/pandora_console/images/first_task/icono_grande_reconserver.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_reconserver.png rename to pandora_console/images/first_task/icono_grande_reconserver.png diff --git a/pandora_console/images/firts_task/icono_grande_registro_plugin.png b/pandora_console/images/first_task/icono_grande_registro_plugin.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_registro_plugin.png rename to pandora_console/images/first_task/icono_grande_registro_plugin.png diff --git a/pandora_console/images/firts_task/icono_grande_servicios.png b/pandora_console/images/first_task/icono_grande_servicios.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_servicios.png rename to pandora_console/images/first_task/icono_grande_servicios.png diff --git a/pandora_console/images/firts_task/icono_grande_topology.png b/pandora_console/images/first_task/icono_grande_topology.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_topology.png rename to pandora_console/images/first_task/icono_grande_topology.png diff --git a/pandora_console/images/firts_task/icono_grande_visualconsole.png b/pandora_console/images/first_task/icono_grande_visualconsole.png similarity index 100% rename from pandora_console/images/firts_task/icono_grande_visualconsole.png rename to pandora_console/images/first_task/icono_grande_visualconsole.png diff --git a/pandora_console/images/firts_task/icono_manage_agents.png b/pandora_console/images/first_task/icono_manage_agents.png similarity index 100% rename from pandora_console/images/firts_task/icono_manage_agents.png rename to pandora_console/images/first_task/icono_manage_agents.png diff --git a/pandora_console/images/firts_task/op_workspace.menu.png b/pandora_console/images/first_task/op_workspace.menu.png similarity index 100% rename from pandora_console/images/firts_task/op_workspace.menu.png rename to pandora_console/images/first_task/op_workspace.menu.png diff --git a/pandora_console/images/firts_task/slave-mode.png b/pandora_console/images/first_task/slave-mode.png similarity index 100% rename from pandora_console/images/firts_task/slave-mode.png rename to pandora_console/images/first_task/slave-mode.png diff --git a/pandora_console/operation/incidents/incident.php b/pandora_console/operation/incidents/incident.php index 5057b4d281..62e2f33fee 100755 --- a/pandora_console/operation/incidents/incident.php +++ b/pandora_console/operation/incidents/incident.php @@ -372,7 +372,7 @@ if ($count_total >= 1) { } if ($count_total < 1) { - include_once $config['homedir'].'/general/firts_task/incidents.php'; + include_once $config['homedir'].'/general/first_task/incidents.php'; } else { // TOTAL incidents $url = 'index.php?sec=workspace&sec2=operation/incidents/incident'; diff --git a/pandora_console/operation/servers/recon_view.php b/pandora_console/operation/servers/recon_view.php index 5401f6e307..facf494179 100644 --- a/pandora_console/operation/servers/recon_view.php +++ b/pandora_console/operation/servers/recon_view.php @@ -36,7 +36,7 @@ if ($servers === false) { $recon_task = db_get_all_rows_sql('SELECT * FROM trecon_task'); if ($recon_task === false) { ui_print_page_header(__('Recon View'), 'images/op_recon.png', false, '', false); - include_once $config['homedir'].'/general/firts_task/recon_view.php'; + include_once $config['homedir'].'/general/first_task/recon_view.php'; return; } else { include_once $config['homedir'].'/include/functions_graph.php'; From 672ce6db22ff055802e6a673904866f8944ae22f Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 13 Nov 2019 15:24:44 +0100 Subject: [PATCH 36/66] first task omnishell and minor style checks --- .../general/first_task/omnishell.php | 56 ++++++++++++++++++ .../images/first_task/omnishell.png | Bin 0 -> 54739 bytes .../styles/{firts_task.css => first_task.css} | 9 ++- 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 pandora_console/general/first_task/omnishell.php create mode 100644 pandora_console/images/first_task/omnishell.png rename pandora_console/include/styles/{firts_task.css => first_task.css} (88%) diff --git a/pandora_console/general/first_task/omnishell.php b/pandora_console/general/first_task/omnishell.php new file mode 100644 index 0000000000..948204917c --- /dev/null +++ b/pandora_console/general/first_task/omnishell.php @@ -0,0 +1,56 @@ + + true, 'message' => __('There is no command defined yet.') ]); ?> + +
    +
    + __('Omnishell')]); ?> +
    +
    +

    + '.__( + 'Omnishell is an enterprise feature which allows you to execute a structured command along any agent in your %s. The only requirement is to have remote configuration enabled in your agent.', + io_safe_output(get_product_name()) + ).'

    '; + + echo '

    '.__( + 'You can execute any command on as many agents you need, and check the execution on all of them using the Omnishell Command View' + ).'

    '; + ?> +

    + +
    + +
    + +
    +
    diff --git a/pandora_console/images/first_task/omnishell.png b/pandora_console/images/first_task/omnishell.png new file mode 100644 index 0000000000000000000000000000000000000000..93dffe3918c7f8e5f72aecfa9b9814d31971eac1 GIT binary patch literal 54739 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 iUMJQN)TY9pG(&_^18Fc;6Pvw|DA*N1 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уE8MEU}sO9SoGdx4DjA~Vl0v0 zI6?5fNw(KjVK(n8n$&@+GNEdL5TlTJcif2y+v6i`34bXXA)MA{D?ANyXRU5bN&o)w zn)Mi0(Vs36RW?I|fsAb~s?17}<~EV%-k#8tYYI7`?H;!*M!K{+MvEhBlSHT&01XHQwgtn z$2eKwg*xJQtt@X**zBOFao_lpeu>fQSo+d2ig&YZxA>1OzlK=nXadDggmAQf`4R>( zc2dD8rU13ahJ(vYG4sM3OfOJ=Q#NbuDm`@ZW6gyU zn)sOXuQ>iiRb+U)egF1c#9~YAO$?;_-u0{cH>P;)h^=9Bjpe|O=#LQcfZW2uCba19 zB=!D{;}r|Y%X5K9I?OC{(U?}DvD(VqT>drSEn~O)trvh?rR{cJjY>E#!dRIb+^CM9 z5vu+It{RXA!-zy-9txDGTwv+Edhz8XM5N5%RgkdDa0)eRF$dPksmja`(4Vp#ix+e_a(xo& zrR8LB?-=B(2HTpGKhS#49&(!x6I z+3MuxAc5QksnQ&XM_=Ck)0X?&Gv$tfFTSo?C6n-;K^B7Dw$H6y+~Q3`mV&2pB4&G734!P?uWwM7 z2~KQ;&bVR79zxDYyr7Qilc*VcT|GTQUA6A-Dc=F>r^obz*<_gQol^EHb}cL{5MpSa zxQj-HVUUdv4Q0lc>|)q@d*3xVZnck9*G3tD5uz(ZFpSX1Z#a{RDO;71qVe0jn`2|X zMFP&9AC)&apr)4Oq*vp7`F+aN+?+*T4rmy1ax|^1z>@@%5|14_MntTahqH<#7ag4$Ja_7a|O$mOrmWSK$EyC1zj;h)0%yS;H= z1$4B}pYet|BBuwZ6aZl$$uf&WBT8n^OQ0|UUIN813$Rg4PyH>H1wS|!u6>puc<^f+ zS!or=9-r$@;W&`B-|(33f`>!Rr|#|u)Jh!1NhMpiZbg<)>qu9r`F_k*rkqxmmW^Nu zdvr66^XI^$7PHL{^KNnyktl)S-G>;#X?68H~xNlEq{6 zrH_r-bH-?8GieN_%JoRC4_eF%H+1&$ikGR%bQX)zJ@Z*e9?@f)j=GnS5Cn#ulb$L= zfCKhCOpwS6fd+@#M5(~|CIVeh)qIzQ3Qmi>(~ueJ*NGCXFuI?Z_|}?n)8<%02+$C$ zWC5_)K@mmdWIw?YP?y$3GH9*sAF2%Zk3|_3d-K%Y8RUq3s`yaljuJ_00LOaLXXwfUW1gRChC%{!L=M%GRtRp z4*c$~=C$&fd+R`odEjX+A8_E)jj!Ww%LuHXG|e`AB5x#O^b-r7a!gZ@n47USP;VQh zm)p2Gfp#EppfPj%KDT{ddWYV*hTI+mRNN^-H<}q27bgHEF;AR!0AbpKP3FYWv~Wx4 zr0~8_FQBAAH!-5cIqiIO#nG`$zV3OO^Go%@uY?V3!A^Onp65W80%t`s%Gt5Uh9QNd zwvQhXx3nAWKGqB>R8gUEz5vDFs+9@RZ0a2w$pna6YhB}b*2}RD2ML+?Eq&fw2A=0= z4ofCb@i2<6B4usS+eV5jbn9sv5A+cwW; ztqbGOX9Lk;p%p!N+{M{h3y4t5U5zv5mX=xwV`;x7FlC6!hM6xzK)YfNfm#}aZu0%7 z^1Ip$BvR6}zHJ+(Yb-84h}{8JL?^rQkfqFVyho5Uz;!ROOZKb&`R9W}@ z<@tGvOfC=Z>@^9tTlnLXan{T%l8`Pdc!&or>4|m^GDJ(sq^6{(U%V*9<2|-p#@(n3 z;bI7D&~|Z=*jVr1+y!0H2_;eFd0~zLLXBXKqVH2qWk!Wxkuww*ItS!1sdLf$NJ|f% zMBSbJqN2x}d!+16JvseB{0&CVf0u8EuzST_cXPw(oAA?3CxK}1>t2bqv~}3u{$f8q zes;X6+QP(SH16ij^C9YSO{}cYlmC2hmuhlyQdtpc5WpH>iO08r>@k0AjKJ7kr7mlJ z{$~&>^x07wi9$N+>)^Az7MASHHjK`nf0QC`&z2UY*cn)}Cb~Q~X z#(`9G{tVj;LOWr)Xkl(Hq9RlG)8=C!sp_Tb-VUxlE`tpH^fzy~fRH$rnFpx<&*c-+ z>l}`zO#UjQVn=m!YI!%8wL`TYdBxF|CVsus<#@eZtmV6rNSE4jib;MK&_w378%k|| zL|-HbX5cSVdMH7jgf{kw)6yeML4~rhmK+hH_55!1xhTu0TZ)YM>PF z>mD9-@vY~c7fCvonNv15{%O?K*4|;elb82md;aU!W_$(|!Kzf1&nzoN;)U^ic6iyi zyZ_Ahbu3WIaIz8ReFr(|H}KHj9?G z&sn7BK?u#Qj9kbK9O+Zv-cHBkNXb5>c2fK&eVVLZ{M6=X_eU$}vL zYrPH|4n1;jX4@?_w>kXC28@!e_pwD?BE3NF#E^+c?&-Y6)A0~)sSC5s&k9B%@8&Un zry#3-A^$zjeet_DJ%=R*Zj|qT-zu@4oqauNv=C7XsA8K^0b0&0NetFcaR8uPp`Rpb zB2M$uA`0xZn*Vp2Q{Ka2IX_=as-!M9I2mmIj-m$&(0lpAO}zeMb;Z!6Qwc0DTCZ5= zezJ(k`M4BA85tBxnQhphPB_!Et+_vL?hREpOENjap;R-F@#+1Xv5!xM=o+`Qm1iy+ zJr!)9D)RdVXYPx5Ov|&`NZ;hII4&bA`;u#1P4!{d`)MzY*gf0aAGUGK{p)N+915RG zA#hGKlnHy8{hEGWeZFsZwNyq{L6kO+7X=Y6g}5VEAQHtdcJ-?QYN&$(%1m!`*DCOV z{}z@P3*|{m0{jK}zr%L;vcSiO$`WWAeul=zG7tme{OUSpm8-hCF_Lz}te_aJR$uv{_am9UU8cFpM&E4iuWr zYj_!Sd+cqSZ*xQl$Vy97mh^~)z)6Giz8M{k>u*sBi6#>(-$lAI^K}spr6nv*zx#LZ zYIkNbRQF4`ej_3XY3Uk#I$O^Aa;U<9_u z1*uUJOD{?gH}9)ASF4-Q#=#sQPCt>8oo)Tx)OGaZu8d*L;J<)Z&H|%s?jeK;$Q8st z6irG9cKq=p8ob%qqWA8Lqh@*Ms&|JWka%&y0p4ZG?qu{!}}L$se%c!2T~(2zzT44y1?6jfCDtJbQbT+ zJ!Z~R1%tq|IgIdtJctm2Yu8HR!;q9j!o#h!Y&+wDOou`EB|z|o zinaW1$rhi$aR@o7sxY*l7EmrBWllv{5$QqjnYD?SRV|<$(ndz7#3%}>pw2SVDDU0i z4L$3vhQNjPTgQ(cwcaTb!sIz-boOjCpfmn``*Z@F0PBHALh|TMQz2+KgNYg3!?OyH zDHk8T=3_yfZpgx6ghxIh#Sa&m6ayn8%KR=`G?24>x_em(s~aE(SYlKo`9b$w?j^eP zc-{Q2VkREH7!Awx#NA5DtT|{iX$P@TpSv9$kLnlgh8+h3{*heZqA~Ei0D0kur5ueH zJ|kdx>R^`d9NU8`{v0|UEZ6@=z#XT1!gK2Q>}%Fw=(0Tw#402QIImH2+1izr;v)|JPG z|2FXEcPwymaSgrQvSY#V@@4ir!uX^*P#qwZhFk|ZTohTckGmYN;JFdOs@1E#GaKgD zpCR4~gFl?_HlFwW^JZR;@}PItR4K%AC1gW@Cx3|Tg8d(xt^s)#OpP?fZyOuWd3u^s z4^#Bic@C@T3E5O7PW<5@Sw5}*xd zelnKtjGLPjM)wd&y;CnR!vPMZv3bD3NIx3WDGteg1BaE*?wW(4Y8^D`SAiWclZWF) zBK;w}evm1hJ@93+mr9zYo@qnQqE9mSq-CThrMmgquG7|#^~&X~%|J0*xS#4C1Ingr8#Mxp2cLKQu-{ttFS| zfKNOX@micn8voF8#7$7Ie=KS^DT0cNEh zqTAx);)J&Y9V)?i*t{_Us#j?l2QUpmc(JN7BDOFC!6FhG%k7c`HHv1iongow-n+e~z8E>XDmk5l_<2N9n5nj2f*?*>V!2__3@BW! z7~4fN#bhgR+v3d*ujV9ZJRwL#F+8ZZ6J!BoJOE43>HzN^9`3TXgO~d}{pG%j`(1+a zsSH3(h@4a`ca{rmiBP5zRTpobtau8i1K5b=@ss|vT`2v~Qr)wXn`?yd94OuvgjPaH z1MCM?EU5&sa=}g@h7Whi%F1>oi~phMM}QmMuwrD8npo(SGz}c$rXOL!Adf`0=5ATp zyV>>%LA3*WKZ?%}L$p5GQ*!ZufTdI# zCs&o>Kcde$YLbXOff?Z3Ikf;MFbRkYYe$rbY~;P&I-g#l)Axs+ir)J$H-pTC+v~Hr z1qF8Pmpnc1slFhBGP{ccL$3r8WfQ}76D+86Im+ua{eG)cOPVR)ry7w*^BkZhLJ9{E zA#H2(W6J%|S1*Ki+8A8es(Fxg>K!`D_DHOf1 zrO;j&hkJ^kzY#Ng?i|0kRn>_}Wd)K`=CeetNB_DpsO>xPDLor4I8GaQC$}m~@}E#X zc#uD$&lg}Sk~4{n@38Rjp2LR5B3NT^V1d23Pf|)fgN!aBXzJ6ay1Hc`y(n8)t7L#k zfirBYk}Z4uSrTbr{QyL^Q)i*g!ZCnsU*rHib&Y+%Py1hvSg54lg)OiqE&ob!xpyHy z!Gs>Ugg~*?E|e#EJi#C!rK>XrRE`rfg11 zP2C1i3fPtFydM-iXF|7)zF_r2iVR)Y0%l35cY((c=h#s;$Q|$x2t;jf?>8hX>`A;2 zB7=_TJAP8fXl(&laAj8rPlcrmg+K(qX04eba zMalj9bpxD4U)U1Gcs`dt30(Vm;+J0krLx+})Ex zm*By*nRx3l;@JmCF<&JU8MI6bjhGg}HP8(s_Gmlb&O%w|k{-|I7kKWMhnnelO-xMA zBp%yy=D=T1MRblqDw*ID>Af+_>kd@nv`z2Cm zgF3MD`U<`xR7^TynIYNmN%Y zzu#Sm@ap&2>X_rn4npT}&e=IOl#Ykkqv$Ah%gZP4Bl|OYv@PUi-9UZ^jP=x2uj>b` z&rZ9R3(>wsS8v*L{q@-o=`v4Sa{hW(eh~95o8;Sd*Y&3GirHhs9dkFZz;U2K{6;RM z#6(RbQc?v6j(_-5;Q`*@VAZy-L5zn|Ijj$uoiA|Tb^3mxySRu*lvn7VaD-ul$4>u& zJSJQ>FpE19iWJL`+Cl995BCqjvVQ(OrCSpV<%{(609BbZ**=W>@xr;mUyx3j(z;hg zrcdn10}WN`QuLvSa5}rPGR51(_OnTzqWVyiC+*{Iub`#IbaDkn zN>wpF{ce}zTX@PbFg9G3ue?h%tmrog)=0LoKIMh%VK#&ys6Psb%Nk7QI=^Wt;S z(Ld!WluwgZp)%+Tn?J^Xf<#n8vOS6yxV*?rd>v$2%yn|1OX%&PdpkH~IMLj3N?onY zuiBqC;ABL@tAmW3P=RkFX+06po-$L4KIO^F&8^|?{(`9yfAY00{EA^Fk>7~K5W3+C zPdBWel3>I{up1o1v@sMtYktc3Xi-l@-Tds2 zgq3~+TpMx?id<-r>d-)jd{)V0#sS0}qLb3vnA?GqfB$8JzhtwaY8hHFT8~U$Ul0h` zO2!Q?C=Hkx6e6_^4Iv~(lg1q4*AP11Zsc#iAjP$VCL}!8R#DqZMzsmS#Xw9Uh*Wvh zF)&$JeF5(w3OyM#3|;KgtvpqVka))7RlQL< z>{E;0L=_s9U5J^L!lNTbWDFJLwg`b!gDR_Pbz0$nY$EcAp`J$Di6FIeUvtR=h}aAW zhL?M1{K5f*VTob*P`JsG~Xk>%c%d zsRtsw?v;~ZS<5p#o2tO&TU%QPsJ_4kVSrXPpv$pRxTRQ`jkdQbvTw&8ofQ|10scF7 z?Mk&m*e4)n(Qi$r=As3KNkBZf@y0Iokhw2=`AAx)A8mVv$ln zkSN3@A^#ycY8gzHUO(B9(@IUbRhkC}>tPGXXl!jY0xa)zqQp4&zS*N9@qXN|S{VS~ zjKyQaf{E_C*wL8CY$i10W7dux9$VZSfJ`>StKB{be-G#YA%``H7(~L-8$==3c7st! z;wel!n8{(&X0Dh6^@$3qpTRj@bM&;0v&v(Vt7bx$qu#xlhorT84~sjzWf&`kbCA_U zRtfAAI<)$|iEE#R%4e#GAa3DzVlfiK4w_*P=Ig?zLqzLen@TyMXJ8(M?B)EKuoefb zYzS>&C@T3DsH~kuwy`9r!}9EwLLb$va-G^> zueFY!x*J~Ew@%7?9T>T_M&e)Fy)Q8s8~vDV$|g-)|HXT{<{?oReF+_i!Oe|ZRvoT$ ztLwgG+b;6TVkR0{F%w)X)}qL{Dy^eF)(cVaKdYItt8_pSRW z563)|yP`JMeCs^#5d$CXk4`f1|GXg0ZY3w%U4i)qB-^?|T$2E79^3l>8B@#$^*UcX z$$VJy6Q3XxH8n%@XH|i%S`*CxTv0WgowwI11o(fom%9HTw+%$zt6`{~0sh$8RDf38 z@f&%i+xIBQ%bT{`aesfw(Gf>`JMKaNaq_=75LCsX*}-}Or3cMiUtL!m&g;iX6-JWE zLJdNSh>9A@_^gTX!hvqt!7l74SSZo7U2V~Z5gpF1+{x7a*_=kq#R%&WYRh1G> zO(;r`N)1*Yy(Sd7%nZ>DQBU&nSon4x@OOBn;eQg)^0Q|Qc*#zl^}Jcd8PKA~o&}Zw zoD&zsM8ewTx>XC05K%1<+nWYBp=`k&fb<|`Kg_p9UG|BBI)vl{+UG03yAPn5<_F4$ z3>*ZGie2<@bCaZL#=HaghpKXAb(OLigs|yHo?W}x`Oct|4z>gsi(euJoNgGi5ZWCPmDE6izLzjox_@b->}I3xPBa5TbPL1yveEnlhH7Y&mw z`gh_p1&RM#7n0|sLJ$oh5Bby`KDcbY{-iJ)IA{@5w@rT3a>gLqlOlt#I1gBH1+Rfdk>Dl{$2bF0?>oSrp|;G_-J0*QSCsU6X*Cg5=(WxG&@2<$c~3mWg3xHzOKMZXJm`BqAUGlO7-(AT0M zBa{vO|J+1=p<03Q@axgERZ%g8t0UBqk`mTbWPI)R`SSTQalsYf0I1A3a!ZIr>{{yp zXq7_gIJ)@+MMP*JPzvmyAqLL!qnRfz_Y{W~u=xM`dDrR2IjCbGU$a|I@F0{VZ;9uV zsuzyKCWH1F@_gaNfB||H40yPKQg`D{54>PWdeOU%nzt$rqR;Nl9q61(ywPvo?MaGzyGzB z=OE=vtw&cF>FHmQy|O~@`||C%D=o#pH#*|{M!t-@Ip=px=;`WSuZAOf8b#9M*s-Y9 zaOJg(@8fQ7Agbuajcu;g3!jcVlcu4&E$4-@#lyqnW!vQ95X2f9m=p<_4{`GdzS7!v ziO6S$?qRu}cO&5P_ZLKr_xKF)E{N;ups|XDs+y38F7owx4sR1?qb)5f8+6(H>w>YT zqpNFionr%T?E$!jmYe+7w0}*k5}CQEeT>R$lEjaCpybPiR)rV~aXB9@pMim37E~>f z5eKI>3}jmwcod1Dnz-9y?~i1iuzyeA7Ht`R;l^a@u9z2`MvpII_oLq>61MxNM)SUj3zPmyj*^d*@3 zoG22P5le%JC?P-G#;IM=hcqEcU@W)?YyZ%XHow1zh*y div { .image_task { width: 20%; + min-width: 175px; height: 100%; float: left; } @@ -47,7 +54,7 @@ div.new_task_cluster > div { .text_task { width: 70%; - float: right; + float: left; height: 100%; padding-right: 25px; } From 670df456f59cb7c049bd97b9715f4227dd888d2a Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 13 Nov 2019 16:39:24 +0100 Subject: [PATCH 37/66] wip results omnishell --- pandora_console/include/styles/omnishell.css | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css index 8a572388d4..8dab89fd8b 100644 --- a/pandora_console/include/styles/omnishell.css +++ b/pandora_console/include/styles/omnishell.css @@ -40,18 +40,27 @@ .container-msg-target-modal p { font-family: "lato-lighter", "Open Sans", sans-serif; - text-align: center; margin-bottom: 20px; + font-size: 10pt; +} + +span.failed { + color: red; + font-weight: bolder; +} + +span.success { + color: green; font-weight: bolder; } .container-msg-target-modal pre { - font-family: "lato-lighter", "Open Sans", sans-serif; - padding: 15px; + font-family: monospace; + padding: 1em; white-space: pre-wrap; - background-color: #f2f6f7; - border: 3px dashed grey; - border-radius: 10px; + background-color: #222; + color: #fff; + font-size: 1.2em; } ul.wizard li > textarea { From 78443a029d75dfb11135887c34f47a07f2e18656 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Wed, 13 Nov 2019 18:10:16 +0100 Subject: [PATCH 38/66] Omnishell rc1 --- pandora_agents/unix/pandora_agent | 53 ++++++++++++++---- .../images/first_task/omnishell.png | Bin 54739 -> 3129 bytes pandora_console/include/styles/omnishell.css | 15 +++-- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 63cd9e8374..0dfcf8848a 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -24,6 +24,7 @@ Version 6.0 use strict; use warnings; +use Scalar::Util qw(looks_like_number); use POSIX qw(strftime floor); use Sys::Hostname; use File::Basename; @@ -1523,29 +1524,56 @@ sub report_command { print $R_FILE $err_level; close($R_FILE); + + $return->{'stdout'} = '' unless defined ($return->{'stdout'}); + $return->{'stderr'} = '' unless defined ($return->{'stderr'}); + return $return; } +################################################################################ +# Executes a command using defined timeout. +################################################################################ +sub execute_command_timeout { + my ($command, $timeout) = @_; + + if (!looks_like_number($timeout)) { + `$command`; + } else { + `$command`; + } + + return $?>>8; +} + ################################################################################ # Executes a block of commands, returns error level, leaves output in # redirection set by $std_files. E.g: # $std_files = ' >> /tmp/stdout 2>> /tmp/stderr ################################################################################ sub execute_command_block { - my ($commands, $std_files) = @_; + my ($commands, $std_files, $timeout) = @_; - my $err_level; + return 0 unless defined($commands); + + my $err_level = 0; $std_files = '' unless defined ($std_files); if (ref($commands) ne "ARRAY") { - `($commands) $std_files`; - print "($commands) $std_files\n"; - $err_level = $?>>8; + return 0 if $commands eq ''; + $err_level = execute_command_timeout( + "($commands) $std_files", + $timeout + ); + } else { foreach my $comm (@{$commands}) { - `($comm) $std_files`; - print $comm. '=> ' . ($?>>8)."\n"; - $err_level = $?>>8; + next unless defined($comm); + $err_level = execute_command_timeout( + "($comm) $std_files", + $timeout + ); + last unless ($err_level == 0); } } @@ -1576,7 +1604,8 @@ sub evaluate_command { $err_level = execute_command_block( $cmd->{'preconditions'}, - $std_files + $std_files, + $cmd->{'timeout'} ); # Precondition not satisfied. @@ -1585,7 +1614,8 @@ sub evaluate_command { # Main run. $err_level = execute_command_block( $cmd->{'script'}, - $std_files + $std_files, + $cmd->{'timeout'} ); # Script not success. @@ -1594,7 +1624,8 @@ sub evaluate_command { # Check postconditions $err_level = execute_command_block( $cmd->{'postconditions'}, - $std_files + $std_files, + $cmd->{'timeout'} ); # Return results. diff --git a/pandora_console/images/first_task/omnishell.png b/pandora_console/images/first_task/omnishell.png index 93dffe3918c7f8e5f72aecfa9b9814d31971eac1..8724d322fb21ecbccfb69ac82b9e07ceb73725ba 100644 GIT binary patch literal 3129 zcmV-9494?`P)e92`3<&060O&2||{$g6#jPFf|8={}VjF6TDx|v=T+MEE(HahVCkg z1S~Mpr|wp(-4=p{g@uKMg@uKMg@xr1X*K-^{Px@Lv3$Cbj|g8%<>UFUzy7;Cusz7L zd@SW>q#o_N*uHy6dxoJL2s-lVK|cDHL$>lUk^{2M_zY-2w7i|j$H38kCZFysZ>RYE zD~6$Z7}oMBb{qx+a!Jil2MBum9tDI01YNGOfC@?44FzH70RjkUkD0|Z3=6dHdV&D* z)Rca0H&ij)60d=eFvr=f%MeY9Px~p+K9=nx4-fSeXPb7Y&7BWjKJK_TS_{q(;182M(bv zHpYN;v3+9E0wz4qhN+1h?Ki9$s*{C9^+%q^E(qNHP=v2Rmj693B&xfLe1dls(lw$n*6}NKh z7RuRsutXEf27%H-tC~T8@p%&;`5rMo!&tr9`lappgX4_D?l3o?P8nF1c$EO*0AW<8 zwnPxtVt@ZdNypYNF3m9Uw75({XNS-0T80-KvfBX{A`FzTo>#=%9%~Tw-ft$o*f+Dxq6}Hp>D_@ zj3+;-fNX23Sycn(6LhK=1fLYVL;La)CkmYZs{zC=596SvrSXF|6{)#hryrUfRE5cC zCO%y2NSF|}&j4x~^8-2- zzrgGq==kRXC;rX&Oa(-*0v{q0`4Uc|BZ2@n{KtVG`$c?C)Kz`B#XhiRc=Cl2~IxGi)Y*{G&9)0KN1{$Qq%j1fTX+hK4}RFju~fgrJLY64x3Z zV3?90N zBKt~cwTZI;Q$T1HFe`dS*A%gAnv;;(%3#DGLOl?*IV?X)Fgf)doL8HUCwM ztLXbQGYsrZ@wiUYL1?6A$e|&AK^PzxFtTU^a0)jX1hM$Y?gCBmf&)Dv2D}Gt9onHW zAmq{vxb53FW=d@p%`^=`rRKdL2we*ZTO3SX8|Z@yfIKQt
    $OFUNDMjDauDx{K+z`<(7Ci#je9pC1}r;~uLr4FF&^?@(V7Wrti7eN&qmeS z;UrB0$d0zjHMI=YHG;@4A2<{r38s7Xp3tm>2ttZLEby2ap%uo29}Zv^rw!$+8x zl^tF34C!D35j8h9r5JswePpJ2jIHYpRNtFJxfY8;~*%)McDhR|51TD_e7X_{u4^7%9 z41)5e;X>OE?m%W00d@MK8VL8|Bafl+7x$bT3>ogwSW2Bs&8W61`f>3qInxklhoIor}{1eU5a1kVmH~wo#=yv(JUJj*HGxp1h!rJ;!s58ZeDWEDQwE|{0|-HF zb)#u`GX_xIn{w}Fsw(*80OD4ZoA5$yoRtnl>zqNbXa(>OMtH4+In#GJ5j8BKZ5pRk zAll~)f;Q_uou@Jd7`|Q_OWC7~R$`p!np&4Y7s4m_5yE*L1Bf<*&>X26 zh&F@3KpX@E-l8bRM~6W;Eg;&S5X4xr<~w?|yT9dYuMEQJ0CC{~0u1(przg%J92p3$ zicNNT3y67GY6oJFqsg6lN1iOrVDkqOc!>Q<>>VDG+9jeiHfjxO z8-AF}f#d;iGz^J$ce)Kx9sk-F2HVZPrU->;a}pkl;3Ua2Mp>8Sr`o05y6Ld(`>)QS zcd-tXZbG4S(Gqt#Ri@N8V^Tro*~ImJ1*Z$~p&>Z-xH9Z#O?cO8!uMj6l<*-=RrH&~ z$EYFSu%z%C{;$8kyMa7bi+Q!Y|EATAC?YG1HvcK;E$|m_7|=s?-2h8v0;l49MVZa4 zn~_gM_7?a9=2jG4QTS@;jhR8-_V@y50GFgK4JbgZLHgR|sa$xP(-vSkJu;MU2-=-|AD%Q=RH@_@;>zCl~$ov-{^zdQ~e^fAB-}} zLqc1@q#je6yv<{q--lFx;DDOfMohI#sa;_V;7!dL2!00ejZnMKz}eA%{IkTOoKelE!leONSXcs-{|hhx%Xv^( Tj(pQf00000NkvXXu0mjfv>2@* literal 54739 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 iUMJQN)TY9pG(&_^18Fc;6Pvw|DA*N1 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уE8MEU}sO9SoGdx4DjA~Vl0v0 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 textarea { From a8b6f40ca1a5c7177dcff9de2047efa922f51187 Mon Sep 17 00:00:00 2001 From: marcos Date: Thu, 14 Nov 2019 10:51:00 +0100 Subject: [PATCH 39/66] change sap view menu position --- pandora_console/godmode/menu.php | 1 - pandora_console/operation/menu.php | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 062df046b2..edf7be1873 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -56,7 +56,6 @@ if (check_acl($config['id_user'], 0, 'AR') enterprise_hook('applications_menu'); enterprise_hook('cloud_menu'); enterprise_hook('console_task_menu'); - enterprise_hook('SAP_view'); } // Add to menu. diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index 58213ed8ee..dfa52551fc 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -155,6 +155,8 @@ if (!empty($sub2)) { enterprise_hook('cluster_menu'); enterprise_hook('aws_menu'); +enterprise_hook('SAP_view'); + if (!empty($sub)) { $menu_operation['estado']['text'] = __('Monitoring'); From 17f324ef8ddddc008dc95c8ad491b75566029df9 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 14 Nov 2019 17:04:47 +0100 Subject: [PATCH 40/66] Agent remote cmd fixes --- pandora_agents/unix/pandora_agent | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 0dfcf8848a..b1aeb52f03 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -979,6 +979,9 @@ sub read_config (;$) { $Conf{'secondary_server_opts'} = '-x \'' . $Conf{'secondary_server_pwd'} . '\' ' . $Conf{'secondary_server_opts'} if ($Conf{'secondary_server_pwd'} ne ''); $Conf{'secondary_server_opts'} = '-c ' . $Conf{'secondary_server_opts'} if ($Conf{'secondary_server_ssl'} eq '1'); } + + # Check remote commands + prepare_commands(); } ################################################################################# @@ -1421,7 +1424,7 @@ sub check_collections () { ################################################################################ # Check for remote commands defined. ################################################################################ -sub prepare_remote_commands { +sub prepare_commands { if ($YAML == 0) { log_message( 'error', @@ -3272,21 +3275,25 @@ while (1) { check_collections () unless ($Conf{'debug'} eq '1'); if ($Conf{'debug'} ne '1') { - # Check remote commands - prepare_remote_commands (); - - # Cleanup old .rcmd.done files. - my %registered = map { $_.'.rcmd.done' => 1 } keys %{$Conf{'commands'}}; + # Cleanup old .rcmd and .rcmd.done files. + my %registered = map { $_.'.rcmd' => 1 } keys %{$Conf{'commands'}}; if(opendir(my $dir, $ConfDir.'/commands/')) { while (my $item = readdir($dir)) { # Skip other files. - next if ($item !~ /\.rcmd\.done$/); - + next if ($item !~ /\.rcmd$/); # Clean .rcmd.done file if its command is not referenced in conf. if (!defined($registered{$item})) { - unlink ($item); + if (-e $item) { + unlink ($item); + } + if (-e $item.'.done') { + unlink ($item.'.done'); + } } } + + # Close dir. + closedir($dir); } } From 14128590d67e943b0abc1701be0745993c581ace Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 14 Nov 2019 17:05:01 +0100 Subject: [PATCH 41/66] Minor corrections&fixes --- pandora_console/include/class/HelpFeedBack.class.php | 4 ++-- pandora_console/operation/search_agents.php | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/class/HelpFeedBack.class.php b/pandora_console/include/class/HelpFeedBack.class.php index 825d3c923f..fbee53e0b7 100644 --- a/pandora_console/include/class/HelpFeedBack.class.php +++ b/pandora_console/include/class/HelpFeedBack.class.php @@ -143,7 +143,7 @@ class HelpFeedBack extends Wizard 'block_content' => [ [ 'arguments' => [ - 'label' => __('Sugesstion'), + 'label' => __('Suggestion'), 'type' => 'radio_button', 'attributes' => 'class="btn"', 'name' => 'suggestion', @@ -154,7 +154,7 @@ class HelpFeedBack extends Wizard ], [ 'arguments' => [ - 'label' => __('Something is not quite right'), + 'label' => __('Something is wrong'), 'type' => 'radio_button', 'attributes' => 'class="btn"', 'name' => 'report', diff --git a/pandora_console/operation/search_agents.php b/pandora_console/operation/search_agents.php index 7edd7be878..05383df31a 100755 --- a/pandora_console/operation/search_agents.php +++ b/pandora_console/operation/search_agents.php @@ -30,6 +30,7 @@ if (!$agents || !$searchAgents) { echo "
    ".__('Zero results found')."
    \n"; } } else { + $table = new StdClass(); $table->cellpadding = 4; $table->cellspacing = 4; $table->width = '98%'; From 0d3817d64d97a49b01b5e2b139d7fbb05415d38a Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 14 Nov 2019 17:45:45 +0100 Subject: [PATCH 42/66] dynamic toggle in wizard input printForm --- pandora_console/extensions/quick_shell.php | 44 +++++++++++-------- .../godmode/wizards/Wizard.main.php | 30 +++++++++++-- pandora_console/include/functions_ui.php | 17 +++++-- pandora_console/include/styles/pandora.css | 4 ++ 4 files changed, 70 insertions(+), 25 deletions(-) diff --git a/pandora_console/extensions/quick_shell.php b/pandora_console/extensions/quick_shell.php index 13924f56e2..a286ce4b95 100644 --- a/pandora_console/extensions/quick_shell.php +++ b/pandora_console/extensions/quick_shell.php @@ -442,25 +442,31 @@ function quickShellSettings() ], ], [ - 'label' => __('Gotty user').ui_print_help_tip( - __('Optional, set a user to access gotty service'), - true - ), - 'arguments' => [ - 'type' => 'text', - 'name' => 'gotty_user', - 'value' => $config['gotty_user'], - ], - ], - [ - 'label' => __('Gotty password').ui_print_help_tip( - __('Optional, set a password to access gotty service'), - true - ), - 'arguments' => [ - 'type' => 'password', - 'name' => 'gotty_pass', - 'value' => io_output_password($config['gotty_pass']), + 'toggle' => true, + 'toggle_name' => 'Advanced', + 'block_content' => [ + [ + 'label' => __('Gotty user').ui_print_help_tip( + __('Optional, set a user to access gotty service'), + true + ), + 'arguments' => [ + 'type' => 'text', + 'name' => 'gotty_user', + 'value' => $config['gotty_user'], + ], + ], + [ + 'label' => __('Gotty password').ui_print_help_tip( + __('Optional, set a password to access gotty service'), + true + ), + 'arguments' => [ + 'type' => 'password', + 'name' => 'gotty_pass', + 'value' => io_output_password($config['gotty_pass']), + ], + ], ], ], [ diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index 6f1d59d56b..30b0706342 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -458,6 +458,7 @@ class Wizard if (is_array($input['block_content']) === true) { $direct = (bool) $input['direct']; + $toggle = (bool) $input['toggle']; // Print independent block of inputs. $output .= '
  • " + + settings.emptyli + + "
  • "; + $("#ul-al-" + settings.id_alert).append(emptyli); + } + }, + error: function(error) { + console.log(error); + } + }); + } + }); +} From 8811095a3e171bdd9c63e97185abf1d5e0ae4518 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Date: Mon, 18 Nov 2019 15:25:35 +0100 Subject: [PATCH 62/66] WIP ALerts --- pandora_console/include/javascript/alert.js | 56 +++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/pandora_console/include/javascript/alert.js b/pandora_console/include/javascript/alert.js index d293e247d8..435649833d 100644 --- a/pandora_console/include/javascript/alert.js +++ b/pandora_console/include/javascript/alert.js @@ -116,3 +116,59 @@ function delete_alert_action(settings) { } }); } + +function standby_alert(settings) { + confirmDialog({ + title: settings.title, + message: settings.msg, + onAccept: function() { + $.ajax({ + method: "post", + url: settings.url, + data: { + page: settings.page, + method: "standByAlert", + id_alert: settings.id_alert, + standby: settings.standby + }, + dataType: "html", + success: function(data) { + $("#standby-alert-" + settings.id_alert).empty(); + $("#standby-alert-" + settings.id_alert).append(data); + }, + error: function(error) { + console.log(error); + } + }); + } + }); +} + +function disabled_alert(settings) { + confirmDialog({ + title: settings.title, + message: settings.msg, + onAccept: function() { + $.ajax({ + method: "post", + url: settings.url, + data: { + page: settings.page, + method: "disabledAlert", + id_alert: settings.id_alert, + disabled: settings.disabled + }, + dataType: "json", + success: function(data) { + $("#disabled-alert-" + settings.id_alert).empty(); + $("#disabled-alert-" + settings.id_alert).append(data.disabled); + $("#status-alert-" + settings.id_alert).empty(); + $("#status-alert-" + settings.id_alert).append(data.status); + }, + error: function(error) { + console.log(error); + } + }); + } + }); +} From 4d7f92e3f0082f591863c74e2d32718823f6282b Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Wed, 20 Nov 2019 13:25:16 +0100 Subject: [PATCH 63/66] Add button diagnostic --- .../include/class/Diagnostics.class.php | 31 ++++++++++++++++++- pandora_console/tools/diagnostics.php | 2 +- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/pandora_console/include/class/Diagnostics.class.php b/pandora_console/include/class/Diagnostics.class.php index 94acbc4ba2..c062793b9d 100644 --- a/pandora_console/include/class/Diagnostics.class.php +++ b/pandora_console/include/class/Diagnostics.class.php @@ -68,6 +68,10 @@ class Diagnostics extends Wizard // Check access. check_login(); + $this->url = ui_get_full_url( + 'index.php?sec=gextensions&sec2=tools/diagnostics' + ); + $this->ajaxController = $page; $this->pdf = $pdf; $this->product_name = io_safe_output(get_product_name()); @@ -123,15 +127,34 @@ class Diagnostics extends Wizard { global $config; + if ($this->pdf === true) { + $this->exportPDF(); + exit; + } + ui_require_css_file('diagnostics'); + $pdf_url = $this->url.'&pdf=true'; + $pdf_img = html_print_image( + 'images/pdf.png', + true, + ['title' => __('Export to PDF')] + ); + $header_buttons = [ + 'csv' => [ + 'active' => false, + 'text' => ''.$pdf_img.'', + ], + ]; + // Header. ui_print_page_header( __('%s Diagnostic tool', $this->product_name), 'images/gm_massive_operations.png', false, 'diagnostic_tool_tab', - true + true, + $header_buttons ); // Print all Methods Diagnostic Info. @@ -2080,6 +2103,10 @@ class Diagnostics extends Wizard enterprise_include_once('/include/class/Pdf.class.php'); $mpdf = new Pdf([]); + // Ignore pending HTML outputs. + while (@ob_end_clean()) { + } + // ADD style. $mpdf->addStyle($config['homedir'].'/include/styles/diagnostics.css'); @@ -2112,6 +2139,8 @@ class Diagnostics extends Wizard // Write html filename. $mpdf->writePDFfile($filename); + + exit; } diff --git a/pandora_console/tools/diagnostics.php b/pandora_console/tools/diagnostics.php index 30be89efc4..fc2b2fecd2 100644 --- a/pandora_console/tools/diagnostics.php +++ b/pandora_console/tools/diagnostics.php @@ -32,7 +32,7 @@ global $config; require_once $config['homedir'].'/include/class/Diagnostics.class.php'; $ajaxPage = 'tools/diagnostics'; -$pdf = false; +$pdf = get_parameter('pdf', false); // Control call flow. From 61568ee3b7d760a13398e4382b3f4872d1db9181 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin Date: Wed, 20 Nov 2019 13:26:02 +0100 Subject: [PATCH 64/66] Add button diagnostic --- pandora_console/include/class/Diagnostics.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/pandora_console/include/class/Diagnostics.class.php b/pandora_console/include/class/Diagnostics.class.php index c062793b9d..ee61ec743d 100644 --- a/pandora_console/include/class/Diagnostics.class.php +++ b/pandora_console/include/class/Diagnostics.class.php @@ -2105,6 +2105,7 @@ class Diagnostics extends Wizard // Ignore pending HTML outputs. while (@ob_end_clean()) { + $ignore_me; } // ADD style. From 6f8bf104b44377a7d3a0497eea00e3728042a367 Mon Sep 17 00:00:00 2001 From: marcos Date: Mon, 25 Nov 2019 13:50:26 +0100 Subject: [PATCH 65/66] update sap view --- .../operation/agentes/ver_agente.php | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index aa91a09ee6..9c8ca5748b 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -1532,25 +1532,28 @@ switch ($tab) { break; } -ui_print_page_header( - agents_get_alias($id_agente), - $icon, - false, - $help_header, - false, - $onheader, - false, - '', - $config['item_title_size_text'], - '', - ui_print_breadcrums( - [ - __('Monitoring'), - __('View'), - ''.$tab_name.'', - ] - ) -); +if (!$config['pure']) { + ui_print_page_header( + agents_get_alias($id_agente), + $icon, + false, + $help_header, + false, + $onheader, + false, + '', + $config['item_title_size_text'], + '', + ui_print_breadcrums( + [ + __('Monitoring'), + __('View'), + ''.$tab_name.'', + ] + ) + ); +} + switch ($tab) { From 0490024abc0b21cab1f4f73e86524057d3e74dcd Mon Sep 17 00:00:00 2001 From: marcos Date: Mon, 25 Nov 2019 15:01:27 +0100 Subject: [PATCH 66/66] add sap view to autorefresh edit my user --- pandora_console/operation/users/user_edit.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php index fcc719dfaa..7aa3c5f839 100644 --- a/pandora_console/operation/users/user_edit.php +++ b/pandora_console/operation/users/user_edit.php @@ -469,6 +469,9 @@ $autorefresh_list_out['operation/agentes/pandora_networkmap'] = 'Network map'; $autorefresh_list_out['operation/visual_console/render_view'] = 'Visual console'; $autorefresh_list_out['operation/events/events'] = 'Events'; $autorefresh_list_out['enterprise/godmode/reporting/cluster_view'] = 'Cluster view'; +if (enterprise_installed()) { + $autorefresh_list_out['general/sap_view'] = 'SAP view'; +} if (!isset($autorefresh_list)) { $select = db_process_sql("SELECT autorefresh_white_list FROM tusuario WHERE id_user = '".$config['id_user']."'");
  • '; @@ -471,14 +472,37 @@ class Wizard $output .= '
      '; } - foreach ($input['block_content'] as $input) { - $output .= $this->printBlock( - $input, + $html = ''; + + foreach ($input['block_content'] as $in) { + $html .= $this->printBlock( + $in, $return, (bool) $direct ); } + if ($toggle === true) { + $output .= ui_print_toggle( + [ + 'name' => (isset($input['toggle_name']) ? $input['toggle_name'] : 'toggle_'.uniqid()), + 'content' => $html, + 'title' => $input['toggle_title'], + 'id' => $input['toggle_id'], + 'hidden_default' => $input['toggle_hidden_default'], + 'return' => (isset($input['toggle_return']) ? $input['toggle_return'] : true), + 'toggle_class' => $input['toggle_toggle_class'], + 'main_class' => $input['toggle_main_class'], + 'container_class' => $input['toggle_container_class'], + 'img_a' => $input['toggle_img_a'], + 'img_b' => $input['toggle_img_b'], + 'clean' => (isset($input['toggle_clean']) ? $input['toggle_clean'] : true), + ] + ); + } else { + $output .= $html; + } + // Close block. if (!$direct) { $output .= '
    '; diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 0ad31cf931..0e1c9e09c0 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -3667,6 +3667,7 @@ function ui_print_event_priority( * @param string $main_class Main object class. * @param string $img_a Image (closed). * @param string $img_b Image (opened). + * @param string $clean Do not encapsulate with class boxes, clean print. * * @return string HTML. */ @@ -3681,7 +3682,8 @@ function ui_toggle( $container_class='white-box-content', $main_class='box-shadow white_table_graph', $img_a='images/arrow_down_green.png', - $img_b='images/arrow_right_green.png' + $img_b='images/arrow_right_green.png', + $clean=false ) { // Generate unique Id. $uniqid = uniqid(''); @@ -3697,9 +3699,17 @@ function ui_toggle( $original = $img_a; } + $header_class = ''; + if ($clean === false) { + $header_class = 'white_table_graph_header'; + } else { + $main_class = ''; + $container_class = 'white-box-content-clean'; + } + // Link to toggle. $output = '
    '; - $output .= '
    '.html_print_image( + $output .= '
    '.html_print_image( $original, true, [ @@ -3767,7 +3777,8 @@ function ui_print_toggle($data) (isset($data['container_class']) === true) ? $data['container_class'] : 'white-box-content', (isset($data['main_class']) === true) ? $data['main_class'] : 'box-shadow white_table_graph', (isset($data['img_a']) === true) ? $data['img_a'] : 'images/arrow_down_green.png', - (isset($data['img_b']) === true) ? $data['img_b'] : 'images/arrow_right_green.png' + (isset($data['img_b']) === true) ? $data['img_b'] : 'images/arrow_right_green.png', + (isset($data['clean']) === true) ? $data['clean'] : false ); } diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index aba0f03a81..acdfd7a981 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -5700,6 +5700,10 @@ div#status_pie { padding: 1em; min-width: 100%; } +.white-box-content-clean { + padding-left: 2em; + padding-top: 1em; +} .white_table_graph_content { border: 1px solid #e2e2e2; From f348310675f42d8dac2d8989a4515133a5c671e8 Mon Sep 17 00:00:00 2001 From: marcos Date: Thu, 14 Nov 2019 19:01:23 +0100 Subject: [PATCH 43/66] ADD function to get SAP agents and sap view to sap agents --- .../godmode/agentes/configurar_agente.php | 27 ++++++++ pandora_console/include/functions_agents.php | 63 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 61d33193d3..741fb536bb 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -486,6 +486,20 @@ if ($id_agente) { $agent_wizard['active'] = false; } + $is_sap = agents_get_sap_agents($id_agente); + if ($is_sap) { + $saptab['text'] = ''.html_print_image('images/chart_curve.png', true, ['title' => __('SAP view')]).''; + + if ($tab == 'sap_view') { + $saptab['active'] = true; + } else { + $saptab['active'] = false; + } + } else { + $saptab = ''; + } + + $total_incidents = agents_get_count_incidents($id_agente); // Incident tab. @@ -531,6 +545,7 @@ if ($id_agente) { 'group' => $grouptab, 'gis' => $gistab, 'agent_wizard' => $agent_wizard, + 'sap_view' => $saptab, ]; } else { $onheader = [ @@ -546,6 +561,8 @@ if ($id_agente) { 'group' => $grouptab, 'gis' => $gistab, 'agent_wizard' => $agent_wizard, + 'sap_view' => $saptab, + ]; } @@ -691,6 +708,12 @@ if ($id_agente) { } break; + case 'sap_view': + $tab_description = '- '.__('SAP view'); + $help_header = 'sap_view'; + $tab_name = 'SAP View'; + break; + default: // Default. break; @@ -2346,6 +2369,10 @@ switch ($tab) { include 'agent_wizard.php'; break; + case 'sap_view': + include 'general/sap_view.php'; + break; + default: if (enterprise_hook('switch_agent_tab', [$tab])) { // This will make sure that blank pages will have at least some diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index 826ca971c5..28940170c7 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -3481,3 +3481,66 @@ function agents_get_status_animation($up=true) ); } } + + +/** + * Return if an agent is SAP or or an a agent SAP list. + * If function receive false, you will return all SAP agents, + * but if you receive an id agent, check if it is a sap agent + * and return true or false. + * + * @param integer $id_agent + * @return boolean + */ +function agents_get_sap_agents($id_agent) +{ + // Available modules. + // If you add more modules, please update SAP.pm. + $sap_modules = [ + 160 => __('SAP Login OK'), + 109 => __('SAP Dumps'), + 111 => __('SAP List lock'), + 113 => __('SAP Cancel Jobs'), + 121 => __('SAP Batch input erroneus'), + 104 => __('SAP Idoc erroneus'), + 105 => __('SAP IDOC OK'), + 150 => __('SAP WP without active restart'), + 151 => __('SAP WP stopped'), + 102 => __('Average time of SAPGUI response '), + 180 => __('Dialog response time'), + 103 => __('Dialog Logged users '), + 192 => __('SYSFAIL, delivery attempts tRFC wrong entries number'), + 195 => __('SYSFAIL, queue qRFC INPUT, wrong entries number '), + 116 => __('Number of Update WPs in error'), + ]; + + $array_agents = []; + foreach ($sap_modules as $module => $key) { + $array_agents = array_merge( + $array_agents, + db_get_all_rows_sql( + 'SELECT ta.id_agente,ta.alias + FROM tagente ta + INNER JOIN tagente_modulo tam + ON tam.id_agente = ta.id_agente + WHERE tam.nombre + LIKE "%SAP%" + GROUP BY ta.id_agente' + ) + ); + } + + $indexed_agents = index_array($array_agents, 'id_agente', false); + + if ($id_agent === false) { + return $indexed_agents; + } + + foreach ($indexed_agents as $agent => $key) { + if ($agent === $id_agent) { + return true; + } + } + + return false; +} From 9dec1709c4c9e686521af501084b2b33ec54c106 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 14 Nov 2019 19:10:31 +0100 Subject: [PATCH 44/66] Fixed help content well printed --- pandora_console/extensions/quick_shell.php | 7 ++++++- pandora_console/include/class/HelpFeedBack.class.php | 5 +++-- pandora_console/include/functions.php | 7 +++++++ pandora_console/include/functions_ui.php | 7 ++++++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/pandora_console/extensions/quick_shell.php b/pandora_console/extensions/quick_shell.php index a286ce4b95..6d135260d2 100644 --- a/pandora_console/extensions/quick_shell.php +++ b/pandora_console/extensions/quick_shell.php @@ -381,7 +381,12 @@ function quickShellSettings() } // Interface. - ui_print_page_header(__('QuickShell settings')); + ui_print_page_header( + __('QuickShell settings'), + '', + false, + 'quickshell_settings' + ); if ($changes > 0) { $msg = __('%d Updated', $changes); diff --git a/pandora_console/include/class/HelpFeedBack.class.php b/pandora_console/include/class/HelpFeedBack.class.php index 825d3c923f..1132550cff 100644 --- a/pandora_console/include/class/HelpFeedBack.class.php +++ b/pandora_console/include/class/HelpFeedBack.class.php @@ -93,12 +93,13 @@ class HelpFeedBack extends Wizard ui_require_css_File('discovery'); ui_require_css_file('help_feedback'); - $help_url = get_parameter('url', null); + $help_url = get_parameter('b', null); + $help_url = base64_decode($help_url); if ($help_url === null) { echo __('Page not found'); } else { ?> - diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index a7d94d43bc..fbc41ce961 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -5431,6 +5431,13 @@ function get_help_info($section_name) $result .= 'GIS&printable=yes#Operation'; } break; + + case 'quickshell_settings': + if ($es) { + $result .= 'Configuracion_Consola&printable=yes#Websocket_Engine'; + } else { + $result .= 'Console_Setup&printable=yes#Websocket_engine'; + } } return $result; diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 0e1c9e09c0..9179f60aaf 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -1404,14 +1404,19 @@ function ui_print_help_icon( } $url = get_help_info($help_id); + $b = base64_encode($url); + $help_handler = 'index.php?sec=view&sec2=general/help_feedback'; + // Needs to use url encoded to avoid anchor lost. + $help_handler .= '&b='.$b; + $help_handler .= '&pure=1&url='.$url; $output = html_print_image( $image, true, [ 'class' => 'img_help', 'title' => __('Help'), - 'onclick' => "open_help ('".ui_get_full_url('index.php?sec=view&sec2=general/help_feedback&pure=1&url='.$url)."')", + 'onclick' => "open_help ('".ui_get_full_url($help_handler)."')", 'id' => $id, ], false, From 546b8dc44821d8757b0edd54f8ef9ab5a52fb7e0 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 14 Nov 2019 20:55:55 +0100 Subject: [PATCH 45/66] omnishell minor changes --- pandora_console/include/functions_ui.php | 148 +++++++------------ pandora_console/include/styles/omnishell.css | 6 + pandora_console/include/styles/progress.css | 1 + 3 files changed, 58 insertions(+), 97 deletions(-) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 0ad31cf931..d6afa8ffac 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -2915,119 +2915,73 @@ function ui_progress( * Generates a progress bar CSS based. * Requires css progress.css * - * @param array $progress Progress. - * @param string $width Width. - * @param integer $height Height in 'em'. - * @param array $color status color. - * @param boolean $return Return or paint (if false). - * @param boolean $text Text to be displayed,by default progress %. - * @param array $ajax Ajax: [ 'page' => 'page', 'data' => 'data' ] Sample: - * [ - * 'page' => 'operation/agentes/ver_agente', Target page. - * 'interval' => 100 / $agent["intervalo"], Ask every interval seconds. - * 'data' => [ Data to be sent to target page. - * 'id_agente' => $id_agente, - * 'refresh_contact' => 1, - * ], - * ]. + * @param array $data With following content: + * + * 'slices' => [ + * 'label' => [ // Name of the slice + * 'value' => value + * 'color' => color of the slice. + * ] + * ], + * 'width' => Width + * 'height' => Height in 'em' + * 'return' => Boolean, return or paint. * * @return string HTML code. */ function ui_progress_extend( - $progress, - $width='100%', - $height='2.5', - $color='#82b92e', - $return=true, - $text='', - $ajax=false + array $data ) { - if (!$progress['total']) { - $progress = 0; + if (is_array($data) === false) { + // Failed. + return false; } - $totalW = ($progress['total'] * 100); - if ($totalW > 100) { - $totalW = 100; + if (is_array($data['slices']) === false) { + // Failed. + return false; } - if ($totalW < 0) { - $totalW = 0; + if (isset($data['width']) === false) { + $data['width'] = '100'; } - if (empty($text)) { - $text = $totalW.'%'; + if (isset($data['height']) === false) { + $data['height'] = '1.3'; + } + + $total = array_reduce( + $data['slices'], + function ($carry, $item) { + $carry += $item['value']; + return $carry; + } + ); + if ($total == 0) { + return null; } - $badW = (($progress['bad'] * 100 ) / $progress['total']); - $goodW = (($progress['good'] * 100 ) / $progress['total']); - $unknownW = (($progress['unknown'] * 100 ) / $progress['total']); ui_require_css_file('progress'); - $output .= '
    '; - $output .= '
    '; - $output .= '
    '; - $output .= '
    '; + + // Main container. + $output .= '
    '; + + foreach ($data['slices'] as $label => $def) { + $width = ($def['value'] * 100 / $total); + $output .= '
    $value) { - $output .= ' - '.$token.':"'.$value.'",'; - } - } - - $output .= ' - page: "'.$ajax['page'].'" - }, - success: function(data) { - try { - val = JSON.parse(data); - $(".progress_main").attr("data-label", val["last_contact"]+" s"); - $(".progress").width(val["progress"]+"%"); - } catch (e) { - console.error(e); - $(".progress_text").attr("data-label", (last -1) + " s"); - if (width < 100) { - $(".progress").width((width+width_interval) + "%"); - } - } - } - }); - } else { - $(".progress_main").attr("data-label", (last -1) + " s"); - if (width < 100) { - $(".progress").width((width+width_interval) + "%"); - } - } - }, 1000); - }); - '; - } - - if (!$return) { + if (!$data['return']) { echo $output; } diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css index b6dcd37826..e1d1a6ad98 100644 --- a/pandora_console/include/styles/omnishell.css +++ b/pandora_console/include/styles/omnishell.css @@ -19,6 +19,12 @@ height: 20px; } +.element-target-big { + width: 100px; + margin: 2px; + height: 100px; +} + .status-normal { background-color: #add570; } diff --git a/pandora_console/include/styles/progress.css b/pandora_console/include/styles/progress.css index f263e87fcf..c88687a204 100644 --- a/pandora_console/include/styles/progress.css +++ b/pandora_console/include/styles/progress.css @@ -4,6 +4,7 @@ position: relative; width: 100%; display: inline-block; + display: flex; } .progress_main:before { content: attr(data-label); From dcd9467bfb142d2468bdfa70b54b5eff0049bf3c Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 14 Nov 2019 21:10:46 +0100 Subject: [PATCH 46/66] fix symbols in gotty credentials --- pandora_console/extensions/quick_shell.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandora_console/extensions/quick_shell.php b/pandora_console/extensions/quick_shell.php index 6d135260d2..a8cce0b8de 100644 --- a/pandora_console/extensions/quick_shell.php +++ b/pandora_console/extensions/quick_shell.php @@ -218,7 +218,8 @@ function quickShell() if (empty($config['gotty_user']) === false && empty($config['gotty_pass']) === false ) { - $auth_str = $config['gotty_user'].':'.$config['gotty_pass']; + $auth_str = io_safe_output($config['gotty_user']); + $auth_str .= ':'.io_output_password($config['gotty_pass']); $gotty_url = $auth_str.'@'.$host.':'.$port; } From cb43d06c13be50b86eaa5d606ffc8f9b79b05c0d Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 14 Nov 2019 21:31:07 +0100 Subject: [PATCH 47/66] minor fix --- pandora_agents/unix/pandora_agent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 914896e60d..d9b3d32b3f 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1439,7 +1439,7 @@ sub prepare_commands { my $rcmd_file = $ConfDir.'/commands/'.$ref.'.rcmd'; # Check for local .rcmd.done files - if (-e $Conf{'temporal'}.'/'.$ref.'.rcmd.done') { + if (-e $rcmd_file.'.done') { # Ignore. delete $Conf{'commands'}->{$ref}; next; From 8edbb7435458171caa93b5fd32f15174a7137cc4 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Thu, 14 Nov 2019 21:52:02 +0100 Subject: [PATCH 48/66] discovery help link and minor fixes --- pandora_console/godmode/menu.php | 2 +- pandora_console/godmode/servers/discovery.php | 2 +- pandora_console/include/functions.php | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 3a9e3de9c0..af09d9ff0d 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -28,7 +28,7 @@ if (check_acl($config['id_user'], 0, 'AR') || check_acl($config['id_user'], 0, 'PM') ) { $sub = []; - $sub['godmode/servers/discovery&wiz=main']['text'] = __('Main'); + $sub['godmode/servers/discovery&wiz=main']['text'] = __('Start'); $sub['godmode/servers/discovery&wiz=main']['id'] = 'Discovery'; $sub['godmode/servers/discovery&wiz=tasklist']['text'] = __('Task list'); $sub['godmode/servers/discovery&wiz=tasklist']['id'] = 'tasklist'; diff --git a/pandora_console/godmode/servers/discovery.php b/pandora_console/godmode/servers/discovery.php index 2d0fcec8a1..7215ee7dfb 100755 --- a/pandora_console/godmode/servers/discovery.php +++ b/pandora_console/godmode/servers/discovery.php @@ -54,7 +54,7 @@ function get_wiz_class($str) __('Discovery'), '', false, - '', + 'discovery', true, '', false, diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index fbc41ce961..d75570107d 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -5438,6 +5438,15 @@ function get_help_info($section_name) } else { $result .= 'Console_Setup&printable=yes#Websocket_engine'; } + break; + + case 'discovery': + if ($es) { + $result .= 'Discovery&printable=yes'; + } else { + $result .= 'Discovery&printable=yes'; + } + break; } return $result; From 990ad339d3209baa52a6a48b88f8eb5344fbb56e Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 15 Nov 2019 09:45:49 +0100 Subject: [PATCH 49/66] db schema --- pandora_console/extras/mr/33.sql | 4 ++-- pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql | 4 ++-- pandora_console/pandoradb.sql | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pandora_console/extras/mr/33.sql b/pandora_console/extras/mr/33.sql index 85a38a4fa7..3bc3cb9919 100644 --- a/pandora_console/extras/mr/33.sql +++ b/pandora_console/extras/mr/33.sql @@ -26,8 +26,8 @@ CREATE TABLE `tremote_command_target` ( `rcmd_id` bigint unsigned NOT NULL, `id_agent` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, - `stdout` text, - `stderr` text, + `stdout` MEDIUMTEXT, + `stderr` MEDIUMTEXT, `errorlevel` int(10) unsigned NOT NULL default 0, PRIMARY KEY (`id`), FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index fd51f73668..c3970da228 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -2324,8 +2324,8 @@ CREATE TABLE `tremote_command_target` ( `rcmd_id` bigint unsigned NOT NULL, `id_agent` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, - `stdout` text, - `stderr` text, + `stdout` MEDIUMTEXT, + `stderr` MEDIUMTEXT, `errorlevel` int(10) unsigned NOT NULL default 0, PRIMARY KEY (`id`), FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 910961ec94..37f31f60bb 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -3683,8 +3683,8 @@ CREATE TABLE `tremote_command_target` ( `rcmd_id` bigint unsigned NOT NULL, `id_agent` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, - `stdout` text, - `stderr` text, + `stdout` MEDIUMTEXT, + `stderr` MEDIUMTEXT, `errorlevel` int(10) unsigned NOT NULL default 0, PRIMARY KEY (`id`), FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) From e561b1f9068773736ecc0c1bb818ec0c73689ba8 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 15 Nov 2019 13:07:23 +0100 Subject: [PATCH 50/66] omnishell multiselect --- pandora_console/include/functions_agents.php | 26 +++++++++++++++ pandora_console/include/styles/omnishell.css | 32 +++++++++++++++++++ .../operation/agentes/ver_agente.php | 9 +----- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index 826ca971c5..bc5ef43430 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -132,6 +132,32 @@ function agents_get_agent_id_by_alias($alias) } +/** + * Return seconds left to contact again with agent. + * + * @param integer $id_agente Target agent + * + * @return integer|null Seconds left. + */ +function agents_get_next_contact_time_left(int $id_agente) +{ + $last_contact = false; + + if ($id_agente > 0) { + $last_contact = db_get_value_sql( + sprintf( + 'SELECT format(intervalo,2) - (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(IF(ultimo_contacto > ultimo_contacto_remoto, ultimo_contacto, ultimo_contacto_remoto))) as "val" + FROM `tagente` + WHERE id_agente = %d ', + $id_agente + ) + ); + } + + return $last_contact; +} + + /** * Creates an agent. * diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css index e1d1a6ad98..265ca5f445 100644 --- a/pandora_console/include/styles/omnishell.css +++ b/pandora_console/include/styles/omnishell.css @@ -25,6 +25,32 @@ height: 100px; } +.element-target-big:hover { + box-shadow: 0 0 10px -5px #424242; +} + +.element-target-big:before { + content: attr(data-label); + position: relative; + text-align: center; + width: 100%; + height: 100%; + color: #373737; + font-weight: bolder; + display: flex; + flex-direction: row; + font-size: 1.8em; + align-items: center; + justify-content: center; + overflow: hidden; + font-family: "lato-bolder", "Open Sans", sans-serif; + text-decoration: none; +} + +.container-target a:hover { + text-decoration: none; +} + .status-normal { background-color: #add570; } @@ -156,6 +182,12 @@ ul.wizard { display: flex; } +.no-class.action-buttons.mw120px.textright.sorting_disabled, +.textright { + text-align: right; + padding-right: 2em; +} + /* * Discovery css global */ diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index 7444dda595..fa53e1c6ec 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -68,14 +68,7 @@ if (is_ajax()) { if ($refresh_contact) { $id_agente = get_parameter('id_agente', 0); if ($id_agente > 0) { - $last_contact = db_get_value_sql( - sprintf( - 'SELECT format(intervalo,2) - (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(IF(ultimo_contacto > ultimo_contacto_remoto, ultimo_contacto, ultimo_contacto_remoto))) as "val" - FROM `tagente` - WHERE id_agente = %d ', - $id_agente - ) - ); + $last_contact = agents_get_next_contact_time_left($id_agente); $progress = agents_get_next_contact($id_agente); if ($progress < 0 || $progress > 100) { From 91f28384b87a4d3e7b1ff41f554bc2e034b1c66a Mon Sep 17 00:00:00 2001 From: marcos Date: Fri, 15 Nov 2019 16:22:30 +0100 Subject: [PATCH 51/66] changed sap icon button --- .../godmode/agentes/configurar_agente.php | 2 +- pandora_console/images/sap_icon.png | Bin 0 -> 324 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 pandora_console/images/sap_icon.png diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 741fb536bb..4f6c3e463e 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -488,7 +488,7 @@ if ($id_agente) { $is_sap = agents_get_sap_agents($id_agente); if ($is_sap) { - $saptab['text'] = ''.html_print_image('images/chart_curve.png', true, ['title' => __('SAP view')]).''; + $saptab['text'] = ''.html_print_image('images/sap_icon.png', true, ['title' => __('SAP view')]).''; if ($tab == 'sap_view') { $saptab['active'] = true; diff --git a/pandora_console/images/sap_icon.png b/pandora_console/images/sap_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..536c43b28b8bc6407d4197fc7db3abab6b170229 GIT binary patch literal 324 zcmV-K0lWT*P) Date: Fri, 15 Nov 2019 16:35:25 +0100 Subject: [PATCH 52/66] minor fix omnishell functionality - unix agent --- pandora_agents/unix/pandora_agent | 232 +++++++++++++++++++++++++----- 1 file changed, 194 insertions(+), 38 deletions(-) diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index d9b3d32b3f..d6095d6d24 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -296,6 +296,77 @@ sub load_libraries() { } } +################################################################################ +# Erase blank spaces before and after the string +################################################################################ +sub trim { + my $string = shift; + if (empty($string)){ + return ""; + } + + $string =~ s/\r//g; + + chomp($string); + $string =~ s/^\s+//g; + $string =~ s/\s+$//g; + + return $string; +} + +################################################################################ +# Mix hashses +################################################################################ +sub merge_hashes { + my $_h1 = shift; + my $_h2 = shift; + + if (ref($_h1) ne "HASH") { + return \%{$_h2} if (ref($_h2) eq "HASH"); + } + + if (ref($_h2) ne "HASH") { + return \%{$_h1} if (ref($_h1) eq "HASH"); + } + + if ((ref($_h1) ne "HASH") && (ref($_h2) ne "HASH")) { + return {}; + } + + my %ret = (%{$_h1}, %{$_h2}); + + return \%ret; +} + +################################################################################ +# Empty +################################################################################ +sub empty { + my $str = shift; + + if (!(defined($str)) ){ + return 1; + } + + if(looks_like_number($str)){ + return 0; + } + + if (ref($str) eq "ARRAY") { + return (($#{$str}<0)?1:0); + } + + if (ref($str) eq "HASH") { + my @tmp = keys %{$str}; + return (($#tmp<0)?1:0); + } + + if ($str =~ /^\ *[\n\r]{0,2}\ *$/) { + return 1; + } + return 0; +} + ################################################################################ # Check a regular expression. Returns 1 if its valid, 0 otherwise. ################################################################################ @@ -731,13 +802,6 @@ sub parse_conf_modules($) { # Macros } elsif ($line =~ /^\s*module_macro(\S+)\s+(.*)\s*$/) { $module->{'macros'}{$1} = $2; - # Commands - } elsif ($line =~ /^\s*cmd_file\s+(.+)$/) { - if (ref ($Conf{'commands'}) ne "HASH") { - $Conf{'commands'} = {}; - } - # Initialize empty command hash. - $Conf{'commands'}->{$1} = {}; } } return; @@ -832,7 +896,21 @@ sub read_config (;$) { next if ($line =~ /^module\s*\w*/); #Configuration token - if ($line =~ /^\s*(\S+)\s+(.*)$/) { + if ($line =~ /^\s*(\S+)\s+(.*)$/) { + # Reserved keyword. + next if ($1 eq "commands"); + + if ($1 eq "cmd_file") { + # Commands + if (ref ($Conf{'commands'}) ne "HASH") { + $Conf{'commands'} = {}; + } + # Initialize empty command hash. + $Conf{'commands'}->{$2} = {}; + log_message('setup', "Command required $2"); + next; + } + log_message ('setup', "$1 is $2"); $Conf{$1} = $2; @@ -980,8 +1058,6 @@ sub read_config (;$) { $Conf{'secondary_server_opts'} = '-c ' . $Conf{'secondary_server_opts'} if ($Conf{'secondary_server_ssl'} eq '1'); } - # Check remote commands - prepare_commands(); } ################################################################################# @@ -1292,6 +1368,10 @@ sub check_remote_config () { %Collections = (); %Conf = %DefaultConf; + # Supposed to discard current configuration but not. + # Cleanup old commands configuration. + $Conf{'commands'} = {}; + # Reload the new configuration read_config (); @@ -1433,6 +1513,20 @@ sub prepare_commands { return; } + # Force configuration file read. + my @commands = read_config('cmd_file'); + + if (empty(\@commands)) { + $Conf{'commands'} = {}; + } else { + foreach my $rcmd (@commands) { + $Conf{'commands'}->{trim($rcmd)} = {}; + } + } + + # Cleanup old commands. Not registered. + cleanup_old_commands(); + foreach my $ref (keys %{$Conf{'commands'}}) { my $file_content; my $download = 0; @@ -1534,19 +1628,101 @@ sub report_command { return $return; } +################################################################################ +# Cleanup unreferenced rcmd and rcmd.done files. +################################################################################ +sub cleanup_old_commands { + # Cleanup old .rcmd and .rcmd.done files. + my %registered = map { $_.'.rcmd' => 1 } keys %{$Conf{'commands'}}; + if(opendir(my $dir, $ConfDir.'/commands/')) { + while (my $item = readdir($dir)) { + + # Skip other files. + next if ($item !~ /\.rcmd$/); + + # Clean .rcmd.done file if its command is not referenced in conf. + if (!defined($registered{$item})) { + if (-e $ConfDir.'/commands/'.$item) { + unlink($ConfDir.'/commands/'.$item); + } + if (-e $ConfDir.'/commands/'.$item.'.done') { + unlink($ConfDir.'/commands/'.$item.'.done'); + } + } + } + + # Close dir. + closedir($dir); + } + +} + ################################################################################ # Executes a command using defined timeout. ################################################################################ sub execute_command_timeout { - my ($command, $timeout) = @_; + my ($cmd, $timeout) = @_; - if (!looks_like_number($timeout)) { - `$command`; - } else { - `$command`; + if (!defined($timeout) + || !looks_like_number($timeout) + || $timeout <= 0 + ) { + `$cmd`; + return $?>>8; } - return $?>>8; + my $remaining_timeout = $timeout; + + my $RET; + my $output; + + my $pid = open ($RET, "-|"); + if (!defined($pid)) { + # Failed to fork. + log_message('error', '[command] Failed to fork.'); + return undef; + } + if ($pid == 0) { + # Child. + my $ret; + eval { + local $SIG{ALRM} = sub { die "timeout\n" }; + alarm $timeout; + `$cmd`; + alarm 0; + }; + + my $result = ($?>>8); + print $result; + + # Exit child. + # Child finishes. + exit; + + } else { + # Parent waiting. + while( --$remaining_timeout > 0 ){ + if (wait == -1) { + last; + } + # Wait child up to timeout seconds. + sleep 1; + } + } + + if ($remaining_timeout > 0) { + # Retrieve output from child. + $output = do { local $/; <$RET> }; + $output = $output>>8; + } + else { + # Timeout expired. + return 124; + } + + close($RET); + + return $output; } ################################################################################ @@ -3274,28 +3450,8 @@ while (1) { # Check file collections check_collections () unless ($Conf{'debug'} eq '1'); - if ($Conf{'debug'} ne '1') { - # Cleanup old .rcmd and .rcmd.done files. - my %registered = map { $_.'.rcmd' => 1 } keys %{$Conf{'commands'}}; - if(opendir(my $dir, $ConfDir.'/commands/')) { - while (my $item = readdir($dir)) { - # Skip other files. - next if ($item !~ /\.rcmd$/); - # Clean .rcmd.done file if its command is not referenced in conf. - if (!defined($registered{$item})) { - if (-e $item) { - unlink ($item); - } - if (-e $item.'.done') { - unlink ($item.'.done'); - } - } - } - - # Close dir. - closedir($dir); - } - } + # Check scheduled commands + prepare_commands() unless ($Conf{'debug'} eq '1'); # Launch broker agents @BrokerPid = (); From 17918cd5c6183ac856e25023ff493e172e22c81e Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 15 Nov 2019 16:35:25 +0100 Subject: [PATCH 53/66] minor fix omnishell functionality - unix agent --- pandora_agents/unix/pandora_agent | 232 +++++++++++++++++++++++++----- 1 file changed, 194 insertions(+), 38 deletions(-) diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index d9b3d32b3f..d6095d6d24 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -296,6 +296,77 @@ sub load_libraries() { } } +################################################################################ +# Erase blank spaces before and after the string +################################################################################ +sub trim { + my $string = shift; + if (empty($string)){ + return ""; + } + + $string =~ s/\r//g; + + chomp($string); + $string =~ s/^\s+//g; + $string =~ s/\s+$//g; + + return $string; +} + +################################################################################ +# Mix hashses +################################################################################ +sub merge_hashes { + my $_h1 = shift; + my $_h2 = shift; + + if (ref($_h1) ne "HASH") { + return \%{$_h2} if (ref($_h2) eq "HASH"); + } + + if (ref($_h2) ne "HASH") { + return \%{$_h1} if (ref($_h1) eq "HASH"); + } + + if ((ref($_h1) ne "HASH") && (ref($_h2) ne "HASH")) { + return {}; + } + + my %ret = (%{$_h1}, %{$_h2}); + + return \%ret; +} + +################################################################################ +# Empty +################################################################################ +sub empty { + my $str = shift; + + if (!(defined($str)) ){ + return 1; + } + + if(looks_like_number($str)){ + return 0; + } + + if (ref($str) eq "ARRAY") { + return (($#{$str}<0)?1:0); + } + + if (ref($str) eq "HASH") { + my @tmp = keys %{$str}; + return (($#tmp<0)?1:0); + } + + if ($str =~ /^\ *[\n\r]{0,2}\ *$/) { + return 1; + } + return 0; +} + ################################################################################ # Check a regular expression. Returns 1 if its valid, 0 otherwise. ################################################################################ @@ -731,13 +802,6 @@ sub parse_conf_modules($) { # Macros } elsif ($line =~ /^\s*module_macro(\S+)\s+(.*)\s*$/) { $module->{'macros'}{$1} = $2; - # Commands - } elsif ($line =~ /^\s*cmd_file\s+(.+)$/) { - if (ref ($Conf{'commands'}) ne "HASH") { - $Conf{'commands'} = {}; - } - # Initialize empty command hash. - $Conf{'commands'}->{$1} = {}; } } return; @@ -832,7 +896,21 @@ sub read_config (;$) { next if ($line =~ /^module\s*\w*/); #Configuration token - if ($line =~ /^\s*(\S+)\s+(.*)$/) { + if ($line =~ /^\s*(\S+)\s+(.*)$/) { + # Reserved keyword. + next if ($1 eq "commands"); + + if ($1 eq "cmd_file") { + # Commands + if (ref ($Conf{'commands'}) ne "HASH") { + $Conf{'commands'} = {}; + } + # Initialize empty command hash. + $Conf{'commands'}->{$2} = {}; + log_message('setup', "Command required $2"); + next; + } + log_message ('setup', "$1 is $2"); $Conf{$1} = $2; @@ -980,8 +1058,6 @@ sub read_config (;$) { $Conf{'secondary_server_opts'} = '-c ' . $Conf{'secondary_server_opts'} if ($Conf{'secondary_server_ssl'} eq '1'); } - # Check remote commands - prepare_commands(); } ################################################################################# @@ -1292,6 +1368,10 @@ sub check_remote_config () { %Collections = (); %Conf = %DefaultConf; + # Supposed to discard current configuration but not. + # Cleanup old commands configuration. + $Conf{'commands'} = {}; + # Reload the new configuration read_config (); @@ -1433,6 +1513,20 @@ sub prepare_commands { return; } + # Force configuration file read. + my @commands = read_config('cmd_file'); + + if (empty(\@commands)) { + $Conf{'commands'} = {}; + } else { + foreach my $rcmd (@commands) { + $Conf{'commands'}->{trim($rcmd)} = {}; + } + } + + # Cleanup old commands. Not registered. + cleanup_old_commands(); + foreach my $ref (keys %{$Conf{'commands'}}) { my $file_content; my $download = 0; @@ -1534,19 +1628,101 @@ sub report_command { return $return; } +################################################################################ +# Cleanup unreferenced rcmd and rcmd.done files. +################################################################################ +sub cleanup_old_commands { + # Cleanup old .rcmd and .rcmd.done files. + my %registered = map { $_.'.rcmd' => 1 } keys %{$Conf{'commands'}}; + if(opendir(my $dir, $ConfDir.'/commands/')) { + while (my $item = readdir($dir)) { + + # Skip other files. + next if ($item !~ /\.rcmd$/); + + # Clean .rcmd.done file if its command is not referenced in conf. + if (!defined($registered{$item})) { + if (-e $ConfDir.'/commands/'.$item) { + unlink($ConfDir.'/commands/'.$item); + } + if (-e $ConfDir.'/commands/'.$item.'.done') { + unlink($ConfDir.'/commands/'.$item.'.done'); + } + } + } + + # Close dir. + closedir($dir); + } + +} + ################################################################################ # Executes a command using defined timeout. ################################################################################ sub execute_command_timeout { - my ($command, $timeout) = @_; + my ($cmd, $timeout) = @_; - if (!looks_like_number($timeout)) { - `$command`; - } else { - `$command`; + if (!defined($timeout) + || !looks_like_number($timeout) + || $timeout <= 0 + ) { + `$cmd`; + return $?>>8; } - return $?>>8; + my $remaining_timeout = $timeout; + + my $RET; + my $output; + + my $pid = open ($RET, "-|"); + if (!defined($pid)) { + # Failed to fork. + log_message('error', '[command] Failed to fork.'); + return undef; + } + if ($pid == 0) { + # Child. + my $ret; + eval { + local $SIG{ALRM} = sub { die "timeout\n" }; + alarm $timeout; + `$cmd`; + alarm 0; + }; + + my $result = ($?>>8); + print $result; + + # Exit child. + # Child finishes. + exit; + + } else { + # Parent waiting. + while( --$remaining_timeout > 0 ){ + if (wait == -1) { + last; + } + # Wait child up to timeout seconds. + sleep 1; + } + } + + if ($remaining_timeout > 0) { + # Retrieve output from child. + $output = do { local $/; <$RET> }; + $output = $output>>8; + } + else { + # Timeout expired. + return 124; + } + + close($RET); + + return $output; } ################################################################################ @@ -3274,28 +3450,8 @@ while (1) { # Check file collections check_collections () unless ($Conf{'debug'} eq '1'); - if ($Conf{'debug'} ne '1') { - # Cleanup old .rcmd and .rcmd.done files. - my %registered = map { $_.'.rcmd' => 1 } keys %{$Conf{'commands'}}; - if(opendir(my $dir, $ConfDir.'/commands/')) { - while (my $item = readdir($dir)) { - # Skip other files. - next if ($item !~ /\.rcmd$/); - # Clean .rcmd.done file if its command is not referenced in conf. - if (!defined($registered{$item})) { - if (-e $item) { - unlink ($item); - } - if (-e $item.'.done') { - unlink ($item.'.done'); - } - } - } - - # Close dir. - closedir($dir); - } - } + # Check scheduled commands + prepare_commands() unless ($Conf{'debug'} eq '1'); # Launch broker agents @BrokerPid = (); From 84c6640032732631d34bffee263baef6f980b8ff Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Fri, 15 Nov 2019 16:51:53 +0100 Subject: [PATCH 54/66] minor style fix --- pandora_console/include/functions_ui.php | 2 +- pandora_console/include/styles/progress.css | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index d6afa8ffac..c66b96a48e 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -2964,7 +2964,7 @@ function ui_progress_extend( ui_require_css_file('progress'); // Main container. - $output .= '
    '; diff --git a/pandora_console/include/styles/progress.css b/pandora_console/include/styles/progress.css index c88687a204..bfbb2409ef 100644 --- a/pandora_console/include/styles/progress.css +++ b/pandora_console/include/styles/progress.css @@ -6,6 +6,15 @@ display: inline-block; display: flex; } + +.progress_main_noborder { + height: 2.5em; + position: relative; + width: 100%; + display: inline-block; + display: flex; +} + .progress_main:before { content: attr(data-label); position: absolute; From 2f807592273a221a7ee590191fd699f271ca94c3 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 18 Nov 2019 10:04:47 +0100 Subject: [PATCH 55/66] minor updates pandora sap --- pandora_server/conf/pandora_server.conf.new | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pandora_server/conf/pandora_server.conf.new b/pandora_server/conf/pandora_server.conf.new index a5896e6050..ae8b980b14 100644 --- a/pandora_server/conf/pandora_server.conf.new +++ b/pandora_server/conf/pandora_server.conf.new @@ -130,9 +130,15 @@ networkserver 1 dataserver 1 -# Activate (1) Pandora FMS Recon server +# Activate (1) Pandora FMS Discovery server -reconserver 1 +discoveryserver 1 + +# Discovery SAP (PANDORA FMS ENTERPRISE ONLY) +# java /usr/bin/java + +# Discovery SAP utils (PANDORA FMS ENTERPRISE ONLY) +# sap_utils /usr/share/pandora_server/util/recon_scripts/SAP # pluginserver : 1 or 0. Set to 1 to activate plugin server with this setup From 1cacbbc08f62cbf5aef4df7b2c59bd5af7fabac9 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 18 Nov 2019 10:40:02 +0100 Subject: [PATCH 56/66] fix tools --- pandora_server/lib/PandoraFMS/Tools.pm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index c161a464ed..05adbf79d1 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -499,11 +499,17 @@ sub credential_store_get_key($$$) { my ($pa_config, $dbh, $identifier) = @_; my $sql = 'SELECT * FROM tcredential_store WHERE identifier = ?'; - my $key = get_db_single_row($dbh, $sql, $identifier); + my $key = PandoraFMS::DB::get_db_single_row($dbh, $sql, $identifier); return { - 'username' => pandora_output_password($pa_config, $key->{'username'}), - 'password' => pandora_output_password($pa_config, $key->{'password'}), + 'username' => PandoraFMS::Core::pandora_output_password( + $pa_config, + $key->{'username'} + ), + 'password' => PandoraFMS::Core::pandora_output_password( + $pa_config, + $key->{'password'} + ), 'extra_1' => $key->{'extra_1'}, 'extra_2' => $key->{'extra_2'}, }; From 99b071485062ca7b4029fd8d51ac9654759ff4a5 Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 18 Nov 2019 11:06:27 +0100 Subject: [PATCH 57/66] PWE keep db connection up --- .../include/lib/WebSocketServer.php | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pandora_console/include/lib/WebSocketServer.php b/pandora_console/include/lib/WebSocketServer.php index 2d9eb1d9fd..5ce45845d5 100644 --- a/pandora_console/include/lib/WebSocketServer.php +++ b/pandora_console/include/lib/WebSocketServer.php @@ -439,6 +439,9 @@ abstract class WebSocketServer if ((time() - $this->lastTickTimestamp) > $this->tickInterval) { $this->lastTickTimestamp = time(); $this->tick(); + + // Keep connection with DB active. + $this->dbHearthbeat(); } socket_select($read, $write, $except, 0, $this->timeout); @@ -1530,4 +1533,25 @@ abstract class WebSocketServer } + /** + * Keeps db connection opened. + * + * @return void + */ + public function dbHearthbeat() + { + global $config; + + \hd($config['dbconnection']); + + if (isset($config['dbconnection']) === false + || mysqli_ping($config['dbconnection']) === false + ) { + // Retry connection. + db_select_engine(); + $config['dbconnection'] = db_connect(); + } + } + + } From 85ca03b054e843c36b3552a98eee1f817934679e Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 18 Nov 2019 11:07:04 +0100 Subject: [PATCH 58/66] fix- removed traces --- pandora_console/include/lib/WebSocketServer.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/pandora_console/include/lib/WebSocketServer.php b/pandora_console/include/lib/WebSocketServer.php index 5ce45845d5..dfdc81d075 100644 --- a/pandora_console/include/lib/WebSocketServer.php +++ b/pandora_console/include/lib/WebSocketServer.php @@ -1542,8 +1542,6 @@ abstract class WebSocketServer { global $config; - \hd($config['dbconnection']); - if (isset($config['dbconnection']) === false || mysqli_ping($config['dbconnection']) === false ) { From a5ab29e90ed409dc9f0891e34413eadeeb730eca Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 18 Nov 2019 11:22:54 +0100 Subject: [PATCH 59/66] omnishell retries --- pandora_agents/unix/pandora_agent | 38 +++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index d6095d6d24..79f8586b15 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1731,28 +1731,48 @@ sub execute_command_timeout { # $std_files = ' >> /tmp/stdout 2>> /tmp/stderr ################################################################################ sub execute_command_block { - my ($commands, $std_files, $timeout) = @_; + my ($commands, $std_files, $timeout, $retry) = @_; return 0 unless defined($commands); + my $retries = $retry; + + $retries = 1 unless looks_like_number($retries) && $retries > 0; + my $err_level = 0; $std_files = '' unless defined ($std_files); if (ref($commands) ne "ARRAY") { return 0 if $commands eq ''; - $err_level = execute_command_timeout( - "($commands) $std_files", - $timeout - ); + + do { + $err_level = execute_command_timeout( + "($commands) $std_files", + $timeout + ); + + # Do not retry if success. + last if looks_like_number($err_level) && $err_level == 0; + } while ((--$retries) > 0); } else { foreach my $comm (@{$commands}) { next unless defined($comm); - $err_level = execute_command_timeout( - "($comm) $std_files", - $timeout - ); + $retries = $retry; + $retries = 1 unless looks_like_number($retries) && $retries > 0; + do { + $err_level = execute_command_timeout( + "($comm) $std_files", + $timeout + ); + + # Do not retry if success. + last if looks_like_number($err_level) && $err_level == 0; + + } while ((--$retries) > 0); + + # Do not continue evaluating block if failed. last unless ($err_level == 0); } } From 61ccd5bdbc108efe865c67f8be3e48aacdf7bb9d Mon Sep 17 00:00:00 2001 From: fbsanchez Date: Mon, 18 Nov 2019 12:30:12 +0100 Subject: [PATCH 60/66] help_link omnishell --- pandora_console/include/functions.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index a7d94d43bc..042e27b170 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -5416,6 +5416,14 @@ function get_help_info($section_name) } break; + case 'omnishell': + if ($es) { + $result .= 'Omnishell&printable=yes'; + } else { + $result .= 'Omnishell&printable=yes'; + } + break; + case 'module_type_tab': if ($es) { $result .= 'Operacion&printable=yes#Tipos_de_m.C3.B3dulos'; From 79f5e879cc6f10c5413c11a2188a8a44f1f54ed8 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Date: Mon, 18 Nov 2019 13:37:10 +0100 Subject: [PATCH 61/66] WIP Alerts --- pandora_console/include/javascript/alert.js | 118 ++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 pandora_console/include/javascript/alert.js diff --git a/pandora_console/include/javascript/alert.js b/pandora_console/include/javascript/alert.js new file mode 100644 index 0000000000..d293e247d8 --- /dev/null +++ b/pandora_console/include/javascript/alert.js @@ -0,0 +1,118 @@ +/* eslint-disable no-unused-vars */ +/* global $, load_modal, generalShowMsg, confirmDialog */ + +function allowDrop(ev) { + ev.preventDefault(); +} + +function drag(ev) { + ev.dataTransfer.setData("html", ev.target.outerHTML); +} + +function drop(ev) { + ev.preventDefault(); + var data = document.createElement("span"); + var content = ev.dataTransfer.getData("html"); + if (content.includes("nexo")) { + content = "
    " + content; + } + data.innerHTML = content; + document.getElementById(ev.target.id).appendChild(data); +} + +function add_alert_action(settings) { + load_modal({ + target: $("#modal-add-action-form"), + form: "modal_form_add_actions", + url: settings.url_ajax, + modal: { + title: settings.title, + cancel: settings.btn_cancel, + ok: settings.btn_text + }, + onshow: { + page: settings.url, + method: "addAlertActionForm", + extradata: { + id: settings.id + } + }, + onsubmit: { + page: settings.url, + method: "addAlertAction", + dataType: "json" + }, + ajax_callback: add_alert_action_acept, + idMsgCallback: "msg-add-action" + }); +} + +function add_alert_action_acept(data, idMsg) { + if (data.error === 1) { + console.log(data.text); + return; + } + + if ($("#emptyli-al-" + data.id_alert).length > 0) { + $("#emptyli-al-" + data.id_alert).remove(); + } + + $.ajax({ + method: "post", + url: data.url, + data: { + page: data.page, + method: "addRowActionAjax", + id_alert: data.id_alert, + id_action: data.id_action + }, + dataType: "html", + success: function(li) { + $(".ui-dialog-content").dialog("close"); + $("#ul-al-" + data.id_alert).append(li); + }, + error: function(error) { + console.log(error); + } + }); +} + +function delete_alert_action(settings) { + confirmDialog({ + title: settings.title, + message: settings.msg, + onAccept: function() { + $.ajax({ + method: "post", + url: settings.url, + data: { + page: settings.page, + method: "deleteActionAlert", + id_alert: settings.id_alert, + id_action: settings.id_action + }, + dataType: "json", + success: function(data) { + // Delete row table. + $( + "#li-al-" + settings.id_alert + "-act-" + settings.id_action + ).remove(); + + var num_row = $("#ul-al-" + settings.id_alert + " li").length; + if (num_row === 0) { + var emptyli = + "