diff --git a/extras/bin/gotty b/extras/bin/gotty new file mode 100755 index 0000000000..1a1de33cf6 Binary files /dev/null and b/extras/bin/gotty differ diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 3ef505359c..ce165fde19 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.740 +Version: 7.0NG.740-191029 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 9af189b481..a4a8dce448 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.740" +pandora_version="7.0NG.740-191029" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 3aa3d9c388..4bbac522b1 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -42,7 +42,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.740'; -use constant AGENT_BUILD => '191028'; +use constant AGENT_BUILD => '191029'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index dc23e90e2d..79f2310c11 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.740 -%define release 1 +%define release 191029 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index cf4330bba0..392fa174ce 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.740 -%define release 1 +%define release 191029 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 05570423aa..cc4b78b51c 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.740" -PI_BUILD="191028" +PI_BUILD="191029" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index 8e5e36a97d..730edbe5de 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{191028} +{191029} ViewReadme {Yes} @@ -2387,7 +2387,7 @@ Windows,BuildSeparateArchives {No} Windows,Executable -{<%AppName%>-Setup<%Ext%>} +{<%AppName%>-<%Version%>-Setup<%Ext%>} Windows,FileDescription {<%AppName%> <%Version%> Setup} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 7a7ab195eb..823b486b0e 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.740(Build 191028)") +#define PANDORA_VERSION ("7.0NG.740(Build 191029)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index e76449bf45..d714543482 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.740(Build 191028))" + VALUE "ProductVersion", "(7.0NG.740(Build 191029))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index c932f3baa0..cab514f37e 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.740 +Version: 7.0NG.740-191029 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 3b439db8c6..64140d02ad 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.740" +pandora_version="7.0NG.740-191029" package_pear=0 package_pandora=1 diff --git a/pandora_console/composer.json b/pandora_console/composer.json index 208e2d3d14..4138dc77c2 100644 --- a/pandora_console/composer.json +++ b/pandora_console/composer.json @@ -1,5 +1,5 @@ { - "name": "Pandora FMS", + "name": "pandorafms/console", "description": "Pandora Flexible Monitoring System ", "authors": [ { @@ -14,7 +14,9 @@ "autoload": { "psr-4": { "Models\\": "include/rest-api/models", - "Enterprise\\Models\\": "enterprise/include/rest-api/models" + "Enterprise\\Models\\": "enterprise/include/rest-api/models", + "PandoraFMS\\": "include/lib", + "PandoraFMS\\Enterprise\\": "enterprise/include/lib" } }, "autoload-dev": { diff --git a/pandora_console/extensions/quick_shell.php b/pandora_console/extensions/quick_shell.php new file mode 100644 index 0000000000..8c87577abc --- /dev/null +++ b/pandora_console/extensions/quick_shell.php @@ -0,0 +1,503 @@ +printForm( + [ + 'form' => [ + 'method' => 'POST', + 'action' => '#', + ], + 'inputs' => [ + [ + 'class' => 'w100p', + 'arguments' => [ + 'name' => 'submit', + 'label' => __('Retry'), + 'type' => 'submit', + 'attributes' => 'class="sub next"', + 'return' => true, + ], + ], + ], + ] + ); + + return; + } + + $wiz->printForm( + [ + 'form' => [ + 'action' => '#', + 'class' => 'wizard', + 'method' => 'post', + ], + 'inputs' => [ + [ + 'label' => __('Username'), + 'arguments' => [ + 'type' => 'text', + 'name' => 'username', + ], + ], + [ + 'label' => __('Port'), + 'arguments' => [ + 'type' => 'text', + 'id' => 'port', + 'name' => 'port', + 'value' => 22, + ], + ], + [ + 'label' => __('Method'), + 'arguments' => [ + 'type' => 'select', + 'name' => 'method', + 'fields' => [ + 'ssh' => __('SSH'), + 'telnet' => __('Telnet'), + ], + 'script' => "p=22; if(this.value == 'telnet') { p=23; } $('#text-port').val(p);", + ], + ], + [ + 'arguments' => [ + 'type' => 'submit', + 'label' => __('Connect'), + 'attributes' => 'class="sub next"', + ], + ], + ], + ], + false, + true + ); + + return; + } + + // Initialize Gotty Client. + $host = $config['gotty_host']; + if ($method == 'ssh') { + // SSH. + $port = $config['gotty_ssh_port']; + $command_arguments = "var args = '?arg=".$username.'@'.$address; + $command_arguments .= '&arg=-p '.$method_port."';"; + } else if ($method == 'telnet') { + // Telnet. + $port = $config['gotty_telnet_port']; + $command_arguments = "var args = '?arg=-l ".$username; + $command_arguments .= '&arg='.$address; + $command_arguments .= '&arg='.$method_port."';"; + } else { + ui_print_error_message(__('Please use SSH or Telnet.')); + return; + } + + // If rediretion is enabled, we will try to connect to http:// or https:// endpoint. + $test = get_headers($ws_url); + if ($test === false) { + if (empty($wiz) === true) { + $wiz = new Wizard(); + } + + ui_print_error_message(__('WebService engine has not been started, please check documentation.')); + echo $wiz->printGoBackButton('#'); + return; + } + + // Check credentials. + $auth_str = ''; + $gotty_url = $host.':'.$port; + if (empty($config['gotty_user']) === false + && empty($config['gotty_pass']) === false + ) { + $auth_str = $config['gotty_user'].':'.$config['gotty_pass']; + $gotty_url = $auth_str.'@'.$host.':'.$port; + } + + $r = file_get_contents('http://'.$gotty_url.'/js/hterm.js'); + if (empty($r) === true) { + if (empty($wiz) === true) { + $wiz = new Wizard(); + } + + ui_print_error_message(__('WebService engine is not working properly, please check documentation.')); + echo $wiz->printGoBackButton('#'); + return; + } + + // Override gotty client settings. + if (empty($auth_str) === true) { + $r .= "var gotty_auth_token = '';"; + } else { + $r .= "var gotty_auth_token = '"; + $r .= $auth_str."';"; + } + + // Set websocket target and method. + $gotty = file_get_contents('http://'.$gotty_url.'/js/gotty.js'); + $url = "var url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname + 'ws';"; + if (empty($config['ws_proxy_url']) === true) { + $new = "var url = (httpsEnabled ? 'wss://' : 'ws://')"; + $new .= " + window.location.host + ':"; + $new .= $config['ws_port'].'/'.$method."';"; + } else { + $new = "var url = '"; + $new .= $config['ws_proxy_url'].'/'.$method."';"; + } + + // Update url. + $gotty = str_replace($url, $new, $gotty); + + // Update websocket arguments. + $args = 'var args = window.location.search;'; + $new = $command_arguments; + + // Update arguments. + $gotty = str_replace($args, $new, $gotty); + + ?> + +
+ + + 0) { + $msg = __('%d Updated', $changes); + if ($critical > 0) { + $msg = __( + '%d Updated, please restart WebSocket engine service', + $changes + ); + } + + ui_print_success_message($msg); + } + + // Form. + $wiz = new Wizard(); + + $wiz->printForm( + [ + 'form' => [ + 'action' => '#', + 'class' => 'wizard', + 'method' => 'post', + ], + 'inputs' => [ + [ + 'label' => __('Gotty path').ui_print_help_tip( + __('Leave blank if using an external Gotty service') + ), + 'arguments' => [ + 'type' => 'text', + 'name' => 'gotty', + 'value' => $config['gotty'], + ], + ], + [ + 'label' => __('Gotty host'), + 'arguments' => [ + 'type' => 'text', + 'name' => 'gotty_host', + 'value' => $config['gotty_host'], + ], + ], + [ + 'label' => __('Gotty ssh port'), + 'arguments' => [ + 'type' => 'text', + 'name' => 'gotty_ssh_port', + 'value' => $config['gotty_ssh_port'], + ], + ], + [ + 'label' => __('Gotty telnet port'), + 'arguments' => [ + 'type' => 'text', + 'name' => 'gotty_telnet_port', + 'value' => $config['gotty_telnet_port'], + ], + ], + [ + 'label' => __('Gotty user').ui_print_help_tip( + __('Optional, set a user to access gotty service') + ), + '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') + ), + 'arguments' => [ + 'type' => 'password', + 'name' => 'gotty_pass', + 'value' => io_output_password($config['gotty_pass']), + ], + ], + [ + 'arguments' => [ + 'type' => 'submit', + 'label' => __('Update'), + 'attributes' => 'class="sub next"', + ], + ], + ], + ], + false, + true + ); + +} + + +// This extension is usefull only if the agent has associated IP. +$agent_id = get_parameter('id_agente'); +if (empty($agent_id) === false + && get_parameter('sec2', '') == 'operation/agentes/ver_agente' +) { + $address = agents_get_address($agent_id); + if (empty($address) === false) { + // Extension registration. + extensions_add_opemode_tab_agent( + // TabId. + 'quick_shell', + // TabName. + __('QuickShell'), + // TabIcon. + 'images/ehorus/terminal.png', + // TabFunction. + 'quickShell', + // Version. + 'N/A', + // Acl. + 'PM' + ); + } +} + +extensions_add_godmode_menu_option( + // Name. + __('QuickShell settings'), + // Acl. + 'PM', + // FatherId. + 'gextensions', + // Icon. + 'images/ehorus/terminal.png', + // Version. + 'N/A', + // SubfatherId. + null +); + +extensions_add_godmode_function('quickShellSettings'); diff --git a/pandora_console/extensions/resource_exportation.php b/pandora_console/extensions/resource_exportation.php index ddfa9866ad..14384aaec3 100755 --- a/pandora_console/extensions/resource_exportation.php +++ b/pandora_console/extensions/resource_exportation.php @@ -238,19 +238,6 @@ function output_xml_report($id) echo ''; echo ''; break; - - /* - case 'TTRT': - break; - - case 'TTO': - break; - - case 'MTBF': - break; - - case 'MTTR': - break;*/ } echo "\n"; diff --git a/pandora_console/extensions/resource_registration.php b/pandora_console/extensions/resource_registration.php index ea9a5f50e8..dae61e3a78 100755 --- a/pandora_console/extensions/resource_registration.php +++ b/pandora_console/extensions/resource_registration.php @@ -375,19 +375,6 @@ function process_upload_xml_report($xml, $group_filter=0) $values['line_separator'] = io_safe_input($item['line_separator']); $values['column_separator'] = io_safe_input($item['column_separator']); break; - - /* - case 'TTRT': - break; - - case 'TTO': - break; - - case 'MTBF': - break; - - case 'MTTR': - break;*/ } if (empty($agents_item)) { diff --git a/pandora_console/extensions/sample_agent.php b/pandora_console/extensions/sample_agent.php new file mode 100644 index 0000000000..ba92debae9 --- /dev/null +++ b/pandora_console/extensions/sample_agent.php @@ -0,0 +1,66 @@ + $id_agente], 'id_agente_modulo'); + $count_modules = count($modules); + + // Update of layout 1 (Rack sample). + $images_rack_server = [ + 'rack_server_rack', + 'rack_server', + 'rack_switch', + 'rack_firewall', + 'rack_double_server', + 'rack_frame', + 'rack_pdu', + ]; + $query = 'UPDATE `tlayout_data` SET `id_agent` = '.$id_agente.', `id_agente_modulo` = CASE '; + for ($i = 0; $i < $count_modules; $i++) { + $query .= 'WHEN `image` = "'.$images_rack_server[$i].'" THEN '.$modules[$i]['id_agente_modulo'].' '; + } + + $query .= 'END WHERE `id_layout` = 1 AND `image` IN ("'.implode('","', $images_rack_server).'");'; + + db_process_sql($query); + // Update of layout 2 (Dashboard). + $query = 'UPDATE `tlayout_data` SET `id_agent`= '.$id_agente.', `id_agente_modulo` = CASE '; + $query .= 'WHEN `id` = 107 THEN '.$modules[0]['id_agente_modulo'].' '; + $query .= 'WHEN `id` = 108 THEN '.$modules[1]['id_agente_modulo'].' '; + $query .= 'WHEN `id` = 109 THEN '.$modules[2]['id_agente_modulo'].' '; + $query .= 'WHEN `id` = 110 THEN '.$modules[2]['id_agente_modulo'].' '; + $query .= 'WHEN `id` = 111 THEN '.$modules[3]['id_agente_modulo'].' '; + $query .= 'WHEN `id` = 112 THEN '.$modules[4]['id_agente_modulo'].' '; + $query .= 'WHEN `id` = 113 THEN '.$modules[5]['id_agente_modulo'].' '; + $query .= 'WHEN `id` = 114 THEN '.$modules[6]['id_agente_modulo'].' '; + $query .= 'END WHERE `id_layout` = 2 AND `id` IN (107,108,109,110,111,112,113,114);'; + + db_process_sql($query); + + // This setting will avoid regenerate all the times the visual consoles. + config_update_value('sample_agent_deployed', 1); +} + +extensions_add_main_function('sample_agent_deployment'); diff --git a/pandora_console/extras/mr/33.sql b/pandora_console/extras/mr/33.sql index eeca8ed5d7..3d5e32a42d 100644 --- a/pandora_console/extras/mr/33.sql +++ b/pandora_console/extras/mr/33.sql @@ -1,9 +1,11 @@ START TRANSACTION; +ALTER TABLE `tlayout_template_data` ADD COLUMN `cache_expiration` INTEGER UNSIGNED NOT NULL DEFAULT 0; + INSERT INTO `ttipo_modulo` VALUES (34,'remote_cmd', 10, 'Remote execution, numeric data', 'mod_remote_cmd.png'), (35,'remote_cmd_proc', 10, 'Remote execution, boolean data', 'mod_remote_cmd_proc.png'), (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'); -COMMIT; \ No newline at end of file +COMMIT; diff --git a/pandora_console/extras/pandora_diag.php b/pandora_console/extras/pandora_diag.php index eb9a199456..b047106679 100644 --- a/pandora_console/extras/pandora_diag.php +++ b/pandora_console/extras/pandora_diag.php @@ -1,796 +1,2 @@ - - $value) { - db_process_sql_update( - 'tupdate_settings', - [db_escape_key_identifier('value') => $value], - [db_escape_key_identifier('key') => $key] - ); - } - - ui_print_success_message(__('License updated')); -} - -ui_require_javascript_file_enterprise('load_enterprise'); -enterprise_include_once('include/functions_license.php'); -$license = enterprise_hook('license_get_info'); - -$rows = db_get_all_rows_in_table('tupdate_settings'); - -$settings = new StdClass; -foreach ($rows as $row) { - $settings->{$row['key']} = $row['value']; -} - -echo ''; - - -function render_info($table) -{ - global $console_mode; - - $info = db_get_sql("SELECT COUNT(*) FROM $table"); - render_row($info, "DB Table $table"); -} - - -function render_info_data($query, $label) -{ - global $console_mode; - - $info = db_get_sql($query); - render_row($info, $label); -} - - -function render_row($data, $label) -{ - global $console_mode; - - if ($console_mode == 1) { - echo $label; - echo '|'; - echo $data; - echo "\n"; - } else { - echo ''; - echo "
".$label; - echo '
'; - echo "
".$data; - echo '
'; - echo ''; - } -} - - -function get_value_sum($arr) -{ - foreach ($arr as $clave) { - foreach ($clave as $valor) { - if (is_numeric($valor) === true) { - $result += $valor; - } - } - } - - return $result; -} - - -function execution_time() -{ - $times = db_get_all_rows_sql('SELECT datos FROM tagente_datos WHERE id_agente_modulo = 29 ORDER BY utimestamp DESC LIMIT 2'); - if ($times[0]['datos'] > ($times[1]['datos'] * 1.2)) { - return "Warning Status   The execution time could be degrading. For a more extensive information of this data consult the Execution Time graph"; - } else { - return "Normal Status   The execution time is correct. For more information about this data, check the Execution Time graph"; - } -} - - -function get_logs_size($file) -{ - $file_name = '/var'.$file.''; - $size_server_log = filesize($file_name); - return $size_server_log; - -} - - -function get_status_logs($path) -{ - $status_server_log = ''; - $size_server_log = number_format(get_logs_size($path)); - $size_server_log = (0 + str_replace(',', '', $size_server_log)); - if ($size_server_log <= 10485760) { - $status_server_log = "Normal Status   You have less than 10 MB of logs"; - } else { - $status_server_log = "Warning Status   You have more than 10 MB of logs"; - } - - return $status_server_log; -} - - -function percentage_modules_per_agent() -{ - $status_average_modules = ''; - $total_agents = db_get_value_sql('SELECT count(*) FROM tagente'); - $total_modules = db_get_value_sql('SELECT count(*) FROM tagente_modulo'); - $average_modules_per_agent = ($total_modules / $total_agents); - if ($average_modules_per_agent <= 40) { - $status_average_modules = "Normal Status   The average of modules per agent is less than 40"; - } else { - $status_average_modules = "Warning Status  The average of modules per agent is more than 40. You can have performance problems"; - } - - return $status_average_modules; -} - - -function license_capacity() -{ - $license = enterprise_hook('license_get_info'); - $license_limit = $license['limit']; - $status_license_capacity = ''; - $current_count = db_get_value_sql('SELECT count(*) FROM tagente'); - if ($current_count > ($license_limit * 90 / 100)) { - $status_license_capacity = "Warning Status   License capacity exceeds 90 percent"; - } else { - $status_license_capacity = "Normal Status   License capacity is less than 90 percent"; - } - - return $status_license_capacity; -} - - -function status_license_params($license_param) -{ - $status_license_par = ''; - if ($license_param <= 0) { - $status_license_par = 'OFF'; - } else { - $status_license_par = 'ON'; - } - - return $status_license_par; -} - - -function interval_average_of_network_modules() -{ - $total_network_modules = db_get_value_sql('SELECT count(*) FROM tagente_modulo WHERE id_tipo_modulo BETWEEN 6 AND 18'); - $total_module_interval_time = db_get_value_sql('SELECT SUM(module_interval) FROM tagente_modulo WHERE id_tipo_modulo BETWEEN 6 AND 18'); - $average_time = ((int) $total_module_interval_time / $total_network_modules); - - if ($average_time < 180) { - $status_average_modules = "Warning Status   The system is overloaded (average time $average_time) and a very fine configuration is required"; - } else { - $status_average_modules = "Normal Status   The system is not overloaded (average time $average_time) "; - } - - if ($average_time == 0) { - $status_average_modules = "Normal Status   The system has no load"; - } - - return $status_average_modules; -} - - -$attachment_total_files = count(glob($config['homedir'].'/attachment/{*.*}', GLOB_BRACE)); - - -function files_attachment_folder($total_files) -{ - if ($total_files <= 700) { - $status_total_files = "Normal Status   The attached folder contains less than 700 files."; - } else { - $status_total_files = "Warning Status   The attached folder contains more than 700 files."; - } - - return $status_total_files; -} - - -$tagente_datos_size = db_get_value_sql('SELECT COUNT(*) FROM tagente_datos'); - - -function status_tagente_datos($tagente_datos_size) -{ - if ($tagente_datos_size <= 3000000) { - $tagente_datos_size = "Normal Status   The tagente_datos table contains an acceptable amount of data."; - } else { - $tagente_datos_size = "Warning Status   The tagente_datos table contains too much data. A historical database is recommended."; - } - - return $tagente_datos_size; -} - - -function status_values($val_rec, $val) -{ - if ($val_rec <= $val) { - return $val." (Min. Recommended Value ".$val_rec.')'; - } else { - return $val." (Min. Recommended Value ".$val_rec.") Warning Status"; - } -} - - -$tables_fragmentation = db_get_sql( - "SELECT (data_free/(index_length+data_length)) -as frag_ratio from information_schema.tables where DATA_FREE > 0 and table_name='tagente_datos' and table_schema='pandora'" -); -$db_size = db_get_all_rows_sql( - 'SELECT table_schema, -ROUND(SUM(data_length+index_length)/1024/1024,3) -FROM information_schema.TABLES -GROUP BY table_schema;' -); - -if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { - $total_server_threads = shell_exec('ps -T aux | grep pandora_server | grep -v grep | wc -l'); - $percentage_threads_ram = shell_exec("ps axo pmem,cmd | grep pandora_server | awk '{sum+=$1} END {print sum}'"); - $percentage_threads_cpu = shell_exec("ps axo pcpu,cmd | grep pandora_server | awk '{sum+=$1} END {print sum}'"); - $innodb_buffer_pool_size_min_rec_value = shell_exec("cat /proc/meminfo | grep -i total | head -1 | awk '{print $(NF-1)*0.4/1024}'"); -} - -$path_server_logs = '/log/pandora/pandora_server.log'; -$path_err_logs = '/log/pandora/pandora_server.error'; -$path_console_logs = '/www/html/pandora_console/pandora_console.log'; -$innodb_log_file_size_min_rec_value = '64M'; -$innodb_log_buffer_size_min_rec_value = '16M'; -$innodb_flush_log_at_trx_commit_min_rec_value = 0; -$query_cache_limit_min_rec_value = 2; -$max_allowed_packet_min_rec_value = 32; -$innodb_buffer_pool_size_min_rec_value = shell_exec("cat /proc/meminfo | grep -i total | head -1 | awk '{print $(NF-1)*0.4/1024}'"); -$sort_buffer_size_min_rec_value = 32; -$join_buffer_size_min_rec_value = 265; -$query_cache_type_min_rec_value = 'ON'; -$query_cache_size_min_rec_value = 24; -$innodb_lock_wait_timeout_max_rec_value = 120; -$tables_fragmentation_max_rec_value = 10; -$thread_cache_size_max_rec_value = 8; -$thread_stack_min_rec_value = 256; -$max_connections_max_rec_value = 150; -$key_buffer_size_min_rec_value = 256; -$read_buffer_size_min_rec_value = 32; -$read_rnd_buffer_size_min_rec_value = 32; -$query_cache_min_res_unit_min_rec_value = 2; -$innodb_file_per_table_min_rec_value = 1; - - -function status_fragmentation_tables($tables_fragmentation_max_rec_value, $tables_fragmentation) -{ - $status_tables_frag = ''; - if ($tables_fragmentation > $tables_fragmentation_max_rec_value) { - $status_tables_frag = "Warning Status   Table fragmentation is higher than recommended. They should be defragmented."; - } else { - $status_tables_frag = "Normal Status   Table fragmentation is correct."; - } - - return $status_tables_frag; -} - - -$console_mode = 1; -if (!isset($argc)) { - $console_mode = 0; -} - -if ($console_mode == 1) { - echo "\nPandora FMS PHP diagnostic tool v3.2 (c) Artica ST 2009-2010 \n"; - - if ($argc == 1 || in_array($argv[1], ['--help', '-help', '-h', '-?'])) { - echo "\nThis command line script contains information about Pandora FMS database. - This program can only be executed from the console, and it needs a parameter, the - full path to Pandora FMS 'config.php' file. - - Usage: - php pandora_diag.php path_to_pandora_console - - Example: - php pandora_diag.php /var/www/pandora_console - -"; - exit; - } - - if (preg_match('/[^a-zA-Z0-9_\/\.]|(\/\/)|(\.\.)/', $argv[1])) { - echo "Invalid path: $argv[1]. Always use absolute paths."; - exit; - } - - include $argv[1].'/include/config.php'; -} else { - if (file_exists('../include/config.php')) { - include '../include/config.php'; - } - - // Not from console, this is a web session. - if ((!isset($config['id_user'])) || (!check_acl($config['id_user'], 0, 'PM'))) { - echo "

You don't have privileges to use diagnostic tool

"; - echo '

Please login with an administrator account before try to use this tool

'; - exit; - } - - // Header. - ui_print_page_header( - __('Pandora FMS Diagnostic tool'), - '', - false, - 'diagnostic_tool_tab', - true - ); - - echo ""; - echo "'; -} - -render_row($build_version, 'Pandora FMS Build'); -render_row($pandora_version, 'Pandora FMS Version'); -render_info_data("SELECT value FROM tconfig where token ='MR'", 'Minor Release'); -render_row($config['homedir'], 'Homedir'); -render_row($config['homeurl'], 'HomeUrl'); -render_info_data( - "SELECT `value` - FROM tconfig - WHERE `token` = 'enterprise_installed'", - 'Enterprise installed' -); - - $full_key = db_get_sql( - "SELECT value - FROM tupdate_settings - WHERE `key` = 'customer_key'" - ); - - $compressed_key = substr($full_key, 0, 5).'...'.substr($full_key, -5); - - render_row($compressed_key, 'Update Key'); - - render_info_data( - "SELECT value - FROM tupdate_settings - WHERE `key` = 'updating_code_path'", - 'Updating code path' - ); - - render_info_data( - "SELECT value - FROM tupdate_settings - WHERE `key` = 'current_update'", - 'Current Update #' - ); - - - echo "'; - - - render_row(phpversion(), 'PHP Version'); - - render_row(ini_get('max_execution_time').' seconds', 'PHP Max execution time'); - - render_row(ini_get('max_input_time').' seconds', 'PHP Max input time'); - - render_row(ini_get('memory_limit'), 'PHP Memory limit'); - - render_row(ini_get('session.cookie_lifetime'), 'Session cookie lifetime'); - - echo "'; - - render_info_data('SELECT COUNT(*) FROM tagente', 'Total agents'); - render_info_data('SELECT COUNT(*) FROM tagente_modulo', 'Total modules'); - render_info_data('SELECT COUNT(*) FROM tgrupo', 'Total groups'); - render_info_data('SELECT COUNT(*) FROM tagente_datos', 'Total module data records'); - render_info_data('SELECT COUNT(*) FROM tagent_access', 'Total agent access record'); - render_info_data('SELECT COUNT(*) FROM tevento', 'Total events'); - - if ($config['enterprise_installed']) { - render_info_data('SELECT COUNT(*) FROM ttrap', 'Total traps'); - } - - render_info_data('SELECT COUNT(*) FROM tusuario', 'Total users'); - render_info_data('SELECT COUNT(*) FROM tsesion', 'Total sessions'); - - echo "'; - - render_info_data( - 'SELECT COUNT( DISTINCT tagente.id_agente) - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente.disabled = 0 - AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo - AND tagente_modulo.disabled = 0 - AND tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.estado = 3', - 'Total unknown agents' - ); - - render_info_data( - 'SELECT COUNT(tagente_estado.estado) - FROM tagente_estado - WHERE tagente_estado.estado = 4', - 'Total not-init modules' - ); - - - $last_run_difference = ''; - - $diferencia = (time() - date( - db_get_sql( - "SELECT `value` - FROM tconfig - WHERE `token` = 'db_maintance'" - ) - )); - - $last_run_difference_months = 0; - $last_run_difference_weeks = 0; - $last_run_difference_days = 0; - $last_run_difference_minutos = 0; - $last_run_difference_seconds = 0; - - while ($diferencia >= 2419200) { - $diferencia -= 2419200; - $last_run_difference_months++; - } - - while ($diferencia >= 604800) { - $diferencia -= 604800; - $last_run_difference_weeks++; - } - - while ($diferencia >= 86400) { - $diferencia -= 86400; - $last_run_difference_days++; - } - - while ($diferencia >= 3600) { - $diferencia -= 3600; - $last_run_difference_hours++; - } - - while ($diferencia >= 60) { - $diferencia -= 60; - $last_run_difference_minutes++; - } - - $last_run_difference_seconds = $diferencia; - - if ($last_run_difference_months > 0) { - $last_run_difference .= $last_run_difference_months.'month/s '; - } - - if ($last_run_difference_weeks > 0) { - $last_run_difference .= $last_run_difference_weeks.' week/s '; - } - - if ($last_run_difference_days > 0) { - $last_run_difference .= $last_run_difference_days.' day/s '; - } - - if ($last_run_difference_hours > 0) { - $last_run_difference .= $last_run_difference_hours.' hour/s '; - } - - if ($last_run_difference_minutes > 0) { - $last_run_difference .= $last_run_difference_minutes.' minute/s '; - } - - $last_run_difference .= $last_run_difference_seconds.' second/s ago'; - - render_row( - date( - 'Y/m/d H:i:s', - db_get_sql( - "SELECT `value` - FROM tconfig - WHERE `token` = 'db_maintance'" - ) - ).' ('.$last_run_difference.')'.' *', - 'PandoraDB Last run' - ); - - echo "'; - - switch ($config['dbtype']) { - case 'mysql': - render_info_data( - "SELECT `value` - FROM tconfig - WHERE `token` = 'db_scheme_first_version'", - 'DB Schema Version (first installed)' - ); - render_info_data( - "SELECT `value` - FROM tconfig - WHERE `token` = 'db_scheme_version'", - 'DB Schema Version (actual)' - ); - render_info_data( - "SELECT `value` - FROM tconfig - WHERE `token` = 'db_scheme_build'", - 'DB Schema Build' - ); - - render_row(get_value_sum($db_size).'M', 'DB Size'); - - - if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { - echo "'; - - $output = 'cat /proc/cpuinfo | grep "model name" | tail -1 | cut -f 2 -d ":"'; - $output2 = 'cat /proc/cpuinfo | grep "processor" | wc -l'; - - render_row(exec($output).' x '.exec($output2), 'CPU'); - - $output = 'cat /proc/meminfo | grep "MemTotal"'; - - render_row(exec($output), 'RAM'); - } - break; - - case 'postgresql': - render_info_data( - "SELECT \"value\" - FROM tconfig - WHERE \"token\" = 'db_scheme_version'", - 'DB Schema Version' - ); - render_info_data( - "SELECT \"value\" - FROM tconfig - WHERE \"token\" = 'db_scheme_build'", - 'DB Schema Build' - ); - render_info_data( - "SELECT \"value\" - FROM tconfig - WHERE \"token\" = 'enterprise_installed'", - 'Enterprise installed' - ); - render_row( - date( - 'Y/m/d H:i:s', - db_get_sql( - "SELECT \"value\" - FROM tconfig WHERE \"token\" = 'db_maintance'" - ) - ), - 'PandoraDB Last run' - ); - - render_info_data( - "SELECT value - FROM tupdate_settings - WHERE \"key\" = 'customer_key';", - 'Update Key' - ); - render_info_data( - "SELECT value - FROM tupdate_settings - WHERE \"key\" = 'updating_code_path'", - 'Updating code path' - ); - render_info_data( - "SELECT value - FROM tupdate_settings - WHERE \"key\" = 'current_update'", - 'Current Update #' - ); - break; - - case 'oracle': - render_info_data( - "SELECT value - FROM tconfig - WHERE token = 'db_scheme_version'", - 'DB Schema Version' - ); - render_info_data( - "SELECT value - FROM tconfig - WHERE token = 'db_scheme_build'", - 'DB Schema Build' - ); - render_info_data( - "SELECT value - FROM tconfig - WHERE token = 'enterprise_installed'", - 'Enterprise installed' - ); - render_row( - db_get_sql( - "SELECT value - FROM tconfig - WHERE token = 'db_maintance'" - ), - 'PandoraDB Last run' - ); - - render_info_data( - 'SELECT '.db_escape_key_identifier('value')." FROM tupdate_settings - WHERE \"key\" = 'customer_key'", - 'Update Key' - ); - render_info_data( - 'SELECT '.db_escape_key_identifier('value')." FROM tupdate_settings - WHERE \"key\" = 'updating_code_path'", - 'Updating code path' - ); - render_info_data( - 'SELECT '.db_escape_key_identifier('value')." FROM tupdate_settings - WHERE \"key\" = 'current_update'", - 'Current Update #' - ); - break; - } - - $innodb_log_file_size = (db_get_value_sql('SELECT @@innodb_log_file_size') / 1048576); - $innodb_log_buffer_size = (db_get_value_sql('SELECT @@innodb_log_buffer_size') / 1048576); - $innodb_flush_log_at_trx_commit = db_get_value_sql('SELECT @@innodb_flush_log_at_trx_commit'); - $max_allowed_packet = (db_get_value_sql('SELECT @@max_allowed_packet') / 1048576); - $innodb_buffer_pool_size = (db_get_value_sql('SELECT @@innodb_buffer_pool_size') / 1024); - $sort_buffer_size = number_format((db_get_value_sql('SELECT @@sort_buffer_size') / 1024), 2); - $join_buffer_size = (db_get_value_sql('SELECT @@join_buffer_size') / 1024); - $query_cache_type = db_get_value_sql('SELECT @@query_cache_type'); - $query_cache_size = (db_get_value_sql('SELECT @@query_cache_size') / 1048576); - $query_cache_limit = (db_get_value_sql('SELECT @@query_cache_limit') / 1048576); - $innodb_lock_wait_timeout = db_get_value_sql('SELECT @@innodb_lock_wait_timeout'); - $thread_cache_size = db_get_value_sql('SELECT @@thread_cache_size'); - $thread_stack = (db_get_value_sql('SELECT @@thread_stack') / 1024); - $max_connections = db_get_value_sql('SELECT @@max_connections'); - $key_buffer_size = (db_get_value_sql('SELECT @@key_buffer_size') / 1024); - $read_buffer_size = (db_get_value_sql('SELECT @@read_buffer_size') / 1024); - $read_rnd_buffer_size = (db_get_value_sql('SELECT @@read_rnd_buffer_size') / 1024); - $query_cache_min_res_unit = (db_get_value_sql('SELECT @@query_cache_min_res_unit') / 1024); - $innodb_file_per_table = db_get_value_sql('SELECT @@innodb_file_per_table'); - echo "'; - - render_row(status_values($innodb_log_file_size_min_rec_value, $innodb_log_file_size), 'InnoDB log file size ', 'InnoDB log file size '); - render_row(status_values($innodb_log_buffer_size_min_rec_value, $innodb_log_buffer_size), 'InnoDB log buffer size ', 'InnoDB log buffer size '); - render_row(status_values($innodb_flush_log_at_trx_commit_min_rec_value, $innodb_flush_log_at_trx_commit), 'InnoDB flush log at trx-commit ', 'InnoDB flush log at trx-commit '); - render_row(status_values($max_allowed_packet_min_rec_value, $max_allowed_packet), 'Maximun allowed packet ', 'Maximun allowed packet '); - render_row(status_values($innodb_buffer_pool_size_min_rec_value, $innodb_buffer_pool_size), 'InnoDB buffer pool size ', 'InnoDB buffer pool size '); - render_row(status_values($sort_buffer_size_min_rec_value, $sort_buffer_size), 'Sort buffer size ', 'Sort buffer size '); - render_row(status_values($join_buffer_size_min_rec_value, $join_buffer_size), 'Join buffer size ', 'Join buffer size '); - render_row(status_values($query_cache_type_min_rec_value, $query_cache_type), 'Query cache type ', 'Query cache type '); - render_row(status_values($query_cache_size_min_rec_value, $query_cache_size), 'Query cache size ', 'Query cache size '); - render_row(status_values($query_cache_limit_min_rec_value, $query_cache_limit), 'Query cache limit ', 'Query cache limit '); - render_row(status_values($innodb_lock_wait_timeout_max_rec_value, $innodb_lock_wait_timeout), 'InnoDB lock wait timeout ', 'InnoDB lock wait timeout '); - render_row(status_values($thread_cache_size_max_rec_value, $thread_cache_size), 'Thread cache size ', 'Thread cache size '); - render_row(status_values($thread_stack_min_rec_value, $thread_stack), 'Thread stack ', 'Thread stack '); - render_row(status_values($max_connections_max_rec_value, $max_connections), 'Maximum connections ', 'Maximun connections '); - render_row(status_values($key_buffer_size_min_rec_value, $key_buffer_size), 'Key buffer size ', 'Key buffer size '); - render_row(status_values($read_buffer_size_min_rec_value, $read_buffer_size), 'Read buffer size ', 'Read buffer size '); - render_row(status_values($read_rnd_buffer_size_min_rec_value, $read_rnd_buffer_size), 'Read rnd-buffer size ', 'Read rnd-buffer size '); - render_row(status_values($query_cache_min_res_unit_min_rec_value, $query_cache_min_res_unit), 'Query cache min-res-unit ', 'Query cache min-res-unit '); - render_row(status_values($innodb_file_per_table_min_rec_value, $innodb_file_per_table), 'InnoDB file per table ', 'InnoDB file per table '); - echo "'; - - - - render_row($tables_fragmentation_max_rec_value.'%', 'Tables fragmentation (maximum recommended value)'); - render_row(number_format($tables_fragmentation, 2).'%', 'Tables fragmentation (current value)'); - render_row(status_fragmentation_tables($tables_fragmentation_max_rec_value, $tables_fragmentation), 'Table fragmentation status'); - - echo "'; - - render_row(number_format((get_logs_size($path_server_logs) / 1048576), 3).'M', 'Size server logs (current value)'); - render_row(get_status_logs($path_server_logs), 'Status server logs'); - render_row(number_format((get_logs_size($path_err_logs) / 1048576), 3).'M', 'Size error logs (current value)'); - render_row(get_status_logs($path_err_logs), 'Status error logs'); - render_row(number_format((get_logs_size($path_console_logs) / 1048576), 3).'M', 'Size console logs (current value)'); - render_row(get_status_logs($path_console_logs), 'Status console logs'); - - echo "'; - - render_row(html_print_textarea('keys[customer_key]', 10, 255, $settings->customer_key, 'style="height:40px; width:450px;"', true), 'Customer key'); - render_row($license['expiry_date'], $license['expiry_caption']); - render_row($license['limit'].' agents', 'Platform Limit'); - render_row($license['count'].' agents', 'Current Platform Count'); - render_row($license['count_enabled'].' agents', 'Current Platform Count (enabled: items)'); - render_row($license['count_disabled'].' agents', 'Current Platform Count (disabled: items)'); - render_row($license['license_mode'], 'License Mode'); - render_row(status_license_params($license['nms']), 'Network Management System'); - render_row(status_license_params($license['dhpm']), 'Satellite'); - render_row($license['licensed_to'], 'Licensed to'); - render_row(license_capacity(), 'Status of agents capacity'); - render_row(percentage_modules_per_agent(), 'Status of average modules per agent'); - render_row(interval_average_of_network_modules(), 'Interval average of the network modules'); - - echo "'; - - render_row($attachment_total_files, 'Total files in the attached folder'); - render_row(files_attachment_folder($attachment_total_files), 'Status of the attachment folder'); - - echo "'; - - render_row($tagente_datos_size, 'Total data in tagente_datos table'); - render_row(status_tagente_datos($tagente_datos_size), 'Tangente_datos table status'); - render_row(execution_time(), 'Execution time degradation when executing a count'); - - echo "'; - - render_row($total_server_threads, 'Total server threads'); - render_row($percentage_threads_ram.'%', 'Percentage of threads used by the RAM'); - render_row($percentage_threads_cpu.'%', 'Percentage of threads used by the CPU'); - - echo "'; - - $server_name = db_get_value_sql('SELECT name FROM tserver WHERE master = 1'); - $agent_id = db_get_value_sql("SELECT id_agente FROM tagente WHERE nombre = '$server_name'"); - - $id_modules = agents_get_modules($agent_id); - - $id_modules = [ - modules_get_agentmodule_id('Agents_Unknown', $agent_id), - modules_get_agentmodule_id('Database Maintenance', $agent_id), - modules_get_agentmodule_id('FreeDisk_SpoolDir', $agent_id), - modules_get_agentmodule_id('Free_RAM', $agent_id), - modules_get_agentmodule_id('Queued_Modules', $agent_id), - modules_get_agentmodule_id('Status', $agent_id), - modules_get_agentmodule_id('System_Load_AVG', $agent_id), - modules_get_agentmodule_id('Execution_time', $agent_id), - ]; - - foreach ($id_modules as $id_module) { - $params = [ - 'agent_module_id' => $id_module['id_agente_modulo'], - 'period' => SECONDS_1MONTH, - 'date' => time(), - 'height' => '150', - ]; - render_row(grafico_modulo_sparse($params), 'Graph of the '.$id_module['nombre'].' module.'); - } - - if ($console_mode == 0) { - echo '
".__('Pandora status info').'
".__('PHP setup').'
".__('Database size stats').'
".__('Database sanity').'
".__('Database status info').'
".__('System info').'
".__('MySQL Performance metrics').' '.ui_print_help_icon('performance_metrics_tab', true).'
".__('Tables fragmentation in the Pandora FMS database').'
".__(' Pandora FMS logs dates').'
".__(' Pandora FMS Licence Information').'
".__(' Status of the attachment folder').'
".__(' Information from the tagente_datos table').'
".__(' Pandora FMS server threads').'
".__(' Graphs modules that represent the self-monitoring system').'
'; - } - - echo "
"; - - echo ''.__( - '(*) Please check your Pandora Server setup and make sure that the database maintenance daemon is running. It\' is very important to - keep the database up-to-date to get the best performance and results in Pandora' - ).'


