diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 12c86842bb..5cca3bfc08 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.760-220308 +Version: 7.0NG.760-220323 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 db3dac0ba8..1cd4bb6a44 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.760-220308" +pandora_version="7.0NG.760-220323" 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 031891f6f7..1fb038bd67 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1015,7 +1015,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.760'; -use constant AGENT_BUILD => '220308'; +use constant AGENT_BUILD => '220323'; # 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 c139325a33..c4e7643283 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.760 -%define release 220308 +%define release 220323 Summary: Pandora FMS Linux agent, PERL version Name: %{name} @@ -24,7 +24,7 @@ Requires(preun): chkconfig /bin/rm /usr/sbin/userdel Requires: coreutils unzip Requires: util-linux procps grep Requires: /sbin/ip /bin/awk -Requires: perl perl(Sys::Syslog) perl(IO::Compress::Zip) +Requires: perl(Sys::Syslog) perl(IO::Compress::Zip) # Required by plugins #Requires: sh-utils sed passwd net-tools rpm AutoReq: 0 diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 5a86e5fde6..c82c54a8b8 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.760 -%define release 220308 +%define release 220323 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 b56b236a58..5ad8783635 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.760" -PI_BUILD="220308" +PI_BUILD="220323" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index d0a547543d..2562c227cd 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{220308} +{220323} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 9ae0dc6643..ac0d6ecf37 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.760 Build 220308") +#define PANDORA_VERSION ("7.0NG.760 Build 220323") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index e3dc078a25..31e8d991b3 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.760(Build 220308))" + VALUE "ProductVersion", "(7.0NG.760(Build 220323))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 3166e9ae22..f6becafe45 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.760-220308 +Version: 7.0NG.760-220323 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 cf5d20c7fb..5ad1d08da0 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.760-220308" +pandora_version="7.0NG.760-220323" package_pear=0 package_pandora=1 diff --git a/pandora_console/extensions/dbmanager.php b/pandora_console/extensions/dbmanager.php index fbe3d7cb47..8c248367dc 100644 --- a/pandora_console/extensions/dbmanager.php +++ b/pandora_console/extensions/dbmanager.php @@ -11,6 +11,9 @@ // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. +use PandoraFMS\Enterprise\Metaconsole\Node; + + function dbmanager_query($sql, &$error, $dbconnection) { global $config; @@ -88,6 +91,10 @@ function dbmgr_extension_main() global $config; + if (is_metaconsole() === true) { + open_meta_frame(); + } + if (!is_user_admin($config['id_user'])) { db_pandora_audit( AUDIT_LOG_ACL_VIOLATION, @@ -98,11 +105,59 @@ function dbmgr_extension_main() } $sql = (string) get_parameter('sql'); + $node_id = (int) get_parameter('node_id', -1); ui_print_page_header(__('Database interface'), 'images/gm_db.png', false, false, true); - echo '
'; - echo __( + if (is_metaconsole() === true) { + $img = '../../images/warning_modern.png'; + } else { + $img = 'images/warning_modern.png'; + } + + $msg = '
'.html_print_image( + $img, + true + ); + $msg .= '
'.__( + 'Warning, you are accessing the database directly. You can leave the system inoperative if you run an inappropriate SQL statement' + ).'
'; + + $warning_message = ''; + + if (empty($sql) === true) { + echo $warning_message; + } + + echo "
"; + + $table = new stdClass(); + $table->id = 'db_interface'; + $table->class = 'databox'; + $table->width = '100%'; + $table->data = []; + $table->head = []; + $table->colspan = []; + $table->rowstyle = []; + + $table->colspan[0][0] = 2; + $table->colspan[1][0] = 2; + $table->rowspan[2][0] = 3; + + $table->rowclass[0] = 'notify'; + $table->rowclass[3] = 'pdd_5px'; + $table->rowclass[3] = 'flex-content-right'; + $table->rowclass[4] = 'flex-content-right'; + + $data[0][0] = __( "This is an advanced extension to interface with %s database directly from WEB console using native SQL sentences. Please note that you can damage your %s installation if you don't know exactly what are you are doing, @@ -113,19 +168,59 @@ function dbmgr_extension_main() get_product_name(), get_product_name() ); - echo '
'; - echo '
'; - echo "Some samples of usage:
SHOW STATUS;
DESCRIBE tagente
SELECT * FROM tserver
UPDATE tagente SET id_grupo = 15 WHERE nombre LIKE '%194.179%'
"; + $data[1][0] = "Some samples of usage:
SHOW STATUS;
DESCRIBE tagente
SELECT * FROM tserver
UPDATE tagente SET id_grupo = 15 WHERE nombre LIKE '%194.179%'
"; - echo '

'; - echo ""; - html_print_textarea('sql', 5, 50, html_entity_decode($sql, ENT_QUOTES)); - echo '
'; - echo '
'; - echo '
'; - html_print_submit_button(__('Execute SQL'), '', false, 'class="sub next"'); - echo '
'; + \enterprise_include_once('include/functions_metaconsole.php'); + $servers = \metaconsole_get_servers(); + if (is_array($servers) === true) { + $servers = array_reduce( + $servers, + function ($carry, $item) { + $carry[$item['id']] = $item['server_name']; + return $carry; + } + ); + } else { + $servers = []; + } + + $data[2][0] = html_print_textarea( + 'sql', + 5, + 50, + html_entity_decode($sql, ENT_QUOTES), + '', + true + ); + + if (is_metaconsole() === true) { + $data[3][2] = html_print_input( + [ + 'name' => 'node_id', + 'type' => 'select', + 'fields' => $servers, + 'selected' => $node_id, + 'nothing' => __('This metaconsole'), + 'nothing_value' => -1, + 'return' => true, + 'label' => _('Select query target'), + ] + ); + } + + $data[4][2] = '
'; + $data[4][2] .= html_print_submit_button( + __('Execute SQL'), + '', + false, + 'class="sub next"', + true + ); + $data[4][2] .= '
'; + + $table->data = $data; + html_print_table($table); echo ''; // Processing SQL Code @@ -137,10 +232,29 @@ function dbmgr_extension_main() echo '
'; echo '
'; - $dbconnection = $config['dbconnection']; - $error = ''; - - $result = dbmanager_query($sql, $error, $dbconnection); + try { + if (\is_metaconsole() === true && $node_id !== -1) { + $node = new Node($node_id); + $dbconnection = @get_dbconnection( + [ + 'dbhost' => $node->dbhost(), + 'dbport' => $node->dbport(), + 'dbname' => $node->dbname(), + 'dbuser' => $node->dbuser(), + 'dbpass' => $node->dbpass(), + ] + ); + $error = ''; + $result = dbmanager_query($sql, $error, $dbconnection); + } else { + $dbconnection = $config['dbconnection']; + $error = ''; + $result = dbmanager_query($sql, $error, $dbconnection); + } + } catch (\Exception $e) { + $error = __('Error querying database node'); + $result = false; + } if ($result === false) { echo 'An error has occured when querying the database.
'; @@ -181,9 +295,29 @@ function dbmgr_extension_main() html_print_table($table); echo ''; + + if (is_metaconsole()) { + close_meta_frame(); + } + } +if (is_metaconsole() === true) { + // This adds a option in the operation menu. + extensions_add_meta_menu_option( + 'DB interface', + 'PM', + 'gextensions', + 'database.png', + 'v1r1', + 'gdbman' + ); + + extensions_add_meta_function('dbmgr_extension_main'); +} else { +} + // This adds a option in the operation menu extensions_add_godmode_menu_option(__('DB interface'), 'PM', 'gextensions', 'dbmanager/icon.png', 'v1r1', 'gdbman'); diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index 9cbab3b020..f7e065e3b0 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -119,4 +119,8 @@ godmode/admin_access_logs.php enterprise/extensions/backup/main.php enterprise/extensions/backup.php mobile/include/javascript/jquery.mobile-1.4.5.js -mobile/include/style/jquery.mobile-1.4.5.css \ No newline at end of file +mobile/include/style/jquery.mobile-1.4.5.css +enterprise/extensions/backup/backup.js +enterprise/extensions/backup/sql/backup.sql +enterprise/extensions/backup/sql/backup.oracle.sql +enterprise/extensions/backup/sql/backup.postgreSQL.sql \ No newline at end of file diff --git a/pandora_console/extras/mr/53.sql b/pandora_console/extras/mr/53.sql new file mode 100644 index 0000000000..dfb7976a91 --- /dev/null +++ b/pandora_console/extras/mr/53.sql @@ -0,0 +1,19 @@ +START TRANSACTION; + +ALTER TABLE `tipam_vlan` ADD COLUMN `custom_id` bigint(20) unsigned DEFAULT NULL; + +UPDATE `tuser_task` SET `parameters` = 'a:3:{i:0;a:2:{s:11:"description";s:11:"Description";s:4:"type";s:4:"text";}i:1;a:3:{s:11:"description";s:20:"Save to disk in path";s:4:"type";s:6:"string";s:13:"default_value";s:21:"_%_ATTACHMENT_PATH_%_";}i:2;a:3:{s:11:"description";s:14:"Active backups";s:4:"type";s:6:"number";s:13:"default_value";i:3;}}' WHERE `function_name` = 'cron_task_do_backup'; + +CREATE TABLE IF NOT EXISTS `tbackup` ( + `id` SERIAL, + `utimestamp` BIGINT DEFAULT 0, + `filename` VARCHAR(512) DEFAULT '', + `id_user` VARCHAR(60) DEFAULT '', + `description` MEDIUMTEXT, + `pid` INT UNSIGNED DEFAULT 0, + `filepath` VARCHAR(512) DEFAULT '', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; + + +COMMIT; diff --git a/pandora_console/general/header.php b/pandora_console/general/header.php index 3c82f32566..9b0333c55a 100644 --- a/pandora_console/general/header.php +++ b/pandora_console/general/header.php @@ -36,30 +36,32 @@ echo sprintf('
', $menuTypeClass); ).'
'; // ======= Servers List =============================================== - $servers_list = '
'; - $servers = []; - $servers['all'] = (int) db_get_value('COUNT(id_server)', 'tserver'); - if ($servers['all'] != 0) { - $servers['up'] = (int) servers_check_status(); - $servers['down'] = ($servers['all'] - $servers['up']); - if ($servers['up'] == 0) { - // All Servers down or no servers at all. - $servers_check_img = html_print_image('images/header_down_gray.png', true, ['alt' => 'cross', 'class' => 'bot', 'title' => __('All systems').': '.__('Down')]); - } else if ($servers['down'] != 0) { - // Some servers down. - $servers_check_img = html_print_image('images/header_warning_gray.png', true, ['alt' => 'error', 'class' => 'bot', 'title' => $servers['down'].' '.__('servers down')]); - } else { - // All servers up. - $servers_check_img = html_print_image('images/header_ready_gray.png', true, ['alt' => 'ok', 'class' => 'bot', 'title' => __('All systems').': '.__('Ready')]); - } + if ((bool) check_acl($config['id_user'], 0, 'AW') !== false) { + $servers_list = '
'; + $servers = []; + $servers['all'] = (int) db_get_value('COUNT(id_server)', 'tserver'); + if ($servers['all'] != 0) { + $servers['up'] = (int) servers_check_status(); + $servers['down'] = ($servers['all'] - $servers['up']); + if ($servers['up'] == 0) { + // All Servers down or no servers at all. + $servers_check_img = html_print_image('images/header_down_gray.png', true, ['alt' => 'cross', 'class' => 'bot', 'title' => __('All systems').': '.__('Down')]); + } else if ($servers['down'] != 0) { + // Some servers down. + $servers_check_img = html_print_image('images/header_warning_gray.png', true, ['alt' => 'error', 'class' => 'bot', 'title' => $servers['down'].' '.__('servers down')]); + } else { + // All servers up. + $servers_check_img = html_print_image('images/header_ready_gray.png', true, ['alt' => 'ok', 'class' => 'bot', 'title' => __('All systems').': '.__('Ready')]); + } - unset($servers); - // Since this is the header, we don't like to trickle down variables. - $servers_check_img_link = ''; - $servers_check_img_link .= $servers_check_img; - $servers_check_img_link .= ''; - }; - $servers_list .= $servers_check_img_link.'
'; + unset($servers); + // Since this is the header, we don't like to trickle down variables. + $servers_check_img_link = ''; + $servers_check_img_link .= $servers_check_img; + $servers_check_img_link .= ''; + }; + $servers_list .= $servers_check_img_link.'
'; + } diff --git a/pandora_console/general/main_menu.php b/pandora_console/general/main_menu.php index 8ed74c4cbd..f0b75c51a5 100644 --- a/pandora_console/general/main_menu.php +++ b/pandora_console/general/main_menu.php @@ -39,7 +39,7 @@ $(document).ready(function(){ var menuType_value = ""; if (menuType_value === '' || menuType_value === 'classic') { - $('ul.submenu').css('left', '214px'); + $('ul.submenu').css('left', '214px'); } else{ $('ul.submenu').css('left', '59px'); @@ -107,7 +107,12 @@ echo ''; require 'operation/menu.php'; require 'godmode/menu.php'; -echo sprintf('
', $menuTypeClass); +html_print_div( + [ + 'id' => 'button_collapse', + 'class' => sprintf('button_collapse button_%s', $menuTypeClass), + ] +); echo ''; // Menu_container. @@ -122,7 +127,7 @@ if (isset($config['fixed_header']) === true) { diff --git a/pandora_console/godmode/agentes/agent_manager.php b/pandora_console/godmode/agentes/agent_manager.php index 2076d50975..d1246b298c 100644 --- a/pandora_console/godmode/agentes/agent_manager.php +++ b/pandora_console/godmode/agentes/agent_manager.php @@ -191,7 +191,7 @@ if ($disk_conf_delete) { @unlink($filename['conf']); } -echo '
'; +echo ''; // Custom ID. $custom_id_div = '
'; @@ -452,123 +452,14 @@ if (!$new_agent && $alias != '') { echo '
'; if (enterprise_installed()) { - $secondary_groups_selected = enterprise_hook('agents_get_secondary_groups', [$id_agente]); - $adv_secondary_groups_label = '

'.__('Secondary groups').'

'; - $adv_secondary_groups_left = html_print_select_groups( - // Id_user. - // Use the current user to select the groups. - false, - // Privilege. - // ACL permission. - 'AR', - // ReturnAllGroup. - // Not all group. - false, - // Name. - // HTML id. - 'secondary_groups', - // Selected. - // No select any by default. - '', - // Script. - // Javascript onChange code. - '', - // Nothing. - // Do not user no selected value. - false, - // Nothing_value. - // Do not use no selected value. - 0, - // Return. - // Return HTML (not echo). - true, - // Multiple. - // Multiple selection. - true, - // Sort. - // Sorting by default. - true, - // Class. - // CSS classnames (default). - '', - // Disabled. - // Not disabled (default). - false, - // Style. - // Inline styles (default). - 'min-width:170px;', - // Option_style. - // Option style select (default). - false, - // Id_group. - // Do not truncate the users tree (default). - false, - // Keys_field. - // Key to get as value (default). - 'id_grupo', - // Strict_user. - // Not strict user (default). - false, - // Delete_groups. - // Do not show the primary group in this selection. - array_merge( - (empty($secondary_groups_selected['plain']) === false) ? $secondary_groups_selected['plain'] : [], - [$agent['id_grupo']] - ) - // Include_groups. - // Size. - // Simple_multiple_options. - ); - - $adv_secondary_groups_arrows = html_print_input_image( - 'add_secondary', - 'images/darrowright_green.png', - 1, - '', - true, - [ - 'id' => 'right_autorefreshlist', - 'title' => __('Add secondary groups'), - 'onclick' => 'agent_manager_add_secondary_groups(event, '.$id_agente.');', - ] - ).html_print_input_image( - 'remove_secondary', - 'images/darrowleft_green.png', - 1, - '', - true, - [ - 'id' => 'left_autorefreshlist', - 'title' => __('Remove secondary groups'), - 'onclick' => 'agent_manager_remove_secondary_groups(event, '.$id_agente.');', - ] - ); - - $adv_secondary_groups_right .= html_print_select( - // Values. - $secondary_groups_selected['for_select'], - // HTML id. - 'secondary_groups_selected', - // Selected. - '', - // Javascript onChange code. - '', - // Nothing selected. - false, - // Nothing selected. - 0, - // Return HTML (not echo). - true, - // Multiple selection. - true, - // Sort. - true, - // Class. - '', - // Disabled. - false, - // Style. - 'min-width:170px;' + $adv_secondary_groups_label = '
'; + $adv_secondary_groups_label .= '

'; + $adv_secondary_groups_label .= __('Secondary groups'); + $adv_secondary_groups_label .= '