'; +// remove 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 006a66c5e6..e8bd9064bc 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 @@ -1912,6 +1912,7 @@ CREATE TABLE IF NOT EXISTS `tlayout_template_data` ( `linked_layout_status_as_service_warning` FLOAT(20, 3) NOT NULL default 0, `linked_layout_status_as_service_critical` FLOAT(20, 3) NOT NULL default 0, `linked_layout_node_id` INT(10) NOT NULL default 0, + `cache_expiration` INTEGER UNSIGNED NOT NULL default 0, PRIMARY KEY(`id`), FOREIGN KEY (`id_layout_template`) REFERENCES tlayout_template(`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/general/firts_task/planned_downtime.php b/pandora_console/general/firts_task/planned_downtime.php index dcd98fdebb..21bfb4b083 100644 --- a/pandora_console/general/firts_task/planned_downtime.php +++ b/pandora_console/general/firts_task/planned_downtime.php @@ -33,7 +33,7 @@ ui_require_css_file('firts_task'); ); ?>

-
+
diff --git a/pandora_console/general/header.php b/pandora_console/general/header.php index 99bb38cc21..157388a43e 100644 --- a/pandora_console/general/header.php +++ b/pandora_console/general/header.php @@ -328,9 +328,27 @@ if ($config['menu_type'] == 'classic') { $header_autorefresh_counter .= $autorefresh_additional; $header_autorefresh_counter .= ''; + // Button for feedback pandora. + if (enterprise_installed()) { + $header_feedback = '
'; + $header_feedback .= ''; + $header_feedback .= ''; + $header_feedback .= html_print_image( + '/images/feedback-header.png', + true, + [ + 'title' => __('Feedback'), + 'id' => 'feedback-header', + 'alt' => __('Feedback'), + 'style' => 'cursor: pointer; width: 27px;', + ] + ); + $header_feedback .= '
'; + } + // Support. - if (defined('PANDORA_ENTERPRISE')) { + if (enterprise_installed()) { $header_support_link = 'https://support.artica.es/'; } else { $header_support_link = 'https://pandorafms.com/forums/'; @@ -388,9 +406,9 @@ if ($config['menu_type'] == 'classic') { echo '
'.$config['custom_title_header'].''.$config['custom_subtitle_header'].'
'.$header_searchbar.'
-
'.$header_chat, $header_autorefresh, $header_autorefresh_counter, $header_discovery, $servers_list, $header_support, $header_docu, $header_user, $header_logout.'
'; +
'.$header_chat, $header_autorefresh, $header_autorefresh_counter, $header_discovery, $servers_list, $header_feedback, $header_support, $header_docu, $header_user, $header_logout.'
'; ?> - + @@ -610,8 +628,47 @@ if ($config['menu_type'] == 'classic') { }); var fixed_header = ; - + var new_chat = ; + + /** + * Loads modal from AJAX to add feedback. + */ + function show_feedback() { + + var btn_ok_text = ''; + var btn_cancel_text = ''; + var title = ''; + var url = ''; + + load_modal({ + target: $('#modal-feedback-form'), + form: 'modal_form_feedback', + url: '', + modal: { + title: title, + ok: btn_ok_text, + cancel: btn_cancel_text, + }, + onshow: { + page: url, + method: 'formFeedback', + }, + onsubmit: { + page: url, + method: 'createdScheduleFeedbackTask', + dataType: 'json', + }, + ajax_callback: generalShowMsg, + idMsgCallback: 'msg-header', + }); + } + $(document).ready (function () { // Check new notifications on a periodic way @@ -661,7 +718,15 @@ if ($config['menu_type'] == 'classic') { $("#ui_close_dialog_titlebar").click(function () { $("#agent_access").css("display",""); }); - + + // Feedback. + $("#feedback-header").click(function () { + // Clean DOM. + $("#feedback-header").empty(); + // Function charge Modal. + show_feedback(); + }); + function blinkpubli(){ $(".publienterprise").delay(100).fadeTo(300,0.2).delay(100).fadeTo(300,1, blinkpubli); } diff --git a/pandora_console/general/help_feedback.php b/pandora_console/general/help_feedback.php new file mode 100644 index 0000000000..1f702d6d36 --- /dev/null +++ b/pandora_console/general/help_feedback.php @@ -0,0 +1,77 @@ + '[HelpFeedBack]'.$e->getMessage() ]); + exit; + } else { + echo '[HelpFeedBack]'.$e->getMessage(); + } + + // Stop this execution, but continue 'globally'. + return; +} + +// Ajax controller. +if (is_ajax()) { + $method = get_parameter('method', ''); + + if (method_exists($helpfeedback, $method) === true) { + if ($helpfeedback->ajaxMethod($method) === true) { + $helpfeedback->{$method}(); + } else { + $helpfeedback->error('Unavailable method.'); + } + } else { + $helpfeedback->error('Method not found. ['.$method.']'); + } + + + // Stop any execution. + exit; +} else { + // Run. + $helpfeedback->run(); +} diff --git a/pandora_console/general/register.php b/pandora_console/general/register.php index b1d58aada4..e7097b994e 100644 --- a/pandora_console/general/register.php +++ b/pandora_console/general/register.php @@ -30,6 +30,7 @@ global $config; require_once $config['homedir'].'/include/functions_update_manager.php'; +require_once $config['homedir'].'/include/class/WelcomeWindow.class.php'; if (is_ajax()) { @@ -122,6 +123,8 @@ if (is_ajax()) { exit(); } + + ui_require_css_file('register'); $initial = isset($config['initial_wizard']) !== true @@ -170,6 +173,16 @@ if (!$config['disabled_newsletter']) { } } +$welcome = !$registration && !$show_newsletter && !$initial; +try { + $welcome_window = new WelcomeWindow($welcome); + if ($welcome_window !== null) { + $welcome_window->run(); + } +} catch (Exception $e) { + $welcome = false; +} + $newsletter = null; ?> diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 664b173748..61d33193d3 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -2278,6 +2278,10 @@ if ($updateGIS) { // ----------------------------------- // Load page depending on tab selected // ----------------------------------- +if ($_SESSION['create_module'] && $config['welcome_state'] == 1) { + $edit_module = true; +} + switch ($tab) { case 'main': include 'agent_manager.php'; diff --git a/pandora_console/godmode/agentes/module_manager_editor.php b/pandora_console/godmode/agentes/module_manager_editor.php index 874fe3a9d1..9428a362bc 100644 --- a/pandora_console/godmode/agentes/module_manager_editor.php +++ b/pandora_console/godmode/agentes/module_manager_editor.php @@ -391,6 +391,9 @@ if ($id_agent_module) { } else { if (isset($moduletype) === false) { $moduletype = (string) get_parameter('moduletype'); + if ($_SESSION['create_module'] && $config['welcome_state'] == 1) { + $moduletype = 'networkserver'; + } // Clean up specific network modules fields. $name = ''; diff --git a/pandora_console/godmode/agentes/planned_downtime.editor.php b/pandora_console/godmode/agentes/planned_downtime.editor.php index eef8d5fbdf..ebf64a87c1 100644 --- a/pandora_console/godmode/agentes/planned_downtime.editor.php +++ b/pandora_console/godmode/agentes/planned_downtime.editor.php @@ -827,7 +827,7 @@ $table->data[5][1] = " '; -echo '
'; +echo ''; if ($id_downtime > 0) { echo ''; @@ -929,7 +929,7 @@ if ($id_downtime > 0) { $disabled_add_button = true; } - echo ""; + echo ""; html_print_select_groups(false, $access, true, 'filter_group', $filter_group, '', '', '', false, false, true, '', false, 'min-width:180px;margin-right:15px;'); html_print_checkbox('recursion', 1, $recursion, false, false, ''); @@ -939,7 +939,7 @@ if ($id_downtime > 0) { echo ''; // Show available agents to include into downtime echo '

'.__('Available agents').':

'; - echo ""; + echo ""; echo html_print_select($agents, 'id_agents[]', -1, '', _('Any'), -2, false, true, true, '', false, 'width: 180px;'); @@ -1085,7 +1085,7 @@ if ($id_downtime > 0) { $data[5] = ''.html_print_image('images/config.png', true, ['border' => '0', 'alt' => __('Delete')]).''; } - $data[5] .= ''.html_print_image('images/cross.png', true, ['border' => '0', 'alt' => __('Delete')]).''; + $data[5] .= ''.html_print_image('images/cross.png', true, ['border' => '0', 'alt' => __('Delete')]).''; } $table->data['agent_'.$downtime_agent['id_agente']] = $data; diff --git a/pandora_console/godmode/agentes/planned_downtime.list.php b/pandora_console/godmode/agentes/planned_downtime.list.php index 49a72f125d..01f30afba6 100755 --- a/pandora_console/godmode/agentes/planned_downtime.list.php +++ b/pandora_console/godmode/agentes/planned_downtime.list.php @@ -357,7 +357,7 @@ if (!$downtimes && !$filter_performed) { // No downtimes cause the user performed a search. else if (!$downtimes) { // Filter form. - echo ""; + echo ""; html_print_table($table_form); echo ''; @@ -369,7 +369,7 @@ else if (!$downtimes) { // Create button. if ($write_permisson) { echo ' '; - echo ''; + echo ''; html_print_submit_button(__('Create'), 'create', false, 'class="sub next"'); echo ''; } @@ -378,11 +378,11 @@ else if (!$downtimes) { } // Has downtimes. else { - echo ""; + echo ""; html_print_table($table_form); echo ''; - ui_pagination($downtimes_number, "index.php?sec=estado&sec2=godmode/agentes/planned_downtime.list&$filter_params_str", $offset); + ui_pagination($downtimes_number, "index.php?sec=extensions&sec2=godmode/agentes/planned_downtime.list&$filter_params_str", $offset); // User groups with AR, AD or AW permission. $groupsAD = users_get_groups($config['id_user'], $access); @@ -476,7 +476,7 @@ else { if (in_array($downtime['id_group'], $groupsAD)) { // Stop button if ($downtime['type_execution'] == 'once' && $downtime['executed'] == 1) { - $data['stop'] = ''.html_print_image('images/cancel.png', true, ['title' => __('Stop downtime')]); + $data['stop'] = ''.html_print_image('images/cancel.png', true, ['title' => __('Stop downtime')]); } else { $data['stop'] = ''; } @@ -484,12 +484,12 @@ else { // Edit & delete buttons. if ($downtime['executed'] == 0) { // Edit. - $data['edit'] = ''.html_print_image('images/config.png', true, ['title' => __('Update')]).''; + $data['edit'] = ''.html_print_image('images/config.png', true, ['title' => __('Update')]).''; // Delete. - $data['delete'] = ''.html_print_image('images/cross.png', true, ['title' => __('Delete')]); + $data['delete'] = ''.html_print_image('images/cross.png', true, ['title' => __('Delete')]); } else if ($downtime['executed'] == 1 && $downtime['type_execution'] == 'once') { // Edit. - $data['edit'] = ''.html_print_image('images/config.png', true, ['title' => __('Update')]).''; + $data['edit'] = ''.html_print_image('images/config.png', true, ['title' => __('Update')]).''; // Delete. $data['delete'] = __('N/A'); } else { @@ -515,7 +515,7 @@ else { } html_print_table($table); - ui_pagination($downtimes_number, "index.php?sec=estado&sec2=godmode/agentes/planned_downtime.list&$filter_params_str", $offset, 0, false, 'offset', true, 'pagination-bottom'); + ui_pagination($downtimes_number, "index.php?sec=extensions&sec2=godmode/agentes/planned_downtime.list&$filter_params_str", $offset, 0, false, 'offset', true, 'pagination-bottom'); echo '
'; // CSV export button. @@ -532,7 +532,7 @@ else { // Create button. if ($write_permisson) { echo ' '; - echo '
'; + echo ''; html_print_submit_button(__('Create'), 'create', false, 'class="sub next"'); echo ''; } @@ -559,7 +559,7 @@ $(document).ready (function () { if ( && ) { if (confirm("")) { - window.location.href = "index.php?sec=estado&sec2=godmode/agentes/planned_downtime.list&migrate_malformed=1"; + window.location.href = "index.php?sec=extensions&sec2=godmode/agentes/planned_downtime.list&migrate_malformed=1"; } } }); diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 7175081912..edf7be1873 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -339,13 +339,13 @@ if (check_acl($config['id_user'], 0, 'PM') || check_acl($config['id_user'], 0, ' $sub = []; if (check_acl($config['id_user'], 0, 'PM')) { - // Audit //meter en extensiones + // Audit //meter en extensiones. $sub['godmode/admin_access_logs']['text'] = __('System audit log'); $sub['godmode/admin_access_logs']['id'] = 'System audit log'; $sub['godmode/setup/links']['text'] = __('Links'); $sub['godmode/setup/links']['id'] = 'Links'; - $sub['extras/pandora_diag']['text'] = __('Diagnostic info'); - $sub['extras/pandora_diag']['id'] = 'Diagnostic info'; + $sub['tools/diagnostics']['text'] = __('Diagnostic info'); + $sub['tools/diagnostics']['id'] = 'Diagnostic info'; $sub['godmode/setup/news']['text'] = __('Site news'); $sub['godmode/setup/news']['id'] = 'Site news'; $sub['godmode/setup/file_manager']['text'] = __('File manager'); diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index b59dbc2ee5..e7201ab155 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -482,51 +482,6 @@ switch ($action) { $period = $item['period']; break; - /* - case 'TTRT': - $description = $item['description']; - $idAgentModule = $item['id_agent_module']; - $idAgent = db_get_value_filter( - 'id_agente', - 'tagente_modulo', - ['id_agente_modulo' => $idAgentModule] - ); - $period = $item['period']; - break; - - case 'TTO': - $description = $item['description']; - $idAgentModule = $item['id_agent_module']; - $idAgent = db_get_value_filter( - 'id_agente', - 'tagente_modulo', - ['id_agente_modulo' => $idAgentModule] - ); - $period = $item['period']; - break; - - case 'MTBF': - $description = $item['description']; - $idAgentModule = $item['id_agent_module']; - $idAgent = db_get_value_filter( - 'id_agente', - 'tagente_modulo', - ['id_agente_modulo' => $idAgentModule] - ); - $period = $item['period']; - break; - - case 'MTTR': - $description = $item['description']; - $idAgentModule = $item['id_agent_module']; - $idAgent = db_get_value_filter( - 'id_agente', - 'tagente_modulo', - ['id_agente_modulo' => $idAgentModule] - ); - $period = $item['period']; - break; - */ case 'alert_report_module': $description = $item['description']; $idAgentModule = $item['id_agent_module']; @@ -791,11 +746,6 @@ switch ($action) { case 'avg_value': case 'projection_graph': case 'prediction_date': - /* - case 'TTRT': - case 'TTO': - case 'MTBF': - case 'MTTR':*/ case 'simple_baseline_graph': case 'event_report_log': case 'increment': @@ -3757,10 +3707,6 @@ $(document).ready (function () { case 'event_report_module': case 'simple_graph': case 'simple_baseline_graph': -/* case 'TTRT': - case 'TTO': - case 'MTBF': - case 'MTTR':*/ case 'prediction_date': case 'projection_graph': case 'avg_value': @@ -3798,10 +3744,6 @@ $(document).ready (function () { case 'event_report_module': case 'simple_graph': case 'simple_baseline_graph': -/* case 'TTRT': - case 'TTO': - case 'MTBF': - case 'MTTR':*/ case 'prediction_date': case 'projection_graph': case 'avg_value': @@ -4833,38 +4775,6 @@ function chooseType() { $("#row_period").show(); $("#row_historical_db_check").hide(); break; -/* - case 'TTRT': - $("#row_description").show(); - $("#row_agent").show(); - $("#row_module").show(); - $("#row_period").show(); - $("#row_historical_db_check").hide(); - break; - - case 'TTO': - $("#row_description").show(); - $("#row_agent").show(); - $("#row_module").show(); - $("#row_period").show(); - $("#row_historical_db_check").hide(); - break; - - case 'MTBF': - $("#row_description").show(); - $("#row_agent").show(); - $("#row_module").show(); - $("#row_period").show(); - $("#row_historical_db_check").hide(); - break; - - case 'MTTR': - $("#row_description").show(); - $("#row_agent").show(); - $("#row_module").show(); - $("#row_period").show(); - $("#row_historical_db_check").hide(); - break;*/ case 'alert_report_module': $("#row_description").show(); @@ -5218,10 +5128,6 @@ function chooseType() { case 'min_value': case 'max_value': case 'avg_value': - /* case 'TTRT': - case 'TTO': - case 'MTBF': - case 'MTTR':*/ case 'simple_baseline_graph': $("#row_label").show(); break; diff --git a/pandora_console/godmode/reporting/reporting_builder.php b/pandora_console/godmode/reporting/reporting_builder.php index 40ce45b5bb..823713877b 100755 --- a/pandora_console/godmode/reporting/reporting_builder.php +++ b/pandora_console/godmode/reporting/reporting_builder.php @@ -2006,11 +2006,6 @@ switch ($action) { case 'avg_value': case 'projection_graph': case 'prediction_date': - /* - case 'TTRT': - case 'TTO': - case 'MTBF': - case 'MTTR':*/ case 'simple_baseline_graph': case 'nt_top_n': if ($label != '') { @@ -2613,11 +2608,6 @@ switch ($action) { case 'avg_value': case 'projection_graph': case 'prediction_date': - /* - case 'TTRT': - case 'TTO': - case 'MTBF': - case 'MTTR':*/ case 'simple_baseline_graph': case 'nt_top_n': if ($label != '') { diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index 1385a9f193..46c2c00e44 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -63,9 +63,20 @@ if (is_ajax()) { $test_address = get_parameter('test_address', ''); - $res = enterprise_hook('send_email_attachment', [$test_address, __('This is an email test sent from Pandora FMS. If you can read this, your configuration works.'), __('Testing Pandora FMS email'), null]); + $res = enterprise_hook( + 'send_email_attachment', + [ + $test_address, + __('This is an email test sent from Pandora FMS. If you can read this, your configuration works.'), + __('Testing Pandora FMS email'), + null, + ] + ); echo $res; + + // Exit after ajax response. + exit(); } $table = new StdClass(); @@ -389,6 +400,52 @@ html_print_input_hidden('update_config', 1); html_print_table($table_mail_conf); +echo ''; + +echo '
'; +echo ''.__('WebSocket settings').''; + +$t = new StdClass(); +$t->data = []; +$t->width = '100%'; +$t->class = 'databox filters'; +$t->data = []; +$t->style[0] = 'font-weight: bold'; + +$t->data[0][0] = __('Bind address'); +$t->data[0][1] = html_print_input_text( + 'ws_bind_address', + $config['ws_bind_address'], + '', + 30, + 100, + true +); + +$t->data[1][0] = __('Bind port'); +$t->data[1][2] = html_print_input_text( + 'ws_port', + $config['ws_port'], + '', + 30, + 100, + true +); + +$t->data[2][0] = __('WebSocket proxy url').ui_print_help_tip(__('If you had configured a wsproxy set here target URL (for instance ws://your.public.fqdn/ws).'), true); +$t->data[2][2] = html_print_input_text( + 'ws_proxy_url', + $config['ws_proxy_url'], + '', + 30, + 100, + true +); + +html_print_input_hidden('update_config', 1); +html_print_table($t); + + echo '
'; echo '
'; diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index cb29d78c06..5ffeb716d9 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -404,13 +404,42 @@ class Wizard /** * Print a block of inputs. + * Example, using direct to 'anidate' inputs directly to wrapper: + * [ + * 'wrapper' => 'div', + * 'block_id' => 'example_id', + * 'class' => 'your class', + * 'direct' => 1, + * 'block_content' => [ + * [ + * 'arguments' => [ + * 'label' => __('Sugesstion'), + * 'type' => 'button', + * 'attributes' => 'class="sub ok btn_sug"', + * 'name' => 'option_1', + * 'id' => 'option_1', + * 'script' => 'change_option1()', + * ], + * ], + * [ + * 'arguments' => [ + * 'label' => __('Something is not quite right'), + * 'type' => 'button', + * 'attributes' => 'class="sub ok btn_something"', + * 'name' => 'option_2', + * 'id' => 'option_2', + * 'script' => 'change_option2()', + * ], + * ], + * ], + * ]. * * @param array $input Definition of target block to be printed. * @param boolean $return Return as string or direct output. * * @return string HTML content. */ - public function printBlock(array $input, bool $return=false) + public function printBlock(array $input, bool $return=false, bool $not_direct=false) { $output = ''; if ($input['hidden'] == 1) { @@ -424,33 +453,47 @@ class Wizard } if (is_array($input['block_content']) === true) { + $not_direct = (bool) $input['direct']; + // Print independent block of inputs. + $output .= '
  • '; + if ($input['wrapper']) { - $output .= '
  • '; $output .= '<'.$input['wrapper'].' id="'.$input['block_id'].'" class="'.$class.'">'; - } else { - $output .= '
  • '; } - $output .= '
      '; + if (!$not_direct) { + // Avoid encapsulation if input is direct => 1. + $output .= '
        '; + } + foreach ($input['block_content'] as $input) { - $output .= $this->printBlock($input, $return); + $output .= $this->printBlock($input, $return, (bool) $not_direct); } // Close block. - if ($input['wrapper']) { - $output .= '
      '; - } else { - $output .= '
  • '; + if (!$not_direct) { + $output .= ''; } + + if ($input['wrapper']) { + $output .= ''; + } + + $output .= ''; } else { if ($input['arguments']['type'] != 'hidden') { - $output .= '
  • '; + if (!$not_direct) { + $output .= '
  • '; + } + $output .= ''; $output .= $this->printInput($input['arguments']); // Allow dynamic content. $output .= $input['extra']; - $output .= '
  • '; + if (!$not_direct) { + $output .= ''; + } } else { $output .= $this->printInput($input['arguments']); // Allow dynamic content. diff --git a/pandora_console/images/feedback-header.png b/pandora_console/images/feedback-header.png new file mode 100644 index 0000000000..c77ff461e4 Binary files /dev/null and b/pandora_console/images/feedback-header.png differ diff --git a/pandora_console/include/ajax/welcome_window.php b/pandora_console/include/ajax/welcome_window.php new file mode 100644 index 0000000000..fc2e278a6f --- /dev/null +++ b/pandora_console/include/ajax/welcome_window.php @@ -0,0 +1,62 @@ +ajaxMethod($method) === true) { + $welcome_actions->{$method}(); + } else { + $welcome_actions->error('Unavailable method.'); + } +} else { + $welcome_actions->error('Method not found. ['.$method.']'); +} + + +// Stop any execution. +exit; diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php index 013a7e967f..e6b2720dd8 100644 --- a/pandora_console/include/class/ConsoleSupervisor.php +++ b/pandora_console/include/class/ConsoleSupervisor.php @@ -2354,26 +2354,52 @@ class ConsoleSupervisor public function checkConsoleServerVersions() { global $config; - // List all servers except satellite server + // List all servers except satellite server. $server_version_list = db_get_all_rows_sql( - 'SELECT name, version FROM tserver WHERE server_type != '.SERVER_TYPE_ENTERPRISE_SATELLITE + sprintf( + 'SELECT `name`, `version` + FROM tserver + WHERE server_type != %d + GROUP BY `version`', + SERVER_TYPE_ENTERPRISE_SATELLITE + ) ); - foreach ($server_version_list as $server) { - if (strpos($server['version'], $config['current_package_enterprise']) === false) { - $title_ver_misaligned = $server['name'].' version misaligned with Console'; - $message_ver_misaligned = 'Server '.$server['name'].' and this console have different versions. This might cause several malfunctions. Please, update this server.'; + $missed = 0; - $this->notify( - [ - 'type' => 'NOTIF.SERVER.MISALIGNED', - 'title' => __($title_ver_misaligned), - 'message' => __($message_ver_misaligned), - 'url' => ui_get_full_url('index.php?sec=messages&sec2=godmode/update_manager/update_manager&tab=online'), - ] - ); + if (is_array($server_version_list) === true) { + foreach ($server_version_list as $server) { + if (strpos( + $server['version'], + $config['current_package_enterprise'] + ) === false + ) { + $missed++; + $title_ver_misaligned = __( + '%s version misaligned with Console', + $server['name'] + ); + $message_ver_misaligned = __( + 'Server %s and this console have different versions. This might cause several malfunctions. Please, update this server.', + $server['name'] + ); + + $this->notify( + [ + 'type' => 'NOTIF.SERVER.MISALIGNED', + 'title' => __($title_ver_misaligned), + 'message' => __($message_ver_misaligned), + 'url' => ui_get_full_url('index.php?sec=messages&sec2=godmode/update_manager/update_manager&tab=online'), + ] + ); + } } } + + // Cleanup notifications if exception is recovered. + if ($missed == 0) { + $this->cleanNotifications('NOTIF.SERVER.MISALIGNED'); + } } diff --git a/pandora_console/include/class/Diagnostics.class.php b/pandora_console/include/class/Diagnostics.class.php new file mode 100644 index 0000000000..af65aa8066 --- /dev/null +++ b/pandora_console/include/class/Diagnostics.class.php @@ -0,0 +1,2176 @@ +ajaxController = $page; + $this->pdf = $pdf; + } + + + /** + * Allowed methods to be called using AJAX request. + * + * @var array + */ + public $AJAXMethods = [ + 'getStatusInfo', + 'getPHPSetup', + 'getDatabaseSizeStats', + 'getDatabaseHealthStatus', + 'getDatabaseStatusInfo', + 'getSystemInfo', + 'getMySQLPerformanceMetrics', + 'getTablesFragmentation', + 'getPandoraFMSLogsDates', + 'getLicenceInformation', + 'getAttachmentFolder', + 'getInfoTagenteDatos', + 'getServerThreads', + 'getShowEngine', + 'datatablesDraw', + 'getChartAjax', + 'formFeedback', + 'createdScheduleFeedbackTask', + ]; + + + /** + * Checks if target method is available to be called using AJAX. + * + * @param string $method Target method. + * + * @return boolean True allowed, false not. + */ + public function ajaxMethod(string $method):bool + { + return in_array($method, $this->AJAXMethods); + } + + + /** + * Show view diagnostics. + * + * @return void + */ + public function run() + { + global $config; + + ui_require_css_file('diagnostics'); + + // Header. + ui_print_page_header( + __('Pandora FMS Diagnostic tool'), + 'images/gm_massive_operations.png', + false, + 'diagnostic_tool_tab', + true + ); + + // Print all Methods Diagnostic Info. + echo $this->printMethodsDiagnostigsInfo(); + + // Print all charts Monitoring. + echo $this->printCharts(); + + echo ''; + } + + + /** + * Print Methods: + * Info status pandoraFms. + * PHP setup. + * Database size stats. + * Database health status. + * Database status info. + * System Info. + * MySQL Performance metrics. + * Tables fragmentation in the Pandora FMS database. + * Pandora FMS logs dates. + * Pandora FMS Licence Information. + * Status of the attachment folder. + * Information from the tagente_datos table. + * Pandora FMS server threads. + * + * @return string Html. + */ + public function printMethodsDiagnostigsInfo():string + { + $infoMethods = [ + 'getStatusInfo', + 'getPHPSetup', + 'getDatabaseSizeStats', + 'getDatabaseHealthStatus', + 'getDatabaseStatusInfo', + 'getSystemInfo', + 'getMySQLPerformanceMetrics', + 'getTablesFragmentation', + 'getPandoraFMSLogsDates', + 'getLicenceInformation', + 'getAttachmentFolder', + 'getInfoTagenteDatos', + 'getServerThreads', + ]; + + if ($this->pdf === true) { + $infoMethods[] = 'getShowEngine'; + } + + $return = ''; + + foreach ($infoMethods as $key => $method) { + switch ($method) { + case 'getStatusInfo': + $title = __('Info status pandoraFms'); + break; + + case 'getPHPSetup': + $title = __('PHP setup'); + break; + + case 'getDatabaseSizeStats': + $title = __('Database size stats'); + break; + + case 'getDatabaseHealthStatus': + $title = __('Database health status'); + break; + + case 'getDatabaseStatusInfo': + $title = __('Database status info'); + break; + + case 'getSystemInfo': + $title = __('System Info'); + break; + + case 'getMySQLPerformanceMetrics': + $title = __('MySQL Performance metrics'); + break; + + case 'getTablesFragmentation': + $title = __( + 'Tables fragmentation in the Pandora FMS database' + ); + break; + + case 'getPandoraFMSLogsDates': + $title = __('Pandora FMS logs dates'); + break; + + case 'getLicenceInformation': + $title = __('Pandora FMS Licence Information'); + break; + + case 'getAttachmentFolder': + $title = __('Status of the attachment folder'); + break; + + case 'getInfoTagenteDatos': + $title = __('Information from the tagente_datos table'); + break; + + case 'getServerThreads': + $title = __('Pandora FMS server threads'); + break; + + case 'getShowEngine': + $title = __('SQL show engine innodb status'); + break; + + default: + // Not possible. + $title = ''; + break; + } + + $return .= '
    '; + $return .= $this->printData($method, $title); + $return .= '
    '; + } + + return $return; + } + + + /** + * Print table graps: + * Graph of the Agents Unknown module. + * Graph of the Database Maintenance module. + * Graph of the Free Disk Spool Dir module. + * Graph of the Free RAM module. + * Graph of the Queued Modules module. + * Graph of the Status module. + * Graph of the System Load AVG module. + * Graph of the Execution Time module. + * + * @return string + */ + public function printCharts() + { + /* + * Agent id with name Master Server. + */ + + $agentIdMasterServer = $this->getAgentIdMasterServer(); + + $result = ''; + if ($agentIdMasterServer !== 0) { + $agentMonitoring = [ + 'chartAgentsUnknown' => [ + 'title' => __( + 'Graph of the Agents Unknown module.' + ), + 'nameModule' => 'Agents_Unknown', + 'idAgent' => $agentIdMasterServer, + ], + 'chartDatabaseMain' => [ + 'title' => __( + 'Graph of the Database Maintenance module.' + ), + 'nameModule' => 'Database Maintenance', + 'idAgent' => $agentIdMasterServer, + ], + 'chartFreeDiskSpoolDir' => [ + 'title' => __( + 'Graph of the Free Disk Spool Dir module.' + ), + 'nameModule' => 'FreeDisk_SpoolDir', + 'idAgent' => $agentIdMasterServer, + ], + 'chartFreeRAM' => [ + 'title' => __('Graph of the Free RAM module.'), + 'nameModule' => 'Free_RAM', + 'idAgent' => $agentIdMasterServer, + ], + 'chartQueuedModules' => [ + 'title' => __( + 'Graph of the Queued Modules module.' + ), + 'nameModule' => 'Queued_Modules', + 'idAgent' => $agentIdMasterServer, + ], + 'chartStatus' => [ + 'title' => __('Graph of the Status module.'), + 'nameModule' => 'Status', + 'idAgent' => $agentIdMasterServer, + ], + 'chartSystemLoadAVG' => [ + 'title' => __( + 'Graph of the System Load AVG module.' + ), + 'nameModule' => 'System_Load_AVG', + 'idAgent' => $agentIdMasterServer, + ], + 'chartExecutionTime' => [ + 'title' => __( + 'Graph of the Execution Time module.' + ), + 'nameModule' => 'Execution_time', + 'idAgent' => $agentIdMasterServer, + ], + ]; + + $return .= '
    '; + $return .= __( + 'Graphs modules that represent the self-monitoring system' + ); + $return .= '
    '; + $return .= '
    '; + foreach ($agentMonitoring as $key => $value) { + $return .= $this->printDataCharts($value); + } + + $return .= '
    '; + } + + return $return; + } + + + /** + * Info status pandoraFms. + * + * @return string + */ + public function getStatusInfo(): string + { + global $config; + global $build_version; + global $pandora_version; + + $sql = sprintf( + "SELECT `key`, `value` + FROM `tupdate_settings` + WHERE `key` = '%s' + OR `key` = '%s' + OR `key` = '%s'", + 'current_update', + 'customer_key', + 'updating_code_path' + ); + + $values_key = db_get_all_rows_sql($sql); + $values_key = array_reduce( + $values_key, + function ($carry, $item) { + if ($item['key'] === 'customer_key') { + $customer = substr($item['value'], 0, 5); + $customer .= '...'; + $customer .= substr($item['value'], -5); + $item['value'] = $customer; + } + + $carry[$item['key']] = $item['value']; + return $carry; + } + ); + + $result = [ + 'error' => false, + 'data' => [ + 'buildVersion' => [ + 'name' => __('Pandora FMS Build'), + 'value' => $build_version, + ], + 'version' => [ + 'name' => __('Pandora FMS Version'), + 'value' => $pandora_version, + ], + 'mr' => [ + 'name' => __('Minor Release'), + 'value' => $config['MR'], + ], + 'homeDir' => [ + 'name' => __('Homedir'), + 'value' => $config['homedir'], + ], + 'homeUrl' => [ + 'name' => __('HomeUrl'), + 'value' => $config['homeurl'], + ], + 'isEnterprise' => [ + 'name' => __('Enterprise installed'), + 'value' => (enterprise_installed()) ? __('true') : __('false'), + ], + 'customerKey' => [ + 'name' => __('Update Key'), + 'value' => $values_key['customer_key'], + ], + 'updatingCode' => [ + 'name' => __('Updating code path'), + 'value' => $values_key['updating_code_path'], + ], + 'currentUpdate' => [ + 'name' => __('Current Update #'), + 'value' => $values_key['current_update'], + ], + + ], + ]; + + return json_encode($result); + } + + + /** + * PHP Status. + * + * @return string + */ + public function getPHPSetup(): string + { + global $config; + + $result = [ + 'error' => false, + 'data' => [ + 'phpVersion' => [ + 'name' => __('PHP Version'), + 'value' => phpversion(), + ], + 'maxExecutionTime' => [ + 'name' => __('PHP Max execution time'), + 'value' => ini_get('max_execution_time'), + ], + 'maxInputTime' => [ + 'name' => __('PHP Max input time'), + 'value' => ini_get('max_input_time'), + ], + 'memoryLimit' => [ + 'name' => __('PHP Memory limit'), + 'value' => ini_get('memory_limit'), + ], + 'sessionLifetime' => [ + 'name' => __('Session cookie lifetime'), + 'value' => ini_get('session.cookie_lifetime'), + ], + ], + ]; + + return json_encode($result); + } + + + /** + * Database size stats. + * + * @return string + */ + public function getDatabaseSizeStats(): string + { + global $config; + + $countAgents = db_get_value_sql('SELECT COUNT(*) FROM tagente'); + $countModules = db_get_value_sql('SELECT COUNT(*) FROM tagente_modulo'); + $countGroups = db_get_value_sql('SELECT COUNT(*) FROM tgrupo'); + $countModuleData = db_get_value_sql( + 'SELECT COUNT(*) FROM tagente_datos' + ); + $countAgentAccess = db_get_value_sql( + 'SELECT COUNT(*) FROM tagent_access' + ); + $countEvents = db_get_value_sql('SELECT COUNT(*) FROM tevento'); + + if (enterprise_installed() === true) { + $countTraps = db_get_value_sql('SELECT COUNT(*) FROM ttrap'); + } + + $countUsers = db_get_value_sql('SELECT COUNT(*) FROM tusuario'); + $countSessions = db_get_value_sql('SELECT COUNT(*) FROM tsesion'); + + $result = [ + 'error' => false, + 'data' => [ + 'countAgents' => [ + 'name' => __('Total agentsy'), + 'value' => $countAgents, + ], + 'countModules' => [ + 'name' => __('Total modules'), + 'value' => $countModules, + ], + 'countGroups' => [ + 'name' => __('Total groups'), + 'value' => $countGroups, + ], + 'countModuleData' => [ + 'name' => __('Total module data records'), + 'value' => $countModuleData, + ], + 'countAgentAccess' => [ + 'name' => __('Total agent access record'), + 'value' => $countAgentAccess, + ], + 'countEvents' => [ + 'name' => __('Total events'), + 'value' => $countEvents, + ], + 'countTraps' => [ + 'name' => __('Total traps'), + 'value' => $countTraps, + ], + 'countUsers' => [ + 'name' => __('Total users'), + 'value' => $countUsers, + ], + 'countSessions' => [ + 'name' => __('Total sessions'), + 'value' => $countSessions, + ], + ], + ]; + + return json_encode($result); + } + + + /** + * Database health status. + * + * @return string + */ + public function getDatabaseHealthStatus(): string + { + global $config; + + // Count agents unknowns. + $sqlUnknownAgents = 'SELECT COUNT( DISTINCT tagente.id_agente) + FROM tagente_estado, tagente, tagente_modulo + WHERE tagente.disabled = 0 + AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo + AND tagente_modulo.disabled = 0 + AND tagente_estado.id_agente = tagente.id_agente + AND tagente_estado.estado = 3'; + $unknownAgents = db_get_sql($sqlUnknownAgents); + + // Count modules not initialize. + $sqlNotInitAgents = 'SELECT COUNT(tagente_estado.estado) + FROM tagente_estado + WHERE tagente_estado.estado = 4'; + $notInitAgents = db_get_sql($sqlNotInitAgents); + + $dateDbMantenaince = $config['db_maintance']; + + $currentTime = time(); + + $pandoraDbLastRun = __('Pandora DB has never been executed'); + if ($dateDbMantenaince !== false) { + $difference = ($currentTime - $dateDbMantenaince); + $pandoraDbLastRun = human_time_comparation($difference); + $pandoraDbLastRun .= ' '.__('Ago'); + } + + $result = [ + 'error' => false, + 'data' => [ + 'unknownAgents' => [ + 'name' => __('Total unknown agents'), + 'value' => $unknownAgents, + ], + 'notInitAgents' => [ + 'name' => __('Total not-init modules'), + 'value' => $notInitAgents, + ], + 'pandoraDbLastRun' => [ + 'name' => __('PandoraDB Last run'), + 'value' => $pandoraDbLastRun, + ], + ], + ]; + + return json_encode($result); + } + + + /** + * Database status info. + * + * @return string + */ + public function getDatabaseStatusInfo(): string + { + global $config; + + // Size BBDD. + $dbSizeSql = db_get_value_sql( + 'SELECT ROUND(SUM(data_length+index_length)/1024/1024,3) + FROM information_schema.TABLES' + ); + + // Add unit size. + $dbSize = $dbSizeSql.' M'; + + $result = [ + 'error' => false, + 'data' => [ + 'dbSchemeFirstVersion' => [ + 'name' => __('DB Schema Version (first installed)'), + 'value' => $config['db_scheme_first_version'], + ], + 'dbSchemeVersion' => [ + 'name' => __('DB Schema Version (actual)'), + 'value' => $config['db_scheme_version'], + ], + 'dbSchemeBuild' => [ + 'name' => __('DB Schema Build'), + 'value' => $config['db_scheme_build'], + ], + 'dbSize' => [ + 'name' => __('DB Size'), + 'value' => $dbSize, + ], + ], + ]; + + return json_encode($result); + } + + + /** + * Database status info. + * + * @return string + */ + public function getSystemInfo(): string + { + global $config; + + $result = []; + if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { + $cpuModelName = 'cat /proc/cpuinfo | grep "model name" | tail -1 | cut -f 2 -d ":"'; + $cpuProcessor = 'cat /proc/cpuinfo | grep "processor" | wc -l'; + $ramMemTotal = 'cat /proc/meminfo | grep "MemTotal"'; + + $result = [ + 'error' => false, + 'data' => [ + 'cpuInfo' => [ + 'name' => __('CPU'), + 'value' => exec($cpuModelName).' x '.exec($cpuProcessor), + ], + 'ramInfo' => [ + 'name' => __('RAM'), + 'value' => exec($ramMemTotal), + ], + ], + ]; + } + + return json_encode($result); + } + + + /** + * MySQL Performance metrics. + * + * @return string + */ + public function getMySQLPerformanceMetrics(): string + { + global $config; + + $variablesMsql = db_get_all_rows_sql('SHOW VARIABLES'); + $variablesMsql = array_reduce( + $variablesMsql, + function ($carry, $item) { + $bytes = 1048576; + $mega = 1024; + switch ($item['Variable_name']) { + case 'sql_mode': + $name = __('Sql mode'); + $value = ($item['Value']); + $status = (empty($item['Value']) === true) ? 1 : 0; + $message = __('Must be empty'); + break; + + case 'innodb_log_file_size': + $name = __('InnoDB log file size'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 64) ? 1 : 0; + $message = __('Min. Recommended Value').' 64M'; + break; + + case 'innodb_log_buffer_size': + $name = __('InnoDB log buffer size'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 16) ? 1 : 0; + $message = __('Min. Recommended Value').' 16M'; + break; + + case 'innodb_flush_log_at_trx_commit': + $name = __('InnoDB flush log at trx-commit'); + $value = $item['Value']; + $status = (($item['Value'] / $bytes) >= 0) ? 1 : 0; + $message = __('Min. Recommended Value').' 0'; + break; + + case 'max_allowed_packet': + $name = __('Maximun allowed packet'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 32) ? 1 : 0; + $message = __('Min. Recommended Value').' 32M'; + break; + + case 'innodb_buffer_pool_size': + $name = __('InnoDB buffer pool size'); + $value = ($item['Value'] / $mega); + $status = (($item['Value'] / $mega) >= 250) ? 1 : 0; + $message = __( + 'It has to be 40% of the server memory not recommended to be greater or less' + ); + break; + + case 'sort_buffer_size': + $name = __('Sort buffer size'); + $value = number_format(($item['Value'] / $mega), 2); + $status = (($item['Value'] / $bytes) >= 32) ? 1 : 0; + $message = __('Min. Recommended Value').' 32'; + break; + + case 'join_buffer_size': + $name = __('Join buffer size'); + $value = ($item['Value'] / $mega); + $status = (($item['Value'] / $bytes) >= 265) ? 1 : 0; + $message = __('Min. Recommended Value 265'); + break; + + case 'query_cache_type': + $name = __('Query cache type'); + $value = $item['Value']; + $status = ($item['Value'] === 'ON') ? 1 : 0; + $message = __('Recommended ON'); + break; + + case 'query_cache_size': + $name = __('Query cache size'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 32) ? 1 : 0; + $message = __('Min. Recommended Value').' 32MB'; + break; + + case 'query_cache_limit': + $name = __('Query cache limit'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 256) ? 1 : 0; + $message = __('Min. Recommended Value').' 256K'; + break; + + case 'innodb_lock_wait_timeout': + $name = __('InnoDB lock wait timeout'); + $value = $item['Value']; + $status = (($item['Value'] / $bytes) >= 90) ? 1 : 0; + $message = __('Min. Recommended Value').' 90s'; + break; + + case 'thread_cache_size': + $name = __('Thread cache size'); + $value = $item['Value']; + $status = (($item['Value'] / $bytes) >= 8) ? 1 : 0; + $message = __('Min. Recommended Value').' 8'; + break; + + case 'thread_stack': + $name = __('Thread stack'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 256) ? 1 : 0; + $message = __('Min. Recommended Value').' 256K'; + break; + + case 'max_connections': + $name = __('Maximun connections'); + $value = $item['Value']; + $status = (($item['Value'] / $bytes) >= 90) ? 1 : 0; + $message = __('Min. Recommended Value').' 90'; + break; + + case 'key_buffer_size': + $name = __('Key buffer size'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 256) ? 1 : 0; + $message = __('Min. Recommended Value').' 256'; + break; + + case 'read_buffer_size': + $name = __('Read buffer size'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 32) ? 1 : 0; + $message = __('Min. Recommended Value').' 32'; + break; + + case 'read_rnd_buffer_size': + $name = __('Read rnd-buffer size'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 32) ? 1 : 0; + $message = __('Min. Recommended Value').' 32'; + break; + + case 'query_cache_min_res_unit': + $name = __('Query cache min-res-unit'); + $value = ($item['Value'] / $bytes); + $status = (($item['Value'] / $bytes) >= 2) ? 1 : 0; + $message = __('Min. Recommended Value').' 2k'; + break; + + case 'innodb_file_per_table': + $name = __('InnoDB file per table'); + $value = $item['Value']; + $status = ($item['Value'] === 'ON') ? 1 : 0; + $message = __('Recommended ON'); + break; + + default: + $name = ''; + $value = 0; + break; + } + + if (empty($name) !== true) { + $carry[$item['Variable_name']] = [ + 'name' => $name, + 'value' => $value, + 'status' => $status, + 'message' => $message, + ]; + } + + return $carry; + }, + [] + ); + + $result = [ + 'error' => false, + 'data' => $variablesMsql, + ]; + + return json_encode($result); + } + + + /** + * Tables fragmentation in the Pandora FMS database. + * + * @return string + */ + public function getTablesFragmentation(): string + { + global $config; + + // Estimated fragmentation percentage as maximum. + $tFragmentationMax = 10; + + // Extract the fragmentation value. + $tFragmentationValue = db_get_sql( + sprintf( + "SELECT (data_free/(index_length+data_length)) as frag_ratio + FROM information_schema.tables + WHERE DATA_FREE > 0 + AND table_name='tagente_datos' + AND table_schema='%s'", + $config['dbname'] + ) + ); + + // Check if it meets the fragmentation value. + $status_tables_frag = ''; + if ($tFragmentationValue > $tFragmentationMax) { + $tFragmentationMsg = __( + 'Table fragmentation is higher than recommended. They should be defragmented.' + ); + $tFragmentationStatus = 0; + } else { + $tFragmentationMsg = __('Table fragmentation is correct.'); + $tFragmentationStatus = 1; + } + + $result = [ + 'error' => false, + 'data' => [ + 'tablesFragmentationMax' => [ + 'name' => __( + 'Tables fragmentation (maximum recommended value)' + ), + 'value' => $tFragmentationMax.'%', + ], + 'tablesFragmentationValue' => [ + 'name' => __('Tables fragmentation (current value)'), + 'value' => number_format($tFragmentationValue, 2).'%', + ], + 'tablesFragmentationStatus' => [ + 'name' => __('Table fragmentation status'), + 'value' => $status_tables_frag, + 'status' => $tFragmentationStatus, + ], + ], + ]; + + return json_encode($result); + } + + + /** + * Pandora FMS logs dates. + * + * @return string + */ + public function getPandoraFMSLogsDates(): string + { + global $config; + + $unit = 'M'; + + $pathServerLogs = 'var/log/pandora/pandora_server.log'; + $servers = $this->getLogInfo($pathServerLogs); + + $pathErrLogs = 'var/log/pandora/pandora_server.error'; + $errors = $this->getLogInfo($pathErrLogs); + + $pathConsoleLogs = $config['homedir'].'/pandora_console.log'; + $console = $this->getLogInfo($pathConsoleLogs); + + $result = [ + 'error' => false, + 'data' => [ + 'sizeServerLog' => [ + 'name' => __('Size server logs (current value)'), + 'value' => $servers['value'].' '.$unit, + ], + 'statusServerLog' => [ + 'name' => __('Status server logs'), + 'value' => $servers['message'], + 'status' => $servers['status'], + ], + 'sizeErrorLog' => [ + 'name' => __('Size error logs (current value)'), + 'value' => $errors['value'].' '.$unit, + ], + 'statusErrorLog' => [ + 'name' => __('Status error logs'), + 'value' => $errors['message'], + 'status' => $errors['status'], + ], + 'sizeConsoleLog' => [ + 'name' => __('Size console logs (current value)'), + 'value' => $console['value'].' '.$unit, + ], + 'statusConsoleLog' => [ + 'name' => __('Status console logs'), + 'value' => $console['message'], + 'status' => $console['status'], + ], + ], + ]; + + return json_encode($result); + } + + + /** + * Pandora FMS Licence Information. + * + * @return string + */ + public function getLicenceInformation(): string + { + global $config; + + // Extract customer key. + $sql = sprintf( + "SELECT `value` + FROM `tupdate_settings` + WHERE `key` = '%s'", + 'customer_key' + ); + $customerKey = db_get_value_sql($sql); + + // Extract Info license. + $license = enterprise_hook('license_get_info'); + + // Agent Capacity. + $agentCount = db_get_value_sql('SELECT count(*) FROM tagente'); + $agentsCapacity = __('License capacity is less than 90 percent'); + $agentsCapacitySt = 1; + if ($agentCount > ($license['limit'] * 90 / 100)) { + $agentsCapacity = __('License capacity exceeds 90 percent'); + $agentsCapacitySt = 0; + } + + // Modules average. + $modulesCount = db_get_value_sql('SELECT count(*) FROM tagente_modulo'); + $average = ($modulesCount / $agentCount); + $averageMsg = __( + 'The average of modules per agent is more than 40. You can have performance problems' + ); + $averageSt = 0; + if ($average <= 40) { + $averageMsg = __( + 'The average of modules per agent is less than 40' + ); + $averageSt = 1; + } + + // Modules Networks average. + $totalNetworkModules = db_get_value_sql( + 'SELECT count(*) + FROM tagente_modulo + WHERE id_tipo_modulo + BETWEEN 6 AND 18' + ); + $totalModuleIntervalTime = db_get_value_sql( + 'SELECT SUM(module_interval) + FROM tagente_modulo + WHERE id_tipo_modulo + BETWEEN 6 AND 18' + ); + + $averageTime = 0; + if ($totalModuleIntervalTime !== false) { + $averageTime = number_format( + ((int) $totalModuleIntervalTime / (int) $totalNetworkModules), + 3 + ); + } + + $moduleNetworkmsg = __( + sprintf( + 'The system is not overloaded (average time %d)', + $average_time + ) + ); + $moduleNetworkst = 1; + if ($average_time === 0) { + $moduleNetworkmsg = __('The system has no load'); + $moduleNetworkst = 0; + } else if ($averageTime < 180) { + $moduleNetworkmsg = __( + sprintf( + 'The system is overloaded (average time %d) and a very fine configuration is required', + $average_time + ) + ); + $moduleNetworkst = 0; + } + + $result = [ + 'error' => false, + 'data' => [ + 'customerKey' => [ + 'name' => __('Customer key'), + 'value' => $customerKey, + ], + 'customerExpires' => [ + 'name' => __('Support expires'), + 'value' => $license['expiry_date'], + ], + 'customerLimit' => [ + 'name' => __('Platform Limit'), + 'value' => $license['limit'].' '.__('Agents'), + ], + 'customerPfCount' => [ + 'name' => __('Current Platform Count'), + 'value' => $license['count'].' '.__('Agents'), + ], + 'customerPfCountEnabled' => [ + 'name' => __('Current Platform Count (enabled: items)'), + 'value' => $license['count_enabled'].' '.__('Agents'), + ], + 'customerPfCountDisabled' => [ + 'name' => __('Current Platform Count (disabled: items)'), + 'value' => $license['count_disabled'].' '.__('Agents'), + ], + 'customerMode' => [ + 'name' => __('License Mode'), + 'value' => $license['license_mode'], + ], + 'customerNMS' => [ + 'name' => __('Network Management System'), + 'value' => ($license['nms'] > 0) ? __('On') : __('Off'), + ], + 'customerSatellite' => [ + 'name' => __('Satellite'), + 'value' => ($license['dhpm'] > 0) ? __('On') : __('Off'), + ], + 'customerLicenseTo' => [ + 'name' => __('Licensed to'), + 'value' => $license['licensed_to'], + ], + 'customerCapacity' => [ + 'name' => __('Status of agents capacity'), + 'value' => $agentsCapacity, + 'status' => $agentsCapacitySt, + ], + 'customerAverage' => [ + 'name' => __('Status of average modules per agent'), + 'value' => $averageMsg, + 'status' => $averageSt, + ], + + 'customerAverageNetwork' => [ + 'name' => __('Interval average of the network modules'), + 'value' => $moduleNetworkmsg, + 'status' => $moduleNetworkst, + ], + ], + ]; + + return json_encode($result); + } + + + /** + * Status of the attachment folder. + * + * @return string + */ + public function getAttachmentFolder(): string + { + global $config; + + // Count files in attachment. + $attachmentFiles = count( + glob( + $config['homedir'].'/attachment/{*.*}', + GLOB_BRACE + ) + ); + + // Check status attachment. + $attachmentMsg = __( + 'The attached folder contains more than 700 files.' + ); + $attachmentSt = 0; + if ($attachmentFiles <= 700) { + $attachmentMsg = __( + 'The attached folder contains less than 700 files.' + ); + $attachmentSt = 1; + } + + $result = [ + 'error' => false, + 'data' => [ + 'attachFiles' => [ + 'name' => __('Total files in the attached folder'), + 'value' => $attachmentFiles, + ], + 'attachStatus' => [ + 'name' => __('Status of the attachment folder'), + 'value' => $attachmentMsg, + 'status' => $attachmentSt, + ], + ], + ]; + + return json_encode($result); + } + + + /** + * Information from the tagente_datos table. + * + * @return string + */ + public function getInfoTagenteDatos(): string + { + global $config; + + $agentDataCount = db_get_value_sql( + 'SELECT COUNT(*) + FROM tagente_datos' + ); + + $taMsg = __( + 'The tagente_datos table contains too much data. A historical database is recommended.' + ); + $taStatus = 0; + if ($agentDataCount <= 3000000) { + $taMsg = __( + 'The tagente_datos table contains an acceptable amount of data.' + ); + $taStatus = 1; + } + + $result = [ + 'error' => false, + 'data' => [ + 'agentDataCount' => [ + 'name' => __('Total data in tagente_datos table'), + 'value' => $agentDataCount, + ], + 'agentDataStatus' => [ + 'name' => __('Tagente_datos table status'), + 'value' => $taMsg, + 'status' => $taStatus, + ], + ], + ]; + + return json_encode($result); + } + + + /** + * Pandora FMS server threads. + * + * @return string + */ + public function getServerThreads(): string + { + global $config; + + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { + return []; + } + + $totalServerThreads = shell_exec( + 'ps -T aux | grep pandora_server | grep -v grep | wc -l' + ); + $percentageThreadsRam = shell_exec( + "ps axo pmem,cmd | grep pandora_server | awk '{sum+=$1} END {print sum}'" + ); + $percentageThreadsCpu = shell_exec( + "ps axo pcpu,cmd | grep pandora_server | awk '{sum+=$1} END {print sum}'" + ); + + $result = [ + 'error' => false, + 'data' => [ + 'totalServerThreads' => [ + 'name' => __('Total server threads'), + 'value' => $totalServerThreads, + ], + 'percentageThreadsRam' => [ + 'name' => __('Percentage of threads used by the RAM'), + 'value' => $percentageThreadsRam.' %', + ], + 'percentageThreadsCpu' => [ + 'name' => __('Percentage of threads used by the CPU'), + 'value' => $percentageThreadsCpu.' %', + ], + ], + ]; + + return json_encode($result); + } + + + /** + * SQL show engine innodb status. + * + * @return string + */ + public function getShowEngine(): string + { + global $config; + + try { + // Trick to avoid showing error in case + // you don't have enough permissions. + $backup = error_reporting(); + error_reporting(0); + $innodb = db_get_all_rows_sql('show engine innodb status'); + error_reporting($backup); + } catch (Exception $e) { + $innodb['Status'] = $e->getMessage(); + } + + $result = []; + if (isset($innodb[0]['Status']) === true + && $innodb[0]['Status'] !== false + ) { + $lenght = strlen($innodb[0]['Status']); + + $data = []; + for ($i = 0; $i < $lenght; $i = ($i + 500)) { + $str = substr($innodb[0]['Status'], $i, ($i + 500)); + $data['showEngine-'.$i] = [ + 'name' => '', + 'value' => '
    '.$str.'
    ', + ]; + } + + $result = [ + 'error' => false, + 'data' => $data, + 'id' => 'showEngine', + ]; + } + + return json_encode($result); + } + + + /** + * Agent Id whit name is equal to Server Name. + * + * @return integer Id agent module. + */ + public function getAgentIdMasterServer(): int + { + global $config; + + $serverName = db_get_value_sql( + 'SELECT `name` + FROM tserver + WHERE `name` IS NOT NULL + AND `master` > 0 + ORDER BY `master` DESC' + ); + $agentId = (int) db_get_value_sql( + sprintf( + 'SELECT id_agente + FROM tagente + WHERE nombre = "%s"', + $serverName + ) + ); + + if (isset($agentId) === false || is_numeric($agentId) === false) { + $agentId = 0; + } + + return $agentId; + } + + + /** + * Graph. + * + * @param integer $id Id agent. + * @param string $name Name module. + * @param boolean $image Chart interactive or only image. + * @param boolean $base64 Image or base64. + * + * @return string + */ + public function getChart( + int $id, + string $name, + bool $image=false, + bool $base64=false + ): string { + global $config; + + include_once $config['homedir'].'/include/functions_graph.php'; + $data = modules_get_agentmodule_id($name, $id); + $params = [ + 'agent_module_id' => $data['id_agente_modulo'], + 'period' => SECONDS_1MONTH, + 'date' => time(), + 'height' => '200', + 'only_image' => $image, + 'return_img_base_64' => $base64, + ]; + + return grafico_modulo_sparse($params); + } + + + /** + * Check pandoradb installed. + * + * @return string + */ + public function checkPandoraDB(): string + { + global $config; + $result = ''; + + if (isset($config['db_maintenance']) === false) { + $result .= '(*) '; + $result .= __( + 'Please check your Pandora Server setup and make sure that the database maintenance daemon is running.' + ); + $result .= ' '; + $result .= __( + 'It\' is very important to keep the database up-to-date to get the best performance and results in Pandora' + ); + } + + return $result; + } + + + /** + * Draw table. + * + * @param string $method Method. + * @param string $title Title. + * + * @return string Return html. + */ + public function printData(string $method, string $title): string + { + global $config; + + if (is_ajax()) { + // TODO: Call method. + $result = $method; + } else { + // Datatables list. + try { + $columns = [ + [ + 'class' => 'datatables-td-title', + 'text' => 'name', + ], + [ + 'class' => 'datatables-td-max', + 'text' => 'value', + ], + 'message', + ]; + + $columnNames = [ + [ + 'style' => 'display:none;', + 'text' => '', + ], + [ + 'style' => 'display:none', + 'text' => '', + ], + [ + 'style' => 'display:none', + 'text' => '', + ], + ]; + + $tableId = $method.'_'.uniqid(); + // Load datatables user interface. + if ($this->pdf === false) { + $result = ui_print_datatable( + [ + 'id' => $tableId, + 'class' => 'info_table caption_table', + 'style' => 'width: 100%', + 'columns' => $columns, + 'column_names' => $columnNames, + 'ajax_data' => [ + 'method' => 'datatablesDraw', + 'name' => $method, + ], + 'ajax_url' => $this->ajaxController, + 'paging' => 0, + 'no_sortable_columns' => [-1], + 'caption' => $title, + 'print' => true, + ] + ); + } else { + $data = json_decode( + $this->datatablesDraw($method, true), + true + ); + + $table = new stdClass(); + $table->width = '100%'; + $table->class = 'pdf-report'; + $table->style = []; + $table->style[0] = 'font-weight: bolder;'; + + // FIX tables break content. + if ($data['idTable'] === 'showEngine') { + $table->styleTable = 'page-break-inside: auto;'; + } else { + $table->autosize = 1; + } + + $table->head = []; + $table->head_colspan[0] = 3; + $table->head[0] = $title; + $table->data = []; + + if (isset($data) === true + && is_array($data) === true + && count($data) > 0 + ) { + $i = 0; + foreach ($data['data'] as $key => $value) { + $table->data[$i][0] = $value['name']; + $table->data[$i][1] = $value['value']; + $table->data[$i][2] = $value['message']; + $i++; + } + } + + $result = html_print_table($table, true); + } + } catch (Exception $e) { + $result = $e->getMessage(); + } + } + + return $result; + } + + + /** + * Prepare params for getCarts. + * + * @return void + */ + public function getChartAjax():void + { + global $config; + + $params = json_decode( + io_safe_output(get_parameter('params', '')), + true + ); + + $return = ''; + if (isset($params['idAgent']) === true + && empty($params['idAgent']) === false + && isset($params['nameModule']) + && empty($params['nameModule']) === false + ) { + $return = $this->getChart( + $params['idAgent'], + $params['nameModule'] + ); + } + + exit($return); + } + + + /** + * Paint table with charts. + * + * @param array $params Info charts. + * + * @return string Html. + */ + public function printDataCharts(array $params): string + { + global $config; + + if (!$params) { + $params = get_parameter('params'); + } + + if (is_ajax()) { + // TODO: Call method. + $return = $method; + } else { + // Datatables list. + try { + $id = str_replace( + ' ', + '', + io_safe_output($params['nameModule']) + ); + + if ($this->pdf === false) { + $return = '
    '; + $settings = [ + 'type' => 'POST', + 'dataType' => 'html', + 'url' => ui_get_full_url( + 'ajax.php', + false, + false, + false + ), + 'data' => [ + 'page' => $this->ajaxController, + 'method' => 'getChartAjax', + 'params' => json_encode($params), + ], + ]; + + ?> + + width = '100%'; + $table->class = 'pdf-report'; + $table->style = []; + $table->style[0] = 'font-weight: bolder;'; + $table->autosize = 1; + + $table->head = []; + $table->head[0] = $params['nameModule']; + + $table->data = []; + $table->data[0] = $this->getChart( + $params['idAgent'], + $params['nameModule'], + true, + false + ); + + $return = html_print_table($table, true); + } + } catch (Exception $e) { + $return = $e->getMessage(); + } + } + + return $return; + } + + + /** + * Private function for Info size path. + * + * @param string $path Route file. + * + * @return array With values size file and message and status. + */ + private function getLogInfo(string $path): array + { + global $config; + + // Vars. + $mega = 1048576; + $tenMega = 10485760; + + $result = [ + 'value' => 0, + 'message' => '', + 'status' => 0, + ]; + + if (is_file($path) === true) { + $fileSize = filesize($path); + $sizeServerLog = number_format($fileSize); + $sizeServerLog = (0 + str_replace(',', '', $sizeServerLog)); + + $value = number_format(($fileSize / $mega), 3); + $message = __('You have more than 10 MB of logs'); + $status = 0; + if ($sizeServerLog <= $tenMega) { + $message = __('You have less than 10 MB of logs'); + $status = 1; + } + + $result = [ + 'value' => $value, + 'message' => $message, + 'status' => $status, + ]; + } + + return $result; + } + + + /** + * Undocumented function + * + * @param string|null $method Method data requested. + * @param boolean $return Type return. + * + * @return string|null + */ + public function datatablesDraw( + ?string $method=null, + bool $return=false + ):?string { + if (isset($method) === false) { + $method = get_parameter('name', ''); + } + + if (method_exists($this, $method) === true) { + $data = json_decode($this->{$method}(), true); + } + + $result = []; + if (isset($data) === true + && is_array($data) === true + && count($data) > 0 + ) { + $items = $data['data']; + $dataReduce = array_reduce( + array_keys($data['data']), + function ($carry, $key) use ($items) { + // Transforms array of arrays $data into an array + // of objects, making a post-process of certain fields. + if (isset($items[$key]['status']) === true) { + $acumValue = $items[$key]['value']; + if ($items[$key]['status'] === 1) { + $items[$key]['value'] = html_print_image( + 'images/exito.png', + true, + [ + 'title' => __('Succesfuly'), + 'style' => 'width:15px;', + ] + ); + } else { + $items[$key]['value'] = html_print_image( + 'images/error_1.png', + true, + [ + 'title' => __('Error'), + 'style' => 'width:15px;', + ] + ); + } + + $items[$key]['value'] .= ' '.$acumValue; + } + + // FIX for customer key. + if ($key === 'customerKey') { + $customerKey = ui_print_truncate_text( + $items[$key]['value'], + 30, + false, + true, + false + ); + $spanValue = ''.$customerKey.''; + $items[$key]['value'] = $spanValue; + } + + if (isset($items[$key]['message']) === false) { + $items[$key]['message'] = ''; + } + + $carry[] = (object) $items[$key]; + return $carry; + } + ); + + $result = [ + 'data' => $dataReduce, + 'recordsTotal' => count($dataReduce), + 'recordsFiltered' => count($dataReduce), + 'idTable' => (isset($data['id']) === true) ? $data['id'] : '', + ]; + } + + // Datatables format: RecordsTotal && recordsfiltered. + if ($return === false) { + echo json_encode($result); + return null; + } else { + return json_encode($result); + } + } + + + /** + * Print Diagnostics Form feedback. + * + * @return void + */ + public function formFeedback(): void + { + $form = [ + 'action' => '#', + 'id' => 'modal_form_feedback', + 'onsubmit' => 'return false;', + 'class' => 'modal', + 'extra' => 'novalidate', + ]; + + $inputs = []; + + $inputs[] = [ + 'label' => __('What happened').'?', + 'id' => 'div-what-happened', + 'class' => 'flex-row', + 'arguments' => [ + 'name' => 'what-happened', + 'type' => 'textarea', + 'value' => '', + 'return' => true, + 'rows' => 1, + 'columns' => 1, + 'size' => 25, + 'attributes' => 'required="required"', + ], + ]; + + $inputs[] = [ + 'label' => __('Your email'), + 'class' => 'flex-row-baseline', + 'arguments' => [ + 'name' => 'email', + 'id' => 'email', + 'type' => 'email', + 'size' => 42, + 'required' => 'required', + ], + ]; + + $inputs[] = [ + 'label' => __('Include installation data'), + 'class' => 'flex-row-vcenter', + 'arguments' => [ + 'name' => 'include_installation_data', + 'id' => 'include_installation_data', + 'type' => 'switch', + 'value' => 1, + ], + ]; + + exit( + $this->printForm( + [ + 'form' => $form, + 'inputs' => $inputs, + ], + true + ) + ); + } + + + /** + * Create cron task form feedback. + * + * @return void Json result AJAX request. + */ + public function createdScheduleFeedbackTask():void + { + global $config; + + $mail_feedback = 'feedback@artica.es'; + $email = $mail_feedback; + $subject = 'PandoraFMS Report '.$config['pandora_uid']; + $text = get_parameter('what-happened', ''); + $attachment = get_parameter_switch('include_installation_data', 0); + $email_from = get_parameter_switch('email', ''); + $title = __('Hello Feedback-Men'); + + $product_name = io_safe_output(get_product_name()); + + if (check_acl($config['id_user'], 0, 'PM') !== 1) { + $email = get_mail_admin(); + $name_admin = get_name_admin(); + + $subject = __('Feedback').' '.$product_name.' '.$config['pandora_uid']; + + $title = __('Hello').' '.$name_admin; + } + + $p1 = __( + 'User %s is reporting an issue in its %s experience', + $email_from, + $product_name + ); + $p1 .= ':'; + + $p2 = $text; + + if ($attachment === 1) { + $msg_attch = __('Find some files attached to this mail'); + $msg_attch .= '. '; + $msg_attch .= __( + 'PDF is the diagnostic information retrieved at report time' + ); + $msg_attch .= '. '; + $msg_attch .= __('CSV contains the statuses of every product file'); + $msg_attch .= '. '; + } + + $p3 = __( + 'If you think this report must be escalated, feel free to forward this mail to "%s"', + $mail_feedback + ); + + $legal = __('LEGAL WARNING'); + $legal1 = __( + 'The information contained in this transmission is privileged and confidential information intended only for the use of the individual or entity named above' + ); + $legal1 .= '. '; + $legal2 = __( + 'If the reader of this message is not the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited' + ); + $legal2 .= '. '; + $legal3 = __( + 'If you have received this transmission in error, do not read it' + ); + $legal3 .= '. '; + $legal4 = __( + 'Please immediately reply to the sender that you have received this communication in error and then delete it' + ); + $legal4 .= '.'; + + $patterns = [ + '/__title__/', + '/__p1__/', + '/__p2__/', + '/__attachment__/', + '/__p3__/', + '/__legal__/', + '/__legal1__/', + '/__legal2__/', + '/__legal3__/', + '/__legal4__/', + ]; + + $substitutions = [ + $title, + $p1, + $p2, + $msg_attch, + $p3, + $legal, + $legal1, + $legal2, + $legal3, + $legal4, + ]; + + $html_template = file_get_contents( + $config['homedir'].'/include/templates/feedback_send_mail.html' + ); + + $text = preg_replace($patterns, $substitutions, $html_template); + + $idUserTask = db_get_value( + 'id', + 'tuser_task', + 'function_name', + 'cron_task_feedback_send_mail' + ); + + // Params for send mail with cron. + $parameters = [ + 0 => '0', + 1 => $email, + 2 => $subject, + 3 => $text, + 4 => $attachment, + 'first_execution' => strtotime('now'), + ]; + + // Values insert task cron. + $values = [ + 'id_usuario' => $config['id_user'], + 'id_user_task' => $idUserTask, + 'args' => serialize($parameters), + 'scheduled' => 'no', + 'id_grupo' => 0, + ]; + + $result = db_process_sql_insert( + 'tuser_task_scheduled', + $values + ); + + $error = 1; + if ($result === false) { + $error = 0; + } + + $return = [ + 'error' => $error, + 'title' => [ + __('Failed'), + __('Success'), + ], + 'text' => [ + ui_print_error_message(__('Invalid cron task'), '', true), + ui_print_success_message(__('Cron task generated'), '', true), + ], + ]; + + exit(json_encode($return)); + } + + + /** + * Print Diagnostics PDF report. + * + * @param string|null $filename Filename. + * + * @return void + */ + public function exportPDF(?string $filename=null):void + { + global $config; + + $this->pdf = true; + + enterprise_include_once('/include/class/Pdf.class.php'); + $mpdf = new Pdf([]); + + // ADD style. + $mpdf->addStyle($config['homedir'].'/include/styles/diagnostics.css'); + + // ADD Metadata. + $product_name = io_safe_output(get_product_name()); + $mpdf->setMetadata( + __('Diagnostics Info'), + $product_name.' Enteprise', + $product_name, + __( + 'Automated %s report for user defined report', + $product_name + ) + ); + + // ADD Header. + $mpdf->setHeaderHTML(__('Diagnostics Info')); + + // ADD content to report. + $mpdf->addHTML( + $this->printMethodsDiagnostigsInfo() + ); + + $mpdf->addHTML( + $this->printCharts() + ); + + // ADD Footer. + $mpdf->setFooterHTML(); + + // Write html filename. + $mpdf->writePDFfile($filename); + } + + + /** + * Send Csv md5 files. + * + * @return string + */ + public function csvMd5Files():string + { + global $config; + + // Extract files. + $files = $this->recursiveDirValidation($config['homedir']); + + // Type divider. + $divider = html_entity_decode($config['csv_divider']); + + // BOM. + $result = pack('C*', 0xEF, 0xBB, 0xBF); + + $result .= __('Path').$divider.__('MD5')."\n"; + foreach ($files as $key => $value) { + $result .= $key.$divider.$value."\n"; + } + + return $result; + } + + + /** + * Function to return array with name file -> MD%. + * + * @param string $dir Directory. + * + * @return array Result all files in directory recursively. + */ + private function recursiveDirValidation(string $dir):array + { + $result = []; + + $dir_content = scandir($dir); + + // Dont check attachment. + if (strpos($dir, $config['homedir'].'/attachment') === false) { + if (is_array($dir_content) === true) { + foreach (scandir($dir) as $file) { + if ('.' === $file || '..' === $file) { + continue; + } + + if (is_dir($dir.'/'.$file) === true) { + $result += $this->recursiveDirValidation( + $dir.'/'.$file + ); + } else { + $result[$dir.'/'.$file] = md5_file($dir.'/'.$file); + } + } + } + } + + return $result; + } + + + /** + * Send PHP info in report. + * + * @param string $filename Download dir report. + * + * @return void + */ + public function phpInfoReports(string $filename) + { + global $config; + + $this->pdf = true; + + // Extract info PHP. + ob_start(); + phpinfo(); + $php_info = ob_get_clean(); + + enterprise_include_once('/include/class/Pdf.class.php'); + $mpdf = new Pdf([]); + + // ADD Metadata. + $product_name = io_safe_output(get_product_name()); + $mpdf->setMetadata( + __('PHP Info'), + $product_name.' Enteprise', + $product_name, + __( + 'Automated %s report for user defined report', + $product_name + ) + ); + + // ADD Header. + $mpdf->setHeaderHTML(__('PHP Info')); + + // ADD content to report. + $mpdf->addHTML($php_info); + + // ADD Footer. + $mpdf->setFooterHTML(); + + // Write html filename. + $mpdf->writePDFfile($filename); + } + + +} diff --git a/pandora_console/include/class/HelpFeedBack.class.php b/pandora_console/include/class/HelpFeedBack.class.php new file mode 100644 index 0000000000..074f3d8df2 --- /dev/null +++ b/pandora_console/include/class/HelpFeedBack.class.php @@ -0,0 +1,310 @@ +AJAXMethods); + } + + + /** + * Constructor. + * + * @param string $ajax_controller Controller. + * + * @return object + */ + public function __construct($ajax_controller) + { + $this->ajaxController = $ajax_controller; + + return $this; + } + + + /** + * Main method. + * + * @return void + */ + public function run() + { + ui_require_css_file('help_feedback'); + + $help_url = get_parameter('url', null); + if ($help_url === null) { + echo __('Page not found'); + } else { + ?> + + '; + // Load feedback form. + echo $this->loadFeedbackForm(); + echo '
    '; + } + + + /** + * Loads a feedback form + * + * @return​ ​string HTML code for form. + * + * @return Function loadFeedbackForm. + */ + public function loadFeedbackForm() + { + global $config; + + ui_require_css_file('helper'); + + $form = [ + 'action' => '#', + 'id' => 'feedback_form', + 'onsubmit' => 'return false;', + ]; + + $inputs = [ + [ + 'wrapper' => 'div', + 'block_id' => 'btn_section', + 'class' => 'btn_section', + 'direct' => 1, + 'block_content' => [ + [ + 'arguments' => [ + 'label' => __('Sugesstion'), + 'type' => 'button', + 'attributes' => 'class="btn_sug"', + 'name' => 'option_1', + 'id' => 'option_1', + 'script' => 'change_option1()', + ], + ], + [ + 'arguments' => [ + 'label' => __('Something is not quite right'), + 'type' => 'button', + 'attributes' => 'class="btn_something"', + 'name' => 'option_2', + 'id' => 'option_2', + 'script' => 'change_option2()', + ], + ], + ], + ], + [ + + 'label' => __('What Happend?'), + 'arguments' => [ + 'class' => 'textarea_feedback', + 'id' => 'feedback_text', + 'type' => 'textarea', + 'name' => 'feedback_text', + ], + ], + [ + 'label' => __('Your Email'), + 'arguments' => [ + 'id' => 'feedback_email', + 'name' => 'feedback_email', + 'input_class' => 'email_feedback', + 'class' => 'email_feedback', + 'type' => 'text', + ], + ], + [ + 'arguments' => [ + 'button_class' => 'btn_submit', + 'class' => 'btn_submit', + 'attributes' => 'class="sub next btn_submit_feed_back"', + 'type' => 'submit', + 'id' => 'submit_feedback', + 'label' => __('Submit'), + ], + ], + ]; + + $output = ui_toggle( + $this->printForm( + [ + 'form' => $form, + 'inputs' => $inputs, + ], + true + ), + __('Feedback'), + '', + '', + true, + false, + '', + 'no-border' + ); + + $output .= $this->loadJS(); + return $output; + } + + + /** + * Function send_mail_method,we use send_email_attachment method + * from functions_cron.php. + * + * @param​ ​string​ $feedback_option type fo mail. + * @param​ ​string​ $feedback_text text mail. + * @param​ ​string​ $feedback_mail costumer mail. + * + * @return integer Status of the email send task. + */ + public function sendMailMethod() + { + $subject = get_parameter('feedback_option', null); + $feedback_text = get_parameter('feedback_text', null); + $feedback_mail = get_parameter('feedback_email', null); + + $subject; + + if ($subject === null) { + echo json_encode(['error' => __('No ha seleccionado una opcion')]); + exit; + } + + enterprise_include_once('include/functions_cron.php'); + + $feedback_text .= ' + From '.$feedback_mail.' '; + + $res = enterprise_hook('send_email_attachment', ['feedback@artica.es', $feedback_text, $subject]); + + return $res; + + } + + + public function loadJS() + { + ob_start(); + ?> + + map; + // ACL. + $networkmap_write = check_acl( + $config['id_user'], + $networkmap['id_group'], + 'MW' + ); + $simulate = false; if (isset($networkmap['__simulated']) === false) { $networkmap['filter'] = json_decode( @@ -2711,6 +2720,7 @@ class NetworkMap $output .= 'var networkmap_center = [ '.$networkmap['center_x'].', '.$networkmap['center_y']."];\n"; $output .= 'var networkmap_dimensions = [ '.$networkmap['width'].', '.$networkmap['height']."];\n"; $output .= 'var enterprise_installed = '.((int) enterprise_installed()).";\n"; + $output .= 'var networkmap_write = '.$networkmap_write.";\n"; $output .= 'var node_radius = '.$networkmap['filter']['node_radius'].";\n"; $output .= 'var networkmap_holding_area_dimensions = '.json_encode($networkmap['filter']['holding_area']).";\n"; $output .= "var networkmap = {'nodes': [], 'links': []};\n"; diff --git a/pandora_console/include/class/WelcomeWindow.class.php b/pandora_console/include/class/WelcomeWindow.class.php new file mode 100644 index 0000000000..4381323439 --- /dev/null +++ b/pandora_console/include/class/WelcomeWindow.class.php @@ -0,0 +1,760 @@ + $msg] + ); + } + + + /** + * Checks if target method is available to be called using AJAX. + * + * @param string $method Target method. + * + * @return boolean True allowed, false not. + */ + public function ajaxMethod($method) + { + global $config; + + // Check access. + check_login(); + + return in_array($method, $this->AJAXMethods); + } + + + /** + * Constructor. + * + * @param boolean $must_run Must run or not. + * @param string $ajax_controller Controller. + * + * @return object + * @throws Exception On error. + */ + public function __construct( + bool $must_run=false, + $ajax_controller='include/ajax/welcome_window' + ) { + $this->ajaxController = $ajax_controller; + + if ($this->initialize($must_run) !== true) { + throw new Exception('Must not be shown'); + } + + return $this; + } + + + /** + * Main method. + * + * @return void + */ + public function run() + { + ui_require_css_file('new_installation_welcome_window'); + echo '
    width.'; '.$styleTable.' '.$table->tablealign; } else { - $output .= '
    tablealign; } $output .= ' cellpadding="'.$table->cellpadding.'" cellspacing="'.$table->cellspacing.'"'; @@ -3003,23 +3093,24 @@ function html_print_csrf_error() /** - * Print an swith button + * Print an swith button. * - * @param array $atributes. Valid params: - * name: Usefull to handle in forms - * value: If is checked or not - * disabled: Disabled. Cannot be pressed. - * id: Optional id for the switch. - * class: Additional classes (string). - * @return string with HTML of button + * @param array $attributes Valid params. + * name: Usefull to handle in forms. + * value: If is checked or not. + * disabled: Disabled. Cannot be pressed. + * id: Optional id for the switch. + * class: Additional classes (string). + * + * @return string with HTML of button. */ function html_print_switch($attributes=[]) { $html_expand = ''; // Check the load values on status. - $html_expand .= (bool) $attributes['value'] ? ' checked' : ''; - $html_expand .= (bool) $attributes['disabled'] ? ' disabled' : ''; + $html_expand .= (bool) ($attributes['value']) ? ' checked' : ''; + $html_expand .= (bool) ($attributes['disabled']) ? ' disabled' : ''; // Only load the valid attributes. $valid_attrs = [ @@ -3042,7 +3133,7 @@ function html_print_switch($attributes=[]) } return ""; } @@ -3200,6 +3291,10 @@ function html_print_input($data, $wrapper='div', $input_only=false) ); break; + case 'email': + $output .= html_print_input_email($data); + break; + case 'hidden': $output .= html_print_input_hidden( $data['name'], diff --git a/pandora_console/include/functions_reporting.php b/pandora_console/include/functions_reporting.php index 1d0355cf97..799b22cae2 100755 --- a/pandora_console/include/functions_reporting.php +++ b/pandora_console/include/functions_reporting.php @@ -224,7 +224,12 @@ function reporting_make_reporting_data( // General reports with 0 period means last value // Avoid to overwrite it by template value. - if (!empty($period) && ($content['type'] !== 'general' && $content['period'] != 0)) { + $general_last_value = false; + if ($content['type'] === 'general' && $content['period'] == 0) { + $general_last_value = true; + } + + if (!empty($period) && $general_last_value === false) { $content['period'] = $period; } @@ -506,43 +511,6 @@ function reporting_make_reporting_data( ); break; - /* - case 'MTTR': - $report['contents'][] = reporting_value( - $report, - $content, - 'MTTR', - $pdf - ); - break; - - case 'MTBF': - $report['contents'][] = reporting_value( - $report, - $content, - 'MTBF', - $pdf - ); - break; - - case 'TTO': - $report['contents'][] = reporting_value( - $report, - $content, - 'TTO', - $pdf - ); - break; - - case 'TTRT': - $report['contents'][] = reporting_value( - $report, - $content, - 'TTRT', - $pdf - ); - break; - */ case 'agent_configuration': $report['contents'][] = io_safe_output( reporting_agent_configuration( @@ -3276,6 +3244,7 @@ function reporting_database_serialized($report, $content) } $return['keys'] = $keys; + $return['agent_name_db'] = agents_get_name($id_agent); $return['agent_name'] = $agent_alias; $return['module_name'] = $module_name; @@ -4303,6 +4272,7 @@ function reporting_monitor_report($report, $content) ); } + $return['agent_name_db'] = agents_get_name($id_agent); $return['agent_name'] = $agent_alias; $return['module_name'] = $module_name; @@ -4475,6 +4445,7 @@ function reporting_prediction_date($report, $content) $agent_name = io_safe_output( modules_get_agentmodule_agent_alias($content['id_agent_module']) ); + $agent_name_db = io_safe_output(modules_get_agentmodule_agent_name($content['id_agent_module'])); $return['title'] = $content['name']; $return['subtitle'] = $agent_name.' - '.$module_name; @@ -4482,6 +4453,7 @@ function reporting_prediction_date($report, $content) $return['date'] = reporting_get_date_text($report, $content); $return['label'] = (isset($content['style']['label'])) ? $content['style']['label'] : ''; + $return['agent_name_db'] = $agent_name_db; $return['agent_name'] = $agent_name; $return['module_name'] = $module_name; @@ -4526,12 +4498,14 @@ function reporting_projection_graph( $module_name = io_safe_output(modules_get_agentmodule_name($content['id_agent_module'])); $agent_name = io_safe_output(modules_get_agentmodule_agent_alias($content['id_agent_module'])); + $agent_name_db = io_safe_output(modules_get_agentmodule_agent_name($content['id_agent_module'])); $return['title'] = $content['name']; $return['subtitle'] = $agent_name.' - '.$module_name; $return['description'] = $content['description']; $return['date'] = reporting_get_date_text($report, $content); $return['label'] = (isset($content['style']['label'])) ? $content['style']['label'] : ''; + $return['agent_name_db'] = $agent_name_db; $return['agent_name'] = $agent_name; $return['module_name'] = $module_name; @@ -4727,23 +4701,6 @@ function reporting_value($report, $content, $type, $pdf=false) case 'sum': $return['type'] = 'sumatory'; break; - - /* - case 'MTTR': - $return['type'] = 'MTTR'; - break; - - case 'MTBF': - $return['type'] = 'MTBF'; - break; - - case 'TTO': - $return['type'] = 'TTO'; - break; - - case 'TTRT': - $return['type'] = 'TTRT'; - break;*/ } if (empty($content['name'])) { @@ -4763,23 +4720,6 @@ function reporting_value($report, $content, $type, $pdf=false) case 'sum': $content['name'] = __('Summatory'); break; - - /* - case 'MTTR': - $content['name'] = __('MTTR'); - break; - - case 'MTBF': - $content['name'] = __('MTBF'); - break; - - case 'TTO': - $content['name'] = __('TTO'); - break; - - case 'TTRT': - $content['name'] = __('TTRT'); - break;*/ } } @@ -4796,6 +4736,9 @@ function reporting_value($report, $content, $type, $pdf=false) $agent_name = io_safe_output( modules_get_agentmodule_agent_alias($content['id_agent_module']) ); + $agent_name_db = io_safe_output( + modules_get_agentmodule_agent_name($content['id_agent_module']) + ); $unit = db_get_value( 'unit', 'tagente_modulo', @@ -4812,6 +4755,7 @@ function reporting_value($report, $content, $type, $pdf=false) $return['id_agent'] = $content['id_agent']; $return['id_agent_module'] = $content['id_agent_module']; + $return['agent_name_db'] = $agent_name_db; $return['agent_name'] = $agent_name; $return['module_name'] = $module_name; @@ -4952,51 +4896,6 @@ function reporting_value($report, $content, $type, $pdf=false) $formated_value = format_for_graph($value, $config['graph_precision']).' '.$unit; } break; - - /* - case 'MTTR': - $value = reporting_get_agentmodule_mttr( - $content['id_agent_module'], - $content['period'], - $report['datetime'] - ); - $formated_value = null; - break; - - case 'MTBF': - $value = reporting_get_agentmodule_mtbf( - $content['id_agent_module'], - $content['period'], - $report['datetime'] - ); - $formated_value = null; - break; - - case 'TTO': - $value = reporting_get_agentmodule_tto( - $content['id_agent_module'], - $content['period'], - $report['datetime'] - ); - if ($value == 0) { - $formated_value = null; - } else { - $formated_value = human_time_description_raw($value); - } - break; - - case 'TTRT': - $value = reporting_get_agentmodule_ttr( - $content['id_agent_module'], - $content['period'], - $report['datetime'] - ); - if ($value == 0) { - $formated_value = null; - } else { - $formated_value = human_time_description_raw($value); - } - break;*/ } $return['data'] = [ @@ -7755,6 +7654,7 @@ function reporting_simple_graph( $return['title'] = $content['name']; $return['subtitle'] = $agent_alias.' - '.$module_name; + $return['agent_name_db'] = agents_get_name($id_agent); $return['agent_name'] = $agent_alias; $return['module_name'] = $module_name; $return['description'] = $content['description']; diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index cf1fa60e70..5dc38d3b9d 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -288,23 +288,6 @@ function reporting_html_print_report($report, $mini=false, $report_info=1) reporting_html_sum_value($table, $item, $mini); break; - /* - case 'MTTR': - reporting_html_MTTR_value($table, $item, $mini, true, true); - break; - - case 'MTBF': - reporting_html_MTBF_value($table, $item, $mini, true, true); - break; - - case 'TTO': - reporting_html_TTO_value($table, $item, $mini, false, true); - break; - - case 'TTRT': - reporting_html_TTRT_value($table, $item, $mini, false, true); - break; - */ case 'agent_configuration': reporting_html_agent_configuration($table, $item); break; @@ -2729,31 +2712,6 @@ function reporting_html_agent_configuration( } -/* - function reporting_html_TTRT_value(&$table, $item, $mini, $only_value=false, $check_empty=false) - { - reporting_html_value($table, $item, $mini, $only_value, $check_empty); - } - - - function reporting_html_TTO_value(&$table, $item, $mini, $only_value=false, $check_empty=false) - { - reporting_html_value($table, $item, $mini, $only_value, $check_empty); - } - - - function reporting_html_MTBF_value(&$table, $item, $mini, $only_value=false, $check_empty=false) - { - reporting_html_value($table, $item, $mini, $only_value, $check_empty); - } - - - function reporting_html_MTTR_value(&$table, $item, $mini, $only_value=false, $check_empty=false) - { - reporting_html_value($table, $item, $mini, $only_value, $check_empty); - } -*/ - function reporting_html_sum_value(&$table, $item, $mini) { reporting_html_value($table, $item, $mini); diff --git a/pandora_console/include/functions_reports.php b/pandora_console/include/functions_reports.php index 319690946e..e20fdd01fa 100755 --- a/pandora_console/include/functions_reports.php +++ b/pandora_console/include/functions_reports.php @@ -679,24 +679,6 @@ function reports_get_report_types($template=false, $not_editor=false) 'name' => __('Module Histogram graph'), ]; - /* - $types['TTRT'] = [ - 'optgroup' => __('ITIL'), - 'name' => __('TTRT'), - ]; - $types['TTO'] = [ - 'optgroup' => __('ITIL'), - 'name' => __('TTO'), - ]; - $types['MTBF'] = [ - 'optgroup' => __('ITIL'), - 'name' => __('MTBF'), - ]; - $types['MTTR'] = [ - 'optgroup' => __('ITIL'), - 'name' => __('MTTR'), - ]; - */ $types['SLA'] = [ 'optgroup' => __('SLA'), 'name' => __('S.L.A.'), diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 493cbd1156..cc3b40ffbb 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -1411,7 +1411,7 @@ function ui_print_help_icon( [ 'class' => 'img_help', 'title' => __('Help'), - 'onclick' => "open_help ('".$url."')", + 'onclick' => "open_help ('".ui_get_full_url('index.php?sec=view&sec2=general/help_feedback&pure=1&url='.$url)."')", 'id' => $id, ], false, @@ -3015,6 +3015,10 @@ function ui_print_datatable(array $parameters) $parameters['default_pagination'] = $config['block_size']; } + if (!isset($parameters['paging'])) { + $parameters['paging'] = true; + } + $no_sortable_columns = []; if (isset($parameters['no_sortable_columns'])) { $no_sortable_columns = json_encode($parameters['no_sortable_columns']); @@ -3175,7 +3179,7 @@ function ui_print_datatable(array $parameters) $table = '
    '; - $table .= ''; + $table .= ''; if (isset($parameters['column_names']) && is_array($parameters['column_names']) @@ -3224,7 +3228,7 @@ function ui_print_datatable(array $parameters) }, processing: true, serverSide: true, - paging: true, + paging: '.$parameters['paging'].', pageLength: '.$parameters['default_pagination'].', searching: false, responsive: true, @@ -3324,10 +3328,18 @@ function ui_print_datatable(array $parameters) $("#'.$form_id.'_search_bt").click(function (){ dt_'.$table_id.'.draw().page(0) - }); - }); + });'; -'; + if (isset($parameters['caption']) === true + && empty($parameters['caption']) === false + ) { + $js .= '$("#'.$table_id.'").append("");'; + $js .= '$(".datatables_thead_tr").css("height", 0);'; + } + + $js .= '});'; + + $js .= ''; // Order. $err_msg = '
    '; @@ -3343,7 +3355,7 @@ function ui_print_datatable(array $parameters) $output = $include.$output; // Print datatable if needed. - if (!(isset($parameters['print']) && $parameters['print'] === false)) { + if (isset($parameters['print']) === false || $parameters['print'] === false) { echo $output; } diff --git a/pandora_console/include/functions_users.php b/pandora_console/include/functions_users.php index 97d97c7273..86e4475eea 100755 --- a/pandora_console/include/functions_users.php +++ b/pandora_console/include/functions_users.php @@ -1236,3 +1236,29 @@ function users_get_explode_tags(&$group) } } + + +/** + * Get mail admin. + * + * @return string Return mail admin. + */ +function get_mail_admin():string +{ + $mail = db_get_value('email', 'tusuario', 'is_admin', 1); + + return $mail; +} + + +/** + * Get name admin. + * + * @return string Return name admin. + */ +function get_name_admin():string +{ + $mail = db_get_value('fullname', 'tusuario', 'is_admin', 1); + + return $mail; +} diff --git a/pandora_console/include/javascript/functions_pandora_networkmap.js b/pandora_console/include/javascript/functions_pandora_networkmap.js index e5a0b87f7e..5d3477dca1 100644 --- a/pandora_console/include/javascript/functions_pandora_networkmap.js +++ b/pandora_console/include/javascript/functions_pandora_networkmap.js @@ -14,6 +14,7 @@ /* global holding_area_dimensions */ /* global networkmap_id */ /* global enterprise_installed */ +/* global networkmap_write */ /* global force */ /* global layer_graph_nodes */ /* global layer_graph_links */ @@ -2087,7 +2088,12 @@ function show_menu(item, data) { icon: "add_node", disabled: function() { if (enterprise_installed) { - return false; + // Check if user can write network maps. + if (networkmap_write) { + return false; + } else { + return true; + } } else { return true; } @@ -2099,6 +2105,14 @@ function show_menu(item, data) { items_list["center"] = { name: set_center_menu, icon: "center", + disabled: function() { + // Check if user can write network maps. + if (networkmap_write) { + return false; + } else { + return true; + } + }, callback: function(key, options) { set_center(networkmap_id); } @@ -2136,7 +2150,12 @@ function show_menu(item, data) { icon: "restart_map", disabled: function() { if (enterprise_installed) { - return false; + // Check if user can write network maps. + if (networkmap_write) { + return false; + } else { + return true; + } } else { return true; } diff --git a/pandora_console/include/javascript/pandora.js b/pandora_console/include/javascript/pandora.js index 33ab956a1f..c3ed855213 100644 --- a/pandora_console/include/javascript/pandora.js +++ b/pandora_console/include/javascript/pandora.js @@ -1,3 +1,6 @@ +/* global $ */ +/* exported load_modal */ + var ENTERPRISE_DIR = "enterprise"; /* Function to hide/unhide a specific Div id */ @@ -1872,8 +1875,6 @@ function logo_preview(icon_name, icon_path, incoming_options) { } // Advanced Form control. -/* global $ */ -/* exported load_modal */ function load_modal(settings) { var AJAX_RUNNING = 0; var data = new FormData(); @@ -1899,6 +1900,169 @@ function load_modal(settings) { buttons: [] }) .show(); + var required_buttons = []; + if (settings.modal.cancel != undefined) { + //The variable contains a function + // that is responsible for executing the method it receives from settings + // which confirms the closure of a modal + var cancelModal = function() { + settings.target.dialog("close"); + if (AJAX_RUNNING) return; + AJAX_RUNNING = 1; + var formdata = new FormData(); + + formdata.append("page", settings.oncancel.page); + formdata.append("method", settings.oncancel.method); + + $.ajax({ + method: "post", + url: settings.url, + processData: false, + contentType: false, + data: formdata, + success: function(data) { + if (typeof settings.oncancel.callback == "function") { + settings.oncancel.callback(data); + settings.target.dialog("close"); + } + AJAX_RUNNING = 0; + }, + error: function(data) { + // console.log(data); + AJAX_RUNNING = 0; + } + }); + }; + + required_buttons.push({ + class: + "ui-widget ui-state-default ui-corner-all ui-button-text-only sub upd submit-cancel", + text: settings.modal.cancel, + click: function() { + if (settings.oncancel != undefined) { + if (typeof settings.oncancel.confirm == "function") { + //receive function + settings.oncancel.confirm(cancelModal); + } else if (settings.oncancel != undefined) { + cancelModal(); + } + } else { + $(this).dialog("close"); + } + } + }); + } + + if (settings.modal.ok != undefined) { + required_buttons.push({ + class: + "ui-widget ui-state-default ui-corner-all ui-button-text-only sub ok submit-next", + text: settings.modal.ok, + click: function() { + if (AJAX_RUNNING) return; + + if (settings.onsubmit != undefined) { + if (settings.onsubmit.preaction != undefined) { + settings.onsubmit.preaction(); + } + AJAX_RUNNING = 1; + if (settings.onsubmit.dataType == undefined) { + settings.onsubmit.dataType = "html"; + } + + var formdata = new FormData(); + if (settings.extradata) { + settings.extradata.forEach(function(item) { + if (item.value != undefined) + formdata.append(item.name, item.value); + }); + } + formdata.append("page", settings.onsubmit.page); + formdata.append("method", settings.onsubmit.method); + + var flagError = false; + + $("#" + settings.form + " :input").each(function() { + if (this.checkValidity() === false) { + $(this).attr("title", this.validationMessage); + $(this).tooltip({ + tooltipClass: "uitooltip", + position: { + my: "right bottom", + at: "right top", + using: function(position, feedback) { + $(this).css(position); + $("
    ") + .addClass("arrow") + .addClass(feedback.vertical) + .addClass(feedback.horizontal) + .appendTo(this); + } + } + }); + $(this).tooltip("open"); + + var element = $(this); + setTimeout( + function(element) { + element.tooltip("destroy"); + element.removeAttr("title"); + }, + 3000, + element + ); + + flagError = true; + } + + if (this.type == "file") { + if ($(this).prop("files")[0]) { + formdata.append(this.name, $(this).prop("files")[0]); + } + } else { + if ($(this).attr("type") == "checkbox") { + if (this.checked) { + formdata.append(this.name, "on"); + } + } else { + formdata.append(this.name, $(this).val()); + } + } + }); + + if (flagError === false) { + $.ajax({ + method: "post", + url: settings.url, + processData: false, + contentType: false, + data: formdata, + dataType: settings.onsubmit.dataType, + success: function(data) { + if (settings.ajax_callback != undefined) { + if (settings.idMsgCallback != undefined) { + settings.ajax_callback(data, settings.idMsgCallback); + } else { + settings.ajax_callback(data); + } + } + AJAX_RUNNING = 0; + } + }); + } else { + AJAX_RUNNING = 0; + } + } else { + // No onsumbit configured. Directly close. + $(this).dialog("close"); + } + }, + error: function(data) { + // console.log(data); + AJAX_RUNNING = 0; + } + }); + } $.ajax({ method: "post", @@ -1921,69 +2085,131 @@ function load_modal(settings) { opacity: 0.5, background: "black" }, - buttons: [ - { - class: - "ui-widget ui-state-default ui-corner-all ui-button-text-only sub upd submit-cancel", - text: settings.modal.cancel, - click: function() { - $(this).dialog("close"); - if (typeof settings.cleanup == "function") { - settings.cleanup(); - } - } - }, - { - class: - "ui-widget ui-state-default ui-corner-all ui-button-text-only sub ok submit-next", - text: settings.modal.ok, - click: function() { - if (AJAX_RUNNING) return; - AJAX_RUNNING = 1; - if (settings.onsubmit.preaction != undefined) { - settings.onsubmit.preaction(); - } - var formdata = new FormData(); - if (settings.extradata) { - settings.extradata.forEach(function(item) { - if (item.value != undefined) - formdata.append(item.name, item.value); - }); - } - formdata.append("page", settings.onsubmit.page); - formdata.append("method", settings.onsubmit.method); - - $("#" + settings.form + " :input").each(function() { - if (this.type == "file") { - if ($(this).prop("files")[0]) { - formdata.append(this.name, $(this).prop("files")[0]); - } - } else { - formdata.append(this.name, $(this).val()); - } - }); - - $.ajax({ - method: "post", - url: settings.url, - processData: false, - contentType: false, - data: formdata, - success: function(data) { - if (settings.ajax_callback != undefined) { - settings.ajax_callback(data); - } - AJAX_RUNNING = 0; - } - }); - } - } - ], + buttons: required_buttons, closeOnEscape: false, open: function() { $(".ui-dialog-titlebar-close").hide(); } }); + }, + error: function(data) { + // console.log(data); + } + }); +} + +//Function that shows a dialog box to confirm closures of generic manners. The modal id is random +function confirmDialog(settings) { + var randomStr = + Math.random() + .toString(36) + .substring(2, 15) + + Math.random() + .toString(36) + .substring(2, 15); + + $("body").append( + '
    ' + settings.message + "
    " + ); + $("#confirm_" + randomStr); + $("#confirm_" + randomStr) + .dialog({ + title: settings.title, + close: false, + width: 350, + modal: true, + buttons: [ + { + text: "Cancel", + class: + "ui-widget ui-state-default ui-corner-all ui-button-text-only sub upd submit-cancel", + click: function() { + $(this).dialog("close"); + if (typeof settings.onDeny == "function") settings.onDeny(); + } + }, + { + text: "Ok", + class: + "ui-widget ui-state-default ui-corner-all ui-button-text-only sub ok submit-next", + click: function() { + $(this).dialog("close"); + if (typeof settings.onAccept == "function") settings.onAccept(); + } + } + ] + }) + .show(); +} + +/** + * Function to show modal with message Validation. + * + * @param {json} data Json example: + * $return = [ + * 'error' => 0 or 1, + * 'title' => [ + * Failed, + * Success, + * ], + * 'text' => [ + * Failed, + * Success, + * ], + *]; + * @param {string} idMsg ID div charge modal. + * + * @return {void} + */ +function generalShowMsg(data, idMsg) { + var title = data.title[data.error]; + var text = data.text[data.error]; + var failed = !data.error; + + $("#" + idMsg).empty(); + $("#" + idMsg).html(text); + $("#" + idMsg).dialog({ + width: 450, + position: { + my: "center", + at: "center", + of: window, + collision: "fit" + }, + title: title, + buttons: [ + { + class: + "ui-widget ui-state-default ui-corner-all ui-button-text-only sub ok submit-next", + text: "OK", + click: function(e) { + if (!failed) { + $(".ui-dialog-content").dialog("close"); + } else { + $(this).dialog("close"); + } + } + } + ] + }); +} + +/** + * Function for AJAX request. + * + * @param {string} id Id container append data. + * @param {json} settings Json with settings. + * + * @return {void} + */ +function ajaxRequest(id, settings) { + $.ajax({ + type: settings.type, + dataType: settings.html, + url: settings.url, + data: settings.data, + success: function(data) { + $("#" + id).append(data); } }); } diff --git a/pandora_console/include/lib/WSManager.php b/pandora_console/include/lib/WSManager.php new file mode 100644 index 0000000000..f1e4fc6524 --- /dev/null +++ b/pandora_console/include/lib/WSManager.php @@ -0,0 +1,440 @@ + + * Compatible with PHP >= 7.0 + * + * @category External library + * @package Pandora FMS + * @subpackage WebSocketServer + * @version 1.0.0 + * @license See below + * @filesource https://github.com/ghedipunk/PHP-Websockets + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of PHP WebSockets nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +// Begin. +namespace PandoraFMS\WebSockets; + +use \PandoraFMS\Websockets\WebSocketServer; +use \PandoraFMS\Websockets\WebSocketUser; +use \PandoraFMS\User; + + +require_once __DIR__.'/../functions.php'; + +/** + * Redirects ws communication between two endpoints. + */ +class WSManager extends WebSocketServer +{ + + /** + * Target host. + * + * @var string + */ + private $intHost = '127.0.0.1'; + + /** + * Target port + * + * @var integer + */ + private $intPort = 8080; + + /** + * Internal URL. + * + * @var string + */ + private $intUrl = '/ws'; + + /** + * 1MB... overkill for an echo server, but potentially plausible for other + * applications. + * + * @var integer + */ + public $maxBufferSize = 1048576; + + /** + * Interactive mode. + * + * @var boolean + */ + public $interative = true; + + /** + * Use a timeout of 100 milliseconds to search for messages.. + * + * @var integer + */ + public $timeout = 250; + + /** + * Handlers for connected step: + * 'protocol' => 'function'; + * + * @var array + */ + public $handlerConnected = []; + + /** + * Handlers for process step: + * 'protocol' => 'function'; + * + * @var array + */ + public $handlerProcess = []; + + /** + * Handlers for processRaw step: + * 'protocol' => 'function'; + * + * @var array + */ + public $handlerProcessRaw = []; + + /** + * Handlers for tick step: + * 'protocol' => 'function'; + * + * @var array + */ + public $handlerTick = []; + + /** + * Allow only one connection per user session. + * + * @var boolean + */ + public $socketPerSession = false; + + + /** + * Builder. + * + * @param string $listen_addr Target address (external). + * @param integer $listen_port Target port (external). + * @param array $connected Handlers for step. + * @param array $process Handlers for step. + * @param array $processRaw Handlers for step. + * @param array $tick Handlers for step. + * @param integer $bufferLength Max buffer size. + * @param boolean $debug Enable traces. + */ + public function __construct( + $listen_addr, + $listen_port, + $connected=[], + $process=[], + $processRaw=[], + $tick=[], + $bufferLength=1048576, + $debug=false + ) { + $this->maxBufferSize = $bufferLength; + $this->debug = $debug; + + // Configure handlers. + $this->handlerConnected = $connected; + $this->handlerProcess = $process; + $this->handlerProcessRaw = $processRaw; + $this->handlerTick = $tick; + + $this->userClass = '\\PandoraFMS\\Websockets\\WebSocketUser'; + parent::__construct($listen_addr, $listen_port, $bufferLength); + } + + + /** + * Call a target handler function. + * + * @param User $user User. + * @param array $handler Internal handler. + * @param array $arguments Arguments for handler function. + * + * @return mixed handler return or null. + */ + public function callHandler($user, $handler, $arguments) + { + if (isset($user->headers['sec-websocket-protocol'])) { + $proto = $user->headers['sec-websocket-protocol']; + if (isset($handler[$proto]) + && function_exists($handler[$proto]) + ) { + // Launch configured handler. + $this->stderr('Calling '.$handler[$proto]); + return call_user_func_array( + $handler[$proto], + $arguments + ); + } + } + + return null; + } + + + /** + * Read from user's socket. + * + * @param object $user Target user connection. + * + * @return string Buffer. + */ + public function readSocket($user) + { + $buffer; + + $numBytes = socket_recv( + $user->socket, + $buffer, + $this->maxBufferSize, + 0 + ); + if ($numBytes === false) { + // Failed. Disconnect. + $this->handleSocketError($user->socket); + return false; + } else if ($numBytes == 0) { + $this->disconnect($user->socket); + $this->stderr( + 'Client disconnected. TCP connection lost: '.$user->socket + ); + return false; + } + + $user->lastRawPacket = $buffer; + return $buffer; + } + + + /** + * Write to socket. + * + * @param object $user Target user connection. + * @param string $message Target message to be sent. + * + * @return void + */ + public function writeSocket($user, $message) + { + if (is_resource($user->socket)) { + if (!socket_write($user->socket, $message)) { + $this->disconnect($user->socket); + } + } else { + // Failed. Disconnect all. + $this->disconnect($user->socket); + $this->disconnect($user->redirect->socket); + } + + } + + + /** + * User already connected. + * + * @param object $user User. + * + * @return void + */ + public function connected($user) + { + global $config; + + $php_session_id = \str_replace( + 'PHPSESSID=', + '', + $user->headers['cookie'] + ); + + // If being redirected from proxy. + if (isset($user->headers['x-forwarded-for']) === true) { + $user->address = $user->headers['x-forwarded-for']; + } + + $user->account = new User(['phpsessionid' => $php_session_id]); + $_SERVER['REMOTE_ADDR'] = $user->address; + + // Ensure user is allowed to connect. + if (\check_login(false) === false) { + $this->disconnect($user->socket); + \db_pandora_audit( + 'WebSockets engine', + 'Trying to access websockets engine without a valid session', + 'N/A' + ); + return; + } + + // User exists, and session is valid. + \db_pandora_audit( + 'WebSockets engine', + 'WebSocket connection started', + $user->account->idUser + ); + $this->stderr('ONLINE '.$user->address.'('.$user->account->idUser.')'); + + if ($this->socketPerSession === true) { + // Disconnect previous sessions. + $this->cleanupSocketByCookie($user); + } + + // Launch registered handler. + $this->callHandler( + $user, + $this->handlerConnected, + [ + $this, + $user, + ] + ); + } + + + /** + * Protocol. + * + * @param string $protocol Protocol. + * + * @return string + */ + public function processProtocol($protocol): string + { + return 'Sec-Websocket-Protocol: '.$protocol."\r\n"; + } + + + /** + * Process programattic function + * + * @return void + */ + public function tick() + { + foreach ($this->users as $user) { + // Launch registered handler. + $this->callHandler( + $user, + $this->handlerTick, + [ + $this, + $user, + ] + ); + } + + } + + + /** + * Process undecoded user message. + * + * @param object $user User. + * @param string $buffer Message. + * + * @return boolean + */ + public function processRaw($user, $buffer) + { + // Launch registered handler. + return $this->callHandler( + $user, + $this->handlerProcessRaw, + [ + $this, + $user, + $buffer, + ] + ); + } + + + /** + * Process user message. Implement. + * + * @param object $user User. + * @param string $message Message. + * @param boolean $str_message String message or not. + * + * @return void + */ + public function process($user, $message, $str_message) + { + if ($str_message === true) { + $remmitent = $user->address.'('.$user->account->idUser.')'; + $this->stderr($remmitent.': '.$message); + } + + // Launch registered handler. + $this->callHandler( + $user, + $this->handlerProcess, + [ + $this, + $user, + $message, + $str_message, + ] + ); + } + + + /** + * Also close internal socket. + * + * @param object $user User. + * + * @return void + */ + public function closed($user) + { + if ($user->account) { + $_SERVER['REMOTE_ADDR'] = $user->address; + \db_pandora_audit( + 'WebSockets engine', + 'WebSocket connection finished', + $user->account->idUser + ); + + $this->stderr('OFFLINE '.$user->address.'('.$user->account->idUser.')'); + } + + // Ensure both sockets are disconnected. + $this->disconnect($user->socket); + if ($user->redirect) { + $this->disconnect($user->redirect->socket); + } + } + + +} diff --git a/pandora_console/include/lib/WebSocketServer.php b/pandora_console/include/lib/WebSocketServer.php new file mode 100644 index 0000000000..2d9eb1d9fd --- /dev/null +++ b/pandora_console/include/lib/WebSocketServer.php @@ -0,0 +1,1533 @@ + + * Compatible with PHP >= 7.0 + * + * @category External library + * @package Pandora FMS + * @subpackage WebSocketServer + * @version 1.0.0 + * @license See below + * @filesource https://github.com/ghedipunk/PHP-Websockets + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of PHP WebSockets nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +// Begin. +namespace PandoraFMS\Websockets; + +/** + * Abstract class to be implemented. + */ +abstract class WebSocketServer +{ + + /** + * Bae class to be created. + * + * @var string + */ + public $userClass = 'WebSocketUser'; + + /** + * Redefine this if you want a custom user class. The custom user class + * should inherit from WebSocketUser. + * + * @var integer + */ + public $maxBufferSize; + + /** + * Max. concurrent connections. + * + * @var integer + */ + public $maxConnections = 20; + + /** + * Undocumented variable + * + * @var [type] + */ + public $master; + + /** + * Incoming sockets. + * + * @var array + */ + public $sockets = []; + + /** + * Outgoing sockets. + * + * @var array + */ + public $remoteSockets = []; + + /** + * Client list. + * + * @var array + */ + public $users = []; + + /** + * Servers list. + * + * @var array + */ + public $remoteUsers = []; + + /** + * Undocumented variable + * + * @var array + */ + public $heldMessages = []; + + /** + * Show output. + * + * @var boolean + */ + public $interactive = true; + + /** + * Debug. + * + * @var boolean + */ + public $debug = false; + + /** + * Undocumented variable + * + * @var array + */ + public $headerOriginRequired = false; + + /** + * Undocumented variable + * + * @var array + */ + public $headerSecWebSocketProtocolRequired = false; + + /** + * Undocumented variable + * + * @var array + */ + public $headerSecWebSocketExtensionsRequired = false; + + /** + * Stored raw headers for redirection. + * + * @var array + */ + public $rawHeaders = []; + + /** + * Use a timeout of 1 second to search for messages.. + * + * @var integer + */ + public $timeout = 1; + + /** + * Do not call tick every iteration, use a minimum time lapse. + * Measure: seconds. + * + * @var integer + */ + public $tickInterval = 1; + + /** + * Last tick call. (unix timestamp). + * + * @var integer + */ + public $lastTickTimestamp = 0; + + + /** + * Builder. + * + * @param string $addr Address where websocketserver will listen. + * @param integer $port Port where listen. + * @param integer $bufferLength Max buffer length. + * @param integer $maxConnections Max concurrent connections. + */ + public function __construct( + $addr, + int $port, + int $bufferLength=2048, + int $maxConnections=20 + ) { + if (isset($this->maxBufferSize) + && $this->maxBufferSize < $bufferLength + ) { + $this->maxBufferSize = $bufferLength; + } + + if (is_numeric($maxConnections) && $maxConnections > 0) { + $this->maxConnections = $maxConnections; + } + + $this->master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + $this->master || die('Failed: socket_create()'); + + $__tmp = socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1); + $__tmp || die('Failed: socket_option()'); + + $__tmp = socket_bind($this->master, $addr, $port); + $__tmp || die('Failed: socket_bind()'); + + $__tmp = socket_listen($this->master, $this->maxConnections); + $__tmp || die('Failed: socket_listen()'); + + $this->sockets['m'] = $this->master; + $this->stderr('Listening on: '.$addr.':'.$port); + $this->stderr('Master socket: '.$this->master."\n"); + + } + + + /** + * Process user message. Implement. + * + * @param object $user User. + * @param string $message Message. + * @param boolean $str_message String message or not. + * + * @return void + */ + abstract public function process($user, $message, $str_message); + + + /** + * Process undecoded user message. + * + * @param object $user User. + * @param string $buffer Message. + * + * @return void + */ + public function processRaw($user, $buffer) + { + + } + + + /** + * Called immediately when the data is recieved. + * + * @param object $user User. + * + * @return void + */ + abstract public function connected($user); + + + /** + * Called after the handshake response is sent to the client. + * + * @param object $user User. + * + * @return void + */ + abstract public function closed($user); + + + /** + * Called after the connection is closed. + * Override to handle a connecting user, after the instance of the User + * is created, but before the handshake has completed. + * + * @param object $user User. + * + * @return void + */ + public function connecting($user) + { + // Optional implementation. + } + + + /** + * Send a message to target user. + * + * @param object $user User. + * @param string $message Message. + * + * @return void + */ + public function send($user, $message) + { + if ($user->handshake) { + $message = $this->frame($message, $user); + $result = socket_write($user->socket, $message, strlen($message)); + } else { + // User has not yet performed their handshake. + // Store for sending later. + $holdingMessage = [ + 'user' => $user, + 'message' => $message, + ]; + $this->heldMessages[] = $holdingMessage; + } + } + + + /** + * Override this for any process that should happen periodically. + * Will happen at least once per second, but possibly more often. + * + * @return void + */ + public function tick() + { + // Optional implementation. + } + + + /** + * Internal backend for tick. + * + * @return void + */ + public function pTick() + { + // Core maintenance processes, such as retrying failed messages. + foreach ($this->heldMessages as $key => $hm) { + $found = false; + foreach ($this->users as $currentUser) { + if ($hm['user']->socket == $currentUser->socket) { + $found = true; + if ($currentUser->handshake) { + unset($this->heldMessages[$key]); + $this->send($currentUser, $hm['message']); + } + } + } + + if (!$found) { + // If they're no longer in the list of connected users, + // drop the message. + unset($this->heldMessages[$key]); + } + } + } + + + /** + * Manage behaviour on socket error. + * + * @param socket $socket Target socket. + * + * @return void + */ + public function handleSocketError($socket) + { + $sockErrNo = socket_last_error($socket); + switch ($sockErrNo) { + case 102: + // ENETRESET + // Network dropped connection because of reset. + case 103: + // ECONNABORTED + // Software caused connection abort. + case 104: + // ECONNRESET + // Connection reset by peer. + case 108: + // ESHUTDOWN + // Cannot send after transport endpoint shutdown + // Probably more of an error on our side, + // if we're trying to write after the socket is + // closed. Probably not a critical error, + // though. + case 110: + // ETIMEDOUT + // Connection timed out. + case 111: + // ECONNREFUSED + // Connection refused + // We shouldn't see this one, since we're + // listening... Still not a critical error. + case 112: + // EHOSTDOWN + // Host is down. + // Again, we shouldn't see this, and again, + // not critical because it's just one connection + // and we still want to listen to/for others. + case 113: + // EHOSTUNREACH + // No route to host. + case 121: + // EREMOTEIO + // Rempte I/O error + // Their hard drive just blew up. + case 125: + // ECANCELED + // Operation canceled. + $this->stderr( + 'Unusual disconnect on socket '.$socket + ); + // Disconnect before clearing error, in case + // someone with their own implementation wants + // to check for error conditions on the socket. + $this->disconnect($socket, true, $sockErrNo); + break; + + default: + $this->stderr( + 'Socket error: '.socket_strerror($sockErrNo) + ); + break; + } + } + + + /** + * Main processing loop + * + * @return void + */ + public function run() + { + while (true) { + if (empty($this->sockets) === true) { + $this->sockets['m'] = $this->master; + } + + $read = $this->sockets; + $except = null; + $write = null; + $this->pTick(); + + if ((time() - $this->lastTickTimestamp) > $this->tickInterval) { + $this->lastTickTimestamp = time(); + $this->tick(); + } + + socket_select($read, $write, $except, 0, $this->timeout); + foreach ($read as $socket) { + if ($socket == $this->master) { + // External to master connection. New client. + $client = socket_accept($socket); + if ($client < 0) { + $this->stderr('Failed: socket_accept()'); + continue; + } else { + $this->connect($client); + $this->stderr('Client connected. '.$client); + } + } else { + if (!$socket) { + $this->disconnect($socket); + continue; + } + + // Updates on 'read' socket. + $numBytes = socket_recv( + $socket, + $buffer, + $this->maxBufferSize, + 0 + ); + if ($numBytes === false) { + $this->handleSocketError($socket); + } else if ($numBytes == 0) { + $this->disconnect($socket); + $this->stderr( + 'Client disconnected. TCP connection lost: '.$socket + ); + } else { + $user = $this->getUserBySocket($socket); + if (!$user->handshake) { + $tmp = str_replace("\r", '', $buffer); + if (strpos($tmp, "\n\n") === false) { + continue; + // If the client has not finished sending the + // header, then wait before sending our upgrade + // response. + } + + $this->doHandshake($user, $buffer); + } else { + if ($this->processRaw($user, $buffer)) { + // Split packet into frame and send it to deframe. + $this->splitPacket( + $numBytes, + $buffer, + $user + ); + } + } + } + } + } + + // Remote updates. + $remotes = $this->remoteSockets; + if (count($remotes) > 0) { + socket_select($remotes, $write, $except, 0, $this->timeout); + foreach ($remotes as $socket) { + // Remote updates - internal. We're client of this sockets. + if (!$socket) { + continue; + } + + $numBytes = socket_recv( + $socket, + $buffer, + $this->maxBufferSize, + 0 + ); + if ($numBytes === false) { + $this->handleSocketError($socket); + } else if ($numBytes == 0) { + $this->disconnect($socket); + $this->stderr( + 'Client disconnected. TCP connection lost: '.$socket + ); + } else { + $user = $this->getUserBySocket($socket); + if (!$user) { + $this->disconnect($socket); + $this->stderr( + 'User was not connected: '.$socket + ); + } else if (!$this->processRaw($user, $buffer)) { + // Split packet into frame and send it to deframe. + $this->splitPacket( + $numBytes, + $buffer, + $user + ); + } + } + } + } + } + } + + + /** + * Register user (and its socket) into master. + * + * @param Socket $socket Socket. + * + * @return void + */ + public function connect($socket) + { + $user = new $this->userClass( + uniqid('u'), + $socket + ); + $this->users[$user->id] = $user; + $this->sockets[$user->id] = $socket; + $this->connecting($user); + } + + + /** + * Disconnect socket from master. + * + * @param Socket $socket Socket. + * @param boolean $triggerClosed Also close. + * @param integer $sockErrNo Clear error. + * + * @return void + */ + public function disconnect( + $socket, + bool $triggerClosed=true, + $sockErrNo=null + ) { + $user = $this->getUserBySocket($socket); + if ($user !== null) { + if (array_key_exists($user->id, $this->users)) { + unset($this->users[$user->id]); + } + + if (array_key_exists($user->id, $this->remoteUsers)) { + unset($this->remoteUsers[$user->id]); + } + + if (array_key_exists($user->id, $this->sockets)) { + unset($this->sockets[$user->id]); + } + + if (array_key_exists($user->id, $this->remoteSockets)) { + unset($this->remoteSockets[$user->id]); + } + + if ($sockErrNo !== null) { + socket_clear_error($socket); + } + + if ($triggerClosed) { + $this->closed($user); + $this->stderr( + 'Client disconnected. '.$user->socket + ); + socket_close($user->socket); + } else { + $message = $this->frame('', $user, 'close'); + socket_write( + $user->socket, + $message, + strlen($message) + ); + } + } + } + + + /** + * Perform a handshake. + * + * @param object $user User. + * @param string $buffer Buffer. + * + * @return void + */ + public function doHandshake($user, $buffer) + { + $magicGUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; + $headers = []; + $lines = explode("\n", $buffer); + foreach ($lines as $line) { + if (strpos($line, ':') !== false) { + $header = explode(':', $line, 2); + $headers[strtolower(trim($header[0]))] = trim($header[1]); + $this->rawHeaders[trim($header[0])] = trim($header[1]); + } else if (stripos($line, 'get ') !== false) { + preg_match('/GET (.*) HTTP/i', $buffer, $reqResource); + $headers['get'] = trim($reqResource[1]); + } + } + + if (isset($headers['get'])) { + $user->requestedResource = $headers['get']; + } else { + // TODO: fail the connection. + $handshakeResponse = "HTTP/1.1 405 Method Not Allowed\r\n\r\n"; + } + + if (!isset($headers['host']) + || !$this->checkHost($headers['host']) + ) { + $handshakeResponse = 'HTTP/1.1 400 Bad Request'; + } + + if (!isset($headers['upgrade']) + || strtolower($headers['upgrade']) != 'websocket' + ) { + $handshakeResponse = 'HTTP/1.1 400 Bad Request'; + } + + if (!isset($headers['connection']) + || strpos(strtolower($headers['connection']), 'upgrade') === false + ) { + $handshakeResponse = 'HTTP/1.1 400 Bad Request'; + } + + if (!isset($headers['sec-websocket-key'])) { + $handshakeResponse = 'HTTP/1.1 400 Bad Request'; + } + + if (!isset($headers['sec-websocket-version']) + || strtolower($headers['sec-websocket-version']) != 13 + ) { + $handshakeResponse = "HTTP/1.1 426 Upgrade Required\r\nSec-WebSocketVersion: 13"; + } + + if (($this->headerOriginRequired + && !isset($headers['origin']) ) + || ($this->headerOriginRequired + && !$this->checkOrigin($headers['origin'])) + ) { + $handshakeResponse = 'HTTP/1.1 403 Forbidden'; + } + + if (($this->headerSecWebSocketProtocolRequired + && !isset($headers['sec-websocket-protocol'])) + || ($this->headerSecWebSocketProtocolRequired + && !$this->checkWebsocProtocol( + $headers['sec-websocket-protocol'] + )) + ) { + $handshakeResponse = 'HTTP/1.1 400 Bad Request'; + } + + if (($this->headerSecWebSocketExtensionsRequired + && !isset($headers['sec-websocket-extensions'])) + || ($this->headerSecWebSocketExtensionsRequired + && !$this->checkWebsocExtensions( + $headers['sec-websocket-extensions'] + )) + ) { + $handshakeResponse = 'HTTP/1.1 400 Bad Request'; + } + + // Done verifying the _required_ headers and optionally required headers. + if (isset($handshakeResponse)) { + socket_write( + $user->socket, + $handshakeResponse, + strlen($handshakeResponse) + ); + $this->disconnect($user->socket); + return; + } + + $user->headers = $headers; + $user->handshake = $buffer; + + $webSocketKeyHash = sha1($headers['sec-websocket-key'].$magicGUID); + + $rawToken = ''; + for ($i = 0; $i < 20; $i++) { + $rawToken .= chr(hexdec(substr($webSocketKeyHash, ($i * 2), 2))); + } + + $handshakeToken = base64_encode($rawToken)."\r\n"; + + $subProtocol = ''; + if (isset($headers['sec-websocket-protocol'])) { + $subProtocol = $this->processProtocol( + $headers['sec-websocket-protocol'] + ); + } + + $extensions = ''; + if (isset($headers['sec-websocket-extensions'])) { + $extensions = $this->processExtensions( + $headers['sec-websocket-extensions'] + ); + } + + $handshakeResponse = "HTTP/1.1 101 Switching Protocols\r\n"; + $handshakeResponse .= "Upgrade: websocket\r\nConnection: Upgrade\r\n"; + $handshakeResponse .= 'Sec-WebSocket-Accept: '; + $handshakeResponse .= $handshakeToken.$subProtocol.$extensions."\r\n"; + socket_write( + $user->socket, + $handshakeResponse, + strlen($handshakeResponse) + ); + $this->connected($user); + } + + + /** + * Check target host. + * + * @param string $hostName Target hostname to be checked. + * + * @return boolean Ok or not. + */ + public function checkHost($hostName): bool + { + // Override and return false if host is not one that you would expect. + // Ex: You only want to accept hosts from the my-domain.com domain, + // but you receive a host from malicious-site.com instead. + return true; + } + + + /** + * Check origin. + * + * @param string $origin Origin of connections. + * + * @return boolean Allowed or not. + */ + public function checkOrigin($origin): bool + { + // Override and return false if origin is not one that you would expect. + return true; + } + + + /** + * Check websocket protocol. + * + * @param string $protocol Protocol received. + * + * @return boolean Expected or not. + */ + public function checkWebsocProtocol($protocol): bool + { + // Override and return false if a protocol is not found that you + // would expect. + return true; + } + + + /** + * Check websocket extension. + * + * @param string $extensions Extension. + * + * @return boolean Allowed or not. + */ + public function checkWebsocExtensions($extensions): bool + { + // Override and return false if an extension is not found that you + // would expect. + return true; + } + + + /** + * Return either + * * "Sec-WebSocket-Protocol: SelectedProtocolFromClientList\r\n" + * or return an empty string. + * + * The carriage return/newline combo must appear at the end of a non-empty + * string, and must not appear at the beginning of the string nor in an + * otherwise empty string, or it will be considered part of the response + * body, which will trigger an error in the client as it will not be + * formatted correctly. + * + * @param string $protocol Selected protocol. + * + * @return string + */ + public function processProtocol($protocol): string + { + return ''; + } + + + /** + * Return either + * * "Sec-WebSocket-Extensions: SelectedExtensions\r\n" + * or return an empty string. + * + * @param string $extensions Selected extensions. + * + * @return string + */ + public function processExtensions($extensions): string + { + return ''; + } + + + /** + * Return user associated to target socket. + * + * @param Socket $socket Socket. + * + * @return object + */ + public function getUserBySocket($socket) + { + foreach ($this->users as $user) { + if ($user->socket == $socket) { + return $user; + } + } + + foreach ($this->remoteUsers as $user) { + if ($user->socket == $socket) { + return $user; + } + } + + return null; + } + + + /** + * Disconnects all users matching target cookie but given one. + * + * @param object $user Latest user. + * + * @return void + */ + public function cleanupSocketByCookie($user) + { + $cookie = $user->headers['cookie']; + foreach ($this->users as $u) { + if ($u->id != $user->id + && $u->headers['cookie'] == $cookie + ) { + $this->disconnect($u->socket); + } + } + + } + + + /** + * Return INT user associated to target socket. + * + * @param Socket $socket Socket. + * + * @return object + */ + public function getIntUserBySocket($socket) + { + foreach ($this->users as $user) { + if ($user->intSocket == $socket) { + return [ + 'ext' => $user, + 'int' => $user->intUser, + ]; + } + } + + return null; + } + + + /** + * Dump to stdout. + * + * @param string $message Message. + * + * @return void + */ + public function stdout($message=null) + { + if ((bool) $this->interactive === true) { + echo $message."\n"; + } + } + + + /** + * Dump to stderr. + * + * @param string $message Message. + * + * @return void + */ + public function stderr($message=null) + { + if ($this->interactive === true + && $this->debug === true + ) { + echo date('D M j G:i:s').' - '.$message."\n"; + } + } + + + /** + * Process a frame message. + * + * @param string $message Message. + * @param object $user User. + * @param string $messageType MessageType. + * @param boolean $messageContinues MessageContinues. + * + * @return string Framed message. + */ + public function frame( + $message, + $user, + $messageType='text', + bool $messageContinues=false + ) { + switch ($messageType) { + case 'continuous': + $b1 = 0; + break; + + case 'text': + $b1 = ($user->sendingContinuous) ? 0 : 1; + break; + + case 'binary': + $b1 = ($user->sendingContinuous) ? 0 : 2; + break; + + case 'close': + $b1 = 8; + break; + + case 'ping': + $b1 = 9; + break; + + case 'pong': + $b1 = 10; + break; + + default: + // Ignore. + break; + } + + if ($messageContinues) { + $user->sendingContinuous = true; + } else { + $b1 += 128; + $user->sendingContinuous = false; + } + + $length = strlen($message); + $lengthField = ''; + if ($length < 126) { + $b2 = $length; + } else if ($length < 65536) { + $b2 = 126; + $hexLength = dechex($length); + // $this->stdout("Hex Length: $hexLength"); + if ((strlen($hexLength) % 2) == 1) { + $hexLength = '0'.$hexLength; + } + + $n = (strlen($hexLength) - 2); + + for ($i = $n; $i >= 0; $i = ($i - 2)) { + $lengthField = chr( + hexdec(substr($hexLength, $i, 2)) + ).$lengthField; + } + + $len = strlen($lengthField); + while ($len < 2) { + $lengthField = chr(0).$lengthField; + $len = strlen($lengthField); + } + } else { + $b2 = 127; + $hexLength = dechex($length); + if ((strlen($hexLength) % 2) == 1) { + $hexLength = '0'.$hexLength; + } + + $n = (strlen($hexLength) - 2); + + for ($i = $n; $i >= 0; $i = ($i - 2)) { + $lengthField = chr( + hexdec(substr($hexLength, $i, 2)) + ).$lengthField; + } + + $len = strlen($lengthField); + while ($length < 8) { + $lengthField = chr(0).$lengthField; + $len = strlen($lengthField); + } + } + + $out = chr($b1).chr($b2).$lengthField.$message; + return $out; + } + + + /** + * Check packet if he have more than one frame and process each frame + * individually. + * + * @param integer $length Length. + * @param string $packet Packet. + * @param object $user User. + * + * @return void + */ + public function splitPacket( + int $length, + $packet, + $user + ) { + // Add PartialPacket and calculate the new $length. + if ($user->handlingPartialPacket) { + $packet = $user->partialBuffer.$packet; + $user->handlingPartialPacket = false; + $length = strlen($packet); + } + + $user->lastRawPacket = $packet; + $fullpacket = $packet; + $frame_pos = 0; + $frame_id = 1; + + while ($frame_pos < $length) { + $headers = $this->extractHeaders($packet); + $headers_size = $this->calcOffset($headers); + $framesize = ($headers['length'] + $headers_size); + + // Split frame from packet and process it. + $frame = substr($fullpacket, $frame_pos, $framesize); + + $message = $this->deframe($frame, $user, $headers); + + if ($message !== false) { + if ($user->hasSentClose) { + $this->disconnect($user->socket); + } else { + $str_message = false; + if ((preg_match('//u', $message)) + || ($headers['opcode'] == 2) + ) { + $str_message = true; + } else { + $this->stderr("not UTF-8\n"); + $str_message = false; + } + + $this->process($user, $message, $str_message); + } + } + + // Get the new position also modify packet data. + $frame_pos += $framesize; + $packet = substr($fullpacket, $frame_pos); + $frame_id++; + } + } + + + /** + * Calculate offset. + * + * @param array $headers Headers received. + * + * @return integer Calculated offset. + */ + public function calcOffset(array $headers): int + { + $offset = 2; + if ($headers['hasmask']) { + $offset += 4; + } + + if ($headers['length'] > 65535) { + $offset += 8; + } else if ($headers['length'] > 125) { + $offset += 2; + } + + return $offset; + } + + + /** + * Parse frame. + * + * @param string $message Message received. + * @param object $user Origin. + * + * @return boolean Process ok or not. + */ + public function deframe( + $message, + &$user + ) { + /* + * Debug purposes. + * echo $this->strtohex($message); + */ + + $headers = $this->extractHeaders($message); + $pongReply = false; + $willClose = false; + + switch ($headers['opcode']) { + case 0: + case 1: + case 2: + case 10: + $willClose = false; + break; + + case 8: + // TODO: close the connection. + $user->hasSentClose = true; + return ''; + + case 9: + $pongReply = true; + break; + + default: + /* + * TODO: fail connection. + * $this->disconnect($user->socket); + */ + + $willClose = true; + break; + } + + /* + * Deal by splitPacket() as now deframe() do only one frame at a time. + * if ($user->handlingPartialPacket) { + * $message = $user->partialBuffer . $message; + * $user->handlingPartialPacket = false; + * return $this->deframe($message, $user); + * } + */ + + if ($this->checkRSVBits($headers, $user)) { + return false; + } + + if ($willClose) { + // TODO: fail the connection. + return false; + } + + $payload = $user->partialMessage.$this->extractPayload( + $message, + $headers + ); + + if ($pongReply) { + $reply = $this->frame($payload, $user, 'pong'); + socket_write($user->socket, $reply, strlen($reply)); + return false; + } + + if ($headers['length'] > strlen($this->applyMask($headers, $payload))) { + $user->handlingPartialPacket = true; + $user->partialBuffer = $message; + return false; + } + + $payload = $this->applyMask($headers, $payload); + + if ($headers['fin']) { + $user->partialMessage = ''; + return $payload; + } + + $user->partialMessage = $payload; + + return false; + } + + + /** + * Extract headers from message. + * + * @param string $message Message. + * + * @return array Headers. + */ + public function extractHeaders($message): array + { + $header = [ + 'fin' => ($message[0] & chr(128)), + 'rsv1' => ($message[0] & chr(64)), + 'rsv2' => ($message[0] & chr(32)), + 'rsv3' => ($message[0] & chr(16)), + 'opcode' => (ord($message[0]) & 15), + 'hasmask' => ($message[1] & chr(128)), + 'length' => 0, + 'mask' => '', + ]; + + $header['length'] = ord($message[1]); + if (ord($message[1]) >= 128) { + $header['length'] = (ord($message[1]) - 128); + } + + if ($header['length'] == 126) { + if ($header['hasmask']) { + $header['mask'] = $message[4].$message[5]; + $header['mask'] .= $message[6].$message[7]; + } + + $header['length'] = (ord($message[2]) * 256 + ord($message[3])); + } else if ($header['length'] == 127) { + if ($header['hasmask']) { + $header['mask'] = $message[10].$message[11]; + $header['mask'] .= $message[12].$message[13]; + } + + $header['length'] = (ord($message[2]) * 65536 * 65536 * 65536 * 256); + $header['length'] += (ord($message[3]) * 65536 * 65536 * 65536); + $header['length'] += (ord($message[4]) * 65536 * 65536 * 256); + $header['length'] += (ord($message[5]) * 65536 * 65536); + $header['length'] += (ord($message[6]) * 65536 * 256); + $header['length'] += (ord($message[7]) * 65536); + $header['length'] += (ord($message[8]) * 256); + $header['length'] += ord($message[9]); + } else if ($header['hasmask']) { + if (!isset($message[2])) { + $message[2] = 0x00; + } + + if (!isset($message[3])) { + $message[3] = 0x00; + } + + if (!isset($message[4])) { + $message[4] = 0x00; + } + + if (!isset($message[5])) { + $message[5] = 0x00; + } + + $header['mask'] = $message[2].$message[3].$message[4].$message[5]; + } + + /* + * Debug purposes. + * echo $this->strtohex($message); + * + * $this->printHeaders($header); + */ + + return $header; + } + + + /** + * Get payload from message using headers. + * + * @param string $message Message. + * @param array $headers Headers. + * + * @return string + */ + public function extractPayload( + $message, + array $headers + ) { + $offset = 2; + if ($headers['hasmask']) { + $offset += 4; + } + + if ($headers['length'] > 65535) { + $offset += 8; + } else if ($headers['length'] > 125) { + $offset += 2; + } + + return substr($message, $offset); + } + + + /** + * Apply mask. + * + * @param array $headers Headers. + * @param string $payload Payload. + * + * @return string Xor. + */ + public function applyMask( + array $headers, + $payload + ) { + $effectiveMask = ''; + if ($headers['hasmask']) { + $mask = $headers['mask']; + } else { + return $payload; + } + + $len_mask = strlen($effectiveMask); + $len_payload = strlen($payload); + + // Enlarge. + while ($len_mask < $len_payload) { + $effectiveMask .= $mask; + $len_mask = strlen($effectiveMask); + $len_payload = strlen($payload); + } + + // Decrease. + while ($len_mask > $len_payload) { + $effectiveMask = substr($effectiveMask, 0, -1); + $len_mask = strlen($effectiveMask); + $len_payload = strlen($payload); + } + + return ($effectiveMask ^ $payload); + } + + + /** + * Check RSV bits. + * Override this method if you are using an extension where RSV bits are + * being used. + * + * @param array $headers Headers. + * @param object $user User. + * + * @return boolean OK or not. + */ + public function checkRSVBits( + array $headers, + $user + ): bool { + $len = ord($headers['rsv1']); + $len += ord($headers['rsv2']); + $len += ord($headers['rsv3']); + if ($len > 0) { + /* + * TODO: fail connection. + * $this->disconnect($user->socket); + */ + + return true; + } + + return false; + } + + + /** + * Transforms string into HEX string. + * + * @param string $str String. + * + * @return string HEX string. + */ + public function strtohex( + $str='' + ): string { + $strout = ''; + $len = strlen($str); + for ($i = 0; $i < $len; $i++) { + if (ord($str[$i]) < 16) { + $strout .= '0'.dechex(ord($str[$i])); + } else { + $strout .= dechex(ord($str[$i])); + } + + $strout .= ' '; + if (($i % 32) == 7) { + $strout .= ': '; + } + + if (($i % 32) == 15) { + $strout .= ': '; + } + + if (($i % 32) == 23) { + $strout .= ': '; + } + + if (($i % 32) == 31) { + $strout .= "\n"; + } + } + + return $strout."\n"; + } + + + /** + * Debug purposes. Print headers. + * + * @param array $headers Headers. + * + * @return void + */ + public function printHeaders($headers) + { + echo "Array\n(\n"; + foreach ($headers as $key => $value) { + if ($key == 'length' || $key == 'opcode') { + echo "\t[".$key.'] => '.$value."\n\n"; + } else { + echo "\t[".$key.'] => '.$this->strtohex($value)."\n"; + } + } + + echo ")\n"; + } + + + /** + * View any string as a hexdump. + * + * @param string $data The string to be dumped. + * + * @return string + */ + public function dump($data) + { + // Init. + $hexi = ''; + $ascii = ''; + $dump = "Hex Message:\n"; + $offset = 0; + $len = strlen($data); + + // Iterate string. + for ($i = 0, $j = 0; $i < $len; $i++) { + // Convert to hexidecimal. + $hexi .= sprintf('%02x ', ord($data[$i])); + // Replace non-viewable bytes with '.'. + if (ord($data[$i]) >= 32 && ord($data[$i]) <= 255) { + $ascii .= $data[$i]; + } else { + $ascii .= '.'; + } + + // Add extra column spacing. + if ($j === 7 && $i !== ($len - 1)) { + $hexi .= ' '; + $ascii .= ' '; + } + + // Add row. + if (++$j === 16 || $i === ($len - 1)) { + // Join the hexi / ascii output. + $dump .= sprintf('%04x %-49s %s', $offset, $hexi, $ascii); + // Reset vars. + $hexi = ''; + $ascii = ''; + $offset += 16; + $j = 0; + // Add newline. + if ($i !== ($len - 1)) { + $dump .= "\n"; + } + } + } + + // Finish dump. + $dump .= "\n"; + return $dump; + } + + +} diff --git a/pandora_console/include/lib/WebSocketUser.php b/pandora_console/include/lib/WebSocketUser.php new file mode 100644 index 0000000000..bcbe30cc17 --- /dev/null +++ b/pandora_console/include/lib/WebSocketUser.php @@ -0,0 +1,161 @@ + + * Compatible with PHP >= 7.0 + * + * @category External library + * @package Pandora FMS + * @subpackage WebSocketUser + * @version 1.0.0 + * @license See below + * @filesource https://github.com/ghedipunk/PHP-Websockets + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of PHP WebSockets nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +// Begin. +namespace PandoraFMS\Websockets; + + +/** + * Parent class for WebSocket User. + */ +class WebSocketUser +{ + + /** + * Socket. + * + * @var Socket + */ + public $socket; + + /** + * Id. + * + * @var string + */ + public $id; + + /** + * Headers. + * + * @var array + */ + public $headers = []; + + /** + * Handshake. + * + * @var boolean + */ + public $handshake = false; + + /** + * HandlingPartialPacket. + * + * @var boolean + */ + public $handlingPartialPacket = false; + + /** + * PartialBuffer. + * + * @var string + */ + public $partialBuffer = ''; + + /** + * SendingContinuous. + * + * @var boolean + */ + public $sendingContinuous = false; + + /** + * PartialMessage. + * + * @var string + */ + public $partialMessage = ''; + + /** + * HasSentClose. + * + * @var boolean + */ + public $hasSentClose = false; + + /** + * Raw packet for redirection. + * + * @var string + */ + public $lastRawPacket; + + /** + * Pair resend packages. + * + * @var WebSocketUser + */ + public $redirect; + + /** + * Pandora FMS user account. + * + * @var User + */ + public $account; + + /** + * Remote address. + * + * @var string + */ + public $address; + + + /** + * Initializes a websocket user. + * + * @param string $id Id of the new user. + * @param Socket $socket Socket where communication is stablished. + */ + public function __construct($id, $socket) + { + socket_getpeername($socket, $this->address); + $this->id = $id; + $this->socket = $socket; + } + + +} diff --git a/pandora_console/include/styles/diagnostics.css b/pandora_console/include/styles/diagnostics.css new file mode 100644 index 0000000000..8de918e308 --- /dev/null +++ b/pandora_console/include/styles/diagnostics.css @@ -0,0 +1,66 @@ +.pdf-report { + page-break-inside: avoid; +} + +.pdf-report th, +.title-self-monitoring, +.caption_table caption { + text-align: center; + font-size: 1.5em; + font-weight: bolder; + color: #fff; + background: #282828; + padding: 8px; +} + +.pdf-report tr { + text-align: justify; +} + +.datatables-td-title { + width: 25% !important; + font-weight: bolder; +} + +.datatables-td-max { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + +.datatables-td-max img { + margin-right: 10px; +} + +.datatables-td-max span { + width: 400px; + display: inline-block; + word-wrap: break-word; +} + +.pdf-report td { + font-size: 1.2em; +} + +.container-self-monitoring { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + +.element-self-monitoring { + flex: 2 1 600px; +} + +.footer-self-monitoring { + margin: 30px; + font-style: italic; +} + +#modal_form_feedback { + margin: 10px; +} + +#div-what-happened label { + margin-bottom: 10px; +} diff --git a/pandora_console/include/styles/discovery.css b/pandora_console/include/styles/discovery.css index 82b022050f..5e19c2ed51 100644 --- a/pandora_console/include/styles/discovery.css +++ b/pandora_console/include/styles/discovery.css @@ -205,6 +205,7 @@ label { } li > input[type="text"], +li > input[type="email"], li > input[type="password"], .discovery_text_input > input[type="password"], .discovery_text_input > input[type="text"], @@ -270,3 +271,54 @@ 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/help_feedback.css b/pandora_console/include/styles/help_feedback.css new file mode 100644 index 0000000000..3368f5b3d7 --- /dev/null +++ b/pandora_console/include/styles/help_feedback.css @@ -0,0 +1,105 @@ +html, +body { + width: 100%; + height: 100%; +} + +div.help_feedback { + position: fixed; + bottom: 0; + background: white; + height: auto; + width: 365px; + padding-left: 10px; + padding-right: 10px; +} + +.btn_sug { + margin-right: 10px; + margin-top: 10px; + margin-left: 10px; + + font-weight: normal; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + font-size: 1.2em; + background-repeat: no-repeat; + background-position: 92% 10px; + color: #000; + padding-bottom: 10px; + padding-top: 10px; + padding-left: 10px; + border: none; + font-family: "lato", "Open Sans", sans-serif; + cursor: pointer; + padding-right: 30px; +} + +.btn_something { + margin-top: 10px; + margin-left: 10px; + + font-weight: normal; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + font-size: 1.2em; + background-repeat: no-repeat; + background-position: 92% 10px; + color: #000; + padding-bottom: 10px; + padding-top: 10px; + padding-left: 10px; + border: none; + font-family: "lato", "Open Sans", sans-serif; + cursor: pointer; + padding-right: 30px; +} + +.textarea_feedback { + margin-left: 11px; + max-width: 200px; + margin-top: 10px; + font-weight: bolder; +} + +.email_feedback { + max-width: 200px; + margin-left: 39px; + margin-top: 10px; + margin-bottom: 10px; + font-weight: bolder; +} + +.btn_submit_feed_back { + margin-right: 50px; + margin-top: 5px; + margin-bottom: 10px; +} + +.btn_sug_not_selected { + font-weight: normal; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + font-size: 1.2em; + background-repeat: no-repeat; + background-position: 92% 10px; + color: #000; + padding-bottom: 10px; + padding-top: 10px; + padding-left: 10px; + border: 1px solid #888; + font-family: "lato", "Open Sans", sans-serif; + cursor: pointer; + margin-right: 20px; + margin-top: 10px; + margin-left: 10px; + background-image: url(../../images/input_tick.png); + padding-right: 30px; +} + +.btn_section { + display: flex; +} diff --git a/pandora_console/include/styles/new_installation_welcome_window.css b/pandora_console/include/styles/new_installation_welcome_window.css new file mode 100644 index 0000000000..4aba16193d --- /dev/null +++ b/pandora_console/include/styles/new_installation_welcome_window.css @@ -0,0 +1,62 @@ +.modal { + overflow: hidden; +} + +.welcome_modal_window { + overflow: hidden; +} + +#welcome_modal_window { + /* + max-height: 100%; + height: 100%; + border-left: 1em solid #82b92f; + margin-bottom: -59px; + padding-bottom: 100px; + margin-left: -1px; + */ +} + +#welcome_form ul.wizard li { + padding: 1em; + padding-bottom: 0; + padding-top: 1em; +} + +#welcome_form label { + font-family: "lato-lighter", "Open Sans", sans-serif; + font-weight: normal; +} +.content_position { + display: flex; + margin-top: 5px; + font-family: "lato-lighter", "Open Sans", sans-serif; + font-weight: normal; +} + +.learn_content_indented { + text-indent: 1.5em; + font-family: "lato-lighter", "Open Sans", sans-serif; + font-weight: normal; +} + +#lbl_learn { + font-family: "lato-lighter", "Open Sans", sans-serif; + font-weight: normal; +} + +.go { + background-repeat: no-repeat; + background-size: cover; + width: 20px; + height: 20px; + border: none; +} + +.pending { + background-image: url(../../images/darrowright.png); +} + +.completed { + background-image: url(../../images/input_tick.png); +} diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 459cc5c54d..758114e12d 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -544,6 +544,13 @@ select:-internal-list-box { align-items: baseline; } +.flex-row-vcenter { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; +} + .nowrap { flex-wrap: nowrap; } diff --git a/pandora_console/include/templates/feedback_send_mail.html b/pandora_console/include/templates/feedback_send_mail.html new file mode 100644 index 0000000000..e06b68f246 --- /dev/null +++ b/pandora_console/include/templates/feedback_send_mail.html @@ -0,0 +1,58 @@ + + + + + + + Feedback + + + +

    __title__

    +
    +

    __p1__

    +

    __p2__

    +

    __attachment__

    +

    __p3__

    +
    +
    __legal__
    + + + + + + diff --git a/pandora_console/include/websocket_registrations.php b/pandora_console/include/websocket_registrations.php new file mode 100644 index 0000000000..24f9d9560c --- /dev/null +++ b/pandora_console/include/websocket_registrations.php @@ -0,0 +1,189 @@ +userClass('INTERNAL-'.uniqid('u'), $intSocket); + + $intUser->headers = [ + 'get' => $to_url.' HTTP/1.1', + 'host' => $to_addr, + 'origin' => $to_addr, + 'sec-websocket-protocol' => 'gotty', + ]; + $ws_object->writeSocket($intUser, $c_str); + + return $intUser; +} + + +/** + * Process a connected step on proxied protocols. + * + * @param WSManager $ws_object Main WebSocket manager object. + * @param User $user WebSocketUser. + * + * @return void + */ +function proxyConnected( + $ws_object, + $user +) { + global $config; + + /* + * $user->redirect is connected to internal (reflexive). + * $user->socket is connected to external. + */ + + // Gotty. Based on the command selected, redirect to a target port. + if ($user->requestedResource == '/ssh') { + $port = $config['gotty_ssh_port']; + } else if ($user->requestedResource == '/telnet') { + $port = $config['gotty_telnet_port']; + } else { + $ws_object->disconnect($user->socket); + return; + } + + // Switch between ports... + // Create a new socket connection (internal). + $intUser = connectInt( + $ws_object, + $ws_object->rawHeaders, + $config['gotty_host'], + $port, + '/ws' + ); + + if ($intUser === null) { + $ws_object->disconnect($user->socket); + return; + } + + // Map user. + $user->intUser = $intUser; + // And socket. + $user->intSocket = $intUser->socket; + $user->redirect = $intUser; + $intUser->redirect = $user; + + // Keep an eye on changes. + $ws_object->remoteSockets[$intUser->id] = $intUser->socket; + $ws_object->remoteUsers[$intUser->id] = $intUser; + + // Ignore. Cleanup socket. + $response = $ws_object->readSocket($user->intUser); +} + + +/** + * Redirects input from user to redirection stabished. + * + * @param WSManager $ws_object Main WebSocket manager object. + * @param WebSocketUser $user WebSocket user. + * @param string $buffer Buffer. + * + * @return boolean Ok or not. + */ +function proxyProcessRaw($ws_object, $user, $buffer) +{ + if (isset($user->redirect) !== true) { + $ws_object->disconnect($user->socket); + return false; + } + + $ws_object->stderr($user->id.' >> '.$user->redirect->id); + $ws_object->stderr($ws_object->dump($buffer)); + $ws_object->writeSocket($user->redirect, $buffer); + + return true; +} + + +/* + * ============================================================================ + * * ENDS: GOTTY PROTOCOL: PROXY + * ============================================================================ + */ diff --git a/pandora_console/install.php b/pandora_console/install.php index 130c31a047..4f668fcd81 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
    = 7.0" + rc_failed 5 # program is not installed + rc_exit +fi + +case "$1" in + start) + PANDORA_PID=`pidof_pandora` + if [ ! -z "$PANDORA_PID" ] + then + echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is currently running on this machine with PID ($PANDORA_PID)." + rc_exit # running start on a service already running + fi + + export PERL_LWP_SSL_VERIFY_HOSTNAME=0 + $PHP $WS_ENGINE >> $WS_LOG 2>&1 & + sleep 1 + + PANDORA_PID=`pidof_pandora` + + if [ ! -z "$PANDORA_PID" ] + then + echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is now running with PID $PANDORA_PID" + rc_status -v + else + echo "Cannot start $PANDORA_RB_PRODUCT_NAME Console Websocket engine. Aborted." + echo "Check $PANDORA_RB_PRODUCT_NAME log files at $WS_LOG" + rc_failed 7 # program is not running + fi + ;; + + stop) + PANDORA_PID=`pidof_pandora` + if [ -z "$PANDORA_PID" ] + then + echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is not running, cannot stop it." + rc_exit # running stop on a service already stopped or not running + else + echo "Stopping $PANDORA_RB_PRODUCT_NAME Console Websocket engine" + kill $PANDORA_PID > /dev/null 2>&1 + COUNTER=0 + + while [ $COUNTER -lt $MAXWAIT ] + do + _PID=`pidof_pandora` + if [ "$_PID" != "$PANDORA_PID" ] + then + COUNTER=$MAXWAIT + fi + COUNTER=`expr $COUNTER + 1` + sleep 1 + done + + # Send a KILL -9 signal to process, if it's alive after 60secs, we need + # to be sure is really dead, and not pretending... + if [ "$_PID" = "$PANDORA_PID" ] + then + kill -9 $PANDORA_PID > /dev/null 2>&1 + fi + rc_status -v + fi + ;; + status) + PANDORA_PID=`pidof_pandora` + if [ -z "$PANDORA_PID" ] + then + echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is not running." + rc_failed 7 # program is not running + else + echo "$PANDORA_RB_PRODUCT_NAME Console Websocket engine is running with PID $PANDORA_PID." + rc_status + fi + ;; + force-reload|restart) + $0 stop + $0 start + ;; + *) + echo "Usage: $0 { start | stop | restart | status }" + exit 1 +esac +rc_exit diff --git a/pandora_console/pandora_websocket_engine.service b/pandora_console/pandora_websocket_engine.service new file mode 100644 index 0000000000..fe19ff1490 --- /dev/null +++ b/pandora_console/pandora_websocket_engine.service @@ -0,0 +1,19 @@ +[Unit] +Description=php webSocket +After=syslog.target network.target + +[Service] +User=apache + +Type=simple +ExecStart=php /var/www/html/pandora_console/ws.php >> /var/www/html/pandora_console/pandora_console.log 2>&1 +TimeoutStopSec=20 +KillMode=process +Restart=always +RestartSec=2 +StandardOutput=file:/var/www/html/pandora_console/pandora_console.log +StandardError=file:/var/www/html/pandora_console/pandora_console.log + +[Install] +WantedBy=multi-user.target +Alias=websocket.service \ No newline at end of file diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 3786c4dad3..3b11dccb4d 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -3522,6 +3522,7 @@ CREATE TABLE IF NOT EXISTS `tlayout_template_data` ( `time_format` varchar(60) NOT NULL default "time", `timezone` varchar(60) NOT NULL default "Europe/Madrid", `show_last_value` tinyint(1) UNSIGNED NULL default '0', + `cache_expiration` INTEGER UNSIGNED NOT NULL default 0, PRIMARY KEY(`id`), FOREIGN KEY (`id_layout_template`) REFERENCES tlayout_template(`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index e7d4a81996..8f2d106dba 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -138,7 +138,9 @@ INSERT INTO `tconfig` (`token`, `value`) VALUES ('cr_incident_type', ''), ('cr_incident_status', ''), ('cr_incident_title', ''), -('cr_incident_content', ''); +('cr_incident_content', ''), +('sample_agent', '0'), +('gotty', '/usr/bin/gotty'); UNLOCK TABLES; -- @@ -268,7 +270,7 @@ INSERT INTO `torigen` VALUES -- -- Identifiers 30 and 31 are reserved for Enterprise data types -INSERT INTO `ttipo_modulo` VALUES +INSERT INTO `ttipo_modulo` VALUES (1,'generic_data',0,'Generic numeric','mod_data.png'), (2,'generic_proc',1,'Generic boolean','mod_proc.png'), (3,'generic_data_string',2,'Generic string','mod_string.png'), @@ -283,19 +285,15 @@ INSERT INTO `ttipo_modulo` VALUES (15,'remote_snmp',3,'Remote SNMP network agent, numeric data','mod_snmp_data.png'), (16,'remote_snmp_inc',3,'Remote SNMP network agent, incremental data','mod_snmp_inc.png'), (17,'remote_snmp_string',5,'Remote SNMP network agent, alphanumeric data','mod_snmp_string.png'), -(18,'remote_snmp_proc',4,'Remote SNMP network agent, boolean data','mod_snmp_proc.png'), -(21,'async_proc', 7, 'Asyncronous proc data', 'mod_async_proc.png'), -(22,'async_data', 6, 'Asyncronous numeric data', 'mod_async_data.png'), +(18,'remote_snmp_proc',4,'Remote SNMP network agent, boolean data','mod_snmp_proc.png'), +(21,'async_proc', 7, 'Asyncronous proc data', 'mod_async_proc.png'), +(22,'async_data', 6, 'Asyncronous numeric data', 'mod_async_data.png'), (23,'async_string', 8, 'Asyncronous string data', 'mod_async_string.png'), (25,'web_analysis', 8, 'Web analysis data', 'module-wux.png'), (30,'web_data',9,'Remote HTTP module to check latency','mod_web_data.png'), (31,'web_proc',9,'Remote HTTP module to check server response','mod_web_proc.png'), (32,'web_content_data',9,'Remote HTTP module to retrieve numeric data','mod_web_data.png'), (33,'web_content_string',9,'Remote HTTP module to retrieve string data','mod_web_data.png'), -(34,'remote_cmd', 10, 'Remote execution, numeric data', 'mod_remote_cmd.png'), -(35,'remote_cmd_proc', 10, 'Remote execution, boolean data', 'mod_remote_cmd_proc.png'), -(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'), (100,'keep_alive',-1,'KeepAlive','mod_keepalive.png'); -- diff --git a/pandora_console/tools/diagnostics.php b/pandora_console/tools/diagnostics.php new file mode 100644 index 0000000000..30be89efc4 --- /dev/null +++ b/pandora_console/tools/diagnostics.php @@ -0,0 +1,73 @@ + '[Diagnostics]'.$e->getMessage() ]); + exit; + } else { + echo '[Diagnostics]'.$e->getMessage(); + } + + // Stop this execution, but continue 'globally'. + return; +} + +// AJAX controller. +if (is_ajax()) { + $method = get_parameter('method'); + + if (method_exists($cs, $method) === true) { + if ($cs->ajaxMethod($method) === true) { + $cs->{$method}(); + } else { + $cs->error('Unavailable method.'); + } + } else { + $cs->error('Method not found. ['.$method.']'); + } + + // Stop any execution. + exit; +} else { + // Run. + $cs->run(); +} diff --git a/pandora_console/vendor/composer/LICENSE b/pandora_console/vendor/composer/LICENSE index f27399a042..62ecfd8d00 100644 --- a/pandora_console/vendor/composer/LICENSE +++ b/pandora_console/vendor/composer/LICENSE @@ -1,4 +1,3 @@ - Copyright (c) Nils Adermann, Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy @@ -18,4 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/pandora_console/vendor/composer/autoload_classmap.php b/pandora_console/vendor/composer/autoload_classmap.php index 45ec80bd52..47754b95f5 100644 --- a/pandora_console/vendor/composer/autoload_classmap.php +++ b/pandora_console/vendor/composer/autoload_classmap.php @@ -6,11 +6,321 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'DeepCopy\\DeepCopy' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/DeepCopy.php', + 'DeepCopy\\Exception\\CloneException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php', + 'DeepCopy\\Exception\\PropertyException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php', + 'DeepCopy\\Filter\\Doctrine\\DoctrineCollectionFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php', + 'DeepCopy\\Filter\\Doctrine\\DoctrineEmptyCollectionFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php', + 'DeepCopy\\Filter\\Doctrine\\DoctrineProxyFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php', + 'DeepCopy\\Filter\\Filter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php', + 'DeepCopy\\Filter\\KeepFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php', + 'DeepCopy\\Filter\\ReplaceFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php', + 'DeepCopy\\Filter\\SetNullFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php', + 'DeepCopy\\Matcher\\Doctrine\\DoctrineProxyMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php', + 'DeepCopy\\Matcher\\Matcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php', + 'DeepCopy\\Matcher\\PropertyMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php', + 'DeepCopy\\Matcher\\PropertyNameMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php', + 'DeepCopy\\Matcher\\PropertyTypeMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php', + 'DeepCopy\\Reflection\\ReflectionHelper' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php', + 'DeepCopy\\TypeFilter\\Date\\DateIntervalFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php', + 'DeepCopy\\TypeFilter\\ReplaceFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php', + 'DeepCopy\\TypeFilter\\ShallowCopyFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php', + 'DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedList' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php', + 'DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedListFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php', + 'DeepCopy\\TypeFilter\\TypeFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php', + 'DeepCopy\\TypeMatcher\\TypeMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php', + 'Doctrine\\Common\\Lexer\\AbstractLexer' => $vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php', + 'Egulias\\EmailValidator\\EmailLexer' => $vendorDir . '/egulias/email-validator/EmailValidator/EmailLexer.php', + 'Egulias\\EmailValidator\\EmailParser' => $vendorDir . '/egulias/email-validator/EmailValidator/EmailParser.php', + 'Egulias\\EmailValidator\\EmailValidator' => $vendorDir . '/egulias/email-validator/EmailValidator/EmailValidator.php', + 'Egulias\\EmailValidator\\Exception\\AtextAfterCFWS' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/AtextAfterCFWS.php', + 'Egulias\\EmailValidator\\Exception\\CRLFAtTheEnd' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/CRLFAtTheEnd.php', + 'Egulias\\EmailValidator\\Exception\\CRLFX2' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/CRLFX2.php', + 'Egulias\\EmailValidator\\Exception\\CRNoLF' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/CRNoLF.php', + 'Egulias\\EmailValidator\\Exception\\CharNotAllowed' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/CharNotAllowed.php', + 'Egulias\\EmailValidator\\Exception\\CommaInDomain' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/CommaInDomain.php', + 'Egulias\\EmailValidator\\Exception\\ConsecutiveAt' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ConsecutiveAt.php', + 'Egulias\\EmailValidator\\Exception\\ConsecutiveDot' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ConsecutiveDot.php', + 'Egulias\\EmailValidator\\Exception\\DomainHyphened' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/DomainHyphened.php', + 'Egulias\\EmailValidator\\Exception\\DotAtEnd' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/DotAtEnd.php', + 'Egulias\\EmailValidator\\Exception\\DotAtStart' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/DotAtStart.php', + 'Egulias\\EmailValidator\\Exception\\ExpectedQPair' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingQPair.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingAT' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingAT.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingATEXT' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingATEXT.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingCTEXT' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingCTEXT.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingDTEXT' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingDTEXT.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingDomainLiteralClose' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/ExpectingDomainLiteralClose.php', + 'Egulias\\EmailValidator\\Exception\\InvalidEmail' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/InvalidEmail.php', + 'Egulias\\EmailValidator\\Exception\\NoDNSRecord' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/NoDNSRecord.php', + 'Egulias\\EmailValidator\\Exception\\NoDomainPart' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/NoDomainPart.php', + 'Egulias\\EmailValidator\\Exception\\NoLocalPart' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/NoLocalPart.php', + 'Egulias\\EmailValidator\\Exception\\UnclosedComment' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/UnclosedComment.php', + 'Egulias\\EmailValidator\\Exception\\UnclosedQuotedString' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/UnclosedQuotedString.php', + 'Egulias\\EmailValidator\\Exception\\UnopenedComment' => $vendorDir . '/egulias/email-validator/EmailValidator/Exception/UnopenedComment.php', + 'Egulias\\EmailValidator\\Parser\\DomainPart' => $vendorDir . '/egulias/email-validator/EmailValidator/Parser/DomainPart.php', + 'Egulias\\EmailValidator\\Parser\\LocalPart' => $vendorDir . '/egulias/email-validator/EmailValidator/Parser/LocalPart.php', + 'Egulias\\EmailValidator\\Parser\\Parser' => $vendorDir . '/egulias/email-validator/EmailValidator/Parser/Parser.php', + 'Egulias\\EmailValidator\\Validation\\DNSCheckValidation' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/DNSCheckValidation.php', + 'Egulias\\EmailValidator\\Validation\\EmailValidation' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/EmailValidation.php', + 'Egulias\\EmailValidator\\Validation\\Error\\RFCWarnings' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/Error/RFCWarnings.php', + 'Egulias\\EmailValidator\\Validation\\Error\\SpoofEmail' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/Error/SpoofEmail.php', + 'Egulias\\EmailValidator\\Validation\\Exception\\EmptyValidationList' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/Exception/EmptyValidationList.php', + 'Egulias\\EmailValidator\\Validation\\MultipleErrors' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/MultipleErrors.php', + 'Egulias\\EmailValidator\\Validation\\MultipleValidationWithAnd' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/MultipleValidationWithAnd.php', + 'Egulias\\EmailValidator\\Validation\\NoRFCWarningsValidation' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/NoRFCWarningsValidation.php', + 'Egulias\\EmailValidator\\Validation\\RFCValidation' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/RFCValidation.php', + 'Egulias\\EmailValidator\\Validation\\SpoofCheckValidation' => $vendorDir . '/egulias/email-validator/EmailValidator/Validation/SpoofCheckValidation.php', + 'Egulias\\EmailValidator\\Warning\\AddressLiteral' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/AddressLiteral.php', + 'Egulias\\EmailValidator\\Warning\\CFWSNearAt' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/CFWSNearAt.php', + 'Egulias\\EmailValidator\\Warning\\CFWSWithFWS' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/CFWSWithFWS.php', + 'Egulias\\EmailValidator\\Warning\\Comment' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/Comment.php', + 'Egulias\\EmailValidator\\Warning\\DeprecatedComment' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/DeprecatedComment.php', + 'Egulias\\EmailValidator\\Warning\\DomainLiteral' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/DomainLiteral.php', + 'Egulias\\EmailValidator\\Warning\\DomainTooLong' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/DomainTooLong.php', + 'Egulias\\EmailValidator\\Warning\\EmailTooLong' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/EmailTooLong.php', + 'Egulias\\EmailValidator\\Warning\\IPV6BadChar' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/IPV6BadChar.php', + 'Egulias\\EmailValidator\\Warning\\IPV6ColonEnd' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/IPV6ColonEnd.php', + 'Egulias\\EmailValidator\\Warning\\IPV6ColonStart' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/IPV6ColonStart.php', + 'Egulias\\EmailValidator\\Warning\\IPV6Deprecated' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/IPV6Deprecated.php', + 'Egulias\\EmailValidator\\Warning\\IPV6DoubleColon' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/IPV6DoubleColon.php', + 'Egulias\\EmailValidator\\Warning\\IPV6GroupCount' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/IPV6GroupCount.php', + 'Egulias\\EmailValidator\\Warning\\IPV6MaxGroups' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/IPV6MaxGroups.php', + 'Egulias\\EmailValidator\\Warning\\LabelTooLong' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/LabelTooLong.php', + 'Egulias\\EmailValidator\\Warning\\LocalTooLong' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/LocalTooLong.php', + 'Egulias\\EmailValidator\\Warning\\NoDNSMXRecord' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/NoDNSMXRecord.php', + 'Egulias\\EmailValidator\\Warning\\ObsoleteDTEXT' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/ObsoleteDTEXT.php', + 'Egulias\\EmailValidator\\Warning\\QuotedPart' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/QuotedPart.php', + 'Egulias\\EmailValidator\\Warning\\QuotedString' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/QuotedString.php', + 'Egulias\\EmailValidator\\Warning\\TLD' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/TLD.php', + 'Egulias\\EmailValidator\\Warning\\Warning' => $vendorDir . '/egulias/email-validator/EmailValidator/Warning/Warning.php', 'FPDF_TPL' => $vendorDir . '/setasign/fpdi/fpdf_tpl.php', 'FPDI' => $vendorDir . '/setasign/fpdi/fpdi.php', 'FilterASCII85' => $vendorDir . '/setasign/fpdi/filters/FilterASCII85.php', 'FilterASCIIHexDecode' => $vendorDir . '/setasign/fpdi/filters/FilterASCIIHexDecode.php', 'FilterLZW' => $vendorDir . '/setasign/fpdi/filters/FilterLZW.php', + 'Models\\CachedModel' => $baseDir . '/include/rest-api/models/CachedModel.php', + 'Models\\Model' => $baseDir . '/include/rest-api/models/Model.php', + 'Models\\VisualConsole\\Container' => $baseDir . '/include/rest-api/models/VisualConsole/Container.php', + 'Models\\VisualConsole\\Item' => $baseDir . '/include/rest-api/models/VisualConsole/Item.php', + 'Models\\VisualConsole\\Items\\BarsGraph' => $baseDir . '/include/rest-api/models/VisualConsole/Items/BarsGraph.php', + 'Models\\VisualConsole\\Items\\Box' => $baseDir . '/include/rest-api/models/VisualConsole/Items/Box.php', + 'Models\\VisualConsole\\Items\\Clock' => $baseDir . '/include/rest-api/models/VisualConsole/Items/Clock.php', + 'Models\\VisualConsole\\Items\\ColorCloud' => $baseDir . '/include/rest-api/models/VisualConsole/Items/ColorCloud.php', + 'Models\\VisualConsole\\Items\\DonutGraph' => $baseDir . '/include/rest-api/models/VisualConsole/Items/DonutGraph.php', + 'Models\\VisualConsole\\Items\\EventsHistory' => $baseDir . '/include/rest-api/models/VisualConsole/Items/EventsHistory.php', + 'Models\\VisualConsole\\Items\\Group' => $baseDir . '/include/rest-api/models/VisualConsole/Items/Group.php', + 'Models\\VisualConsole\\Items\\Icon' => $baseDir . '/include/rest-api/models/VisualConsole/Items/Icon.php', + 'Models\\VisualConsole\\Items\\Label' => $baseDir . '/include/rest-api/models/VisualConsole/Items/Label.php', + 'Models\\VisualConsole\\Items\\Line' => $baseDir . '/include/rest-api/models/VisualConsole/Items/Line.php', + 'Models\\VisualConsole\\Items\\ModuleGraph' => $baseDir . '/include/rest-api/models/VisualConsole/Items/ModuleGraph.php', + 'Models\\VisualConsole\\Items\\Percentile' => $baseDir . '/include/rest-api/models/VisualConsole/Items/Percentile.php', + 'Models\\VisualConsole\\Items\\SimpleValue' => $baseDir . '/include/rest-api/models/VisualConsole/Items/SimpleValue.php', + 'Models\\VisualConsole\\Items\\StaticGraph' => $baseDir . '/include/rest-api/models/VisualConsole/Items/StaticGraph.php', + 'Mpdf\\Barcode' => $vendorDir . '/mpdf/mpdf/src/Barcode.php', + 'Mpdf\\Barcode\\AbstractBarcode' => $vendorDir . '/mpdf/mpdf/src/Barcode/AbstractBarcode.php', + 'Mpdf\\Barcode\\BarcodeException' => $vendorDir . '/mpdf/mpdf/src/Barcode/BarcodeException.php', + 'Mpdf\\Barcode\\BarcodeInterface' => $vendorDir . '/mpdf/mpdf/src/Barcode/BarcodeInterface.php', + 'Mpdf\\Barcode\\Codabar' => $vendorDir . '/mpdf/mpdf/src/Barcode/Codabar.php', + 'Mpdf\\Barcode\\Code11' => $vendorDir . '/mpdf/mpdf/src/Barcode/Code11.php', + 'Mpdf\\Barcode\\Code128' => $vendorDir . '/mpdf/mpdf/src/Barcode/Code128.php', + 'Mpdf\\Barcode\\Code39' => $vendorDir . '/mpdf/mpdf/src/Barcode/Code39.php', + 'Mpdf\\Barcode\\Code93' => $vendorDir . '/mpdf/mpdf/src/Barcode/Code93.php', + 'Mpdf\\Barcode\\EanExt' => $vendorDir . '/mpdf/mpdf/src/Barcode/EanExt.php', + 'Mpdf\\Barcode\\EanUpc' => $vendorDir . '/mpdf/mpdf/src/Barcode/EanUpc.php', + 'Mpdf\\Barcode\\I25' => $vendorDir . '/mpdf/mpdf/src/Barcode/I25.php', + 'Mpdf\\Barcode\\Imb' => $vendorDir . '/mpdf/mpdf/src/Barcode/Imb.php', + 'Mpdf\\Barcode\\Msi' => $vendorDir . '/mpdf/mpdf/src/Barcode/Msi.php', + 'Mpdf\\Barcode\\Postnet' => $vendorDir . '/mpdf/mpdf/src/Barcode/Postnet.php', + 'Mpdf\\Barcode\\Rm4Scc' => $vendorDir . '/mpdf/mpdf/src/Barcode/Rm4Scc.php', + 'Mpdf\\Barcode\\S25' => $vendorDir . '/mpdf/mpdf/src/Barcode/S25.php', + 'Mpdf\\Cache' => $vendorDir . '/mpdf/mpdf/src/Cache.php', + 'Mpdf\\Color\\ColorConverter' => $vendorDir . '/mpdf/mpdf/src/Color/ColorConverter.php', + 'Mpdf\\Color\\ColorModeConverter' => $vendorDir . '/mpdf/mpdf/src/Color/ColorModeConverter.php', + 'Mpdf\\Color\\ColorSpaceRestrictor' => $vendorDir . '/mpdf/mpdf/src/Color/ColorSpaceRestrictor.php', + 'Mpdf\\Color\\NamedColors' => $vendorDir . '/mpdf/mpdf/src/Color/NamedColors.php', + 'Mpdf\\Config\\ConfigVariables' => $vendorDir . '/mpdf/mpdf/src/Config/ConfigVariables.php', + 'Mpdf\\Config\\FontVariables' => $vendorDir . '/mpdf/mpdf/src/Config/FontVariables.php', + 'Mpdf\\Conversion\\DecToAlpha' => $vendorDir . '/mpdf/mpdf/src/Conversion/DecToAlpha.php', + 'Mpdf\\Conversion\\DecToCjk' => $vendorDir . '/mpdf/mpdf/src/Conversion/DecToCjk.php', + 'Mpdf\\Conversion\\DecToHebrew' => $vendorDir . '/mpdf/mpdf/src/Conversion/DecToHebrew.php', + 'Mpdf\\Conversion\\DecToOther' => $vendorDir . '/mpdf/mpdf/src/Conversion/DecToOther.php', + 'Mpdf\\Conversion\\DecToRoman' => $vendorDir . '/mpdf/mpdf/src/Conversion/DecToRoman.php', + 'Mpdf\\CssManager' => $vendorDir . '/mpdf/mpdf/src/CssManager.php', + 'Mpdf\\Css\\Border' => $vendorDir . '/mpdf/mpdf/src/Css/Border.php', + 'Mpdf\\Css\\DefaultCss' => $vendorDir . '/mpdf/mpdf/src/Css/DefaultCss.php', + 'Mpdf\\Css\\TextVars' => $vendorDir . '/mpdf/mpdf/src/Css/TextVars.php', + 'Mpdf\\DirectWrite' => $vendorDir . '/mpdf/mpdf/src/DirectWrite.php', + 'Mpdf\\Exception\\InvalidArgumentException' => $vendorDir . '/mpdf/mpdf/src/Exception/InvalidArgumentException.php', + 'Mpdf\\Fonts\\FontCache' => $vendorDir . '/mpdf/mpdf/src/Fonts/FontCache.php', + 'Mpdf\\Fonts\\FontFileFinder' => $vendorDir . '/mpdf/mpdf/src/Fonts/FontFileFinder.php', + 'Mpdf\\Fonts\\GlyphOperator' => $vendorDir . '/mpdf/mpdf/src/Fonts/GlyphOperator.php', + 'Mpdf\\Fonts\\MetricsGenerator' => $vendorDir . '/mpdf/mpdf/src/Fonts/MetricsGenerator.php', + 'Mpdf\\Form' => $vendorDir . '/mpdf/mpdf/src/Form.php', + 'Mpdf\\Gif\\ColorTable' => $vendorDir . '/mpdf/mpdf/src/Gif/ColorTable.php', + 'Mpdf\\Gif\\FileHeader' => $vendorDir . '/mpdf/mpdf/src/Gif/FileHeader.php', + 'Mpdf\\Gif\\Gif' => $vendorDir . '/mpdf/mpdf/src/Gif/Gif.php', + 'Mpdf\\Gif\\Image' => $vendorDir . '/mpdf/mpdf/src/Gif/Image.php', + 'Mpdf\\Gif\\ImageHeader' => $vendorDir . '/mpdf/mpdf/src/Gif/ImageHeader.php', + 'Mpdf\\Gif\\Lzw' => $vendorDir . '/mpdf/mpdf/src/Gif/Lzw.php', + 'Mpdf\\Gradient' => $vendorDir . '/mpdf/mpdf/src/Gradient.php', + 'Mpdf\\Hyphenator' => $vendorDir . '/mpdf/mpdf/src/Hyphenator.php', + 'Mpdf\\Image\\Bmp' => $vendorDir . '/mpdf/mpdf/src/Image/Bmp.php', + 'Mpdf\\Image\\ImageProcessor' => $vendorDir . '/mpdf/mpdf/src/Image/ImageProcessor.php', + 'Mpdf\\Image\\ImageTypeGuesser' => $vendorDir . '/mpdf/mpdf/src/Image/ImageTypeGuesser.php', + 'Mpdf\\Image\\Svg' => $vendorDir . '/mpdf/mpdf/src/Image/Svg.php', + 'Mpdf\\Image\\Wmf' => $vendorDir . '/mpdf/mpdf/src/Image/Wmf.php', + 'Mpdf\\Language\\LanguageToFont' => $vendorDir . '/mpdf/mpdf/src/Language/LanguageToFont.php', + 'Mpdf\\Language\\LanguageToFontInterface' => $vendorDir . '/mpdf/mpdf/src/Language/LanguageToFontInterface.php', + 'Mpdf\\Language\\ScriptToLanguage' => $vendorDir . '/mpdf/mpdf/src/Language/ScriptToLanguage.php', + 'Mpdf\\Language\\ScriptToLanguageInterface' => $vendorDir . '/mpdf/mpdf/src/Language/ScriptToLanguageInterface.php', + 'Mpdf\\Log\\Context' => $vendorDir . '/mpdf/mpdf/src/Log/Context.php', + 'Mpdf\\Mpdf' => $vendorDir . '/mpdf/mpdf/src/Mpdf.php', + 'Mpdf\\MpdfException' => $vendorDir . '/mpdf/mpdf/src/MpdfException.php', + 'Mpdf\\MpdfImageException' => $vendorDir . '/mpdf/mpdf/src/MpdfImageException.php', + 'Mpdf\\Otl' => $vendorDir . '/mpdf/mpdf/src/Otl.php', + 'Mpdf\\OtlDump' => $vendorDir . '/mpdf/mpdf/src/OtlDump.php', + 'Mpdf\\Output\\Destination' => $vendorDir . '/mpdf/mpdf/src/Output/Destination.php', + 'Mpdf\\PageFormat' => $vendorDir . '/mpdf/mpdf/src/PageFormat.php', + 'Mpdf\\Pdf\\Protection' => $vendorDir . '/mpdf/mpdf/src/Pdf/Protection.php', + 'Mpdf\\Pdf\\Protection\\UniqidGenerator' => $vendorDir . '/mpdf/mpdf/src/Pdf/Protection/UniqidGenerator.php', + 'Mpdf\\QrCode\\QrCode' => $vendorDir . '/mpdf/mpdf/src/QrCode/QrCode.php', + 'Mpdf\\QrCode\\QrCodeException' => $vendorDir . '/mpdf/mpdf/src/QrCode/QrCodeException.php', + 'Mpdf\\Shaper\\Indic' => $vendorDir . '/mpdf/mpdf/src/Shaper/Indic.php', + 'Mpdf\\Shaper\\Myanmar' => $vendorDir . '/mpdf/mpdf/src/Shaper/Myanmar.php', + 'Mpdf\\Shaper\\Sea' => $vendorDir . '/mpdf/mpdf/src/Shaper/Sea.php', + 'Mpdf\\SizeConverter' => $vendorDir . '/mpdf/mpdf/src/SizeConverter.php', + 'Mpdf\\TTFontFile' => $vendorDir . '/mpdf/mpdf/src/TTFontFile.php', + 'Mpdf\\TTFontFileAnalysis' => $vendorDir . '/mpdf/mpdf/src/TTFontFileAnalysis.php', + 'Mpdf\\TableOfContents' => $vendorDir . '/mpdf/mpdf/src/TableOfContents.php', + 'Mpdf\\Tag' => $vendorDir . '/mpdf/mpdf/src/Tag.php', + 'Mpdf\\Tag\\A' => $vendorDir . '/mpdf/mpdf/src/Tag/A.php', + 'Mpdf\\Tag\\Acronym' => $vendorDir . '/mpdf/mpdf/src/Tag/Acronym.php', + 'Mpdf\\Tag\\Address' => $vendorDir . '/mpdf/mpdf/src/Tag/Address.php', + 'Mpdf\\Tag\\Annotation' => $vendorDir . '/mpdf/mpdf/src/Tag/Annotation.php', + 'Mpdf\\Tag\\Article' => $vendorDir . '/mpdf/mpdf/src/Tag/Article.php', + 'Mpdf\\Tag\\Aside' => $vendorDir . '/mpdf/mpdf/src/Tag/Aside.php', + 'Mpdf\\Tag\\B' => $vendorDir . '/mpdf/mpdf/src/Tag/B.php', + 'Mpdf\\Tag\\BarCode' => $vendorDir . '/mpdf/mpdf/src/Tag/BarCode.php', + 'Mpdf\\Tag\\Bdi' => $vendorDir . '/mpdf/mpdf/src/Tag/Bdi.php', + 'Mpdf\\Tag\\Bdo' => $vendorDir . '/mpdf/mpdf/src/Tag/Bdo.php', + 'Mpdf\\Tag\\Big' => $vendorDir . '/mpdf/mpdf/src/Tag/Big.php', + 'Mpdf\\Tag\\BlockQuote' => $vendorDir . '/mpdf/mpdf/src/Tag/BlockQuote.php', + 'Mpdf\\Tag\\BlockTag' => $vendorDir . '/mpdf/mpdf/src/Tag/BlockTag.php', + 'Mpdf\\Tag\\Bookmark' => $vendorDir . '/mpdf/mpdf/src/Tag/Bookmark.php', + 'Mpdf\\Tag\\Br' => $vendorDir . '/mpdf/mpdf/src/Tag/Br.php', + 'Mpdf\\Tag\\Caption' => $vendorDir . '/mpdf/mpdf/src/Tag/Caption.php', + 'Mpdf\\Tag\\Center' => $vendorDir . '/mpdf/mpdf/src/Tag/Center.php', + 'Mpdf\\Tag\\Cite' => $vendorDir . '/mpdf/mpdf/src/Tag/Cite.php', + 'Mpdf\\Tag\\Code' => $vendorDir . '/mpdf/mpdf/src/Tag/Code.php', + 'Mpdf\\Tag\\ColumnBreak' => $vendorDir . '/mpdf/mpdf/src/Tag/ColumnBreak.php', + 'Mpdf\\Tag\\Columns' => $vendorDir . '/mpdf/mpdf/src/Tag/Columns.php', + 'Mpdf\\Tag\\Dd' => $vendorDir . '/mpdf/mpdf/src/Tag/Dd.php', + 'Mpdf\\Tag\\Del' => $vendorDir . '/mpdf/mpdf/src/Tag/Del.php', + 'Mpdf\\Tag\\Details' => $vendorDir . '/mpdf/mpdf/src/Tag/Details.php', + 'Mpdf\\Tag\\Div' => $vendorDir . '/mpdf/mpdf/src/Tag/Div.php', + 'Mpdf\\Tag\\Dl' => $vendorDir . '/mpdf/mpdf/src/Tag/Dl.php', + 'Mpdf\\Tag\\DotTab' => $vendorDir . '/mpdf/mpdf/src/Tag/DotTab.php', + 'Mpdf\\Tag\\Dt' => $vendorDir . '/mpdf/mpdf/src/Tag/Dt.php', + 'Mpdf\\Tag\\Em' => $vendorDir . '/mpdf/mpdf/src/Tag/Em.php', + 'Mpdf\\Tag\\FieldSet' => $vendorDir . '/mpdf/mpdf/src/Tag/FieldSet.php', + 'Mpdf\\Tag\\FigCaption' => $vendorDir . '/mpdf/mpdf/src/Tag/FigCaption.php', + 'Mpdf\\Tag\\Figure' => $vendorDir . '/mpdf/mpdf/src/Tag/Figure.php', + 'Mpdf\\Tag\\Font' => $vendorDir . '/mpdf/mpdf/src/Tag/Font.php', + 'Mpdf\\Tag\\Footer' => $vendorDir . '/mpdf/mpdf/src/Tag/Footer.php', + 'Mpdf\\Tag\\Form' => $vendorDir . '/mpdf/mpdf/src/Tag/Form.php', + 'Mpdf\\Tag\\FormFeed' => $vendorDir . '/mpdf/mpdf/src/Tag/FormFeed.php', + 'Mpdf\\Tag\\H1' => $vendorDir . '/mpdf/mpdf/src/Tag/H1.php', + 'Mpdf\\Tag\\H2' => $vendorDir . '/mpdf/mpdf/src/Tag/H2.php', + 'Mpdf\\Tag\\H3' => $vendorDir . '/mpdf/mpdf/src/Tag/H3.php', + 'Mpdf\\Tag\\H4' => $vendorDir . '/mpdf/mpdf/src/Tag/H4.php', + 'Mpdf\\Tag\\H5' => $vendorDir . '/mpdf/mpdf/src/Tag/H5.php', + 'Mpdf\\Tag\\H6' => $vendorDir . '/mpdf/mpdf/src/Tag/H6.php', + 'Mpdf\\Tag\\HGroup' => $vendorDir . '/mpdf/mpdf/src/Tag/HGroup.php', + 'Mpdf\\Tag\\Header' => $vendorDir . '/mpdf/mpdf/src/Tag/Header.php', + 'Mpdf\\Tag\\Hr' => $vendorDir . '/mpdf/mpdf/src/Tag/Hr.php', + 'Mpdf\\Tag\\I' => $vendorDir . '/mpdf/mpdf/src/Tag/I.php', + 'Mpdf\\Tag\\Img' => $vendorDir . '/mpdf/mpdf/src/Tag/Img.php', + 'Mpdf\\Tag\\IndexEntry' => $vendorDir . '/mpdf/mpdf/src/Tag/IndexEntry.php', + 'Mpdf\\Tag\\IndexInsert' => $vendorDir . '/mpdf/mpdf/src/Tag/IndexInsert.php', + 'Mpdf\\Tag\\InlineTag' => $vendorDir . '/mpdf/mpdf/src/Tag/InlineTag.php', + 'Mpdf\\Tag\\Input' => $vendorDir . '/mpdf/mpdf/src/Tag/Input.php', + 'Mpdf\\Tag\\Ins' => $vendorDir . '/mpdf/mpdf/src/Tag/Ins.php', + 'Mpdf\\Tag\\Kbd' => $vendorDir . '/mpdf/mpdf/src/Tag/Kbd.php', + 'Mpdf\\Tag\\Legend' => $vendorDir . '/mpdf/mpdf/src/Tag/Legend.php', + 'Mpdf\\Tag\\Li' => $vendorDir . '/mpdf/mpdf/src/Tag/Li.php', + 'Mpdf\\Tag\\Main' => $vendorDir . '/mpdf/mpdf/src/Tag/Main.php', + 'Mpdf\\Tag\\Mark' => $vendorDir . '/mpdf/mpdf/src/Tag/Mark.php', + 'Mpdf\\Tag\\Meter' => $vendorDir . '/mpdf/mpdf/src/Tag/Meter.php', + 'Mpdf\\Tag\\Nav' => $vendorDir . '/mpdf/mpdf/src/Tag/Nav.php', + 'Mpdf\\Tag\\NewColumn' => $vendorDir . '/mpdf/mpdf/src/Tag/NewColumn.php', + 'Mpdf\\Tag\\NewPage' => $vendorDir . '/mpdf/mpdf/src/Tag/NewPage.php', + 'Mpdf\\Tag\\Ol' => $vendorDir . '/mpdf/mpdf/src/Tag/Ol.php', + 'Mpdf\\Tag\\Option' => $vendorDir . '/mpdf/mpdf/src/Tag/Option.php', + 'Mpdf\\Tag\\P' => $vendorDir . '/mpdf/mpdf/src/Tag/P.php', + 'Mpdf\\Tag\\PageBreak' => $vendorDir . '/mpdf/mpdf/src/Tag/PageBreak.php', + 'Mpdf\\Tag\\PageFooter' => $vendorDir . '/mpdf/mpdf/src/Tag/PageFooter.php', + 'Mpdf\\Tag\\PageHeader' => $vendorDir . '/mpdf/mpdf/src/Tag/PageHeader.php', + 'Mpdf\\Tag\\Pre' => $vendorDir . '/mpdf/mpdf/src/Tag/Pre.php', + 'Mpdf\\Tag\\Progress' => $vendorDir . '/mpdf/mpdf/src/Tag/Progress.php', + 'Mpdf\\Tag\\Q' => $vendorDir . '/mpdf/mpdf/src/Tag/Q.php', + 'Mpdf\\Tag\\S' => $vendorDir . '/mpdf/mpdf/src/Tag/S.php', + 'Mpdf\\Tag\\Samp' => $vendorDir . '/mpdf/mpdf/src/Tag/Samp.php', + 'Mpdf\\Tag\\Section' => $vendorDir . '/mpdf/mpdf/src/Tag/Section.php', + 'Mpdf\\Tag\\Select' => $vendorDir . '/mpdf/mpdf/src/Tag/Select.php', + 'Mpdf\\Tag\\SetHtmlPageFooter' => $vendorDir . '/mpdf/mpdf/src/Tag/SetHtmlPageFooter.php', + 'Mpdf\\Tag\\SetHtmlPageHeader' => $vendorDir . '/mpdf/mpdf/src/Tag/SetHtmlPageHeader.php', + 'Mpdf\\Tag\\SetPageFooter' => $vendorDir . '/mpdf/mpdf/src/Tag/SetPageFooter.php', + 'Mpdf\\Tag\\SetPageHeader' => $vendorDir . '/mpdf/mpdf/src/Tag/SetPageHeader.php', + 'Mpdf\\Tag\\Small' => $vendorDir . '/mpdf/mpdf/src/Tag/Small.php', + 'Mpdf\\Tag\\Span' => $vendorDir . '/mpdf/mpdf/src/Tag/Span.php', + 'Mpdf\\Tag\\Strike' => $vendorDir . '/mpdf/mpdf/src/Tag/Strike.php', + 'Mpdf\\Tag\\Strong' => $vendorDir . '/mpdf/mpdf/src/Tag/Strong.php', + 'Mpdf\\Tag\\Sub' => $vendorDir . '/mpdf/mpdf/src/Tag/Sub.php', + 'Mpdf\\Tag\\SubstituteTag' => $vendorDir . '/mpdf/mpdf/src/Tag/SubstituteTag.php', + 'Mpdf\\Tag\\Summary' => $vendorDir . '/mpdf/mpdf/src/Tag/Summary.php', + 'Mpdf\\Tag\\Sup' => $vendorDir . '/mpdf/mpdf/src/Tag/Sup.php', + 'Mpdf\\Tag\\TBody' => $vendorDir . '/mpdf/mpdf/src/Tag/TBody.php', + 'Mpdf\\Tag\\TFoot' => $vendorDir . '/mpdf/mpdf/src/Tag/TFoot.php', + 'Mpdf\\Tag\\THead' => $vendorDir . '/mpdf/mpdf/src/Tag/THead.php', + 'Mpdf\\Tag\\Table' => $vendorDir . '/mpdf/mpdf/src/Tag/Table.php', + 'Mpdf\\Tag\\Tag' => $vendorDir . '/mpdf/mpdf/src/Tag/Tag.php', + 'Mpdf\\Tag\\Td' => $vendorDir . '/mpdf/mpdf/src/Tag/Td.php', + 'Mpdf\\Tag\\TextArea' => $vendorDir . '/mpdf/mpdf/src/Tag/TextArea.php', + 'Mpdf\\Tag\\TextCircle' => $vendorDir . '/mpdf/mpdf/src/Tag/TextCircle.php', + 'Mpdf\\Tag\\Th' => $vendorDir . '/mpdf/mpdf/src/Tag/Th.php', + 'Mpdf\\Tag\\Time' => $vendorDir . '/mpdf/mpdf/src/Tag/Time.php', + 'Mpdf\\Tag\\Toc' => $vendorDir . '/mpdf/mpdf/src/Tag/Toc.php', + 'Mpdf\\Tag\\TocEntry' => $vendorDir . '/mpdf/mpdf/src/Tag/TocEntry.php', + 'Mpdf\\Tag\\TocPageBreak' => $vendorDir . '/mpdf/mpdf/src/Tag/TocPageBreak.php', + 'Mpdf\\Tag\\Tr' => $vendorDir . '/mpdf/mpdf/src/Tag/Tr.php', + 'Mpdf\\Tag\\Tt' => $vendorDir . '/mpdf/mpdf/src/Tag/Tt.php', + 'Mpdf\\Tag\\Tta' => $vendorDir . '/mpdf/mpdf/src/Tag/Tta.php', + 'Mpdf\\Tag\\Tts' => $vendorDir . '/mpdf/mpdf/src/Tag/Tts.php', + 'Mpdf\\Tag\\Ttz' => $vendorDir . '/mpdf/mpdf/src/Tag/Ttz.php', + 'Mpdf\\Tag\\U' => $vendorDir . '/mpdf/mpdf/src/Tag/U.php', + 'Mpdf\\Tag\\Ul' => $vendorDir . '/mpdf/mpdf/src/Tag/Ul.php', + 'Mpdf\\Tag\\VarTag' => $vendorDir . '/mpdf/mpdf/src/Tag/VarTag.php', + 'Mpdf\\Tag\\WatermarkImage' => $vendorDir . '/mpdf/mpdf/src/Tag/WatermarkImage.php', + 'Mpdf\\Tag\\WatermarkText' => $vendorDir . '/mpdf/mpdf/src/Tag/WatermarkText.php', + 'Mpdf\\Ucdn' => $vendorDir . '/mpdf/mpdf/src/Ucdn.php', + 'Mpdf\\Utils\\Arrays' => $vendorDir . '/mpdf/mpdf/src/Utils/Arrays.php', + 'Mpdf\\Utils\\NumericString' => $vendorDir . '/mpdf/mpdf/src/Utils/NumericString.php', + 'Mpdf\\Utils\\PdfDate' => $vendorDir . '/mpdf/mpdf/src/Utils/PdfDate.php', + 'Mpdf\\Utils\\UtfString' => $vendorDir . '/mpdf/mpdf/src/Utils/UtfString.php', + 'PandoraFMS\\User' => $baseDir . '/include/lib/User.php', + 'PandoraFMS\\WebSockets\\WSManager' => $baseDir . '/include/lib/WSManager.php', + 'PandoraFMS\\Websockets\\WebSocketServer' => $baseDir . '/include/lib/WebSocketServer.php', + 'PandoraFMS\\Websockets\\WebSocketUser' => $baseDir . '/include/lib/WebSocketUser.php', + 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php', + 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php', + 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php', + 'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php', + 'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php', + 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', + 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', + 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', + 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', 'fpdi_pdf_parser' => $vendorDir . '/setasign/fpdi/fpdi_pdf_parser.php', 'pdf_context' => $vendorDir . '/setasign/fpdi/pdf_context.php', ); diff --git a/pandora_console/vendor/composer/autoload_psr4.php b/pandora_console/vendor/composer/autoload_psr4.php index 57404185e1..5d194597c6 100644 --- a/pandora_console/vendor/composer/autoload_psr4.php +++ b/pandora_console/vendor/composer/autoload_psr4.php @@ -8,6 +8,8 @@ $baseDir = dirname($vendorDir); return array( 'Tests\\' => array($baseDir . '/tests'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'PandoraFMS\\Enterprise\\' => array($baseDir . '/enterprise/include/lib'), + 'PandoraFMS\\' => array($baseDir . '/include/lib'), 'Mpdf\\' => array($vendorDir . '/mpdf/mpdf/src'), 'Models\\' => array($baseDir . '/include/rest-api/models'), 'Enterprise\\Models\\' => array($baseDir . '/enterprise/include/rest-api/models'), diff --git a/pandora_console/vendor/composer/autoload_static.php b/pandora_console/vendor/composer/autoload_static.php index f6d8bc0456..8eaa08fa17 100644 --- a/pandora_console/vendor/composer/autoload_static.php +++ b/pandora_console/vendor/composer/autoload_static.php @@ -19,6 +19,8 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa 'P' => array ( 'Psr\\Log\\' => 8, + 'PandoraFMS\\Enterprise\\' => 22, + 'PandoraFMS\\' => 11, ), 'M' => array ( @@ -45,6 +47,14 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa array ( 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', ), + 'PandoraFMS\\Enterprise\\' => + array ( + 0 => __DIR__ . '/../..' . '/enterprise/include/lib', + ), + 'PandoraFMS\\' => + array ( + 0 => __DIR__ . '/../..' . '/include/lib', + ), 'Mpdf\\' => array ( 0 => __DIR__ . '/..' . '/mpdf/mpdf/src', @@ -78,11 +88,321 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa ); public static $classMap = array ( + 'DeepCopy\\DeepCopy' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/DeepCopy.php', + 'DeepCopy\\Exception\\CloneException' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php', + 'DeepCopy\\Exception\\PropertyException' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php', + 'DeepCopy\\Filter\\Doctrine\\DoctrineCollectionFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php', + 'DeepCopy\\Filter\\Doctrine\\DoctrineEmptyCollectionFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php', + 'DeepCopy\\Filter\\Doctrine\\DoctrineProxyFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php', + 'DeepCopy\\Filter\\Filter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php', + 'DeepCopy\\Filter\\KeepFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php', + 'DeepCopy\\Filter\\ReplaceFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php', + 'DeepCopy\\Filter\\SetNullFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php', + 'DeepCopy\\Matcher\\Doctrine\\DoctrineProxyMatcher' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php', + 'DeepCopy\\Matcher\\Matcher' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php', + 'DeepCopy\\Matcher\\PropertyMatcher' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php', + 'DeepCopy\\Matcher\\PropertyNameMatcher' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php', + 'DeepCopy\\Matcher\\PropertyTypeMatcher' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php', + 'DeepCopy\\Reflection\\ReflectionHelper' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php', + 'DeepCopy\\TypeFilter\\Date\\DateIntervalFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php', + 'DeepCopy\\TypeFilter\\ReplaceFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php', + 'DeepCopy\\TypeFilter\\ShallowCopyFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php', + 'DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedList' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php', + 'DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedListFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php', + 'DeepCopy\\TypeFilter\\TypeFilter' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php', + 'DeepCopy\\TypeMatcher\\TypeMatcher' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php', + 'Doctrine\\Common\\Lexer\\AbstractLexer' => __DIR__ . '/..' . '/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php', + 'Egulias\\EmailValidator\\EmailLexer' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/EmailLexer.php', + 'Egulias\\EmailValidator\\EmailParser' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/EmailParser.php', + 'Egulias\\EmailValidator\\EmailValidator' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/EmailValidator.php', + 'Egulias\\EmailValidator\\Exception\\AtextAfterCFWS' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/AtextAfterCFWS.php', + 'Egulias\\EmailValidator\\Exception\\CRLFAtTheEnd' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/CRLFAtTheEnd.php', + 'Egulias\\EmailValidator\\Exception\\CRLFX2' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/CRLFX2.php', + 'Egulias\\EmailValidator\\Exception\\CRNoLF' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/CRNoLF.php', + 'Egulias\\EmailValidator\\Exception\\CharNotAllowed' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/CharNotAllowed.php', + 'Egulias\\EmailValidator\\Exception\\CommaInDomain' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/CommaInDomain.php', + 'Egulias\\EmailValidator\\Exception\\ConsecutiveAt' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ConsecutiveAt.php', + 'Egulias\\EmailValidator\\Exception\\ConsecutiveDot' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ConsecutiveDot.php', + 'Egulias\\EmailValidator\\Exception\\DomainHyphened' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/DomainHyphened.php', + 'Egulias\\EmailValidator\\Exception\\DotAtEnd' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/DotAtEnd.php', + 'Egulias\\EmailValidator\\Exception\\DotAtStart' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/DotAtStart.php', + 'Egulias\\EmailValidator\\Exception\\ExpectedQPair' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingQPair.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingAT' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingAT.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingATEXT' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingATEXT.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingCTEXT' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingCTEXT.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingDTEXT' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingDTEXT.php', + 'Egulias\\EmailValidator\\Exception\\ExpectingDomainLiteralClose' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/ExpectingDomainLiteralClose.php', + 'Egulias\\EmailValidator\\Exception\\InvalidEmail' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/InvalidEmail.php', + 'Egulias\\EmailValidator\\Exception\\NoDNSRecord' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/NoDNSRecord.php', + 'Egulias\\EmailValidator\\Exception\\NoDomainPart' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/NoDomainPart.php', + 'Egulias\\EmailValidator\\Exception\\NoLocalPart' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/NoLocalPart.php', + 'Egulias\\EmailValidator\\Exception\\UnclosedComment' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/UnclosedComment.php', + 'Egulias\\EmailValidator\\Exception\\UnclosedQuotedString' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/UnclosedQuotedString.php', + 'Egulias\\EmailValidator\\Exception\\UnopenedComment' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Exception/UnopenedComment.php', + 'Egulias\\EmailValidator\\Parser\\DomainPart' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Parser/DomainPart.php', + 'Egulias\\EmailValidator\\Parser\\LocalPart' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Parser/LocalPart.php', + 'Egulias\\EmailValidator\\Parser\\Parser' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Parser/Parser.php', + 'Egulias\\EmailValidator\\Validation\\DNSCheckValidation' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/DNSCheckValidation.php', + 'Egulias\\EmailValidator\\Validation\\EmailValidation' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/EmailValidation.php', + 'Egulias\\EmailValidator\\Validation\\Error\\RFCWarnings' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/Error/RFCWarnings.php', + 'Egulias\\EmailValidator\\Validation\\Error\\SpoofEmail' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/Error/SpoofEmail.php', + 'Egulias\\EmailValidator\\Validation\\Exception\\EmptyValidationList' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/Exception/EmptyValidationList.php', + 'Egulias\\EmailValidator\\Validation\\MultipleErrors' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/MultipleErrors.php', + 'Egulias\\EmailValidator\\Validation\\MultipleValidationWithAnd' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/MultipleValidationWithAnd.php', + 'Egulias\\EmailValidator\\Validation\\NoRFCWarningsValidation' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/NoRFCWarningsValidation.php', + 'Egulias\\EmailValidator\\Validation\\RFCValidation' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/RFCValidation.php', + 'Egulias\\EmailValidator\\Validation\\SpoofCheckValidation' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Validation/SpoofCheckValidation.php', + 'Egulias\\EmailValidator\\Warning\\AddressLiteral' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/AddressLiteral.php', + 'Egulias\\EmailValidator\\Warning\\CFWSNearAt' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/CFWSNearAt.php', + 'Egulias\\EmailValidator\\Warning\\CFWSWithFWS' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/CFWSWithFWS.php', + 'Egulias\\EmailValidator\\Warning\\Comment' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/Comment.php', + 'Egulias\\EmailValidator\\Warning\\DeprecatedComment' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/DeprecatedComment.php', + 'Egulias\\EmailValidator\\Warning\\DomainLiteral' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/DomainLiteral.php', + 'Egulias\\EmailValidator\\Warning\\DomainTooLong' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/DomainTooLong.php', + 'Egulias\\EmailValidator\\Warning\\EmailTooLong' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/EmailTooLong.php', + 'Egulias\\EmailValidator\\Warning\\IPV6BadChar' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/IPV6BadChar.php', + 'Egulias\\EmailValidator\\Warning\\IPV6ColonEnd' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/IPV6ColonEnd.php', + 'Egulias\\EmailValidator\\Warning\\IPV6ColonStart' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/IPV6ColonStart.php', + 'Egulias\\EmailValidator\\Warning\\IPV6Deprecated' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/IPV6Deprecated.php', + 'Egulias\\EmailValidator\\Warning\\IPV6DoubleColon' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/IPV6DoubleColon.php', + 'Egulias\\EmailValidator\\Warning\\IPV6GroupCount' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/IPV6GroupCount.php', + 'Egulias\\EmailValidator\\Warning\\IPV6MaxGroups' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/IPV6MaxGroups.php', + 'Egulias\\EmailValidator\\Warning\\LabelTooLong' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/LabelTooLong.php', + 'Egulias\\EmailValidator\\Warning\\LocalTooLong' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/LocalTooLong.php', + 'Egulias\\EmailValidator\\Warning\\NoDNSMXRecord' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/NoDNSMXRecord.php', + 'Egulias\\EmailValidator\\Warning\\ObsoleteDTEXT' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/ObsoleteDTEXT.php', + 'Egulias\\EmailValidator\\Warning\\QuotedPart' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/QuotedPart.php', + 'Egulias\\EmailValidator\\Warning\\QuotedString' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/QuotedString.php', + 'Egulias\\EmailValidator\\Warning\\TLD' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/TLD.php', + 'Egulias\\EmailValidator\\Warning\\Warning' => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator/Warning/Warning.php', 'FPDF_TPL' => __DIR__ . '/..' . '/setasign/fpdi/fpdf_tpl.php', 'FPDI' => __DIR__ . '/..' . '/setasign/fpdi/fpdi.php', 'FilterASCII85' => __DIR__ . '/..' . '/setasign/fpdi/filters/FilterASCII85.php', 'FilterASCIIHexDecode' => __DIR__ . '/..' . '/setasign/fpdi/filters/FilterASCIIHexDecode.php', 'FilterLZW' => __DIR__ . '/..' . '/setasign/fpdi/filters/FilterLZW.php', + 'Models\\CachedModel' => __DIR__ . '/../..' . '/include/rest-api/models/CachedModel.php', + 'Models\\Model' => __DIR__ . '/../..' . '/include/rest-api/models/Model.php', + 'Models\\VisualConsole\\Container' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Container.php', + 'Models\\VisualConsole\\Item' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Item.php', + 'Models\\VisualConsole\\Items\\BarsGraph' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/BarsGraph.php', + 'Models\\VisualConsole\\Items\\Box' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/Box.php', + 'Models\\VisualConsole\\Items\\Clock' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/Clock.php', + 'Models\\VisualConsole\\Items\\ColorCloud' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/ColorCloud.php', + 'Models\\VisualConsole\\Items\\DonutGraph' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/DonutGraph.php', + 'Models\\VisualConsole\\Items\\EventsHistory' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/EventsHistory.php', + 'Models\\VisualConsole\\Items\\Group' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/Group.php', + 'Models\\VisualConsole\\Items\\Icon' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/Icon.php', + 'Models\\VisualConsole\\Items\\Label' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/Label.php', + 'Models\\VisualConsole\\Items\\Line' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/Line.php', + 'Models\\VisualConsole\\Items\\ModuleGraph' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/ModuleGraph.php', + 'Models\\VisualConsole\\Items\\Percentile' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/Percentile.php', + 'Models\\VisualConsole\\Items\\SimpleValue' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/SimpleValue.php', + 'Models\\VisualConsole\\Items\\StaticGraph' => __DIR__ . '/../..' . '/include/rest-api/models/VisualConsole/Items/StaticGraph.php', + 'Mpdf\\Barcode' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode.php', + 'Mpdf\\Barcode\\AbstractBarcode' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/AbstractBarcode.php', + 'Mpdf\\Barcode\\BarcodeException' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/BarcodeException.php', + 'Mpdf\\Barcode\\BarcodeInterface' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/BarcodeInterface.php', + 'Mpdf\\Barcode\\Codabar' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/Codabar.php', + 'Mpdf\\Barcode\\Code11' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/Code11.php', + 'Mpdf\\Barcode\\Code128' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/Code128.php', + 'Mpdf\\Barcode\\Code39' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/Code39.php', + 'Mpdf\\Barcode\\Code93' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/Code93.php', + 'Mpdf\\Barcode\\EanExt' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/EanExt.php', + 'Mpdf\\Barcode\\EanUpc' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/EanUpc.php', + 'Mpdf\\Barcode\\I25' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/I25.php', + 'Mpdf\\Barcode\\Imb' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/Imb.php', + 'Mpdf\\Barcode\\Msi' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/Msi.php', + 'Mpdf\\Barcode\\Postnet' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/Postnet.php', + 'Mpdf\\Barcode\\Rm4Scc' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/Rm4Scc.php', + 'Mpdf\\Barcode\\S25' => __DIR__ . '/..' . '/mpdf/mpdf/src/Barcode/S25.php', + 'Mpdf\\Cache' => __DIR__ . '/..' . '/mpdf/mpdf/src/Cache.php', + 'Mpdf\\Color\\ColorConverter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Color/ColorConverter.php', + 'Mpdf\\Color\\ColorModeConverter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Color/ColorModeConverter.php', + 'Mpdf\\Color\\ColorSpaceRestrictor' => __DIR__ . '/..' . '/mpdf/mpdf/src/Color/ColorSpaceRestrictor.php', + 'Mpdf\\Color\\NamedColors' => __DIR__ . '/..' . '/mpdf/mpdf/src/Color/NamedColors.php', + 'Mpdf\\Config\\ConfigVariables' => __DIR__ . '/..' . '/mpdf/mpdf/src/Config/ConfigVariables.php', + 'Mpdf\\Config\\FontVariables' => __DIR__ . '/..' . '/mpdf/mpdf/src/Config/FontVariables.php', + 'Mpdf\\Conversion\\DecToAlpha' => __DIR__ . '/..' . '/mpdf/mpdf/src/Conversion/DecToAlpha.php', + 'Mpdf\\Conversion\\DecToCjk' => __DIR__ . '/..' . '/mpdf/mpdf/src/Conversion/DecToCjk.php', + 'Mpdf\\Conversion\\DecToHebrew' => __DIR__ . '/..' . '/mpdf/mpdf/src/Conversion/DecToHebrew.php', + 'Mpdf\\Conversion\\DecToOther' => __DIR__ . '/..' . '/mpdf/mpdf/src/Conversion/DecToOther.php', + 'Mpdf\\Conversion\\DecToRoman' => __DIR__ . '/..' . '/mpdf/mpdf/src/Conversion/DecToRoman.php', + 'Mpdf\\CssManager' => __DIR__ . '/..' . '/mpdf/mpdf/src/CssManager.php', + 'Mpdf\\Css\\Border' => __DIR__ . '/..' . '/mpdf/mpdf/src/Css/Border.php', + 'Mpdf\\Css\\DefaultCss' => __DIR__ . '/..' . '/mpdf/mpdf/src/Css/DefaultCss.php', + 'Mpdf\\Css\\TextVars' => __DIR__ . '/..' . '/mpdf/mpdf/src/Css/TextVars.php', + 'Mpdf\\DirectWrite' => __DIR__ . '/..' . '/mpdf/mpdf/src/DirectWrite.php', + 'Mpdf\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/mpdf/mpdf/src/Exception/InvalidArgumentException.php', + 'Mpdf\\Fonts\\FontCache' => __DIR__ . '/..' . '/mpdf/mpdf/src/Fonts/FontCache.php', + 'Mpdf\\Fonts\\FontFileFinder' => __DIR__ . '/..' . '/mpdf/mpdf/src/Fonts/FontFileFinder.php', + 'Mpdf\\Fonts\\GlyphOperator' => __DIR__ . '/..' . '/mpdf/mpdf/src/Fonts/GlyphOperator.php', + 'Mpdf\\Fonts\\MetricsGenerator' => __DIR__ . '/..' . '/mpdf/mpdf/src/Fonts/MetricsGenerator.php', + 'Mpdf\\Form' => __DIR__ . '/..' . '/mpdf/mpdf/src/Form.php', + 'Mpdf\\Gif\\ColorTable' => __DIR__ . '/..' . '/mpdf/mpdf/src/Gif/ColorTable.php', + 'Mpdf\\Gif\\FileHeader' => __DIR__ . '/..' . '/mpdf/mpdf/src/Gif/FileHeader.php', + 'Mpdf\\Gif\\Gif' => __DIR__ . '/..' . '/mpdf/mpdf/src/Gif/Gif.php', + 'Mpdf\\Gif\\Image' => __DIR__ . '/..' . '/mpdf/mpdf/src/Gif/Image.php', + 'Mpdf\\Gif\\ImageHeader' => __DIR__ . '/..' . '/mpdf/mpdf/src/Gif/ImageHeader.php', + 'Mpdf\\Gif\\Lzw' => __DIR__ . '/..' . '/mpdf/mpdf/src/Gif/Lzw.php', + 'Mpdf\\Gradient' => __DIR__ . '/..' . '/mpdf/mpdf/src/Gradient.php', + 'Mpdf\\Hyphenator' => __DIR__ . '/..' . '/mpdf/mpdf/src/Hyphenator.php', + 'Mpdf\\Image\\Bmp' => __DIR__ . '/..' . '/mpdf/mpdf/src/Image/Bmp.php', + 'Mpdf\\Image\\ImageProcessor' => __DIR__ . '/..' . '/mpdf/mpdf/src/Image/ImageProcessor.php', + 'Mpdf\\Image\\ImageTypeGuesser' => __DIR__ . '/..' . '/mpdf/mpdf/src/Image/ImageTypeGuesser.php', + 'Mpdf\\Image\\Svg' => __DIR__ . '/..' . '/mpdf/mpdf/src/Image/Svg.php', + 'Mpdf\\Image\\Wmf' => __DIR__ . '/..' . '/mpdf/mpdf/src/Image/Wmf.php', + 'Mpdf\\Language\\LanguageToFont' => __DIR__ . '/..' . '/mpdf/mpdf/src/Language/LanguageToFont.php', + 'Mpdf\\Language\\LanguageToFontInterface' => __DIR__ . '/..' . '/mpdf/mpdf/src/Language/LanguageToFontInterface.php', + 'Mpdf\\Language\\ScriptToLanguage' => __DIR__ . '/..' . '/mpdf/mpdf/src/Language/ScriptToLanguage.php', + 'Mpdf\\Language\\ScriptToLanguageInterface' => __DIR__ . '/..' . '/mpdf/mpdf/src/Language/ScriptToLanguageInterface.php', + 'Mpdf\\Log\\Context' => __DIR__ . '/..' . '/mpdf/mpdf/src/Log/Context.php', + 'Mpdf\\Mpdf' => __DIR__ . '/..' . '/mpdf/mpdf/src/Mpdf.php', + 'Mpdf\\MpdfException' => __DIR__ . '/..' . '/mpdf/mpdf/src/MpdfException.php', + 'Mpdf\\MpdfImageException' => __DIR__ . '/..' . '/mpdf/mpdf/src/MpdfImageException.php', + 'Mpdf\\Otl' => __DIR__ . '/..' . '/mpdf/mpdf/src/Otl.php', + 'Mpdf\\OtlDump' => __DIR__ . '/..' . '/mpdf/mpdf/src/OtlDump.php', + 'Mpdf\\Output\\Destination' => __DIR__ . '/..' . '/mpdf/mpdf/src/Output/Destination.php', + 'Mpdf\\PageFormat' => __DIR__ . '/..' . '/mpdf/mpdf/src/PageFormat.php', + 'Mpdf\\Pdf\\Protection' => __DIR__ . '/..' . '/mpdf/mpdf/src/Pdf/Protection.php', + 'Mpdf\\Pdf\\Protection\\UniqidGenerator' => __DIR__ . '/..' . '/mpdf/mpdf/src/Pdf/Protection/UniqidGenerator.php', + 'Mpdf\\QrCode\\QrCode' => __DIR__ . '/..' . '/mpdf/mpdf/src/QrCode/QrCode.php', + 'Mpdf\\QrCode\\QrCodeException' => __DIR__ . '/..' . '/mpdf/mpdf/src/QrCode/QrCodeException.php', + 'Mpdf\\Shaper\\Indic' => __DIR__ . '/..' . '/mpdf/mpdf/src/Shaper/Indic.php', + 'Mpdf\\Shaper\\Myanmar' => __DIR__ . '/..' . '/mpdf/mpdf/src/Shaper/Myanmar.php', + 'Mpdf\\Shaper\\Sea' => __DIR__ . '/..' . '/mpdf/mpdf/src/Shaper/Sea.php', + 'Mpdf\\SizeConverter' => __DIR__ . '/..' . '/mpdf/mpdf/src/SizeConverter.php', + 'Mpdf\\TTFontFile' => __DIR__ . '/..' . '/mpdf/mpdf/src/TTFontFile.php', + 'Mpdf\\TTFontFileAnalysis' => __DIR__ . '/..' . '/mpdf/mpdf/src/TTFontFileAnalysis.php', + 'Mpdf\\TableOfContents' => __DIR__ . '/..' . '/mpdf/mpdf/src/TableOfContents.php', + 'Mpdf\\Tag' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag.php', + 'Mpdf\\Tag\\A' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/A.php', + 'Mpdf\\Tag\\Acronym' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Acronym.php', + 'Mpdf\\Tag\\Address' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Address.php', + 'Mpdf\\Tag\\Annotation' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Annotation.php', + 'Mpdf\\Tag\\Article' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Article.php', + 'Mpdf\\Tag\\Aside' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Aside.php', + 'Mpdf\\Tag\\B' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/B.php', + 'Mpdf\\Tag\\BarCode' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/BarCode.php', + 'Mpdf\\Tag\\Bdi' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Bdi.php', + 'Mpdf\\Tag\\Bdo' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Bdo.php', + 'Mpdf\\Tag\\Big' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Big.php', + 'Mpdf\\Tag\\BlockQuote' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/BlockQuote.php', + 'Mpdf\\Tag\\BlockTag' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/BlockTag.php', + 'Mpdf\\Tag\\Bookmark' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Bookmark.php', + 'Mpdf\\Tag\\Br' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Br.php', + 'Mpdf\\Tag\\Caption' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Caption.php', + 'Mpdf\\Tag\\Center' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Center.php', + 'Mpdf\\Tag\\Cite' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Cite.php', + 'Mpdf\\Tag\\Code' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Code.php', + 'Mpdf\\Tag\\ColumnBreak' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/ColumnBreak.php', + 'Mpdf\\Tag\\Columns' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Columns.php', + 'Mpdf\\Tag\\Dd' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Dd.php', + 'Mpdf\\Tag\\Del' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Del.php', + 'Mpdf\\Tag\\Details' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Details.php', + 'Mpdf\\Tag\\Div' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Div.php', + 'Mpdf\\Tag\\Dl' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Dl.php', + 'Mpdf\\Tag\\DotTab' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/DotTab.php', + 'Mpdf\\Tag\\Dt' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Dt.php', + 'Mpdf\\Tag\\Em' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Em.php', + 'Mpdf\\Tag\\FieldSet' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/FieldSet.php', + 'Mpdf\\Tag\\FigCaption' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/FigCaption.php', + 'Mpdf\\Tag\\Figure' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Figure.php', + 'Mpdf\\Tag\\Font' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Font.php', + 'Mpdf\\Tag\\Footer' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Footer.php', + 'Mpdf\\Tag\\Form' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Form.php', + 'Mpdf\\Tag\\FormFeed' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/FormFeed.php', + 'Mpdf\\Tag\\H1' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/H1.php', + 'Mpdf\\Tag\\H2' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/H2.php', + 'Mpdf\\Tag\\H3' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/H3.php', + 'Mpdf\\Tag\\H4' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/H4.php', + 'Mpdf\\Tag\\H5' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/H5.php', + 'Mpdf\\Tag\\H6' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/H6.php', + 'Mpdf\\Tag\\HGroup' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/HGroup.php', + 'Mpdf\\Tag\\Header' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Header.php', + 'Mpdf\\Tag\\Hr' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Hr.php', + 'Mpdf\\Tag\\I' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/I.php', + 'Mpdf\\Tag\\Img' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Img.php', + 'Mpdf\\Tag\\IndexEntry' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/IndexEntry.php', + 'Mpdf\\Tag\\IndexInsert' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/IndexInsert.php', + 'Mpdf\\Tag\\InlineTag' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/InlineTag.php', + 'Mpdf\\Tag\\Input' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Input.php', + 'Mpdf\\Tag\\Ins' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Ins.php', + 'Mpdf\\Tag\\Kbd' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Kbd.php', + 'Mpdf\\Tag\\Legend' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Legend.php', + 'Mpdf\\Tag\\Li' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Li.php', + 'Mpdf\\Tag\\Main' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Main.php', + 'Mpdf\\Tag\\Mark' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Mark.php', + 'Mpdf\\Tag\\Meter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Meter.php', + 'Mpdf\\Tag\\Nav' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Nav.php', + 'Mpdf\\Tag\\NewColumn' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/NewColumn.php', + 'Mpdf\\Tag\\NewPage' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/NewPage.php', + 'Mpdf\\Tag\\Ol' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Ol.php', + 'Mpdf\\Tag\\Option' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Option.php', + 'Mpdf\\Tag\\P' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/P.php', + 'Mpdf\\Tag\\PageBreak' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/PageBreak.php', + 'Mpdf\\Tag\\PageFooter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/PageFooter.php', + 'Mpdf\\Tag\\PageHeader' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/PageHeader.php', + 'Mpdf\\Tag\\Pre' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Pre.php', + 'Mpdf\\Tag\\Progress' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Progress.php', + 'Mpdf\\Tag\\Q' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Q.php', + 'Mpdf\\Tag\\S' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/S.php', + 'Mpdf\\Tag\\Samp' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Samp.php', + 'Mpdf\\Tag\\Section' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Section.php', + 'Mpdf\\Tag\\Select' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Select.php', + 'Mpdf\\Tag\\SetHtmlPageFooter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/SetHtmlPageFooter.php', + 'Mpdf\\Tag\\SetHtmlPageHeader' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/SetHtmlPageHeader.php', + 'Mpdf\\Tag\\SetPageFooter' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/SetPageFooter.php', + 'Mpdf\\Tag\\SetPageHeader' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/SetPageHeader.php', + 'Mpdf\\Tag\\Small' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Small.php', + 'Mpdf\\Tag\\Span' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Span.php', + 'Mpdf\\Tag\\Strike' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Strike.php', + 'Mpdf\\Tag\\Strong' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Strong.php', + 'Mpdf\\Tag\\Sub' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Sub.php', + 'Mpdf\\Tag\\SubstituteTag' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/SubstituteTag.php', + 'Mpdf\\Tag\\Summary' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Summary.php', + 'Mpdf\\Tag\\Sup' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Sup.php', + 'Mpdf\\Tag\\TBody' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/TBody.php', + 'Mpdf\\Tag\\TFoot' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/TFoot.php', + 'Mpdf\\Tag\\THead' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/THead.php', + 'Mpdf\\Tag\\Table' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Table.php', + 'Mpdf\\Tag\\Tag' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Tag.php', + 'Mpdf\\Tag\\Td' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Td.php', + 'Mpdf\\Tag\\TextArea' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/TextArea.php', + 'Mpdf\\Tag\\TextCircle' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/TextCircle.php', + 'Mpdf\\Tag\\Th' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Th.php', + 'Mpdf\\Tag\\Time' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Time.php', + 'Mpdf\\Tag\\Toc' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Toc.php', + 'Mpdf\\Tag\\TocEntry' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/TocEntry.php', + 'Mpdf\\Tag\\TocPageBreak' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/TocPageBreak.php', + 'Mpdf\\Tag\\Tr' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Tr.php', + 'Mpdf\\Tag\\Tt' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Tt.php', + 'Mpdf\\Tag\\Tta' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Tta.php', + 'Mpdf\\Tag\\Tts' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Tts.php', + 'Mpdf\\Tag\\Ttz' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Ttz.php', + 'Mpdf\\Tag\\U' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/U.php', + 'Mpdf\\Tag\\Ul' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/Ul.php', + 'Mpdf\\Tag\\VarTag' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/VarTag.php', + 'Mpdf\\Tag\\WatermarkImage' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/WatermarkImage.php', + 'Mpdf\\Tag\\WatermarkText' => __DIR__ . '/..' . '/mpdf/mpdf/src/Tag/WatermarkText.php', + 'Mpdf\\Ucdn' => __DIR__ . '/..' . '/mpdf/mpdf/src/Ucdn.php', + 'Mpdf\\Utils\\Arrays' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/Arrays.php', + 'Mpdf\\Utils\\NumericString' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/NumericString.php', + 'Mpdf\\Utils\\PdfDate' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/PdfDate.php', + 'Mpdf\\Utils\\UtfString' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/UtfString.php', + 'PandoraFMS\\User' => __DIR__ . '/../..' . '/include/lib/User.php', + 'PandoraFMS\\WebSockets\\WSManager' => __DIR__ . '/../..' . '/include/lib/WSManager.php', + 'PandoraFMS\\Websockets\\WebSocketServer' => __DIR__ . '/../..' . '/include/lib/WebSocketServer.php', + 'PandoraFMS\\Websockets\\WebSocketUser' => __DIR__ . '/../..' . '/include/lib/WebSocketUser.php', + 'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php', + 'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php', + 'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/Psr/Log/LogLevel.php', + 'Psr\\Log\\LoggerAwareInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerAwareInterface.php', + 'Psr\\Log\\LoggerAwareTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerAwareTrait.php', + 'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php', + 'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php', + 'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php', + 'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', 'fpdi_pdf_parser' => __DIR__ . '/..' . '/setasign/fpdi/fpdi_pdf_parser.php', 'pdf_context' => __DIR__ . '/..' . '/setasign/fpdi/pdf_context.php', ); diff --git a/pandora_console/ws.php b/pandora_console/ws.php new file mode 100644 index 0000000000..5eebe58aad --- /dev/null +++ b/pandora_console/ws.php @@ -0,0 +1,159 @@ +> '.__DIR__.'/pandora_console.log 2>&1 &'; + shell_exec($cmd); + + // Launch gotty - telnet. + $cmd = $base_cmd.' --port '.$config['gotty_telnet_port']; + $cmd .= ' telnet >> '.__DIR__.'/pandora_console.log 2>&1 &'; + shell_exec($cmd); + } +} + +// Start Web SocketProxy. +$ws = new WSManager( + // Bind address. + $config['ws_bind_address'], + // Bind port. + $config['ws_port'], + // Connected handlers. + ['gotty' => 'proxyConnected'], + // Process handlers. + [], + // ProcessRaw handlers. + ['gotty' => 'proxyProcessRaw'], + // Tick handlers. + [], + $bufferSize, + $debug +); + +try { + $ws->run(); +} catch (Exception $e) { + $ws->stdout($e->getMessage()); +} diff --git a/pandora_server/DEBIAN/control b/pandora_server/DEBIAN/control index abf754152f..69b27f4f9a 100644 --- a/pandora_server/DEBIAN/control +++ b/pandora_server/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-server -Version: 7.0NG.740 +Version: 7.0NG.740-191029 Architecture: all Priority: optional Section: admin diff --git a/pandora_server/DEBIAN/make_deb_package.sh b/pandora_server/DEBIAN/make_deb_package.sh index 09c0862203..34f150ed54 100644 --- a/pandora_server/DEBIAN/make_deb_package.sh +++ b/pandora_server/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.740" +pandora_version="7.0NG.740-191029" package_cpan=0 package_pandora=1 diff --git a/pandora_server/FreeBSD/pandora_server.conf.new b/pandora_server/FreeBSD/pandora_server.conf.new index 93d9abbc75..01ff859fa5 100644 --- a/pandora_server/FreeBSD/pandora_server.conf.new +++ b/pandora_server/FreeBSD/pandora_server.conf.new @@ -348,6 +348,15 @@ self_monitoring 1 # Self monitoring interval (in seconds). self_monitoring_interval 300 +# Pandora Sample Agent. If enabled, every 10 minutes, this embedded agent +# will make sample data. Disabled by default. + +sample_agent 0 + +# Pandora Sample Agent interval (in seconds). + +sample_agent_interval 600 + # Update parent from the agent xml #update_parent 1 diff --git a/pandora_server/NetBSD/pandora_server.conf.new b/pandora_server/NetBSD/pandora_server.conf.new index 5f38a678da..66743aee36 100644 --- a/pandora_server/NetBSD/pandora_server.conf.new +++ b/pandora_server/NetBSD/pandora_server.conf.new @@ -340,6 +340,15 @@ restart_delay 60 self_monitoring 1 +# Pandora Sample Agent. If enabled, every 10 minutes, this embedded agent +# will make sample data. Disabled by default. + +sample_agent 0 + +# Pandora Sample Agent interval (in seconds). + +sample_agent_interval 600 + # Update parent from the agent xml #update_parent 1 diff --git a/pandora_server/bin/pandora_server b/pandora_server/bin/pandora_server index a367eb7bca..1ce3e3da5e 100755 --- a/pandora_server/bin/pandora_server +++ b/pandora_server/bin/pandora_server @@ -382,6 +382,16 @@ sub pandora_server_tasks ($) { pandora_self_monitoring ($pa_config, $dbh); } + # Pandora sample agent + if (defined($pa_config->{'sample_agent'})) { + if ($pa_config->{'sample_agent'} == 1 + && !is_metaconsole($pa_config) + && $counter % $pa_config->{'sample_agent_interval'} == 0){ + pandora_sample_agent ($pa_config); + } + pandora_update_config_token ($dbh, 'sample_agent', $pa_config->{'sample_agent'}); + } + # Avoid counter overflow if ($counter >= ~0){ $counter = 0; diff --git a/pandora_server/conf/pandora_server.conf.new b/pandora_server/conf/pandora_server.conf.new index 1b76b1cf66..a5896e6050 100644 --- a/pandora_server/conf/pandora_server.conf.new +++ b/pandora_server/conf/pandora_server.conf.new @@ -376,6 +376,15 @@ self_monitoring 1 # Self monitoring interval (in seconds). self_monitoring_interval 300 +# Pandora Sample Agent. If enabled, every 10 minutes, this embedded agent +# will make sample data. Disabled by default. + +sample_agent 0 + +# Pandora Sample Agent interval (in seconds). + +sample_agent_interval 600 + # Update parent from the agent xml #update_parent 1 diff --git a/pandora_server/conf/pandora_server.conf.windows b/pandora_server/conf/pandora_server.conf.windows index c7c5db64b4..a7232e459c 100644 --- a/pandora_server/conf/pandora_server.conf.windows +++ b/pandora_server/conf/pandora_server.conf.windows @@ -330,6 +330,15 @@ restart_delay 60 # Self monitoring interval (in seconds). #self_monitoring_interval 300 +# Pandora Sample Agent. If enabled, every 10 minutes, this embedded agent +# will make sample data. Disabled by default. + +sample_agent 0 + +# Pandora Sample Agent interval (in seconds). + +sample_agent_interval 600 + # Update parent from the agent xml #update_parent 1 diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 4e1472fbff..159990b9d6 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -45,7 +45,7 @@ our @EXPORT = qw( # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.740"; -my $pandora_build = "191028"; +my $pandora_build = "191029"; our $VERSION = $pandora_version." ".$pandora_build; # Setup hash @@ -79,7 +79,7 @@ sub help_screen { sub pandora_init { my $pa_config = $_[0]; my $init_string = $_[1]; - print "\n$init_string $pandora_version Build $pandora_build Copyright (c) 2004-2018 " . pandora_get_initial_copyright_notice() . "\n"; + print "\n$init_string $pandora_version Build $pandora_build Copyright (c) 2004-20".substr($pandora_build,0,2)." " . pandora_get_initial_copyright_notice() . "\n"; print "This program is OpenSource, licensed under the terms of GPL License version 2.\n"; print "You can download latest versions and documentation at official web page.\n\n"; @@ -398,6 +398,12 @@ sub pandora_load_config { # Self monitoring interval $pa_config->{'self_monitoring_interval'} = 300; # 5.1SP1 + # Sample Agent + $pa_config->{'sample_agent'} = 0; + + # Sample agent interval + $pa_config->{'sample_agent_interval'} = 600; + # Process XML data files as a stack $pa_config->{"dataserver_lifo"} = 0; # 5.0 @@ -950,6 +956,12 @@ sub pandora_load_config { elsif ($parametro =~ m/^self_monitoring_interval\s+([0-9]*)/i) { $pa_config->{'self_monitoring_interval'} = clean_blank($1); } + elsif ($parametro =~ m/^sample_agent\s+([0-1])/i) { + $pa_config->{'sample_agent'} = clean_blank($1); + } + elsif ($parametro =~ m/^sample_agent_interval\s+([0-9]*)/i) { + $pa_config->{'sample_agent_interval'} = clean_blank($1); + } elsif ($parametro =~ m/^update_parent\s+([0-1])/i) { $pa_config->{'update_parent'} = clean_blank($1); } diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 09ef9d7878..2cfb8a056b 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -100,6 +100,8 @@ Exported Functions: =item * C +=item * C + =back =head1 METHODS @@ -122,6 +124,7 @@ use threads::shared; use JSON qw(decode_json encode_json); use MIME::Base64; use Text::ParseWords; +use Math::Trig; # Math functions # Debugging #use Data::Dumper; @@ -248,6 +251,7 @@ our @EXPORT = qw( pandora_group_statistics pandora_server_statistics pandora_self_monitoring + pandora_sample_agent pandora_process_policy_queue subst_alert_macros subst_column_macros @@ -5236,6 +5240,83 @@ sub pandora_self_monitoring ($$) { print XMLFILE $xml_output; close (XMLFILE); } +########################################################################## +=head2 C<< xml_module_template (I<$module_name>, I<$module_type>, I<$module_data>) >> + +Module template for sample agent + +=cut +########################################################################## +sub xml_module_template ($$$) { + my ($module_name, $module_type, $module_data) = @_; + my $output = "\n"; + + $module_name = "" if $module_name =~ /[\s+.]+/; + $module_data = "" if $module_data =~ /[\s+.]+/; + + $output .= "\t".$module_name."\n"; + $output .= "\t".$module_type."\n"; + $output .= "\t".$module_data."\n"; + $output .= "\n"; + + return $output; +} +########################################################################## +=head2 C<< pandora_sample_agent (I<$pa_config>) >> + +Pandora agent for make sample data + +=cut +########################################################################## +sub pandora_sample_agent ($) { + + my ($pa_config) = @_; + + my $utimestamp = time (); + my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime()); + # First line + my $xml_output = "\n"; + # Header + $xml_output = "\n"; + # Boolean ever return TRUE + $xml_output .= xml_module_template ("Boolean ever true", "generic_proc","1"); + # Boolean return TRUE at 80% of times + my $sample_boolean_mostly_true = 1; + $sample_boolean_mostly_true = 0 if rand(9) > 7; + $xml_output .= xml_module_template ("Boolean mostly true", "generic_proc",$sample_boolean_mostly_true); + # Boolean return false at 80% of times + my $sample_boolean_mostly_false = 0; + $sample_boolean_mostly_false = 1 if rand(9) > 7; + $xml_output .= xml_module_template ("Boolean mostly false", "generic_proc", $sample_boolean_mostly_false); + # Boolean ever return FALSE + $xml_output .= xml_module_template ("Boolean ever false", "generic_proc","0"); + # Random integer between 0 and 100 + $xml_output .= xml_module_template ("Random integer values", "generic_data",int(rand(100))); + # Random values obtained with sinusoidal curves between 0 and 100 values + my $b = 1; + my $sample_serie_curve = 1 + cos(deg2rad($b)); + $b = $b + rand(20)/10; + $b = 0 if ($b > 180); + $sample_serie_curve = $sample_serie_curve * $b * 10; + $sample_serie_curve =~ s/\,/\./g; + $xml_output .= xml_module_template ("Random serie curve", "generic_data", $sample_serie_curve); + # String with 10 random characters + my $sample_random_text = ""; + my @characters = ('a'..'z','A'..'Z'); + for (1...10){ + $sample_random_text .= $characters[int(rand(@characters))]; + } + $xml_output .= xml_module_template ("Random text", "generic_data_string", $sample_random_text); + # End of xml + $xml_output .= ""; + # File path definition + my $filename = $pa_config->{"incomingdir"}."/".$pa_config->{'servername'}.".sample.".$utimestamp.".data"; + # Opening, Writing and closing of XML + open (my $xmlfile, ">", $filename) or die "[FATAL] Could not open sample XML file for deploying monitorization at '$filename'"; + print $xmlfile $xml_output; + close ($xmlfile); + +} ########################################################################## =head2 C<< set_master (I<$pa_config>, I<$dbh>) >> diff --git a/pandora_server/lib/PandoraFMS/PluginTools.pm b/pandora_server/lib/PandoraFMS/PluginTools.pm index 707243398a..287b11e900 100644 --- a/pandora_server/lib/PandoraFMS/PluginTools.pm +++ b/pandora_server/lib/PandoraFMS/PluginTools.pm @@ -32,7 +32,7 @@ our @ISA = qw(Exporter); # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.740"; -my $pandora_build = "191028"; +my $pandora_build = "191029"; our $VERSION = $pandora_version." ".$pandora_build; our %EXPORT_TAGS = ( 'all' => [ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 5d9aa0c75c..805efb4c41 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.740 -%define release 1 +%define release 191029 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 80e9f80d29..e2eb323b24 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.740 -%define release 1 +%define release 191029 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 6f524cc715..6b1870fadf 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.740" -PI_BUILD="191028" +PI_BUILD="191029" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 4017ec63bf..a9cc09579b 100644 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -34,7 +34,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.740 PS191028"; +my $version = "7.0NG.740 PS191029"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index cfaa9d8f41..a3ffd61ecb 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.740 PS191028"; +my $version = "7.0NG.740 PS191029"; # save program name for logging my $progname = basename($0); @@ -5895,9 +5895,16 @@ sub cli_stop_downtime () { exist_check($downtime_id,'planned downtime',$downtime_id); my $current_time = time; - my $downtime_date_to = get_db_value ($dbh, 'SELECT date_to FROM tplanned_downtime WHERE id=?', $downtime_id); - if($current_time >= $downtime_date_to) { + my $data = get_db_single_row ($dbh, 'SELECT date_to, type_execution, executed FROM tplanned_downtime WHERE id=?', $downtime_id); + + if( $data->{'type_execution'} eq 'periodically' && $data->{'executed'} == 1){ + print_log "[ERROR] Planned_downtime '$downtime_name' cannot be stopped.\n"; + print_log "[INFO] Periodical and running planned downtime cannot be stopped.\n\n"; + exit; + } + + if($current_time >= $data->{'date_to'}) { print_log "[INFO] Planned_downtime '$downtime_name' is already stopped\n\n"; exit; }
    '.$parameters['caption'].'