'; + $adv_secondary_groups_label .= '
'; + $select_agent_secondary = html_print_select_agent_secondary( + $agent, + $id_agente ); // Safe operation mode. @@ -824,19 +715,15 @@ if (enterprise_installed()) { } // General display distribution. -$table_adv_options = $advanced_div.$adv_secondary_groups_label.' -
- '.$adv_secondary_groups_left.' -
-
- '.$adv_secondary_groups_arrows.' -
-
- '.$adv_secondary_groups_right.' -
- -
- '.$table_adv_parent.$table_adv_module_mode.$table_adv_cascade; +$table_adv_options = $advanced_div; +$table_adv_options .= $adv_secondary_groups_label; +$table_adv_options .= $select_agent_secondary; +$table_adv_options .= '
'; + +$table_adv_options .= '
'; +$table_adv_options .= $table_adv_parent; +$table_adv_options .= $table_adv_module_mode; +$table_adv_options .= $table_adv_cascade; if ($new_agent) { // If agent is new, show custom id as old style format. @@ -1113,133 +1000,6 @@ ui_require_jquery_file('bgiframe'); } } - function agent_manager_add_secondary_groups (event, id_agent) { - event.preventDefault(); - var primary_value = $("#grupo").val() - // The selected primary value cannot be selected like secondary - if ($("#secondary_groups option:selected[value=" + primary_value + "]").length > 0) { - alert("") - return - } - - // On agent creation PHP will update the secondary groups table (not via AJAX) - if (id_agent == 0) { - agent_manager_add_secondary_groups_ui(); - agent_manager_update_hidden_input_secondary(); - return; - } - - var selected_items = new Array(); - $("#secondary_groups option:selected").each(function(){ - selected_items.push($(this).val()) - }) - - var data = { - page: "godmode/agentes/agent_manager", - id_agent: id_agent, - groups: selected_items, - add_secondary_groups: 1, - } - - // Make the AJAX call to update the secondary groups - $.ajax({ - type: "POST", - url: "ajax.php", - dataType: "html", - data: data, - success: function (data) { - if (data == 1) { - agent_manager_add_secondary_groups_ui(); - } else { - console.error("Error in AJAX call to add secondary groups") - } - }, - error: function (data) { - console.error("Fatal error in AJAX call to add secondary groups") - } - }); - } - - function agent_manager_remove_secondary_groups (event, id_agent) { - event.preventDefault(); - - // On agent creation PHP will update the secondary groups table (not via AJAX) - if (id_agent == 0) { - agent_manager_remove_secondary_groups_ui(); - agent_manager_update_hidden_input_secondary(); - return; - } - - var selected_items = new Array(); - $("#secondary_groups_selected option:selected").each(function(){ - selected_items.push($(this).val()) - }) - - var data = { - page: "godmode/agentes/agent_manager", - id_agent: id_agent, - groups: selected_items, - remove_secondary_groups: 1, - } - - // Make the AJAX call to update the secondary groups - $.ajax({ - type: "POST", - url: "ajax.php", - dataType: "html", - data: data, - success: function (data) { - if (data == 1) { - agent_manager_remove_secondary_groups_ui(); - } else { - console.error("Error in AJAX call to add secondary groups") - } - }, - error: function (data) { - console.error("Fatal error in AJAX call to add secondary groups") - } - }); - } - - // Move from left input to right input - function agent_manager_add_secondary_groups_ui () { - $("#secondary_groups_selected option[value=0]").remove() - $("#secondary_groups option:selected").each(function() { - $(this).remove().appendTo("#secondary_groups_selected") - }) - } - - // Move from right input to left input - function agent_manager_remove_secondary_groups_ui () { - // Remove the groups selected if success - $("#secondary_groups_selected option:selected").each(function(){ - $(this).remove().appendTo("#secondary_groups") - }) - - // Add none if empty select - if ($("#secondary_groups_selected option").length == 0) { - $("#secondary_groups_selected").append($(''; @@ -367,22 +576,25 @@ else if (!$downtimes) { echo '
'; // Create button. - if ($write_permisson) { + if ($write_permisson === true) { echo ' '; - echo '
'; + echo ''; html_print_submit_button(__('Create'), 'create', false, 'class="sub next"'); echo '
'; } echo '
'; -} -// Has downtimes. -else { - echo "
"; +} else { + // Has downtimes. + echo ''; html_print_table($table_form); echo '
'; - ui_pagination($downtimes_number, "index.php?sec=extensions&sec2=godmode/agentes/planned_downtime.list&$filter_params_str", $offset); + ui_pagination( + $downtimes_number, + $url_list.'&'.$filter_params_str, + $offset + ); // User groups with AR, AD or AW permission. $groupsAD = users_get_groups($config['id_user'], $access); @@ -402,8 +614,11 @@ else { $table->head['execution'] = __('Execution'); $table->head['configuration'] = __('Configuration'); $table->head['running'] = __('Running'); + $table->head['agents_modules'] = __('Affected'); - if ($write_permisson || $manage_permisson) { + if ($write_permisson === true + || $manage_permisson === true + ) { $table->head['stop'] = __('Stop downtime'); $table->head['copy'] = __('Copy'); $table->head['edit'] = __('Edit'); @@ -414,7 +629,9 @@ else { $table->align['group'] = 'center'; $table->align['running'] = 'center'; - if ($write_permisson || $manage_permisson) { + if ($write_permisson === true + || $manage_permisson === true + ) { $table->align['stop'] = 'center'; $table->align['edit'] = 'center'; $table->align['delete'] = 'center'; @@ -430,7 +647,7 @@ else { WHERE id_downtime = '.$downtime['id'] ); - $data['name'] = $downtime['name']." ($total)"; + $data['name'] = $downtime['name'].' ('.$total.')'; $data['description'] = $downtime['description']; $data['group'] = ui_print_group_icon($downtime['id_group'], true); @@ -451,7 +668,7 @@ else { $data['configuration'] = reporting_format_planned_downtime_dates($downtime); - if ($downtime['executed'] == 0) { + if ((int) $downtime['executed'] === 0) { $data['running'] = html_print_image( 'images/pixel_red.png', true, @@ -473,44 +690,124 @@ else { ); } + $settings = [ + 'url' => ui_get_full_url('ajax.php', false, false, false), + 'loadingText' => __('Loading, this operation might take several minutes...'), + 'title' => __('Agents / Modules affected'), + 'id' => $downtime['id'], + ]; + + $data['agents_modules'] = ''; + $data['agents_modules'] .= html_print_image( + 'images/search_big.png', + true, + [ + 'title' => __('Agents and modules affected'), + 'style' => 'width:22px; height: 22px;', + ] + ); + $data['agents_modules'] .= ''; + // If user have writting permissions. - if (in_array($downtime['id_group'], $groupsAD)) { - // Stop button - if ($downtime['type_execution'] == 'once' && $downtime['executed'] == 1) { - if (check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AW') - || check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AD') + if (in_array($downtime['id_group'], $groupsAD) === true) { + // Stop button. + if ($downtime['type_execution'] === 'once' + && (int) $downtime['executed'] === 1 + ) { + if ((bool) check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AW') === true + || (bool) check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AD') === true ) { - $data['stop'] = ''.html_print_image('images/cancel.png', true, ['title' => __('Stop downtime')]); + $url_list_params = $url_list.'&stop_downtime=1&id_downtime='.$downtime['id'].'&'.$filter_params_str; + $data['stop'] = ''; + $data['stop'] .= html_print_image( + 'images/cancel.png', + true, + ['title' => __('Stop downtime')] + ); } else { - $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'] = ''; } // Edit & delete buttons. - if ($downtime['executed'] == 0) { - if (check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AW') - || check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AD') + if ((int) $downtime['executed'] === 0) { + if ((bool) check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AW') === true + || (bool) check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AD') === true ) { // Copy. - $data['copy'] = ''.html_print_image('images/copy.png', true, ['title' => __('Copy'), 'class' => 'invert_filter']).''; + $data['copy'] = ''; + $data['copy'] .= html_print_image( + 'images/copy.png', + true, + [ + 'title' => __('Copy'), + 'class' => 'invert_filter', + ] + ); + $data['copy'] .= ''; + // Edit. - $data['edit'] = ''.html_print_image('images/config.png', true, ['title' => __('Update'), 'class' => 'invert_filter']).''; + $data['edit'] = ''; + $data['edit'] .= html_print_image( + 'images/config.png', + true, + [ + 'title' => __('Update'), + 'class' => 'invert_filter', + ] + ); + $data['edit'] .= ''; + // Delete. - $data['delete'] = ''.html_print_image('images/cross.png', true, ['title' => __('Delete'), 'class' => 'invert_filter']); + $url_delete = $url_list.'&delete_downtime=1&id_downtime='.$downtime['id'].'&'.$filter_params_str; + $data['delete'] = ''; + $data['delete'] .= html_print_image( + 'images/cross.png', + true, + [ + 'title' => __('Delete'), + 'class' => 'invert_filter', + ] + ); + $data['delete'] .= ''; } else { $data['edit'] = ''; $data['delete'] = ''; } - } else if ($downtime['executed'] == 1 && $downtime['type_execution'] == 'once') { - if (check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AW') - || check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AD') + } else if ((int) $downtime['executed'] === 1 + && $downtime['type_execution'] === 'once' + ) { + if ((bool) check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AW') === true + || (bool) check_acl_restricted_all($config['id_user'], $downtime['id_group'], 'AD') === true ) { // Copy. - $data['copy'] = ''.html_print_image('images/copy.png', true, ['title' => __('Copy'), 'class' => 'invert_filter']).''; + $data['copy'] = ''; + $data['copy'] .= html_print_image( + 'images/copy.png', + true, + [ + 'title' => __('Copy'), + 'class' => 'invert_filter', + ] + ); + $data['copy'] .= ''; // Edit. - $data['edit'] = ''.html_print_image('images/config.png', true, ['title' => __('Update'), 'class' => 'invert_filter']).''; + $data['edit'] = ''; + $data['edit'] .= html_print_image( + 'images/config.png', + true, + [ + 'title' => __('Update'), + 'class' => 'invert_filter', + ] + ); + $data['edit'] .= ''; // Delete. $data['delete'] = __('N/A'); } else { @@ -529,7 +826,9 @@ else { $data['delete'] = ''; } - if (!empty($malformed_downtimes_exist) && isset($malformed_downtimes[$downtime['id']])) { + if (empty($malformed_downtimes_exist) === false + && isset($malformed_downtimes[$downtime['id']]) === true + ) { $next_row_num = count($table->data); $table->cellstyle[$next_row_num][0] = 'color: red'; $table->cellstyle[$next_row_num][1] = 'color: red'; @@ -542,7 +841,17 @@ else { } html_print_table($table); - ui_pagination($downtimes_number, "index.php?sec=extensions&sec2=godmode/agentes/planned_downtime.list&$filter_params_str", $offset, 0, false, 'offset', true, 'pagination-bottom'); + ui_pagination( + $downtimes_number, + $url_list.'&'.$filter_params_str, + $offset, + 0, + false, + 'offset', + true, + 'pagination-bottom' + ); + echo '
'; // CSV export button. @@ -551,32 +860,44 @@ else { __('Export to CSV'), 'csv_export', false, - "location.href='godmode/agentes/planned_downtime.export_csv.php?$filter_params_str'", + 'location.href="godmode/agentes/planned_downtime.export_csv.php?'.$filter_params_str.'"', 'class="sub next"' ); echo '
'; // Create button. - if ($write_permisson) { + if ($write_permisson === true) { echo ' '; - echo '
'; - html_print_submit_button(__('Create'), 'create', false, 'class="sub next"'); + echo ''; + html_print_submit_button( + __('Create'), + 'create', + false, + 'class="sub next"' + ); echo '
'; } echo '
'; } -ui_require_jquery_file('ui.datepicker-'.get_user_language(), 'include/javascript/i18n/'); +ui_require_jquery_file( + 'ui.datepicker-'.get_user_language(), + 'include/javascript/i18n/' +); +ui_require_javascript_file('pandora_planned_downtimes'); ?> '; diff --git a/pandora_console/include/ajax/visual_console.ajax.php b/pandora_console/include/ajax/visual_console.ajax.php index b3739d0c97..316d5ff022 100644 --- a/pandora_console/include/ajax/visual_console.ajax.php +++ b/pandora_console/include/ajax/visual_console.ajax.php @@ -37,6 +37,7 @@ $ajax = true; $render_map = (bool) get_parameter('render_map', false); $graph_javascript = (bool) get_parameter('graph_javascript', false); $force_remote_check = (bool) get_parameter('force_remote_check', false); +$load_css_cv = (bool) get_parameter('load_css_cv', false); if ($render_map) { $width = (int) get_parameter('width', '400'); @@ -89,3 +90,12 @@ if ($force_remote_check) { return; } + +if ($load_css_cv === true) { + $uniq = get_parameter('uniq', 0); + $ratio = get_parameter('ratio', 0); + + $output = css_label_styles_visual_console($uniq, $ratio); + echo $output; + return; +} diff --git a/pandora_console/include/class/AgentWizard.class.php b/pandora_console/include/class/AgentWizard.class.php index 7eda54443f..bc34fa5258 100644 --- a/pandora_console/include/class/AgentWizard.class.php +++ b/pandora_console/include/class/AgentWizard.class.php @@ -544,11 +544,6 @@ class AgentWizard extends HTML // Get the servers. $rows = get_proxy_servers(); - // Check if satellite server has remote configuration enabled. - $satellite_remote = config_agents_has_remote_configuration( - $this->idAgent - ); - // Generate a list with allowed servers. if (isset($rows) === true && is_array($rows) === true) { foreach ($rows as $row) { diff --git a/pandora_console/include/class/CredentialStore.class.php b/pandora_console/include/class/CredentialStore.class.php index f6cd726749..82ab94ee97 100644 --- a/pandora_console/include/class/CredentialStore.class.php +++ b/pandora_console/include/class/CredentialStore.class.php @@ -158,7 +158,9 @@ class CredentialStore extends Wizard // Check access. check_login(); - if (! check_acl($config['id_user'], 0, 'AR')) { + if ((bool) check_acl($config['id_user'], 0, 'PM') === false + || (bool) check_acl($config['id_user'], 0, 'UM') === false + ) { db_pandora_audit( AUDIT_LOG_ACL_VIOLATION, 'Trying to access credential store' diff --git a/pandora_console/include/class/Tree.class.php b/pandora_console/include/class/Tree.class.php index 97f70426bf..8d99fb6d82 100644 --- a/pandora_console/include/class/Tree.class.php +++ b/pandora_console/include/class/Tree.class.php @@ -167,8 +167,10 @@ class Tree */ protected function getDisabledFilter() { + $only_disabled = (is_metaconsole() === true) ? (int) $this->filter['show_disabled'] : 0; + if (empty($this->filter['showDisabled'])) { - return ' tam.disabled = 0 AND ta.disabled = 0'; + return ' tam.disabled = 0 AND ta.disabled = '.$only_disabled; } return ' 1 = 1'; diff --git a/pandora_console/include/class/TreeGroup.class.php b/pandora_console/include/class/TreeGroup.class.php index 48c64c898d..a5b9757fba 100644 --- a/pandora_console/include/class/TreeGroup.class.php +++ b/pandora_console/include/class/TreeGroup.class.php @@ -311,13 +311,14 @@ class TreeGroup extends Tree $table = is_metaconsole() ? 'tmetaconsole_agent' : 'tagente'; $table_sec = is_metaconsole() ? 'tmetaconsole_agent_secondary_group' : 'tagent_secondary_group'; + $only_disabled = (is_metaconsole() === true) ? (int) $this->filter['show_disabled'] : 0; $sql_model = "SELECT %s FROM ( SELECT COUNT(DISTINCT(ta.id_agente)) AS total, id_grupo AS g FROM $table ta $module_search_inner - WHERE ta.disabled = 0 + WHERE ta.disabled = $only_disabled %s $agent_search_filter $agent_status_filter @@ -330,7 +331,7 @@ class TreeGroup extends Tree FROM $table ta INNER JOIN $table_sec tasg ON ta.id_agente = tasg.id_agent $module_search_inner - WHERE ta.disabled = 0 + WHERE ta.disabled = $only_disabled %s $agent_search_filter $agent_status_filter @@ -390,37 +391,29 @@ class TreeGroup extends Tree $groups[$group['id']] = $group; } - // Build the module hierarchy + // Build the module hierarchy. foreach ($groups as $id => $group) { - if (isset($groups[$id]['parent']) && ($groups[$id]['parent'] != 0)) { + if (isset($groups[$id]['parent']) === true && ($groups[$id]['parent'] != 0)) { $parent = $groups[$id]['parent']; - // Parent exists - if (!isset($groups[$parent]['children'])) { + // Parent exists. + if (isset($groups[$parent]['children']) === true) { $groups[$parent]['children'] = []; } - // Store a reference to the group into the parent + // Store a reference to the group into the parent. $groups[$parent]['children'][] = &$groups[$id]; - // This group was introduced into a parent + // This group was introduced into a parent. $groups[$id]['have_parent'] = true; } } - // Sort the children groups + // Sort the children groups. foreach ($groups as $id => $group) { - if (isset($groups[$id]['children'])) { + if (isset($groups[$id]['children']) === true) { usort($groups[$id]['children'], ['Tree', 'cmpSortNames']); } } - // Filter groups and eliminates the reference to children groups out of her parent - $groups = array_filter( - $groups, - function ($group) { - return !($group['have_parent'] ?? false); - } - ); - return array_values($groups); } diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index b854509eea..79cd81a13a 100644 --- a/pandora_console/include/config_process.php +++ b/pandora_console/include/config_process.php @@ -20,7 +20,7 @@ /** * Pandora build version and version */ -$build_version = 'PC220308'; +$build_version = 'PC220323'; $pandora_version = 'v7.0NG.760'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index ba7ef746da..c1da547d0a 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -108,6 +108,11 @@ define('SECONDS_1YEAR', 31536000); define('SECONDS_2YEARS', 63072000); define('SECONDS_3YEARS', 94608000); +// PhantomJS Cache cleanup intervals. +define('PHANTOM_CACHE_CLEANUP_ONCE', 0); +define('PHANTOM_CACHE_CLEANUP_WEEKLY', SECONDS_1WEEK); +define('PHANTOM_CACHE_CLEANUP_DAILY', SECONDS_1DAY); + // Separator constats. @@ -788,6 +793,7 @@ define('AUDIT_LOG_MASSIVE_MANAGEMENT', 'Massive operation management'); define('AUDIT_LOG_POLICY_MANAGEMENT', 'Policy management'); define('AUDIT_LOG_AGENT_REMOTE_MANAGEMENT', 'Agent remote configuration'); define('AUDIT_LOG_FILE_COLLECTION', 'File collection'); +define('AUDIT_LOG_FILE_MANAGER', 'File manager'); define('AUDIT_LOG_ALERT_MANAGEMENT', 'Alert management'); define('AUDIT_LOG_ALERT_CORRELATION_MANAGEMENT', 'Alert correlation management'); define('AUDIT_LOG_VISUAL_CONSOLE_MANAGEMENT', 'Visual Console Management'); @@ -796,3 +802,58 @@ define('AUDIT_LOG_SNMP_MANAGEMENT', 'SNMP management'); define('AUDIT_LOG_DASHBOARD_MANAGEMENT', 'Dashboard management'); define('AUDIT_LOG_SERVICE_MANAGEMENT', 'Service management'); define('AUDIT_LOG_INCIDENT_MANAGEMENT', 'Incident management'); + +// MIMEs. +define( + 'MIME_TYPES', + [ + 'txt' => 'text/plain', + 'htm' => 'text/html', + 'html' => 'text/html', + 'php' => 'text/html', + 'css' => 'text/css', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'xml' => 'application/xml', + 'swf' => 'application/x-shockwave-flash', + 'flv' => 'video/x-flv', + // Images. + 'png' => 'image/png', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + 'ico' => 'image/vnd.microsoft.icon', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + // Archives. + 'zip' => 'application/zip', + 'rar' => 'application/x-rar-compressed', + 'exe' => 'application/x-msdownload', + 'msi' => 'application/x-msdownload', + 'cab' => 'application/vnd.ms-cab-compressed', + 'gz' => 'application/x-gzip', + 'gz' => 'application/x-bzip2', + // Audio/Video. + 'mp3' => 'audio/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + // Adobe. + 'pdf' => 'application/pdf', + 'psd' => 'image/vnd.adobe.photoshop', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + // MS Office. + 'doc' => 'application/msword', + 'rtf' => 'application/rtf', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + // Open Source Office files. + 'odt' => 'application/vnd.oasis.opendocument.text', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + ] +); diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index 4de4aa94b7..dcf134d17c 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -750,6 +750,7 @@ function agents_get_agents_selected($group) 'id_tmetaconsole_setup', 'id_agente', 'alias', + 'server_name', ], 'AR', [ @@ -764,7 +765,7 @@ function agents_get_agents_selected($group) $all = array_reduce( $all, function ($carry, $item) { - $carry[$item['id_tmetaconsole_setup'].'|'.$item['id_tagente']] = $item['alias']; + $carry[$item['id_tmetaconsole_setup'].'|'.$item['id_tagente']] = $item['server_name'].' » '.$item['alias']; return $carry; }, [] @@ -1243,6 +1244,11 @@ function agents_get_group_agents( unset($search['string']); } + if (isset($search['matchIds']) === true && is_array($search['matchIds']) === true) { + $filter[] = sprintf('id_agente IN (%s)', implode(', ', $search['matchIds'])); + unset($search['matchIds']); + } + if (isset($search['name']) === true) { $name = io_safe_input($search['name']); $filter[] = "nombre LIKE '$name'"; @@ -3223,8 +3229,8 @@ function agents_get_network_interfaces($agents=false, $agents_filter=false) $ni_by_agents = []; foreach ($agents as $agent) { $agent_id = (isset($agent['id_agente'])) ? $agent['id_agente'] : $agent; - $agent_group_id = $agent['id_grupo']; - $agent_name = $agent['alias']; + $agent_group_id = (isset($agent['id_grupo']) === true) ? $agent['id_grupo'] : ''; + $agent_name = (isset($agent['alias']) === true) ? $agent['alias'] : ''; $agent_interfaces = []; $accepted_module_types = []; @@ -4180,3 +4186,78 @@ function get_planned_downtime_agents_list($id_downtime, $filter_cond, $id_groups return $agents; } + + +/** + * Agent Module status and data + * + * @param integer $id_group Group + * @param array $agents Agents filter. + * @param array $modules Modules filter. + * + * @return array Result. + */ +function get_status_data_agent_modules($id_group, $agents=[], $modules=[]) +{ + $slq_filter_group = ''; + if (empty($id_group) === false) { + $slq_filter_group = sprintf( + ' AND tagente.id_grupo = %d', + $id_group + ); + } + + $slq_filter_agent = ''; + if (empty($agents) === false) { + $slq_filter_agent = sprintf( + ' AND tagente_modulo.id_agente IN (%s)', + implode(',', $agents) + ); + } + + $slq_filter_module = ''; + if (empty($modules) === false) { + $slq_filter_module = sprintf( + ' AND tagente_modulo.id_agente_modulo IN (%s)', + implode(',', $modules) + ); + } + + $sql = sprintf( + 'SELECT tagente_modulo.id_agente_modulo as id_agent_module, + tagente_modulo.nombre as name_module, + tagente_modulo.unit as unit_module, + tagente_modulo.id_agente as id_agent, + tagente_estado.datos as data_module, + tagente_estado.timestamp as data_time_module, + tagente_estado.estado as status_module, + tagente.alias as name_agent, + tagente.id_grupo as id_group, + tgrupo.nombre as name_group + FROM tagente_modulo + INNER JOIN tagente_estado + ON tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo + INNER JOIN tagente + ON tagente_modulo.id_agente = tagente.id_agente + LEFT JOIN tagent_secondary_group + ON tagente.id_agente = tagent_secondary_group.id_agent + INNER JOIN tgrupo + ON tagente.id_grupo = tgrupo.id_grupo + WHERE 1=1 + %s + %s + %s + ', + $slq_filter_group, + $slq_filter_agent, + $slq_filter_module + ); + + $res = db_get_all_rows_sql($sql); + + if ($res === false) { + $res = []; + } + + return $res; +} diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 55f9a1ce02..5bf3dfe5c0 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -13630,7 +13630,7 @@ function api_get_netflow_get_stats($discard_1, $discard_2, $params) return; } - // Parse function parameters + // Parse function parameters. $start_date = $params['data'][0]; $end_date = $params['data'][1]; $filter = json_decode(base64_decode($params['data'][2]), true); @@ -13647,10 +13647,38 @@ function api_get_netflow_get_stats($discard_1, $discard_2, $params) } +/** + * + * @param $trash1 Don't use. + * @param $trash2 Don't use. + * @param array $params Call parameters. + * @return void + */ +function api_get_netflow_get_top_N($trash1, $trash2, $params) +{ + if (is_metaconsole() === true) { + return; + } + + // Parse function parameters. + $start_date = $params['data'][0]; + $end_date = $params['data'][1]; + $filter = json_decode(base64_decode($params['data'][2]), true); + $max = $params['data'][3]; + + // Get netflow data. + $data = netflow_get_top_N($start_date, $end_date, $filter, $max, ''); + + returnData('json', $data); + + return; +} + + // http://localhost/pandora_console/include/api.php?op=get&op2=netflow_get_summary&other=1348562410|1348648810|_base64_encode(json_encode($filter))&other_mode=url_encode_separator_|&apipass=pandora&user=pandora&pass=pandora' function api_get_netflow_get_summary($discard_1, $discard_2, $params) { - if (defined('METACONSOLE')) { + if (is_metaconsole() === true) { return; } diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index f6cc50b08f..6f79be6c76 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -891,6 +891,25 @@ function config_update_config() if (config_update_value('snmpwalk_fallback', get_parameter('snmpwalk_fallback'), true) === false) { $error_update[] = __('SNMP walk binary path (fallback for v1)'); } + + $pjs = get_parameter('phantomjs_cache_interval'); + switch ($pjs) { + case $config['phantomjs_cache_interval']: + default; + // No changes. + break; + + case PHANTOM_CACHE_CLEANUP_ONCE: + case PHANTOM_CACHE_CLEANUP_DAILY: + case PHANTOM_CACHE_CLEANUP_WEEKLY: + enterprise_hook('phantomjs_cache_interval_schedule', [$pjs]); + break; + } + + if (config_update_value('phantomjs_cache_interval', get_parameter('phantomjs_cache_interval'), true) === false + ) { + $error_update[] = __('PhantomJS cache interval'); + } break; case 'vis': diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 26f41a2589..1eb5a1e34b 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -4166,11 +4166,24 @@ function events_get_response_target( } // Parse the event custom data. - if (!empty($event['custom_data'])) { + if (empty($event['custom_data']) === false) { $custom_data = json_decode(base64_decode($event['custom_data'])); foreach ($custom_data as $key => $value) { $target = str_replace('_customdata_'.$key.'_', $value, $target); } + + if (strpos($target, '_customdata_json_') !== false) { + $target = str_replace('_customdata_json_', json_encode($custom_data), $target); + } + + if (strpos($target, '_customdata_text_') !== false) { + $text = ''; + foreach ($custom_data as $key => $value) { + $text .= $key.': '.$value.PHP_EOL; + } + + $target = str_replace('_customdata_text_', $text, $target); + } } // This will replace the macro with the current logged user. @@ -4187,6 +4200,28 @@ function events_get_response_target( ); } + if (strpos($target, '_owner_username_') !== false) { + if (empty($event['owner_user']) === false) { + $fullname = users_get_user_by_id($event['owner_user']); + $target = str_replace( + '_owner_username_', + io_safe_output($fullname['fullname']), + $target + ); + } else { + $target = str_replace('_owner_username_', __('N/A'), $target); + } + } + + if (strpos($target, '_current_username_') !== false) { + $fullname = users_get_user_by_id($config['id_user']); + $target = str_replace( + '_current_username_', + io_safe_output($fullname['fullname']), + $target + ); + } + return $target; } @@ -7588,6 +7623,28 @@ function events_get_field_value_by_event_id( $value = str_replace('_current_user_', $config['id_user'], $value); } + if (strpos($value, '_owner_username_') !== false) { + if (empty($event['owner_user']) === false) { + $fullname = users_get_user_by_id($event['owner_user']); + $value = str_replace( + '_owner_username_', + io_safe_output($fullname['fullname']), + $value + ); + } else { + $value = str_replace('_owner_username_', __('N/A'), $value); + } + } + + if (strpos($value, '_current_username_') !== false) { + $fullname = users_get_user_by_id($config['id_user']); + $value = str_replace( + '_current_username_', + io_safe_output($fullname['fullname']), + $value + ); + } + return $value; } diff --git a/pandora_console/include/functions_filemanager.php b/pandora_console/include/functions_filemanager.php index b33b68aac7..0879ce678c 100644 --- a/pandora_console/include/functions_filemanager.php +++ b/pandora_console/include/functions_filemanager.php @@ -14,7 +14,7 @@ * |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______| * * ============================================================================ - * Copyright (c) 2005-2021 Artica Soluciones Tecnologicas + * Copyright (c) 2005-2022 Artica Soluciones Tecnologicas * Please see http://pandorafms.org for full contribution list * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -48,69 +48,22 @@ if (function_exists('mime_content_type') === false) { */ function mime_content_type(string $filename) { - $mime_types = [ - 'txt' => 'text/plain', - 'htm' => 'text/html', - 'html' => 'text/html', - 'php' => 'text/html', - 'css' => 'text/css', - 'js' => 'application/javascript', - 'json' => 'application/json', - 'xml' => 'application/xml', - 'swf' => 'application/x-shockwave-flash', - 'flv' => 'video/x-flv', - // Images. - 'png' => 'image/png', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'gif' => 'image/gif', - 'bmp' => 'image/bmp', - 'ico' => 'image/vnd.microsoft.icon', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', - // Archives. - 'zip' => 'application/zip', - 'rar' => 'application/x-rar-compressed', - 'exe' => 'application/x-msdownload', - 'msi' => 'application/x-msdownload', - 'cab' => 'application/vnd.ms-cab-compressed', - 'gz' => 'application/x-gzip', - 'gz' => 'application/x-bzip2', - // Audio/Video. - 'mp3' => 'audio/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - // Adobe. - 'pdf' => 'application/pdf', - 'psd' => 'image/vnd.adobe.photoshop', - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - // MS Office. - 'doc' => 'application/msword', - 'rtf' => 'application/rtf', - 'xls' => 'application/vnd.ms-excel', - 'ppt' => 'application/vnd.ms-powerpoint', - // Open Source Office files. - 'odt' => 'application/vnd.oasis.opendocument.text', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - ]; - $ext_fields = explode('.', $filename); $ext = array_pop($ext_fields); $ext = strtolower($ext); - if (array_key_exists($ext, $mime_types) === true) { - return $mime_types[$ext]; + if (array_key_exists($ext, MIME_TYPES) === true) { + return MIME_TYPES[$ext]; } else if (function_exists('finfo_open') === true) { $finfo = finfo_open(FILEINFO_MIME); $mimetype = finfo_file($finfo, $filename); finfo_close($finfo); return $mimetype; } else { - error_log('Warning: Cannot find finfo_open function. Fileinfo extension is not enabled. Please add "extension=fileinfo.so" or "extension=fileinfo.dll" in your php.ini'); + db_pandora_audit( + AUDIT_LOG_FILE_MANAGER, + 'Warning: Cannot find finfo_open function. Fileinfo extension is not enabled. Please add "extension=fileinfo.so" or "extension=fileinfo.dll" in your php.ini' + ); + return 'unknown'; } } @@ -129,10 +82,12 @@ require_once $config['homedir'].'/vendor/autoload.php'; * @param boolean $upload_file_or_zip Upload file or zip. * @param string $default_real_directory String with default directory. * @param string $destination_directory String with destination directory. + * @param array $filterFilesType If come filled, filter uploaded files with this extensions. * + * @throws Exception Exception. * @return void */ -function upload_file($upload_file_or_zip, $default_real_directory, $destination_directory) +function upload_file($upload_file_or_zip, $default_real_directory, $destination_directory, $filterFilesType=[]) { global $config; $config['filemanager'] = []; @@ -179,13 +134,24 @@ function upload_file($upload_file_or_zip, $default_real_directory, $destination_ // controlled by corresponding .htaccess). $config['filemanager']['message'] = ui_print_error_message(__('Security error')); } else { + $result = false; // Copy file to directory and change name. $nombre_archivo = sprintf('%s/%s', $real_directory, $filename); - try { - $result = copy($_FILES['file']['tmp_name'], $nombre_archivo); + $mimeContentType = mime_content_type($_FILES['file']['tmp_name']); + + if (empty($filterFilesType) === true || in_array($mimeContentType, $filterFilesType) === true) { + $result = copy($_FILES['file']['tmp_name'], $nombre_archivo); + } else { + $error_message = 'The uploaded file is not allowed. Only gif, png or jpg files can be uploaded.'; + throw new Exception(__($error_message)); + } } catch (Exception $ex) { - $result = false; + db_pandora_audit( + AUDIT_LOG_FILE_MANAGER, + 'Error Uploading files: '.$ex->getMessage() + ); + $config['filemanager']['message'] = ui_print_error_message(__('Upload error').': '.$ex->getMessage()); } if ($result === true) { @@ -203,8 +169,6 @@ function upload_file($upload_file_or_zip, $default_real_directory, $destination_ $config['filemanager']['correct_upload_file'] = 1; // Delete temporal file. unlink($_FILES['file']['tmp_name']); - } else { - $config['filemanager']['message'] = ui_print_error_message(__('Upload error')); } } } @@ -496,7 +460,7 @@ function filemanager_read_recursive_dir($dir, $relative_path='', $add_empty_dirs * @param boolean $download_button The flag to show download button, by default false. * @param string $umask The umask as hex values to set the new files or updload. * @param boolean $homedir_filemanager Homedir filemanager. - * @param boolean $allowCreateText If true, 'Create Text' button will be shown. + * @param array $options Associative array. ['all' => true] will show all options. Check function for valid options. */ function filemanager_file_explorer( $real_directory, @@ -509,7 +473,7 @@ function filemanager_file_explorer( $download_button=false, $umask='', $homedir_filemanager=false, - $allowCreateText=true + $options=[] ) { global $config; @@ -517,6 +481,9 @@ function filemanager_file_explorer( $real_directory = str_replace('\\', '/', $real_directory); $relative_directory = str_replace('\\', '/', $relative_directory); $father = str_replace('\\', '/', $father); + // Options. + $allowZipFiles = (isset($options['all']) === true) || ((isset($options['allowZipFiles']) === true) && ($options['allowZipFiles'] === true)); + $allowCreateText = (isset($options['all']) === true) || ((isset($options['allowCreateText']) === true) && ($options['allowCreateText'] === true)); if ($homedir_filemanager === false) { $homedir_filemanager = $config['homedir']; @@ -530,7 +497,7 @@ function filemanager_file_explorer( actions_dialog('create_folder'); $("#create_folder").css("display", "block"); check_opened_dialog('create_folder'); - } + } function show_create_text_file() { actions_dialog('create_text_file'); @@ -542,7 +509,7 @@ function filemanager_file_explorer( actions_dialog('upload_file'); $("#upload_file").css("display", "block"); check_opened_dialog('upload_file'); - } + } function check_opened_dialog(check_opened){ if(check_opened !== 'create_folder'){ @@ -579,11 +546,11 @@ function filemanager_file_explorer( case 'upload_file': title_action = ""; break; - + default: break; } - + $('#'+action) .dialog({ title: title_action, @@ -839,15 +806,86 @@ function filemanager_file_explorer( $tabs_dialog .= ''; - echo ''; + // Create folder section. + $createFolderElements = $tabs_dialog; + $createFolderElements .= sprintf('
', $url); + $createFolderElements .= html_print_input_text('dirname', '', '', 30, 255, true); + $createFolderElements .= html_print_submit_button(__('Create'), 'crt', false, 'class="sub next"', true); + $createFolderElements .= html_print_input_hidden('directory', $relative_directory, true); + $createFolderElements .= html_print_input_hidden('create_dir', 1, true); + $createFolderElements .= html_print_input_hidden('hash', md5($relative_directory.$config['server_unique_identifier']), true); + $createFolderElements .= html_print_input_hidden('hash2', md5($relative_directory.$config['server_unique_identifier']), true); + $createFolderElements .= '
'; - echo ''; + html_print_div( + [ + 'id' => 'create_folder', + 'class' => 'invisible', + 'content' => $createFolderElements, + ] + ); + // Upload file section. + $uploadFileElements = $tabs_dialog; + $uploadFileElements .= sprintf('
', $url); + $uploadFileElements .= html_print_input_hidden('umask', $umask, true); + + if ($allowZipFiles === true) { + $uploadFileElements .= ui_print_help_tip(__('The zip upload in this dir, easy to upload multiple files.'), true); + $uploadFileElements .= html_print_input_file('file', true, false); + $uploadFileElements .= html_print_checkbox('decompress', 1, false, true).__('Decompress'); + $uploadFileElements .= html_print_input_hidden('upload_file_or_zip', 1, true); + } else { + $uploadFileElements .= html_print_div( + [ + 'id' => 'upload_file_input_full', + 'content' => html_print_input_file( + 'file', + true, + [ 'style' => 'border:0; padding:0; width:100%' ] + ), + ], + true + ); + $uploadFileElements .= html_print_input_hidden('upload_file', 1, true); + } + + $uploadFileElements .= html_print_submit_button(__('Go'), 'go', false, 'class="sub next"', true); + $uploadFileElements .= html_print_input_hidden('real_directory', $real_directory, true); + $uploadFileElements .= html_print_input_hidden('directory', $relative_directory, true); + $uploadFileElements .= html_print_input_hidden('hash', md5($real_directory.$relative_directory.$config['server_unique_identifier']), true); + $uploadFileElements .= html_print_input_hidden('hash2', md5($relative_directory.$config['server_unique_identifier']), true); + + $uploadFileElements .= '
'; + + html_print_div( + [ + 'id' => 'upload_file', + 'class' => 'invisible', + 'content' => $uploadFileElements, + ] + ); + + // Create text section. if ($allowCreateText === true) { - echo ' '; + $createTextElements = $tabs_dialog; + $createTextElements .= '
'; + $createTextElements .= html_print_input_text('name_file', '', '', 30, 50, true); + $createTextElements .= html_print_submit_button(__('Create'), 'create', false, 'class="sub next"', true); + $createTextElements .= html_print_input_hidden('real_directory', $real_directory, true); + $createTextElements .= html_print_input_hidden('directory', $relative_directory, true); + $createTextElements .= html_print_input_hidden('hash', md5($real_directory.$relative_directory.$config['server_unique_identifier']), true); + $createTextElements .= html_print_input_hidden('umask', $umask, true); + $createTextElements .= html_print_input_hidden('create_text_file', 1, true); + $createTextElements .= '
'; + + html_print_div( + [ + 'id' => 'create_text_file', + 'class' => 'invisible', + 'content' => $createTextElements, + ] + ); } echo "
"; diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index 2b771497fe..a53246c071 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -4267,6 +4267,10 @@ function html_print_input_file($name, $return=false, $options=false) if (isset($options['onchange'])) { $output .= ' onchange="'.$options['onchange'].'"'; } + + if (isset($options['style']) === true) { + $output .= ' style="'.$options['style'].'"'; + } } $output .= ' />'; @@ -4936,7 +4940,13 @@ function html_print_input($data, $wrapper='div', $input_only=false) ((isset($data['size']) === true) ? $data['size'] : false), ((isset($data['modal']) === true) ? $data['modal'] : false), ((isset($data['message']) === true) ? $data['message'] : ''), - ((isset($data['select_all']) === true) ? $data['select_all'] : false) + ((isset($data['select_all']) === true) ? $data['select_all'] : false), + ((isset($data['simple_multiple_options']) === true) ? $data['simple_multiple_options'] : false), + ((isset($data['required']) === true) ? $data['required'] : false), + ((isset($data['truncate_size']) === true) ? $data['truncate_size'] : false), + ((isset($data['select2_enable']) === true) ? $data['select2_enable'] : true), + ((isset($data['select2_multiple_enable']) === true) ? $data['select2_multiple_enable'] : false), + ((isset($data['select2_multiple_enable_all']) === true) ? $data['select2_multiple_enable_all'] : false) ); break; @@ -5728,3 +5738,198 @@ function html_print_select_search( echo $output; } } + + +/** + * Print html select for agents secondary. + * + * @param integer $agent Agent. + * @param integer $id_agente Id Agent. + * @param array $options Array options. + * + * @return string Html output. + */ +function html_print_select_agent_secondary($agent, $id_agente, $options=[]) +{ + ui_require_css_file('agent_manager'); + ui_require_javascript_file('pandora_agents'); + + if (empty($options) === '' || isset($options['id_form']) === false) { + $options['id_form'] = 'form_agent'; + } + + if (empty($options) === '' || isset($options['extra_id']) === false) { + $options['extra_id'] = ''; + } + + if (empty($options) === '' || isset($options['only_select']) === false) { + $options['only_select'] = false; + } + + $secondary_groups_selected = enterprise_hook( + 'agents_get_secondary_groups', + [$id_agente] + ); + + $name = 'secondary_groups'.$options['extra_id']; + if ($options['only_select'] === true) { + $name = 'secondary_groups'.$options['extra_id'].'[]'; + } + + $adv_secondary_groups_left = html_print_select_groups( + // Id_user. + // Use the current user to select the groups. + false, + // Privilege. + // ACL permission. + 'AR', + // ReturnAllGroup. + // Not all group. + false, + // Name. + // HTML id. + $name, + // Selected. + // No select any by default. + '', + // Script. + // Javascript onChange code. + '', + // Nothing. + // Do not user no selected value. + false, + // Nothing_value. + // Do not use no selected value. + 0, + // Return. + // Return HTML (not echo). + true, + // Multiple. + // Multiple selection. + true, + // Sort. + // Sorting by default. + true, + // Class. + // CSS classnames (default). + '', + // Disabled. + // Not disabled (default). + false, + // Style. + // Inline styles (default). + 'min-width:170px;', + // Option_style. + // Option style select (default). + false, + // Id_group. + // Do not truncate the users tree (default). + false, + // Keys_field. + // Key to get as value (default). + 'id_grupo', + // Strict_user. + // Not strict user (default). + false, + // Delete_groups. + // Do not show the primary group in this selection. + array_merge( + (empty($secondary_groups_selected['plain']) === false) ? $secondary_groups_selected['plain'] : [], + [$agent['id_grupo']] + ) + // Include_groups. + // Size. + // Simple_multiple_options. + ); + + if ($options['only_select'] === false) { + $dictionary = base64_encode( + json_encode( + [ + 'primary_group' => __('Primary group cannot be secondary too.'), + 'strNone' => __('None'), + ] + ) + ); + + $adv_secondary_groups_arrows = html_print_input_image( + 'add_secondary', + 'images/darrowright_green.png', + 1, + '', + true, + [ + 'id' => 'right_autorefreshlist'.$options['extra_id'], + 'title' => __('Add secondary groups'), + 'onclick' => 'agent_manager_add_secondary_groups(event, '.$id_agente.',\''.$options['extra_id'].'\', \''.$options['id_form'].'\', \''.$dictionary.'\');', + ] + ); + + $adv_secondary_groups_arrows .= html_print_input_image( + 'remove_secondary', + 'images/darrowleft_green.png', + 1, + '', + true, + [ + 'id' => 'left_autorefreshlist'.$options['extra_id'], + 'title' => __('Remove secondary groups'), + 'onclick' => 'agent_manager_remove_secondary_groups(event, '.$id_agente.',\''.$options['extra_id'].'\', \''.$options['id_form'].'\', \''.$dictionary.'\');', + ] + ); + + $adv_secondary_groups_right .= html_print_select( + // Values. + $secondary_groups_selected['for_select'], + // HTML id. + 'secondary_groups_selected'.$options['extra_id'], + // Selected. + '', + // Javascript onChange code. + '', + // Nothing selected. + false, + // Nothing selected. + 0, + // Return HTML (not echo). + true, + // Multiple selection. + true, + // Sort. + true, + // Class. + '', + // Disabled. + false, + // Style. + 'min-width:170px;' + ); + + $output = ''; + if (isset($options['container']) === true + && $options['container'] === true + ) { + $output = '
'; + } + + $output .= '
'; + $output .= $adv_secondary_groups_left; + $output .= '
'; + $output .= '
'; + $output .= $adv_secondary_groups_arrows; + $output .= '
'; + $output .= '
'; + $output .= $adv_secondary_groups_right; + $output .= '
'; + + if (isset($options['container']) === true + && $options['container'] === true + ) { + $output .= '
'; + } + } else { + $output .= $adv_secondary_groups_left; + } + + return $output; +} diff --git a/pandora_console/include/functions_netflow.php b/pandora_console/include/functions_netflow.php index 60229d79ae..f88f6b751d 100644 --- a/pandora_console/include/functions_netflow.php +++ b/pandora_console/include/functions_netflow.php @@ -321,6 +321,72 @@ function netflow_data_table($data, $start_date, $end_date, $aggregate) } +/** + * Show a table with netflow top N data. + * + * @param array $data Netflow data. + * @param integer $total_bytes Total bytes count to calculate percent data. + * + * @return string HTML data table. + */ +function netflow_top_n_table(array $data, int $total_bytes) +{ + global $nfdump_date_format; + + $values = []; + $table = new stdClass(); + $table->class = 'w100p'; + $table->cellspacing = 0; + $table->data = []; + + $table->head = []; + $table->head[0] = ''.__('Source IP').''; + $table->head[1] = ''.__('Destination IP').''; + $table->head[2] = ''.__('Bytes').''; + $table->head[3] = ''.__('% Traffic').''; + $table->head[4] = ''.__('Avg. Throughput').''; + $table->style[0] = 'padding: 4px'; + + $i = 0; + + foreach ($data as $value) { + $table->data[$i][0] = $value['ip_src']; + $table->data[$i][1] = $value['ip_dst']; + $table->data[$i][2] = network_format_bytes($value['bytes']); + + $traffic = '-'; + + if ($total_bytes > 0) { + $traffic = sprintf( + '%.2f', + (($value['bytes'] / $total_bytes) * 100) + ); + } + + $table->data[$i][3] = $traffic.' %'; + + $units = [ + 'bps', + 'Kbps', + 'Mbps', + 'Gbps', + 'Tbps', + ]; + + $pow = floor((($value['bps'] > 0) ? log($value['bps']) : 0) / log(1024)); + $pow = min($pow, (count($units) - 1)); + + $value['bps'] /= pow(1024, $pow); + + $table->data[$i][4] = round($value['bps'], 2).' '.$units[$pow]; + + $i++; + } + + return html_print_table($table, true); +} + + /** * Show a table with a traffic summary. * @@ -395,6 +461,67 @@ function netflow_is_net($address) } +/** + * Returns netflow top N connections for the given period in an array (based on total traffic). + * + * @param string $start_date Period start date. + * @param string $end_date Period end date. + * @param array $filter Netflow filter. + * @param integer $max Maximum number of aggregates. + * @param string $connection_name Node name when data is get in meta. + * + * @return array An array with netflow stats. + */ +function netflow_get_top_N( + string $start_date, + string $end_date, + array $filter, + int $max, + string $connection_name='' +) { + global $nfdump_date_format; + + // Requesting remote data. + if (is_metaconsole() === true && empty($connection_name) === false) { + $data = metaconsole_call_remote_api( + $connection_name, + 'netflow_get_top_N', + $start_date.'|'.$end_date.'|'.base64_encode(json_encode($filter)).'|'.$max + ); + + return json_decode($data, true); + } + + $options = '-o "fmt:%sap,%dap,%ibyt,%bps" -q -n '.$max.' -s record/bytes -t '.date($nfdump_date_format, $start_date).'-'.date($nfdump_date_format, $end_date); + + $command = netflow_get_command($options, $filter); + + // Execute nfdump. + exec($command, $lines); + + if (is_array($lines) === false) { + return []; + } + + $values = []; + $i = 0; + + foreach ($lines as $line) { + $parsed_line = explode(',', $line); + $parsed_line = array_map('trim', $parsed_line); + + $values[$i]['ip_src'] = $parsed_line[0]; + $values[$i]['ip_dst'] = $parsed_line[1]; + $values[$i]['bytes'] = $parsed_line[2]; + $values[$i]['bps'] = $parsed_line[3]; + + $i++; + } + + return $values; +} + + /** * Returns netflow data for the given period in an array. * @@ -707,7 +834,7 @@ function netflow_get_summary($start_date, $end_date, $filter, $connection_name=' global $config; // Requesting remote data. - if (defined('METACONSOLE') && $connection_name != '') { + if (is_metaconsole() === true && $connection_name != '') { $data = metaconsole_call_remote_api($connection_name, 'netflow_get_summary', "$start_date|$end_date|".base64_encode(json_encode($filter))); return json_decode($data, true); } @@ -1051,6 +1178,7 @@ function netflow_get_chart_types() 'netflow_area' => __('Area graph'), 'netflow_summary' => __('Summary'), 'netflow_data' => __('Data table'), + 'netflow_top_N' => __('Top-N connections'), 'netflow_mesh' => __('Circular mesh'), 'netflow_host_treemap' => __('Host detailed traffic'), ]; @@ -1218,6 +1346,54 @@ function netflow_draw_item( } break; + case 'netflow_top_N': + $data_summary = netflow_get_summary( + $start_date, + $end_date, + $filter, + $connection_name + ); + + if (empty($data_summary) === true) { + break; + } + + $data_top_n = netflow_get_top_N( + $start_date, + $end_date, + $filter, + $max_aggregates, + $connection_name + ); + + if (empty($data_top_n) === true) { + break; + } + + if ($output === 'HTML' || $output === 'PDF') { + $html = ''; + $html .= ''; + $html .= "'; + $html .= ''; + $html .= ''; + $html .= "'; + $html .= ''; + $html .= '
"; + $html .= netflow_summary_table($data_summary); + $html .= '
"; + $html .= netflow_top_n_table($data_top_n, $data_summary['totalbytes']); + $html .= '
'; + + return $html; + } else if ($output === 'XML') { + $xml = ''.$aggregate."\n"; + $xml .= ''.$interval_length."\n"; + // Same as netflow_aggregate_area_xml. + $xml .= netflow_aggregate_area_xml($data_top_n); + return $xml; + } + break; + case 'netflow_mesh': $data = netflow_get_relationships_raw_data( $start_date, @@ -1304,6 +1480,46 @@ function netflow_draw_item( } +/** + * Get data of a netflow report item. + * + * @param string $start_date Period start date. + * @param string $end_date Period end date. + * @param array $filter Netflow filter. + * @param integer $max_aggregates Maximum number of aggregates. + * @param string $connection_name Node name when data is get in meta. + * + * @return array Netflow item data (summary and top N data). + */ +function netflow_get_item_data( + string $start_date, + string $end_date, + array $filter, + int $max_aggregates, + string $connection_name +) { + $data_summary = netflow_get_summary( + $start_date, + $end_date, + $filter, + $connection_name + ); + + $data_top_n = netflow_get_top_N( + $start_date, + $end_date, + $filter, + $max_aggregates, + $connection_name + ); + + return [ + 'summary' => $data_summary, + 'top_n' => $data_top_n, + ]; +} + + /** * Render an aggregated area chart as an XML. * diff --git a/pandora_console/include/functions_planned_downtimes.php b/pandora_console/include/functions_planned_downtimes.php index f6fdf49c11..796f09ab72 100644 --- a/pandora_console/include/functions_planned_downtimes.php +++ b/pandora_console/include/functions_planned_downtimes.php @@ -989,7 +989,7 @@ function planned_downtimes_copy($id_downtime) foreach ($planned_modules as $planned_module) { // Unset id. unset($planned_module['id']); - // Set id_planned downtime + // Set id_planned downtime. $planned_module['id_downtime'] = $result['id_downtime']; $result['id_modules'][] = db_process_sql_insert( 'tplanned_downtime_moduless', @@ -1004,3 +1004,82 @@ function planned_downtimes_copy($id_downtime) return $result; } + + +/** + * Get agentts and modules for planned_downtime. + * + * @param [type] $id Id planned. + * + * @return array Result array data. + */ +function get_agents_modules_planned_dowtime($id, $options, $count=false) +{ + $result = []; + + $filters_agent = ''; + if (isset($options['filters']['filter_agents']) === true + && empty($options['filters']['filter_agents']) === false + ) { + $filters_agent = sprintf( + ' AND (tagente.alias LIKE "%%%s%%")', + $options['filters']['filter_agents'] + ); + } + + $filters_module = ''; + if (isset($options['filters']['filter_modules']) === true + && empty($options['filters']['filter_modules']) === false + ) { + $filters_module = sprintf( + ' AND (tagente_modulo.nombre LIKE "%%%s%%")', + $options['filters']['filter_modules'] + ); + } + + if ($count === false) { + $query = sprintf( + 'SELECT tplanned_downtime_modules.*, + tagente.alias as agent_name, + tagente_modulo.nombre as module_name + FROM tplanned_downtime_modules + INNER JOIN tagente + ON tplanned_downtime_modules.id_agent = tagente.id_agente + INNER JOIN tagente_modulo + ON tplanned_downtime_modules.id_agent_module = tagente_modulo.id_agente_modulo + WHERE id_downtime = %d + %s + %s + ORDER BY %s + LIMIT %d, %d', + $id, + $filters_agent, + $filters_module, + $options['order'], + $options['limit'], + $options['offset'] + ); + } else { + $query = sprintf( + 'SELECT count(tplanned_downtime_modules.id) as total + FROM tplanned_downtime_modules + INNER JOIN tagente + ON tplanned_downtime_modules.id_agent = tagente.id_agente + INNER JOIN tagente_modulo + ON tplanned_downtime_modules.id_agent_module = tagente_modulo.id_agente_modulo + WHERE id_downtime = %d + %s + %s', + $id, + $filters_agent, + $filters_module + ); + } + + $result = db_get_all_rows_sql($query); + if ($result === false) { + $result = []; + } + + return $result; +} diff --git a/pandora_console/include/functions_reporting.php b/pandora_console/include/functions_reporting.php index 3693a72dcd..ba3dc52551 100755 --- a/pandora_console/include/functions_reporting.php +++ b/pandora_console/include/functions_reporting.php @@ -606,6 +606,18 @@ function reporting_make_reporting_data( ); break; + case 'netflow_top_N': + $report['contents'][] = reporting_netflow( + $report, + $content, + $type, + $force_width_chart, + $force_height_chart, + 'netflow_top_N', + $pdf + ); + break; + case 'monitor_report': $report['contents'][] = reporting_monitor_report( $report, @@ -730,6 +742,13 @@ function reporting_make_reporting_data( ); break; + case 'agent_module_status': + $report['contents'][] = reporting_agent_module_status( + $report, + $content + ); + break; + case 'alert_report_actions': $report['contents'][] = reporting_alert_report_actions( $report, @@ -2854,6 +2873,136 @@ function reporting_agent_module($report, $content) } +/** + * Agents module status + * + * @param array $report Info Report. + * @param array $content Info content. + * + * @return array + */ +function reporting_agent_module_status($report, $content) +{ + global $config; + $return['type'] = 'agent_module_status'; + + if (empty($content['name'])) { + $content['name'] = __('Agent/Modules Status'); + } + + $return['title'] = io_safe_output($content['name']); + $return['landscape'] = $content['landscape']; + $return['pagebreak'] = $content['pagebreak']; + $group_name = groups_get_name($content['id_group'], true); + if ($content['id_module_group'] == 0) { + $module_group_name = __('All'); + } else { + $module_group_name = db_get_value( + 'name', + 'tmodule_group', + 'id_mg', + $content['id_module_group'] + ); + } + + $return['subtitle'] = $group_name.' - '.$module_group_name; + $return['description'] = io_safe_output($content['description']); + $return['date'] = reporting_get_date_text($report, $content); + $return['label'] = (isset($content['style']['label'])) ? $content['style']['label'] : ''; + + $return['data'] = []; + + $external_source = json_decode( + $content['external_source'], + true + ); + + $agents = json_decode( + io_safe_output( + base64_decode($external_source['id_agents']) + ), + true + ); + + $modules = json_decode( + io_safe_output( + base64_decode($external_source['module']) + ), + true + ); + + if (is_metaconsole() === true) { + $agents_per_node = []; + $modules_per_node = []; + + if (empty($agents) === false) { + foreach ($agents as $value) { + $agent_array = explode('|', $value); + $agents_per_node[$agent_array[0]][] = $agent_array[1]; + } + } + + if (empty($modules) === false) { + foreach ($modules as $value) { + $module_array = explode('|', $value); + $modules_per_node[$module_array[0]][] = $module_array[1]; + } + } + + if (empty($agents_per_node) === false) { + foreach ($agents_per_node as $server => $agents) { + $connection = metaconsole_get_connection_by_id($server); + if (metaconsole_connect($connection) != NOERR) { + continue; + } + + $res[$connection['server_name']] = get_status_data_agent_modules( + $content['id_group'], + $agents, + $modules_per_node[$server] + ); + + metaconsole_restore_db(); + } + } else { + $metaconsole_connections = metaconsole_get_connection_names(); + // For all nodes. + if (isset($metaconsole_connections) === true + && is_array($metaconsole_connections) === true + ) { + foreach ($metaconsole_connections as $metaconsole) { + // Get server connection data. + $server_data = metaconsole_get_connection($metaconsole); + + // Establishes connection. + if (metaconsole_load_external_db($server_data) !== NOERR) { + continue; + } + + $res[$server_data['server_name']] = get_status_data_agent_modules( + $content['id_group'], + $agents, + $modules + ); + + metaconsole_restore_db(); + } + } + } + } else { + $res['node'] = get_status_data_agent_modules( + $content['id_group'], + $agents, + $modules + ); + } + + $return['data'] = $res; + + return reporting_check_structure_content($return); +} + + function reporting_exception( $report, $content, @@ -5432,6 +5581,10 @@ function reporting_netflow( $return['type'] = 'netflow_summary'; break; + case 'netflow_top_N': + $return['type'] = 'netflow_top_N'; + break; + default: $return['type'] = 'unknown'; break; @@ -5451,6 +5604,10 @@ function reporting_netflow( $content['name'] = __('Netflow Data'); break; + case 'netflow_top_N': + $content['name'] = __('Netflow top-N connections'); + break; + default: $content['name'] = __('Unknown report'); break; @@ -5490,26 +5647,61 @@ function reporting_netflow( true ); - switch ($type) { - case 'dinamic': - case 'static': - case 'data': - $return['chart'] = netflow_draw_item( - ($report['datetime'] - $content['period']), - $report['datetime'], - $content['top_n'], - $type_netflow, - $filter, - $content['top_n_value'], - $content['server_name'], - $pdf ? 'PDF' : 'HTML' - ); - break; + if ($type_netflow === 'netflow_top_N') { + // Always aggregate by destination port. + $filter['aggregate'] = 'dstport'; - case 'data': - default: - // Nothing to do. - break; + switch ($type) { + case 'dinamic': + case 'static': + $return['chart'] = netflow_draw_item( + ($report['datetime'] - $content['period']), + $report['datetime'], + $content['top_n'], + $type_netflow, + $filter, + $content['top_n_value'], + $content['server_name'], + (($pdf === true) ? 'PDF' : 'HTML') + ); + break; + + case 'data': + $return['data'] = netflow_get_item_data( + ($report['datetime'] - $content['period']), + $report['datetime'], + $filter, + $content['top_n_value'], + $content['server_name'] + ); + break; + + default: + // Nothing to do. + break; + } + } else { + switch ($type) { + case 'dinamic': + case 'static': + case 'data': + $return['chart'] = netflow_draw_item( + ($report['datetime'] - $content['period']), + $report['datetime'], + $content['top_n'], + $type_netflow, + $filter, + $content['top_n_value'], + $content['server_name'], + $pdf ? 'PDF' : 'HTML' + ); + break; + + case 'data': + default: + // Nothing to do. + break; + } } $return['subtitle'] = netflow_generate_subtitle_report( @@ -11049,11 +11241,29 @@ function reporting_get_stats_users($data) $tdata = []; $tdata[0] = html_print_image('images/user.png', true, ['title' => __('Defined users'), 'class' => 'invert_filter']); - $user_groups = users_get_strict_mode_groups($config['id_user'], false); - if (array_key_exists(0, $user_groups)) { - $users = users_get_user_users($config['id_user'], 'AR', true); + $user_is_admin = users_is_admin(); + + $users = []; + + if ($user_is_admin) { + $users = get_users('', ['disabled' => 0], ['id_user', 'is_admin']); } else { - $users = users_get_user_users($config['id_user'], 'AR', false); + $group_um = users_get_groups_UM($config['id_user']); + // 0 is the group 'all'. + if (isset($group_um[0])) { + $users = get_users('', ['disabled' => 0], ['id_user', 'is_admin']); + } else { + foreach ($group_um as $group => $value) { + $users = array_merge($users, users_get_users_by_group($group, $value, false)); + } + } + } + + foreach ($users as $user_id => $user_info) { + // If user is not admin then don't display admin users. + if ($user_is_admin === false && (bool) $user_info['is_admin'] === true) { + unset($users[$user_id]); + } } $tdata[1] = count($users); diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index f697b10a01..b18b2a4b91 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -326,6 +326,7 @@ function reporting_html_print_report($report, $mini=false, $report_info=1) case 'netflow_area': case 'netflow_data': case 'netflow_summary': + case 'netflow_top_N': reporting_html_graph($table, $item); break; @@ -377,6 +378,10 @@ function reporting_html_print_report($report, $mini=false, $report_info=1) reporting_html_agent_module($table, $item); break; + case 'agent_module_status': + reporting_html_agent_module_status($table, $item); + break; + case 'alert_report_actions': reporting_html_alert_report_actions($table, $item); break; @@ -1999,6 +2004,125 @@ function reporting_html_agent_module($table, $item) } +/** + * Html report agent modules status. + * + * @param object $table Head table or false if it comes from pdf. + * @param array $item Items data. + * @param integer $pdf Pdf output. + * + * @return mixed + */ +function reporting_html_agent_module_status($table, $item, $pdf=0) +{ + global $config; + + $return_pdf = ''; + + if (empty($item['data']) === true) { + if ($pdf !== 0) { + $return_pdf .= __('No items'); + } else { + $table->colspan['group_report']['cell'] = 3; + $table->cellstyle['group_report']['cell'] = 'text-align: center;'; + $table->data['group_report']['cell'] = __('No items'); + } + } else { + $table_info = new stdClass(); + $table_info->width = '99%'; + + $table_info->align = []; + if (is_metaconsole() === true) { + $table_info->align['server'] = 'left'; + } + + $table_info->align['name_group'] = 'left'; + $table_info->align['name_agent'] = 'left'; + $table_info->align['name_module'] = 'left'; + $table_info->align['status_module'] = 'left'; + $table_info->align['data_module'] = 'left'; + $table_info->align['data_time_module'] = 'left'; + + $table_info->headstyle = []; + if (is_metaconsole() === true) { + $table_info->headstyle['server'] = 'text-align: left'; + } + + $table_info->headstyle['name_group'] = 'text-align: left'; + $table_info->headstyle['name_agent'] = 'text-align: left'; + $table_info->headstyle['name_module'] = 'text-align: left'; + $table_info->headstyle['status_module'] = 'text-align: left'; + $table_info->headstyle['data_module'] = 'text-align: left'; + $table_info->headstyle['data_time_module'] = 'text-align: left'; + + $table_info->head = []; + if (is_metaconsole() === true) { + $table_info->head['server'] = __('Server'); + } + + $table_info->head['name_agent'] = __('Agent'); + $table_info->head['name_module'] = __('Module'); + $table_info->head['name_group'] = __('Group'); + $table_info->head['status_module'] = __('Status'); + $table_info->head['data_module'] = __('Data'); + $table_info->head['data_time_module'] = __('Last time'); + + $table_info->data = []; + + foreach ($item['data'] as $server => $info) { + foreach ($info as $data) { + $row = []; + if (is_metaconsole() === true) { + $row['server'] = $server; + } + + $row['name_agent'] = $data['name_agent']; + $row['name_module'] = $data['name_module']; + $row['name_group'] = $data['name_group']; + $row['status_module'] = ui_print_module_status( + $data['status_module'], + true, + 'status_rounded_rectangles', + null, + ($pdf === 1) ? '       ' : '' + ); + + if (is_numeric($data['data_module']) === true) { + $row['data_module'] = remove_right_zeros( + number_format( + $data['data_module'], + $config['graph_precision'] + ) + ); + } else { + $row['data_module'] = (empty($data['data_module']) === true) ? '--' : $data['data_module']; + } + + $row['data_module'] .= $data['unit_module']; + $row['data_time_module'] = $data['data_time_module']; + + $table_info->data[] = $row; + } + } + + if ($pdf !== 0) { + $table_info->title = $item['title']; + $table_info->titleclass = 'title_table_pdf'; + $table_info->titlestyle = 'text-align:left;'; + $return_pdf .= html_print_table($table_info, true); + } else { + $table->colspan['data']['cell'] = 3; + $table->cellstyle['data']['cell'] = 'text-align: center;'; + $table->data['data']['cell'] = html_print_table($table_info, true); + } + } + + if ($pdf !== 0) { + return $return_pdf; + } +} + + /** * Function to print to HTML Exception report. * diff --git a/pandora_console/include/functions_reports.php b/pandora_console/include/functions_reports.php index f310856ad2..f8fa28a0e7 100755 --- a/pandora_console/include/functions_reports.php +++ b/pandora_console/include/functions_reports.php @@ -653,7 +653,8 @@ function reports_get_report_types($template=false, $not_editor=false) 'optgroup' => __('Graphs'), 'name' => __('Custom graph'), ]; - // Only pandora managers have access to the whole database + + // Only pandora managers have access to the whole database. if (check_acl($config['id_user'], 0, 'PM')) { $types['sql_graph_vbar'] = [ 'optgroup' => __('Graphs'), @@ -711,7 +712,7 @@ function reports_get_report_types($template=false, $not_editor=false) 'name' => __('Hourly S.L.A.'), ]; - if (!$config['metaconsole'] && !$template) { + if ($template === false) { $types['SLA_services'] = [ 'optgroup' => __('SLA'), 'name' => __('Services S.L.A.'), @@ -796,6 +797,11 @@ function reports_get_report_types($template=false, $not_editor=false) } } + $types['agent_module_status'] = [ + 'optgroup' => __('Grouped'), + 'name' => __('Agents/Modules status'), + ]; + // Only pandora managers have access to the whole database. if (check_acl($config['id_user'], 0, 'PM')) { $types['sql'] = [ @@ -901,6 +907,10 @@ function reports_get_report_types($template=false, $not_editor=false) 'optgroup' => __('Netflow'), 'name' => __('Netflow summary table'), ]; + $types['netflow_top_N'] = [ + 'optgroup' => __('Netflow'), + 'name' => __('Netflow top-N connections'), + ]; } if ($config['enterprise_installed'] && $template === false && !is_metaconsole()) { diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index b3b66a4a9b..e25a5d74bb 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -2713,16 +2713,15 @@ function ui_print_status_image( $imagepath = $path; } - if ($imagepath == 'images/status_sets/default') { + if ($imagepath === 'images/status_sets/default') { $image_with_css = true; } - $imagepath .= '/'.$type; - if ($image_with_css === true) { $shape_status = get_shape_status_set($type); return ui_print_status_sets($type, $title, $return, $shape_status, $extra_info); } else { + $imagepath .= '/'.$type; if ($options === false) { $options = []; } @@ -2737,10 +2736,11 @@ function ui_print_status_image( /** * Returns html code to print a shape for a module. * - * @param integer $status Module status. - * @param boolean $return True or false. - * @param string $class Custom class or use defined. - * @param string $title Custom title or inherit from module status. + * @param integer $status Module status. + * @param boolean $return True or false. + * @param string $class Custom class or use defined. + * @param string $title Custom title or inherit from module status. + * @param string $div_content Content. * * @return string HTML code for shape. */ @@ -2748,7 +2748,8 @@ function ui_print_module_status( $status, $return=false, $class='status_rounded_rectangles', - $title=null + $title=null, + $div_content='' ) { $color = modules_get_color_status($status, true); if ($title === null) { @@ -2758,7 +2759,7 @@ function ui_print_module_status( $output = '
'; + $output .= $title.'" data-use_title_for_force_title="1">'.$div_content.'
'; if ($return === false) { echo $output; @@ -2869,7 +2870,7 @@ function ui_print_status_sets( $options = []; } - if (isset($options['style'])) { + if (isset($options['style']) === true) { $options['style'] .= ' display: inline-block;'; } else { $options['style'] = 'display: inline-block;'; @@ -2879,15 +2880,15 @@ function ui_print_status_sets( $options['style'] .= ' background: '.modules_get_color_status($status).';'; } - if (isset($options['class'])) { + if (isset($options['class']) === true) { $options['class'] = $options['class']; } - if ($title != '') { - $options['title'] = empty($extra_info) ? $title : $title.' '.$extra_info; - $options['data-title'] = empty($extra_info) ? $title : $title.'
'.$extra_info; + if (empty($title) === false) { + $options['title'] = (empty($extra_info) === true) ? $title : $title.' '.$extra_info; + $options['data-title'] = (empty($extra_info) === true) ? $title : $title.'
'.$extra_info; $options['data-use_title_for_force_title'] = 1; - if (isset($options['class'])) { + if (isset($options['class']) === true) { $options['class'] .= ' forced_title'; } else { $options['class'] = 'forced_title'; @@ -2899,15 +2900,13 @@ function ui_print_status_sets( $output .= $k.'="'.$v.'"'; } - $output .= '>'; - $output .= ''; + $output .= '> '; if ($return === false) { echo $output; + } else { + return $output; } - - return $output; - } @@ -3618,6 +3617,15 @@ function ui_print_datatable(array $parameters) ui_require_javascript_file('buttons.html5.min'); ui_require_javascript_file('buttons.print.min'); } else { + // Load datatable.min.css. + $output .= ''; // Load tables.css. $output .= ''; if (empty($alias)) { $buffer .= ui_print_truncate_text($title, $numChars); } else { $buffer .= ui_print_truncate_text($alias, $numChars); } + $buffer .= ''; + if ($modal && !enterprise_installed()) { $buffer .= "
diff --git a/pandora_console/include/functions_users.php b/pandora_console/include/functions_users.php index a0cac33b30..f4e6e25be8 100755 --- a/pandora_console/include/functions_users.php +++ b/pandora_console/include/functions_users.php @@ -777,10 +777,13 @@ function users_get_groups_UM($id_user) /** * Obtiene una matriz con los grupos como clave y si tiene o no permiso UM sobre ese grupo(valor) * - * @param string User id + * @param string $id_group User id. + * @param boolean $um Um. + * @param boolean $disabled Reurn also disabled users. + * * @return array Return . */ -function users_get_users_by_group($id_group, $um=false) +function users_get_users_by_group($id_group, $um=false, $disabled=true) { $sql = sprintf( "SELECT tusuario.* FROM tusuario @@ -789,6 +792,10 @@ function users_get_users_by_group($id_group, $um=false) $id_group ); + if ($disabled === false) { + $sql .= 'WHERE tusuario.disabled = 0'; + } + $users = db_get_all_rows_sql($sql); $return = []; foreach ($users as $key => $user) { diff --git a/pandora_console/include/functions_visual_map.php b/pandora_console/include/functions_visual_map.php index f05d0de6e2..9e43dd27f3 100755 --- a/pandora_console/include/functions_visual_map.php +++ b/pandora_console/include/functions_visual_map.php @@ -4139,7 +4139,7 @@ function visual_map_get_layout_status($layout_id, $status_data=[], $depth=0) if ($critical_percentage >= $status_data['linked_layout_status_as_service_critical'] && $critical_percentage !== 0) { return VISUAL_MAP_STATUS_CRITICAL_BAD; - } else if ($critical_percentage >= $status_data['linked_layout_status_as_service_warning'] && $warning_percentage !== 0) { + } else if ($warning_percentage >= $status_data['linked_layout_status_as_service_warning'] && $warning_percentage !== 0) { return VISUAL_MAP_STATUS_WARNING; } else { return VISUAL_MAP_STATUS_NORMAL; @@ -4538,3 +4538,53 @@ function visual_map_load_client_resources() } } } + + +/** + * Labels styles visual console. + * + * @param string $uniq Uniq str. + * @param integer $ratio Ratio. + * + * @return string Css output. + */ +function css_label_styles_visual_console($uniq, $ratio=1) +{ + global $config; + $output = ''; + // Horrible trick! due to the use of tinyMCE + // it is necessary to modify specific classes of each + // of the visual consoles. + $output .= '.c-'.$uniq.' a {color: #3f3f3f } '; + $output .= '.c-'.$uniq.' .label p strong span {display: inline-block !important; line-height: normal !important} '; + $output .= '.c-'.$uniq.' *:not(.parent_graph p table tr td span) { font-size: '.(8 * $ratio).'pt; line-height:'.(8 * ($ratio)).'pt; }'; + $output .= '.c-'.$uniq.' .visual-console-item-label table tr td { padding: 0; margin: 0; }'; + $output .= '.c-'.$uniq.' .visual_font_size_4pt, .c-'.$uniq.' .visual_font_size_4pt * { font-size: '.(4 * $ratio).'pt !important; line-height:'.(4 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_6pt, .c-'.$uniq.' .visual_font_size_6pt * { font-size: '.(6 * $ratio).'pt !important; line-height:'.(6 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_8pt, .c-'.$uniq.' .visual_font_size_8pt * { font-size: '.(8 * $ratio).'pt !important; line-height:'.(8 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_10pt, .c-'.$uniq.' .visual_font_size_10pt * { font-size: '.(10 * $ratio).'pt !important; line-height:'.(10 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_12pt, .c-'.$uniq.' .visual_font_size_12pt * { font-size: '.(12 * $ratio).'pt !important; line-height:'.(12 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_14pt, .c-'.$uniq.' .visual_font_size_14pt * { font-size: '.(14 * $ratio).'pt !important; line-height:'.(14 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_18pt, .c-'.$uniq.' .visual_font_size_18pt * { font-size: '.(18 * $ratio).'pt !important; line-height:'.(18 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_24pt, .c-'.$uniq.' .visual_font_size_24pt * { font-size: '.(24 * $ratio).'pt !important; line-height:'.(24 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_28pt, .c-'.$uniq.' .visual_font_size_28pt * { font-size: '.(28 * $ratio).'pt !important; line-height:'.(28 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_36pt, .c-'.$uniq.' .visual_font_size_36pt * { font-size: '.(36 * $ratio).'pt !important; line-height:'.(36 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_48pt, .c-'.$uniq.' .visual_font_size_48pt * { font-size: '.(48 * $ratio).'pt !important; line-height:'.(48 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_60pt, .c-'.$uniq.' .visual_font_size_60pt * { font-size: '.(60 * $ratio).'pt !important; line-height:'.(60 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_72pt, .c-'.$uniq.' .visual_font_size_72pt * { font-size: '.(72 * $ratio).'pt !important; line-height:'.(72 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_84pt, .c-'.$uniq.' .visual_font_size_84pt * { font-size: '.(84 * $ratio).'pt !important; line-height:'.(84 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_96pt, .c-'.$uniq.' .visual_font_size_96pt * { font-size: '.(96 * $ratio).'pt !important; line-height:'.(96 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_116pt, .c-'.$uniq.' .visual_font_size_116pt * { font-size: '.(116 * $ratio).'pt !important; line-height:'.(116 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_128pt, .c-'.$uniq.' .visual_font_size_128pt * { font-size: '.(128 * $ratio).'pt !important; line-height:'.(128 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_140pt, .c-'.$uniq.' .visual_font_size_140pt * { font-size: '.(140 * $ratio).'pt !important; line-height:'.(140 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_154pt, .c-'.$uniq.' .visual_font_size_154pt * { font-size: '.(154 * $ratio).'pt !important; line-height:'.(154 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual_font_size_196pt, .c-'.$uniq.' .visual_font_size_196pt * { font-size: '.(196 * $ratio).'pt !important; line-height:'.(196 * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .flot-text, .c-'.$uniq.' .flot-text * { font-size: '.(($config['font_size'] - 2) * $ratio).'pt !important; line-height:'.(($config['font_size'] - 2) * ($ratio)).'pt !important; }'; + $output .= '.c-'.$uniq.' .visual-console-item .digital-clock span.time {font-size: '.(50 * $ratio).'px !important; line-height: '.(50 * $ratio).'px !important;}'; + $output .= '.c-'.$uniq.' .visual-console-item .digital-clock span.date {font-size: '.(25 * $ratio).'px !important; line-height: '.(25 * $ratio).'px !important;}'; + $output .= '.c-'.$uniq.' .visual-console-item .digital-clock span.timezone {font-size: '.(25 * $ratio).'px !important; line-height: '.(25 * $ratio).'px !important;}'; + $output .= '.c-'.$uniq.' .visual-console-item .donut-graph * {font-size: '.(8 * $ratio).'px !important; line-height: '.(8 * $ratio).'px !important;}'; + $output .= '.c-'.$uniq.' .visual-console-item .donut-graph g rect {width:'.(25 * $ratio).' !important; height: '.(15 * $ratio).' !important;}'; + + return $output; +} diff --git a/pandora_console/include/javascript/pandora.js b/pandora_console/include/javascript/pandora.js index e26cd5e2a8..677b507285 100644 --- a/pandora_console/include/javascript/pandora.js +++ b/pandora_console/include/javascript/pandora.js @@ -1040,6 +1040,7 @@ function adjustTextUnits(name) { "selected", true ); + $("#" + name + "_units").trigger("change"); $("#text-" + name + "_text").val(restPrev); unitsSelected = true; } @@ -1048,7 +1049,9 @@ function adjustTextUnits(name) { }); if (unitsSelected == false) { + //$("#" + name + "_units option:last").prop("selected", true); $("#" + name + "_units option:last").prop("selected", true); + $("#" + name + "_units").trigger("change"); $("#text-" + name + "_text").val(restPrev); } @@ -2017,3 +2020,11 @@ function progressBarSvg(option) { return svg; } + +function inArray(needle, haystack) { + var length = haystack.length; + for (var i = 0; i < length; i++) { + if (haystack[i] == needle) return true; + } + return false; +} diff --git a/pandora_console/include/javascript/pandora_agents.js b/pandora_console/include/javascript/pandora_agents.js new file mode 100644 index 0000000000..a0ce0614a3 --- /dev/null +++ b/pandora_console/include/javascript/pandora_agents.js @@ -0,0 +1,169 @@ +/* globals $ */ +// eslint-disable-next-line no-unused-vars +function agent_manager_add_secondary_groups( + event, + id_agent, + extra_id, + id_form, + dictionary +) { + event.preventDefault(); + var primary_value = $("#grupo").val(); + dictionary = JSON.parse(atob(dictionary)); + // The selected primary value cannot be selected like secondary. + if ( + $( + "#secondary_groups" + + extra_id + + " option:selected[value=" + + primary_value + + "]" + ).length > 0 + ) { + alert(dictionary.primary_group); + return; + } + + // On agent creation PHP will update the secondary groups table (not via AJAX). + if (id_agent == 0) { + agent_manager_add_secondary_groups_ui(extra_id); + agent_manager_update_hidden_input_secondary(id_form, extra_id); + return; + } + + var selected_items = new Array(); + $("#secondary_groups" + extra_id + " option:selected").each(function() { + selected_items.push($(this).val()); + }); + + var data = { + page: "godmode/agentes/agent_manager", + id_agent: id_agent, + groups: selected_items, + add_secondary_groups: 1 + }; + + // Make the AJAX call to update the secondary groups. + $.ajax({ + type: "POST", + url: "ajax.php", + dataType: "html", + data: data, + success: function(data) { + if (data == 1) { + agent_manager_add_secondary_groups_ui(extra_id); + } else { + console.error("Error in AJAX call to add secondary groups"); + } + }, + error: function(data) { + console.error( + "Fatal error in AJAX call to add secondary groups: " + data + ); + } + }); +} + +// eslint-disable-next-line no-unused-vars +function agent_manager_remove_secondary_groups( + event, + id_agent, + extra_id, + id_form, + dictionary +) { + event.preventDefault(); + + dictionary = JSON.parse(atob(dictionary)); + // On agent creation PHP will update the secondary groups table (not via AJAX). + if (id_agent == 0) { + agent_manager_remove_secondary_groups_ui(dictionary.strNone, extra_id); + agent_manager_update_hidden_input_secondary(id_form, extra_id); + return; + } + + var selected_items = new Array(); + $("#secondary_groups_selected" + extra_id + " option:selected").each( + function() { + selected_items.push($(this).val()); + } + ); + + var data = { + page: "godmode/agentes/agent_manager", + id_agent: id_agent, + groups: selected_items, + remove_secondary_groups: 1 + }; + + // Make the AJAX call to update the secondary groups. + $.ajax({ + type: "POST", + url: "ajax.php", + dataType: "html", + data: data, + success: function(data) { + if (data == 1) { + agent_manager_remove_secondary_groups_ui(dictionary.strNone, extra_id); + } else { + console.error("Error in AJAX call to add secondary groups"); + } + }, + error: function(data) { + console.error( + "Fatal error in AJAX call to add secondary groups: " + data + ); + } + }); +} + +// Move from left input to right input. +function agent_manager_add_secondary_groups_ui(extra_id) { + $("#secondary_groups_selected" + extra_id + " option[value=0]").remove(); + $("#secondary_groups" + extra_id + " option:selected").each(function() { + $(this) + .remove() + .appendTo("#secondary_groups_selected" + extra_id); + }); +} + +// Move from right input to left input. +function agent_manager_remove_secondary_groups_ui(strNone, extra_id) { + // Remove the groups selected if success. + $("#secondary_groups_selected" + extra_id + " option:selected").each( + function() { + $(this) + .remove() + .appendTo("#secondary_groups" + extra_id); + } + ); + + // Add none if empty select. + if ($("#secondary_groups_selected" + extra_id + " option").length == 0) { + $("#secondary_groups_selected" + extra_id).append( + $("