diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 2f579d46f1..6a65e22674 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.740-191113 +Version: 7.0NG.740-191118 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 74a6e96001..775e895a8e 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.740-191113" +pandora_version="7.0NG.740-191118" 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 0dfcf8848a..1423f42e01 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -55,7 +55,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.740'; -use constant AGENT_BUILD => '191113'; +use constant AGENT_BUILD => '191118'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; @@ -296,6 +296,77 @@ sub load_libraries() { } } +################################################################################ +# Erase blank spaces before and after the string +################################################################################ +sub trim { + my $string = shift; + if (empty($string)){ + return ""; + } + + $string =~ s/\r//g; + + chomp($string); + $string =~ s/^\s+//g; + $string =~ s/\s+$//g; + + return $string; +} + +################################################################################ +# Mix hashses +################################################################################ +sub merge_hashes { + my $_h1 = shift; + my $_h2 = shift; + + if (ref($_h1) ne "HASH") { + return \%{$_h2} if (ref($_h2) eq "HASH"); + } + + if (ref($_h2) ne "HASH") { + return \%{$_h1} if (ref($_h1) eq "HASH"); + } + + if ((ref($_h1) ne "HASH") && (ref($_h2) ne "HASH")) { + return {}; + } + + my %ret = (%{$_h1}, %{$_h2}); + + return \%ret; +} + +################################################################################ +# Empty +################################################################################ +sub empty { + my $str = shift; + + if (!(defined($str)) ){ + return 1; + } + + if(looks_like_number($str)){ + return 0; + } + + if (ref($str) eq "ARRAY") { + return (($#{$str}<0)?1:0); + } + + if (ref($str) eq "HASH") { + my @tmp = keys %{$str}; + return (($#tmp<0)?1:0); + } + + if ($str =~ /^\ *[\n\r]{0,2}\ *$/) { + return 1; + } + return 0; +} + ################################################################################ # Check a regular expression. Returns 1 if its valid, 0 otherwise. ################################################################################ @@ -731,13 +802,6 @@ sub parse_conf_modules($) { # Macros } elsif ($line =~ /^\s*module_macro(\S+)\s+(.*)\s*$/) { $module->{'macros'}{$1} = $2; - # Commands - } elsif ($line =~ /^\s*cmd_file\s+(.+)$/) { - if (ref ($Conf{'commands'}) ne "HASH") { - $Conf{'commands'} = {}; - } - # Initialize empty command hash. - $Conf{'commands'}->{$1} = {}; } } return; @@ -832,7 +896,21 @@ sub read_config (;$) { next if ($line =~ /^module\s*\w*/); #Configuration token - if ($line =~ /^\s*(\S+)\s+(.*)$/) { + if ($line =~ /^\s*(\S+)\s+(.*)$/) { + # Reserved keyword. + next if ($1 eq "commands"); + + if ($1 eq "cmd_file") { + # Commands + if (ref ($Conf{'commands'}) ne "HASH") { + $Conf{'commands'} = {}; + } + # Initialize empty command hash. + $Conf{'commands'}->{$2} = {}; + log_message('setup', "Command required $2"); + next; + } + log_message ('setup', "$1 is $2"); $Conf{$1} = $2; @@ -979,6 +1057,7 @@ sub read_config (;$) { $Conf{'secondary_server_opts'} = '-x \'' . $Conf{'secondary_server_pwd'} . '\' ' . $Conf{'secondary_server_opts'} if ($Conf{'secondary_server_pwd'} ne ''); $Conf{'secondary_server_opts'} = '-c ' . $Conf{'secondary_server_opts'} if ($Conf{'secondary_server_ssl'} eq '1'); } + } ################################################################################# @@ -1289,6 +1368,10 @@ sub check_remote_config () { %Collections = (); %Conf = %DefaultConf; + # Supposed to discard current configuration but not. + # Cleanup old commands configuration. + $Conf{'commands'} = {}; + # Reload the new configuration read_config (); @@ -1421,7 +1504,7 @@ sub check_collections () { ################################################################################ # Check for remote commands defined. ################################################################################ -sub prepare_remote_commands { +sub prepare_commands { if ($YAML == 0) { log_message( 'error', @@ -1430,13 +1513,27 @@ sub prepare_remote_commands { return; } + # Force configuration file read. + my @commands = read_config('cmd_file'); + + if (empty(\@commands)) { + $Conf{'commands'} = {}; + } else { + foreach my $rcmd (@commands) { + $Conf{'commands'}->{trim($rcmd)} = {}; + } + } + + # Cleanup old commands. Not registered. + cleanup_old_commands(); + foreach my $ref (keys %{$Conf{'commands'}}) { my $file_content; my $download = 0; my $rcmd_file = $ConfDir.'/commands/'.$ref.'.rcmd'; # Check for local .rcmd.done files - if (-e $Conf{'temporal'}.'/'.$ref.'.rcmd.done') { + if (-e $rcmd_file.'.done') { # Ignore. delete $Conf{'commands'}->{$ref}; next; @@ -1531,19 +1628,101 @@ sub report_command { return $return; } +################################################################################ +# Cleanup unreferenced rcmd and rcmd.done files. +################################################################################ +sub cleanup_old_commands { + # Cleanup old .rcmd and .rcmd.done files. + my %registered = map { $_.'.rcmd' => 1 } keys %{$Conf{'commands'}}; + if(opendir(my $dir, $ConfDir.'/commands/')) { + while (my $item = readdir($dir)) { + + # Skip other files. + next if ($item !~ /\.rcmd$/); + + # Clean .rcmd.done file if its command is not referenced in conf. + if (!defined($registered{$item})) { + if (-e $ConfDir.'/commands/'.$item) { + unlink($ConfDir.'/commands/'.$item); + } + if (-e $ConfDir.'/commands/'.$item.'.done') { + unlink($ConfDir.'/commands/'.$item.'.done'); + } + } + } + + # Close dir. + closedir($dir); + } + +} + ################################################################################ # Executes a command using defined timeout. ################################################################################ sub execute_command_timeout { - my ($command, $timeout) = @_; + my ($cmd, $timeout) = @_; - if (!looks_like_number($timeout)) { - `$command`; - } else { - `$command`; + if (!defined($timeout) + || !looks_like_number($timeout) + || $timeout <= 0 + ) { + `$cmd`; + return $?>>8; } - return $?>>8; + my $remaining_timeout = $timeout; + + my $RET; + my $output; + + my $pid = open ($RET, "-|"); + if (!defined($pid)) { + # Failed to fork. + log_message('error', '[command] Failed to fork.'); + return undef; + } + if ($pid == 0) { + # Child. + my $ret; + eval { + local $SIG{ALRM} = sub { die "timeout\n" }; + alarm $timeout; + `$cmd`; + alarm 0; + }; + + my $result = ($?>>8); + print $result; + + # Exit child. + # Child finishes. + exit; + + } else { + # Parent waiting. + while( --$remaining_timeout > 0 ){ + if (wait == -1) { + last; + } + # Wait child up to timeout seconds. + sleep 1; + } + } + + if ($remaining_timeout > 0) { + # Retrieve output from child. + $output = do { local $/; <$RET> }; + $output = $output>>8; + } + else { + # Timeout expired. + return 124; + } + + close($RET); + + return $output; } ################################################################################ @@ -1552,28 +1731,48 @@ sub execute_command_timeout { # $std_files = ' >> /tmp/stdout 2>> /tmp/stderr ################################################################################ sub execute_command_block { - my ($commands, $std_files, $timeout) = @_; + my ($commands, $std_files, $timeout, $retry) = @_; return 0 unless defined($commands); + my $retries = $retry; + + $retries = 1 unless looks_like_number($retries) && $retries > 0; + my $err_level = 0; $std_files = '' unless defined ($std_files); if (ref($commands) ne "ARRAY") { return 0 if $commands eq ''; - $err_level = execute_command_timeout( - "($commands) $std_files", - $timeout - ); + + do { + $err_level = execute_command_timeout( + "($commands) $std_files", + $timeout + ); + + # Do not retry if success. + last if looks_like_number($err_level) && $err_level == 0; + } while ((--$retries) > 0); } else { foreach my $comm (@{$commands}) { next unless defined($comm); - $err_level = execute_command_timeout( - "($comm) $std_files", - $timeout - ); + $retries = $retry; + $retries = 1 unless looks_like_number($retries) && $retries > 0; + do { + $err_level = execute_command_timeout( + "($comm) $std_files", + $timeout + ); + + # Do not retry if success. + last if looks_like_number($err_level) && $err_level == 0; + + } while ((--$retries) > 0); + + # Do not continue evaluating block if failed. last unless ($err_level == 0); } } @@ -3271,24 +3470,8 @@ while (1) { # Check file collections check_collections () unless ($Conf{'debug'} eq '1'); - if ($Conf{'debug'} ne '1') { - # Check remote commands - prepare_remote_commands (); - - # Cleanup old .rcmd.done files. - my %registered = map { $_.'.rcmd.done' => 1 } keys %{$Conf{'commands'}}; - if(opendir(my $dir, $ConfDir.'/commands/')) { - while (my $item = readdir($dir)) { - # Skip other files. - next if ($item !~ /\.rcmd\.done$/); - - # Clean .rcmd.done file if its command is not referenced in conf. - if (!defined($registered{$item})) { - unlink ($item); - } - } - } - } + # Check scheduled commands + prepare_commands() unless ($Conf{'debug'} eq '1'); # Launch broker agents @BrokerPid = (); diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index 05f8c89559..8707f0cea4 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.740 -%define release 191113 +%define release 191118 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 18ac2f32c0..624fe728fc 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.740 -%define release 191113 +%define release 191118 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 bf85762a39..19e2eac0ea 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.740" -PI_BUILD="191113" +PI_BUILD="191118" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index be5a498d11..04238d3924 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{191113} +{191118} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index b268f7f436..157d2ebe66 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.740(Build 191113)") +#define PANDORA_VERSION ("7.0NG.740(Build 191118)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index e2707bff53..de7973252d 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.740(Build 191113))" + VALUE "ProductVersion", "(7.0NG.740(Build 191118))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 45e4ec20f1..6a00d319d9 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.740-191113 +Version: 7.0NG.740-191118 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 cf617bb4e3..aa35237934 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.740-191113" +pandora_version="7.0NG.740-191118" package_pear=0 package_pandora=1 diff --git a/pandora_console/extensions/quick_shell.php b/pandora_console/extensions/quick_shell.php index 13924f56e2..a8cce0b8de 100644 --- a/pandora_console/extensions/quick_shell.php +++ b/pandora_console/extensions/quick_shell.php @@ -218,7 +218,8 @@ function quickShell() if (empty($config['gotty_user']) === false && empty($config['gotty_pass']) === false ) { - $auth_str = $config['gotty_user'].':'.$config['gotty_pass']; + $auth_str = io_safe_output($config['gotty_user']); + $auth_str .= ':'.io_output_password($config['gotty_pass']); $gotty_url = $auth_str.'@'.$host.':'.$port; } @@ -381,7 +382,12 @@ function quickShellSettings() } // Interface. - ui_print_page_header(__('QuickShell settings')); + ui_print_page_header( + __('QuickShell settings'), + '', + false, + 'quickshell_settings' + ); if ($changes > 0) { $msg = __('%d Updated', $changes); @@ -442,25 +448,31 @@ function quickShellSettings() ], ], [ - 'label' => __('Gotty user').ui_print_help_tip( - __('Optional, set a user to access gotty service'), - true - ), - 'arguments' => [ - 'type' => 'text', - 'name' => 'gotty_user', - 'value' => $config['gotty_user'], - ], - ], - [ - 'label' => __('Gotty password').ui_print_help_tip( - __('Optional, set a password to access gotty service'), - true - ), - 'arguments' => [ - 'type' => 'password', - 'name' => 'gotty_pass', - 'value' => io_output_password($config['gotty_pass']), + 'toggle' => true, + 'toggle_name' => 'Advanced', + 'block_content' => [ + [ + 'label' => __('Gotty user').ui_print_help_tip( + __('Optional, set a user to access gotty service'), + true + ), + 'arguments' => [ + 'type' => 'text', + 'name' => 'gotty_user', + 'value' => $config['gotty_user'], + ], + ], + [ + 'label' => __('Gotty password').ui_print_help_tip( + __('Optional, set a password to access gotty service'), + true + ), + 'arguments' => [ + 'type' => 'password', + 'name' => 'gotty_pass', + 'value' => io_output_password($config['gotty_pass']), + ], + ], ], ], [ diff --git a/pandora_console/extras/mr/33.sql b/pandora_console/extras/mr/33.sql index 84e1d4edb0..e7396397d5 100644 --- a/pandora_console/extras/mr/33.sql +++ b/pandora_console/extras/mr/33.sql @@ -30,12 +30,16 @@ CREATE TABLE `tremote_command_target` ( `rcmd_id` bigint unsigned NOT NULL, `id_agent` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, - `stdout` text, - `stderr` text, + `stdout` MEDIUMTEXT, + `stderr` MEDIUMTEXT, `errorlevel` int(10) unsigned NOT NULL default 0, PRIMARY KEY (`id`), FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO `tconfig`(`token`, `value`) VALUES ('welcome_state', -1); + +ALTER TABLE `tcredential_store` MODIFY COLUMN `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE', 'SAP') default 'CUSTOM'; + COMMIT; diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index 7ec1e1d562..9fcd845c6e 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -2249,7 +2249,7 @@ CREATE TABLE `tvisual_console_elements_cache` ( CREATE TABLE IF NOT EXISTS `tcredential_store` ( `identifier` varchar(100) NOT NULL, `id_group` mediumint(4) unsigned NOT NULL DEFAULT 0, - `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE') default 'CUSTOM', + `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE', 'SAP') default 'CUSTOM', `username` text, `password` text, `extra_1` text, @@ -2327,8 +2327,8 @@ CREATE TABLE `tremote_command_target` ( `rcmd_id` bigint unsigned NOT NULL, `id_agent` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, - `stdout` text, - `stderr` text, + `stdout` MEDIUMTEXT, + `stderr` MEDIUMTEXT, `errorlevel` int(10) unsigned NOT NULL default 0, PRIMARY KEY (`id`), FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) diff --git a/pandora_console/general/sap_view.php b/pandora_console/general/sap_view.php new file mode 100644 index 0000000000..58ee50e563 --- /dev/null +++ b/pandora_console/general/sap_view.php @@ -0,0 +1,77 @@ + '[sap_views]'.$e->getMessage() ]); + exit; + } else { + echo '[sap_views]'.$e->getMessage(); + } + + // Stop this execution, but continue 'globally'. + return; +} + +// Ajax controller. +if (is_ajax()) { + $method = get_parameter('method', ''); + + if (method_exists($sap_views, $method) === true) { + if ($sap_views->ajaxMethod($method) === true) { + $sap_views->{$method}(); + } else { + $sap_views->error('Unavailable method.'); + } + } else { + $sap_views->error('Method not found. ['.$method.']'); + } + + + // Stop any execution. + exit; +} else { + // Run. + $sap_views->run(); +} diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 61d33193d3..4f6c3e463e 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -486,6 +486,20 @@ if ($id_agente) { $agent_wizard['active'] = false; } + $is_sap = agents_get_sap_agents($id_agente); + if ($is_sap) { + $saptab['text'] = ''.html_print_image('images/sap_icon.png', true, ['title' => __('SAP view')]).''; + + if ($tab == 'sap_view') { + $saptab['active'] = true; + } else { + $saptab['active'] = false; + } + } else { + $saptab = ''; + } + + $total_incidents = agents_get_count_incidents($id_agente); // Incident tab. @@ -531,6 +545,7 @@ if ($id_agente) { 'group' => $grouptab, 'gis' => $gistab, 'agent_wizard' => $agent_wizard, + 'sap_view' => $saptab, ]; } else { $onheader = [ @@ -546,6 +561,8 @@ if ($id_agente) { 'group' => $grouptab, 'gis' => $gistab, 'agent_wizard' => $agent_wizard, + 'sap_view' => $saptab, + ]; } @@ -691,6 +708,12 @@ if ($id_agente) { } break; + case 'sap_view': + $tab_description = '- '.__('SAP view'); + $help_header = 'sap_view'; + $tab_name = 'SAP View'; + break; + default: // Default. break; @@ -2346,6 +2369,10 @@ switch ($tab) { include 'agent_wizard.php'; break; + case 'sap_view': + include 'general/sap_view.php'; + break; + default: if (enterprise_hook('switch_agent_tab', [$tab])) { // This will make sure that blank pages will have at least some diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 3a9e3de9c0..af09d9ff0d 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -28,7 +28,7 @@ if (check_acl($config['id_user'], 0, 'AR') || check_acl($config['id_user'], 0, 'PM') ) { $sub = []; - $sub['godmode/servers/discovery&wiz=main']['text'] = __('Main'); + $sub['godmode/servers/discovery&wiz=main']['text'] = __('Start'); $sub['godmode/servers/discovery&wiz=main']['id'] = 'Discovery'; $sub['godmode/servers/discovery&wiz=tasklist']['text'] = __('Task list'); $sub['godmode/servers/discovery&wiz=tasklist']['id'] = 'tasklist'; diff --git a/pandora_console/godmode/servers/discovery.php b/pandora_console/godmode/servers/discovery.php index 2d0fcec8a1..7215ee7dfb 100755 --- a/pandora_console/godmode/servers/discovery.php +++ b/pandora_console/godmode/servers/discovery.php @@ -54,7 +54,7 @@ function get_wiz_class($str) __('Discovery'), '', false, - '', + 'discovery', true, '', false, diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 9b12f2ee36..da6f4e572e 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -773,6 +773,9 @@ class DiscoveryTaskList extends Wizard case DISCOVERY_CLOUD_AWS_RDS: return 'wiz=cloud&mode=amazonws&ki='.$task['auth_strings'].'&sub=rds&page=0'; + case DISCOVERY_APP_SAP: + return 'wiz=app&mode=SAP&page=0'; + default: if ($task['description'] == 'console_task') { return 'wiz=ctask'; diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index 6f1d59d56b..30b0706342 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -458,6 +458,7 @@ class Wizard if (is_array($input['block_content']) === true) { $direct = (bool) $input['direct']; + $toggle = (bool) $input['toggle']; // Print independent block of inputs. $output .= '
  • '; @@ -471,14 +472,37 @@ class Wizard $output .= ''; diff --git a/pandora_console/images/sap_icon.png b/pandora_console/images/sap_icon.png new file mode 100644 index 0000000000..536c43b28b Binary files /dev/null and b/pandora_console/images/sap_icon.png differ diff --git a/pandora_console/include/class/CredentialStore.class.php b/pandora_console/include/class/CredentialStore.class.php index b453318c4b..cf315d4a5b 100644 --- a/pandora_console/include/class/CredentialStore.class.php +++ b/pandora_console/include/class/CredentialStore.class.php @@ -432,7 +432,7 @@ class CredentialStore extends Wizard return $return; } - return false; + return []; } @@ -866,6 +866,7 @@ class CredentialStore extends Wizard 'CUSTOM' => __('Custom'), 'AWS' => __('Aws'), 'AZURE' => __('Azure'), + 'SAP' => __('SAP'), // 'GOOGLE' => __('Google'), ], 'selected' => (isset($values['product']) ? $values['product'] : 'CUSTOM'), @@ -900,6 +901,7 @@ class CredentialStore extends Wizard case 'GOOGLE': // Need further investigation. case 'CUSTOM': + case 'SAP': $user_label = __('Account ID'); $pass_label = __('Password'); $extra1 = false; @@ -1038,7 +1040,12 @@ class CredentialStore extends Wizard $('#div-extra_2 label').text(''); $('#div-extra_1').show(); $('#div-extra_2').show(); - } + } else if ($('#product :selected').val() == "SAP") { + $('#div-username label').text(''); + $('#div-password label').text(''); + $('#div-extra_1').hide(); + $('#div-extra_2').hide(); + } } /** diff --git a/pandora_console/include/class/Diagnostics.class.php b/pandora_console/include/class/Diagnostics.class.php index 1f4b4c94f7..94acbc4ba2 100644 --- a/pandora_console/include/class/Diagnostics.class.php +++ b/pandora_console/include/class/Diagnostics.class.php @@ -70,6 +70,7 @@ class Diagnostics extends Wizard $this->ajaxController = $page; $this->pdf = $pdf; + $this->product_name = io_safe_output(get_product_name()); } @@ -126,7 +127,7 @@ class Diagnostics extends Wizard // Header. ui_print_page_header( - __('Pandora FMS Diagnostic tool'), + __('%s Diagnostic tool', $this->product_name), 'images/gm_massive_operations.png', false, 'diagnostic_tool_tab', @@ -190,7 +191,7 @@ class Diagnostics extends Wizard foreach ($infoMethods as $key => $method) { switch ($method) { case 'getStatusInfo': - $title = __('Info status pandoraFms'); + $title = __('Info status %s', $this->product_name); break; case 'getPHPSetup': @@ -219,16 +220,17 @@ class Diagnostics extends Wizard case 'getTablesFragmentation': $title = __( - 'Tables fragmentation in the Pandora FMS database' + 'Tables fragmentation in the %s database', + $this->product_name ); break; case 'getPandoraFMSLogsDates': - $title = __('Pandora FMS logs dates'); + $title = __('%s logs dates', $this->product_name); break; case 'getLicenceInformation': - $title = __('Pandora FMS Licence Information'); + $title = __('%s Licence Information', $this->product_name); break; case 'getAttachmentFolder': @@ -240,7 +242,7 @@ class Diagnostics extends Wizard break; case 'getServerThreads': - $title = __('Pandora FMS server threads'); + $title = __('%s server threads', $this->product_name); break; case 'getShowEngine': @@ -399,11 +401,11 @@ class Diagnostics extends Wizard 'error' => false, 'data' => [ 'buildVersion' => [ - 'name' => __('Pandora FMS Build'), + 'name' => __('%s Build', $this->product_name), 'value' => $build_version, ], 'version' => [ - 'name' => __('Pandora FMS Version'), + 'name' => __('%s Version', $this->product_name), 'value' => $pandora_version, ], 'mr' => [ @@ -512,7 +514,7 @@ class Diagnostics extends Wizard 'error' => false, 'data' => [ 'countAgents' => [ - 'name' => __('Total agentsy'), + 'name' => __('Total agents'), 'value' => $countAgents, ], 'countModules' => [ @@ -586,7 +588,10 @@ class Diagnostics extends Wizard $pandoraDbLastRun = __('Pandora DB has never been executed'); if ($dateDbMantenaince !== false) { $difference = ($currentTime - $dateDbMantenaince); - $pandoraDbLastRun = human_time_comparation($difference); + $pandoraDbLastRun = human_time_description_raw( + $difference, + true + ); $pandoraDbLastRun .= ' '.__('Ago'); } @@ -602,7 +607,7 @@ class Diagnostics extends Wizard 'value' => $notInitAgents, ], 'pandoraDbLastRun' => [ - 'name' => __('PandoraDB Last run'), + 'name' => __('Pandora DB Last run'), 'value' => $pandoraDbLastRun, ], ], @@ -671,17 +676,54 @@ class Diagnostics extends Wizard $cpuProcessor = 'cat /proc/cpuinfo | grep "processor" | wc -l'; $ramMemTotal = 'cat /proc/meminfo | grep "MemTotal"'; + exec( + "ifconfig | awk '{ print $2}' | grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}'", + $output + ); + + $ips = implode(', ', $output); + $result = [ 'error' => false, 'data' => [ - 'cpuInfo' => [ + 'cpuInfo' => [ 'name' => __('CPU'), 'value' => exec($cpuModelName).' x '.exec($cpuProcessor), ], - 'ramInfo' => [ + 'ramInfo' => [ 'name' => __('RAM'), 'value' => exec($ramMemTotal), ], + 'osInfo' => [ + 'name' => __('Os'), + 'value' => exec('uname -a'), + ], + 'hostnameInfo' => [ + 'name' => __('Hostname'), + 'value' => exec('hostname'), + ], + 'ipInfo' => [ + 'name' => __('Ip'), + 'value' => $ips, + ], + ], + ]; + } else { + $result = [ + 'error' => false, + 'data' => [ + 'osInfo' => [ + 'name' => __('OS'), + 'value' => exec('ver'), + ], + 'hostnameInfo' => [ + 'name' => __('Hostname'), + 'value' => exec('hostname'), + ], + 'ipInfo' => [ + 'name' => __('Ip'), + 'value' => exec('ipconfig | findstr IPv4'), + ], ], ]; } @@ -750,22 +792,6 @@ class Diagnostics extends Wizard $message = __('Min. Recommended Value').' 64M'; break; - /* - case 'join_buffer_size': - $name = __('Join buffer size'); - $value = ($item['Value'] / $bytes); - $status = (($item['Value'] / $bytes) >= 265) ? 1 : 0; - $message = __('Min. Recommended Value 265'); - break; - - case 'key_buffer_size': - $name = __('Key buffer size'); - $value = ($item['Value'] / $bytes); - $status = (($item['Value'] / $bytes) >= 256) ? 1 : 0; - $message = __('Min. Recommended Value').' 256'; - break; - */ - case 'max_allowed_packet': $name = __('Maximun allowed packet'); $value = ($item['Value'] / $bytes); @@ -953,10 +979,10 @@ class Diagnostics extends Wizard $unit = 'M'; - $pathServerLogs = 'var/log/pandora/pandora_server.log'; + $pathServerLogs = '/var/log/pandora/pandora_server.log'; $servers = $this->getLogInfo($pathServerLogs); - $pathErrLogs = 'var/log/pandora/pandora_server.error'; + $pathErrLogs = '/var/log/pandora/pandora_server.error'; $errors = $this->getLogInfo($pathErrLogs); $pathConsoleLogs = $config['homedir'].'/pandora_console.log'; @@ -1018,6 +1044,7 @@ class Diagnostics extends Wizard $customerKey = db_get_value_sql($sql); // Extract Info license. + enterprise_include_once('include/functions_license.php'); $license = enterprise_hook('license_get_info'); // Agent Capacity. @@ -1050,6 +1077,7 @@ class Diagnostics extends Wizard WHERE id_tipo_modulo BETWEEN 6 AND 18' ); + $totalModuleIntervalTime = db_get_value_sql( 'SELECT SUM(module_interval) FROM tagente_modulo @@ -1060,26 +1088,26 @@ class Diagnostics extends Wizard $averageTime = 0; if ($totalModuleIntervalTime !== false) { $averageTime = number_format( - ((int) $totalModuleIntervalTime / (int) $totalNetworkModules), + ((int) $totalNetworkModules / (int) $totalModuleIntervalTime), 3 ); } $moduleNetworkmsg = __( sprintf( - 'The system is not overloaded (average time %d)', - $average_time + 'The system is not overloaded (average time %f)', + $averageTime ) ); $moduleNetworkst = 1; - if ($average_time === 0) { + if ($averageTime === 0) { $moduleNetworkmsg = __('The system has no load'); $moduleNetworkst = 0; - } else if ($averageTime < 180) { + } else if ($averageTime > 180) { $moduleNetworkmsg = __( sprintf( - 'The system is overloaded (average time %d) and a very fine configuration is required', - $average_time + 'The system is overloaded (average time %f) and a very fine configuration is required', + $averageTime ) ); $moduleNetworkst = 0; @@ -1252,37 +1280,47 @@ class Diagnostics extends Wizard { global $config; - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - return []; + $result = []; + $totalServerThreads = 0; + if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { + $totalServerThreads = shell_exec( + 'ps -T aux | grep pandora_server | grep -v grep | wc -l' + ); } - $totalServerThreads = shell_exec( - 'ps -T aux | grep pandora_server | grep -v grep | wc -l' - ); - $percentageThreadsRam = shell_exec( - "ps axo pmem,cmd | grep pandora_server | awk '{sum+=$1} END {print sum}'" - ); - $percentageThreadsCpu = shell_exec( - "ps axo pcpu,cmd | grep pandora_server | awk '{sum+=$1} END {print sum}'" - ); + include_once $config['homedir'].'/include/functions_servers.php'; + $sql = 'SELECT `name`, server_type, threads FROM tserver'; + $servers = db_get_all_rows_sql($sql); - $result = [ - 'error' => false, - 'data' => [ - 'totalServerThreads' => [ - 'name' => __('Total server threads'), - 'value' => $totalServerThreads, - ], - 'percentageThreadsRam' => [ - 'name' => __('Percentage of threads used by the RAM'), - 'value' => $percentageThreadsRam.' %', - ], - 'percentageThreadsCpu' => [ - 'name' => __('Percentage of threads used by the CPU'), - 'value' => $percentageThreadsCpu.' %', - ], - ], - ]; + if (isset($servers) === true && is_array($servers) === true) { + $sum_threads = 0; + foreach ($servers as $key => $value) { + $result['data']['threads_server_'.$value['server_type']] = [ + 'name' => __('Threads').' '.\servers_get_server_string_name( + $value['server_type'] + ), + 'value' => $value['threads'], + ]; + + $sum_threads += $value['threads']; + } + + $result['data']['total_threads'] = [ + 'name' => __('Total threads'), + 'value' => $sum_threads, + 'status' => ($sum_threads < $totalServerThreads) ? 2 : 1, + ]; + + if ($sum_threads < $totalServerThreads) { + $result['data']['total_threads']['message'] = __( + 'Current pandora_server running threads' + ); + } else { + __( + 'There\'s more pandora_server threads than configured, are you running multiple servers simultaneusly?.' + ); + } + } return json_encode($result); } @@ -1315,8 +1353,8 @@ class Diagnostics extends Wizard $lenght = strlen($innodb[0]['Status']); $data = []; - for ($i = 0; $i < $lenght; $i = ($i + 500)) { - $str = substr($innodb[0]['Status'], $i, ($i + 500)); + for ($i = 0; $i < $lenght; $i = ($i + 300)) { + $str = substr($innodb[0]['Status'], $i, ($i + 300)); $data['showEngine-'.$i] = [ 'name' => '', 'value' => '
    '.$str.'
    ', @@ -1673,7 +1711,7 @@ class Diagnostics extends Wizard 'status' => 0, ]; - if (is_file($path) === true) { + if (file_exists($path) === true) { $fileSize = filesize($path); $sizeServerLog = number_format($fileSize); $sizeServerLog = (0 + str_replace(',', '', $sizeServerLog)); @@ -1730,7 +1768,17 @@ class Diagnostics extends Wizard // of objects, making a post-process of certain fields. if (isset($items[$key]['status']) === true) { $acumValue = $items[$key]['value']; - if ($items[$key]['status'] === 1) { + + if ($items[$key]['status'] === 2) { + $items[$key]['value'] = html_print_image( + 'images/icono-warning.png', + true, + [ + 'title' => __('Warning'), + 'style' => 'width:15px;', + ] + ); + } else if ($items[$key]['status'] === 1) { $items[$key]['value'] = html_print_image( 'images/exito.png', true, @@ -1872,7 +1920,7 @@ class Diagnostics extends Wizard $mail_feedback = 'feedback@artica.es'; $email = $mail_feedback; - $subject = 'PandoraFMS Report '.$config['pandora_uid']; + $subject = $this->product_name.' Report '.$config['pandora_uid']; $text = get_parameter('what-happened', ''); $attachment = get_parameter_switch('include_installation_data', 0); $email_from = get_parameter_switch('email', ''); diff --git a/pandora_console/include/class/HelpFeedBack.class.php b/pandora_console/include/class/HelpFeedBack.class.php index 825d3c923f..e97e84ddd9 100644 --- a/pandora_console/include/class/HelpFeedBack.class.php +++ b/pandora_console/include/class/HelpFeedBack.class.php @@ -93,12 +93,13 @@ class HelpFeedBack extends Wizard ui_require_css_File('discovery'); ui_require_css_file('help_feedback'); - $help_url = get_parameter('url', null); + $help_url = get_parameter('b', null); + $help_url = base64_decode($help_url); if ($help_url === null) { echo __('Page not found'); } else { ?> - @@ -143,7 +144,7 @@ class HelpFeedBack extends Wizard 'block_content' => [ [ 'arguments' => [ - 'label' => __('Sugesstion'), + 'label' => __('Suggestion'), 'type' => 'radio_button', 'attributes' => 'class="btn"', 'name' => 'suggestion', @@ -154,7 +155,7 @@ class HelpFeedBack extends Wizard ], [ 'arguments' => [ - 'label' => __('Something is not quite right'), + 'label' => __('Something is wrong'), 'type' => 'radio_button', 'attributes' => 'class="btn"', 'name' => 'report', diff --git a/pandora_console/include/config_process.php b/pandora_console/include/config_process.php index ff5f365d5e..82515500d2 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 = 'PC191113'; +$build_version = 'PC191118'; $pandora_version = 'v7.0NG.740'; // Do not overwrite default timezone set if defined. diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index df171efbca..318496cfa8 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -537,7 +537,7 @@ define('NODE_GENERIC', 3); define('STATUS_OK', 0); define('STATUS_ERROR', 1); -// Maps (new networkmaps and new visualmaps). +// Maps new networkmaps and new visualmaps. define('MAP_TYPE_NETWORKMAP', 0); define('MAP_TYPE_VISUALMAP', 1); @@ -590,6 +590,7 @@ define('DISCOVERY_CLOUD_AWS_EC2', 6); define('DISCOVERY_CLOUD_AWS_RDS', 7); define('DISCOVERY_CLOUD_AZURE_COMPUTE', 8); define('DISCOVERY_DEPLOY_AGENTS', 9); +define('DISCOVERY_APP_SAP', 10); // Discovery types matching definition. diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index a7d94d43bc..720caefc58 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -5416,6 +5416,14 @@ function get_help_info($section_name) } break; + case 'omnishell': + if ($es) { + $result .= 'Omnishell&printable=yes'; + } else { + $result .= 'Omnishell&printable=yes'; + } + break; + case 'module_type_tab': if ($es) { $result .= 'Operacion&printable=yes#Tipos_de_m.C3.B3dulos'; @@ -5431,6 +5439,22 @@ function get_help_info($section_name) $result .= 'GIS&printable=yes#Operation'; } break; + + case 'quickshell_settings': + if ($es) { + $result .= 'Configuracion_Consola&printable=yes#Websocket_Engine'; + } else { + $result .= 'Console_Setup&printable=yes#Websocket_engine'; + } + break; + + case 'discovery': + if ($es) { + $result .= 'Discovery&printable=yes'; + } else { + $result .= 'Discovery&printable=yes'; + } + break; } return $result; diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index 826ca971c5..e85798cfde 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -132,6 +132,32 @@ function agents_get_agent_id_by_alias($alias) } +/** + * Return seconds left to contact again with agent. + * + * @param integer $id_agente Target agent + * + * @return integer|null Seconds left. + */ +function agents_get_next_contact_time_left(int $id_agente) +{ + $last_contact = false; + + if ($id_agente > 0) { + $last_contact = db_get_value_sql( + sprintf( + 'SELECT format(intervalo,2) - (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(IF(ultimo_contacto > ultimo_contacto_remoto, ultimo_contacto, ultimo_contacto_remoto))) as "val" + FROM `tagente` + WHERE id_agente = %d ', + $id_agente + ) + ); + } + + return $last_contact; +} + + /** * Creates an agent. * @@ -3481,3 +3507,66 @@ function agents_get_status_animation($up=true) ); } } + + +/** + * Return if an agent is SAP or or an a agent SAP list. + * If function receive false, you will return all SAP agents, + * but if you receive an id agent, check if it is a sap agent + * and return true or false. + * + * @param integer $id_agent + * @return boolean + */ +function agents_get_sap_agents($id_agent) +{ + // Available modules. + // If you add more modules, please update SAP.pm. + $sap_modules = [ + 160 => __('SAP Login OK'), + 109 => __('SAP Dumps'), + 111 => __('SAP List lock'), + 113 => __('SAP Cancel Jobs'), + 121 => __('SAP Batch input erroneus'), + 104 => __('SAP Idoc erroneus'), + 105 => __('SAP IDOC OK'), + 150 => __('SAP WP without active restart'), + 151 => __('SAP WP stopped'), + 102 => __('Average time of SAPGUI response '), + 180 => __('Dialog response time'), + 103 => __('Dialog Logged users '), + 192 => __('SYSFAIL, delivery attempts tRFC wrong entries number'), + 195 => __('SYSFAIL, queue qRFC INPUT, wrong entries number '), + 116 => __('Number of Update WPs in error'), + ]; + + $array_agents = []; + foreach ($sap_modules as $module => $key) { + $array_agents = array_merge( + $array_agents, + db_get_all_rows_sql( + 'SELECT ta.id_agente,ta.alias + FROM tagente ta + INNER JOIN tagente_modulo tam + ON tam.id_agente = ta.id_agente + WHERE tam.nombre + LIKE "%SAP%" + GROUP BY ta.id_agente' + ) + ); + } + + $indexed_agents = index_array($array_agents, 'id_agente', false); + + if ($id_agent === false) { + return $indexed_agents; + } + + foreach ($indexed_agents as $agent => $key) { + if ($agent === $id_agent) { + return true; + } + } + + return false; +} diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index 89b3c03de2..4ee9e682b8 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -455,6 +455,10 @@ function config_update_config() $error_update[] = __('Ipam Ocuppied Manager Warning'); } + if (!config_update_value('sap_license', get_parameter('sap_license'))) { + $error_update[] = __('Deset SAP license'); + } + $inventory_changes_blacklist = get_parameter('inventory_changes_blacklist', []); if (!config_update_value('inventory_changes_blacklist', implode(',', $inventory_changes_blacklist))) { $error_update[] = __('Inventory changes blacklist'); diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 9563732c68..5fd0ae3481 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -4580,7 +4580,7 @@ function events_page_comments($event, $ajax=false) continue; } - $comments_array[] = json_decode(io_safe_output($comm), true); + $comments_array[] = io_safe_output(json_decode($comm, true)); } } else { // If comments are not stored in json, the format is old. diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 0ad31cf931..a1414f4d7c 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -1404,14 +1404,19 @@ function ui_print_help_icon( } $url = get_help_info($help_id); + $b = base64_encode($url); + $help_handler = 'index.php?sec=view&sec2=general/help_feedback'; + // Needs to use url encoded to avoid anchor lost. + $help_handler .= '&b='.$b; + $help_handler .= '&pure=1&url='.$url; $output = html_print_image( $image, true, [ 'class' => 'img_help', 'title' => __('Help'), - 'onclick' => "open_help ('".ui_get_full_url('index.php?sec=view&sec2=general/help_feedback&pure=1&url='.$url)."')", + 'onclick' => "open_help ('".ui_get_full_url($help_handler)."')", 'id' => $id, ], false, @@ -2915,119 +2920,73 @@ function ui_progress( * Generates a progress bar CSS based. * Requires css progress.css * - * @param array $progress Progress. - * @param string $width Width. - * @param integer $height Height in 'em'. - * @param array $color status color. - * @param boolean $return Return or paint (if false). - * @param boolean $text Text to be displayed,by default progress %. - * @param array $ajax Ajax: [ 'page' => 'page', 'data' => 'data' ] Sample: - * [ - * 'page' => 'operation/agentes/ver_agente', Target page. - * 'interval' => 100 / $agent["intervalo"], Ask every interval seconds. - * 'data' => [ Data to be sent to target page. - * 'id_agente' => $id_agente, - * 'refresh_contact' => 1, - * ], - * ]. + * @param array $data With following content: + * + * 'slices' => [ + * 'label' => [ // Name of the slice + * 'value' => value + * 'color' => color of the slice. + * ] + * ], + * 'width' => Width + * 'height' => Height in 'em' + * 'return' => Boolean, return or paint. * * @return string HTML code. */ function ui_progress_extend( - $progress, - $width='100%', - $height='2.5', - $color='#82b92e', - $return=true, - $text='', - $ajax=false + array $data ) { - if (!$progress['total']) { - $progress = 0; + if (is_array($data) === false) { + // Failed. + return false; } - $totalW = ($progress['total'] * 100); - if ($totalW > 100) { - $totalW = 100; + if (is_array($data['slices']) === false) { + // Failed. + return false; } - if ($totalW < 0) { - $totalW = 0; + if (isset($data['width']) === false) { + $data['width'] = '100'; } - if (empty($text)) { - $text = $totalW.'%'; + if (isset($data['height']) === false) { + $data['height'] = '1.3'; + } + + $total = array_reduce( + $data['slices'], + function ($carry, $item) { + $carry += $item['value']; + return $carry; + } + ); + if ($total == 0) { + return null; } - $badW = (($progress['bad'] * 100 ) / $progress['total']); - $goodW = (($progress['good'] * 100 ) / $progress['total']); - $unknownW = (($progress['unknown'] * 100 ) / $progress['total']); ui_require_css_file('progress'); - $output .= '
    '; - $output .= '
    '; - $output .= '
    '; - $output .= '
    '; + + // Main container. + $output .= '
    '; + + foreach ($data['slices'] as $label => $def) { + $width = ($def['value'] * 100 / $total); + $output .= '
    $value) { - $output .= ' - '.$token.':"'.$value.'",'; - } - } - - $output .= ' - page: "'.$ajax['page'].'" - }, - success: function(data) { - try { - val = JSON.parse(data); - $(".progress_main").attr("data-label", val["last_contact"]+" s"); - $(".progress").width(val["progress"]+"%"); - } catch (e) { - console.error(e); - $(".progress_text").attr("data-label", (last -1) + " s"); - if (width < 100) { - $(".progress").width((width+width_interval) + "%"); - } - } - } - }); - } else { - $(".progress_main").attr("data-label", (last -1) + " s"); - if (width < 100) { - $(".progress").width((width+width_interval) + "%"); - } - } - }, 1000); - }); - '; - } - - if (!$return) { + if (!$data['return']) { echo $output; } @@ -3667,6 +3626,7 @@ function ui_print_event_priority( * @param string $main_class Main object class. * @param string $img_a Image (closed). * @param string $img_b Image (opened). + * @param string $clean Do not encapsulate with class boxes, clean print. * * @return string HTML. */ @@ -3681,7 +3641,8 @@ function ui_toggle( $container_class='white-box-content', $main_class='box-shadow white_table_graph', $img_a='images/arrow_down_green.png', - $img_b='images/arrow_right_green.png' + $img_b='images/arrow_right_green.png', + $clean=false ) { // Generate unique Id. $uniqid = uniqid(''); @@ -3697,9 +3658,17 @@ function ui_toggle( $original = $img_a; } + $header_class = ''; + if ($clean === false) { + $header_class = 'white_table_graph_header'; + } else { + $main_class = ''; + $container_class = 'white-box-content-clean'; + } + // Link to toggle. $output = '
    '; - $output .= '
    '.html_print_image( + $output .= '
    '.html_print_image( $original, true, [ @@ -3767,7 +3736,8 @@ function ui_print_toggle($data) (isset($data['container_class']) === true) ? $data['container_class'] : 'white-box-content', (isset($data['main_class']) === true) ? $data['main_class'] : 'box-shadow white_table_graph', (isset($data['img_a']) === true) ? $data['img_a'] : 'images/arrow_down_green.png', - (isset($data['img_b']) === true) ? $data['img_b'] : 'images/arrow_right_green.png' + (isset($data['img_b']) === true) ? $data['img_b'] : 'images/arrow_right_green.png', + (isset($data['clean']) === true) ? $data['clean'] : false ); } @@ -5868,7 +5838,7 @@ function ui_print_comments($comments) continue; } - $comments_array[] = json_decode(io_safe_output($comm), true); + $comments_array[] = io_safe_output(json_decode($comm, true)); } } diff --git a/pandora_console/include/lib/WebSocketServer.php b/pandora_console/include/lib/WebSocketServer.php index 2d9eb1d9fd..dfdc81d075 100644 --- a/pandora_console/include/lib/WebSocketServer.php +++ b/pandora_console/include/lib/WebSocketServer.php @@ -439,6 +439,9 @@ abstract class WebSocketServer if ((time() - $this->lastTickTimestamp) > $this->tickInterval) { $this->lastTickTimestamp = time(); $this->tick(); + + // Keep connection with DB active. + $this->dbHearthbeat(); } socket_select($read, $write, $except, 0, $this->timeout); @@ -1530,4 +1533,23 @@ abstract class WebSocketServer } + /** + * Keeps db connection opened. + * + * @return void + */ + public function dbHearthbeat() + { + global $config; + + if (isset($config['dbconnection']) === false + || mysqli_ping($config['dbconnection']) === false + ) { + // Retry connection. + db_select_engine(); + $config['dbconnection'] = db_connect(); + } + } + + } diff --git a/pandora_console/include/styles/omnishell.css b/pandora_console/include/styles/omnishell.css index b6dcd37826..265ca5f445 100644 --- a/pandora_console/include/styles/omnishell.css +++ b/pandora_console/include/styles/omnishell.css @@ -19,6 +19,38 @@ height: 20px; } +.element-target-big { + width: 100px; + margin: 2px; + height: 100px; +} + +.element-target-big:hover { + box-shadow: 0 0 10px -5px #424242; +} + +.element-target-big:before { + content: attr(data-label); + position: relative; + text-align: center; + width: 100%; + height: 100%; + color: #373737; + font-weight: bolder; + display: flex; + flex-direction: row; + font-size: 1.8em; + align-items: center; + justify-content: center; + overflow: hidden; + font-family: "lato-bolder", "Open Sans", sans-serif; + text-decoration: none; +} + +.container-target a:hover { + text-decoration: none; +} + .status-normal { background-color: #add570; } @@ -150,6 +182,12 @@ ul.wizard { display: flex; } +.no-class.action-buttons.mw120px.textright.sorting_disabled, +.textright { + text-align: right; + padding-right: 2em; +} + /* * Discovery css global */ diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 66c0f27552..1ecd197ece 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -5712,6 +5712,10 @@ div#status_pie { padding: 1em; min-width: 100%; } +.white-box-content-clean { + padding-left: 2em; + padding-top: 1em; +} .white_table_graph_content { border: 1px solid #e2e2e2; diff --git a/pandora_console/include/styles/progress.css b/pandora_console/include/styles/progress.css index f263e87fcf..bfbb2409ef 100644 --- a/pandora_console/include/styles/progress.css +++ b/pandora_console/include/styles/progress.css @@ -4,7 +4,17 @@ position: relative; width: 100%; display: inline-block; + display: flex; } + +.progress_main_noborder { + height: 2.5em; + position: relative; + width: 100%; + display: inline-block; + display: flex; +} + .progress_main:before { content: attr(data-label); position: absolute; diff --git a/pandora_console/install.php b/pandora_console/install.php index 094f4b3393..4478f8e75a 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -129,7 +129,7 @@
    0) { - $last_contact = db_get_value_sql( - sprintf( - 'SELECT format(intervalo,2) - (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(IF(ultimo_contacto > ultimo_contacto_remoto, ultimo_contacto, ultimo_contacto_remoto))) as "val" - FROM `tagente` - WHERE id_agente = %d ', - $id_agente - ) - ); + $last_contact = agents_get_next_contact_time_left($id_agente); $progress = agents_get_next_contact($id_agente); if ($progress < 0 || $progress > 100) { diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index 58213ed8ee..dfa52551fc 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -155,6 +155,8 @@ if (!empty($sub2)) { enterprise_hook('cluster_menu'); enterprise_hook('aws_menu'); +enterprise_hook('SAP_view'); + if (!empty($sub)) { $menu_operation['estado']['text'] = __('Monitoring'); diff --git a/pandora_console/operation/search_agents.php b/pandora_console/operation/search_agents.php index 7edd7be878..05383df31a 100755 --- a/pandora_console/operation/search_agents.php +++ b/pandora_console/operation/search_agents.php @@ -30,6 +30,7 @@ if (!$agents || !$searchAgents) { echo "
    ".__('Zero results found')."
    \n"; } } else { + $table = new StdClass(); $table->cellpadding = 4; $table->cellspacing = 4; $table->width = '98%'; diff --git a/pandora_console/pandora_console.redhat.spec b/pandora_console/pandora_console.redhat.spec index e5ae6c5f33..bec33ed2a1 100644 --- a/pandora_console/pandora_console.redhat.spec +++ b/pandora_console/pandora_console.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.740 -%define release 191113 +%define release 191118 # User and Group under which Apache is running %define httpd_name httpd diff --git a/pandora_console/pandora_console.rhel7.spec b/pandora_console/pandora_console.rhel7.spec index 26987ff319..5f30a39641 100644 --- a/pandora_console/pandora_console.rhel7.spec +++ b/pandora_console/pandora_console.rhel7.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.740 -%define release 191113 +%define release 191118 # User and Group under which Apache is running %define httpd_name httpd diff --git a/pandora_console/pandora_console.spec b/pandora_console/pandora_console.spec index 6aeac2389f..682c64d177 100644 --- a/pandora_console/pandora_console.spec +++ b/pandora_console/pandora_console.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.740 -%define release 191113 +%define release 191118 %define httpd_name httpd # User and Group under which Apache is running %define httpd_name apache2 diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index a8afe8926c..28bb83d287 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -699,7 +699,7 @@ CREATE TABLE IF NOT EXISTS `tgrupo` ( CREATE TABLE IF NOT EXISTS `tcredential_store` ( `identifier` varchar(100) NOT NULL, `id_group` mediumint(4) unsigned NOT NULL DEFAULT 0, - `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE') default 'CUSTOM', + `product` enum('CUSTOM', 'AWS', 'AZURE', 'GOOGLE', 'SAP') default 'CUSTOM', `username` text, `password` text, `extra_1` text, @@ -3686,8 +3686,8 @@ CREATE TABLE `tremote_command_target` ( `rcmd_id` bigint unsigned NOT NULL, `id_agent` int(10) unsigned NOT NULL, `utimestamp` int(20) unsigned NOT NULL default 0, - `stdout` text, - `stderr` text, + `stdout` MEDIUMTEXT, + `stderr` MEDIUMTEXT, `errorlevel` int(10) unsigned NOT NULL default 0, PRIMARY KEY (`id`), FOREIGN KEY (`rcmd_id`) REFERENCES `tremote_command`(`id`) diff --git a/pandora_server/DEBIAN/control b/pandora_server/DEBIAN/control index 56c06c6394..c72e654976 100644 --- a/pandora_server/DEBIAN/control +++ b/pandora_server/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-server -Version: 7.0NG.740-191113 +Version: 7.0NG.740-191118 Architecture: all Priority: optional Section: admin diff --git a/pandora_server/DEBIAN/make_deb_package.sh b/pandora_server/DEBIAN/make_deb_package.sh index 5c0a5e0bee..ed8851c981 100644 --- a/pandora_server/DEBIAN/make_deb_package.sh +++ b/pandora_server/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.740-191113" +pandora_version="7.0NG.740-191118" package_cpan=0 package_pandora=1 diff --git a/pandora_server/conf/pandora_server.conf.new b/pandora_server/conf/pandora_server.conf.new index 2a2930f7eb..16a4a51b62 100644 --- a/pandora_server/conf/pandora_server.conf.new +++ b/pandora_server/conf/pandora_server.conf.new @@ -130,9 +130,15 @@ networkserver 1 dataserver 1 -# Activate (1) Pandora FMS Recon server +# Activate (1) Pandora FMS Discovery server -reconserver 1 +discoveryserver 1 + +# Discovery SAP (PANDORA FMS ENTERPRISE ONLY) +# java /usr/bin/java + +# Discovery SAP utils (PANDORA FMS ENTERPRISE ONLY) +# sap_utils /usr/share/pandora_server/util/recon_scripts/SAP # pluginserver : 1 or 0. Set to 1 to activate plugin server with this setup diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index ff0ec80d9c..06790c7c87 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -45,7 +45,7 @@ our @EXPORT = qw( # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.740"; -my $pandora_build = "191113"; +my $pandora_build = "191118"; our $VERSION = $pandora_version." ".$pandora_build; # Setup hash @@ -349,6 +349,12 @@ sub pandora_load_config { $pa_config->{"fping"} = "/usr/sbin/fping"; # > 5.1SP2 + # Discovery SAP + $pa_config->{"java"} = "/usr/bin/java"; + + # Discovery SAP utils + $pa_config->{"sap_utils"} = "/usr/share/pandora_server/util/recon_scripts/SAP"; + # braa for enterprise snmp server $pa_config->{"braa"} = "/usr/bin/braa"; @@ -841,6 +847,12 @@ sub pandora_load_config { elsif ($parametro =~ m/^fping\s(.*)/i) { $pa_config->{'fping'}= clean_blank($1); } + elsif ($parametro =~ m/^java\s(.*)/i) { + $pa_config->{'java'}= clean_blank($1); + } + elsif ($parametro =~ m/^sap_utils\s(.*)/i) { + $pa_config->{'sap_utils'}= clean_blank($1); + } elsif ($parametro =~ m/^nmap_timing_template\s+([0-9]*)/i) { $pa_config->{'nmap_timing_template'}= clean_blank($1); } diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 7d90ff411a..5555f61af1 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -56,7 +56,25 @@ my $TaskSem :shared; use constant { OS_OTHER => 10, OS_ROUTER => 17, - OS_SWITCH => 18 + OS_SWITCH => 18, + STEP_SCANNING => 1, + STEP_AFT => 2, + STEP_TRACEROUTE => 3, + STEP_GATEWAY => 4, + STEP_STATISTICS => 1, + STEP_APP_SCAN => 2, + STEP_CUSTOM_QUERIES => 3, + DISCOVERY_HOSTDEVICES => 0, + DISCOVERY_HOSTDEVICES_CUSTOM => 1, + DISCOVERY_CLOUD_AWS => 2, + DISCOVERY_APP_VMWARE => 3, + DISCOVERY_APP_MYSQL => 4, + DISCOVERY_APP_ORACLE => 5, + DISCOVERY_CLOUD_AWS_EC2 => 6, + DISCOVERY_CLOUD_AWS_RDS => 7, + DISCOVERY_CLOUD_AZURE_COMPUTE => 8, + DISCOVERY_DEPLOY_AGENTS => 9, + DISCOVERY_APP_SAP => 10, }; ######################################################################################## @@ -196,6 +214,31 @@ sub data_consumer ($$) { return; } + + if ($task->{'type'} == DISCOVERY_APP_SAP) { + # SAP TASK, retrieve license. + $task->{'sap_license'} = pandora_get_config_value( + $dbh, + 'sap_license' + ); + + # Retrieve credentials for task (optional). + if (defined($task->{'auth_strings'}) + && $task->{'auth_strings'} ne '' + ) { + my $key = credential_store_get_key( + $pa_config, + $dbh, + $task->{'auth_strings'} + ); + + # Inside an eval, here it shouln't fail unless bad configured. + $task->{'username'} = $key->{'username'}; + $task->{'password'} = $key->{'password'}; + + } + } + my $recon = new PandoraFMS::Recon::Base( communities => \@communities, dbh => $dbh, diff --git a/pandora_server/lib/PandoraFMS/PluginTools.pm b/pandora_server/lib/PandoraFMS/PluginTools.pm index 05a2a380b0..0711bc7b20 100644 --- a/pandora_server/lib/PandoraFMS/PluginTools.pm +++ b/pandora_server/lib/PandoraFMS/PluginTools.pm @@ -32,7 +32,7 @@ our @ISA = qw(Exporter); # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.740"; -my $pandora_build = "191113"; +my $pandora_build = "191118"; our $VERSION = $pandora_version." ".$pandora_build; our %EXPORT_TAGS = ( 'all' => [ qw() ] ); diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 335504821e..b444e92672 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -22,7 +22,7 @@ use constant { STEP_TRACEROUTE => 3, STEP_GATEWAY => 4, STEP_STATISTICS => 1, - STEP_DATABASE_SCAN => 2, + STEP_APP_SCAN => 2, STEP_CUSTOM_QUERIES => 3, DISCOVERY_HOSTDEVICES => 0, DISCOVERY_HOSTDEVICES_CUSTOM => 1, @@ -34,6 +34,7 @@ use constant { DISCOVERY_CLOUD_AWS_RDS => 7, DISCOVERY_CLOUD_AZURE_COMPUTE => 8, DISCOVERY_DEPLOY_AGENTS => 9, + DISCOVERY_APP_SAP => 10, }; # $DEVNULL @@ -1440,10 +1441,11 @@ sub cloud_scan($) { my $type = ''; - if ($self->{'task_data'}->{'type'} == DISCOVERY_CLOUD_AWS_EC2 - || $self->{'task_data'}->{'type'} == DISCOVERY_CLOUD_AWS_RDS) { + if ( $self->{'task_data'}->{'type'} == DISCOVERY_CLOUD_AWS_EC2 + || $self->{'task_data'}->{'type'} == DISCOVERY_CLOUD_AWS_RDS) { $type = 'Aws'; } else { + # Unrecognized task type. call('message', 'Unrecognized task type', 1); $self->call('update_progress', -1); @@ -1465,9 +1467,11 @@ sub cloud_scan($) { ); if (!$cloudObj) { + # Failed to initialize, check Cloud credentials or anything. call('message', 'Unable to initialize PandoraFMS::Recon::Cloud::'.$type, 3); } else { + # Let Cloud object manage scan. $cloudObj->scan(); } @@ -1479,6 +1483,85 @@ sub cloud_scan($) { } +########################################################################## +# Performs a database scan. +########################################################################## +sub database_scan($$$) { + my ($self, $type, $obj, $global_percent, $targets) = @_; + + my @data; + my @modules; + + my $dbObjCfg = $obj->get_config(); + + $self->{'summary'}->{'discovered'} += 1; + $self->{'summary'}->{'alive'} += 1; + + push @modules, + { + name => $type . ' connection', + type => 'generic_proc', + data => 1, + description => $type . ' availability' + }; + + # Analyze. + $self->{'step'} = STEP_STATISTICS; + $self->{'c_network_percent'} = 30; + $self->call('update_progress', $global_percent + (30 / (scalar @$targets))); + $self->{'c_network_name'} = $obj->get_host(); + + # Retrieve connection statistics. + # Retrieve uptime statistics + # Retrieve query stats + # Retrieve connections + # Retrieve innodb + # Retrieve cache + $self->{'c_network_percent'} = 50; + $self->call('update_progress', $global_percent + (50 / (scalar @$targets))); + push @modules, $obj->get_statistics(); + + # Custom queries. + $self->{'step'} = STEP_CUSTOM_QUERIES; + $self->{'c_network_percent'} = 80; + $self->call('update_progress', $global_percent + (80 / (scalar @$targets))); + push @modules, $obj->execute_custom_queries(); + + if (defined($dbObjCfg->{'scan_databases'}) + && "$dbObjCfg->{'scan_databases'}" eq "1") { + + # Skip database scan in Oracle tasks + next if $self->{'type'} == DISCOVERY_APP_ORACLE; + + my $__data = $obj->scan_databases(); + + if (ref($__data) eq "ARRAY") { + if (defined($dbObjCfg->{'agent_per_database'}) + && $dbObjCfg->{'agent_per_database'} == 1) { + + # Agent per database detected. + push @data, @{$__data}; + + } else { + + # Merge modules into engine agent. + my @_modules = map { + map { $_ } + @{$_->{'module_data'}} + } @{$__data}; + + push @modules, @_modules; + } + } + } + + return { + 'modules' => @modules, + 'data' => @data + }; +} + + ########################################################################## # Perform an Application scan. ########################################################################## @@ -1487,11 +1570,15 @@ sub app_scan($) { my ($progress, $step); my $type = ''; + my $db_scan = 0; + # APP object initialization. if ($self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL) { $type = 'MySQL'; } elsif ($self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE) { $type = 'Oracle'; + } elsif ($self->{'task_data'}->{'type'} == DISCOVERY_APP_SAP) { + $type = 'SAP'; } else { # Unrecognized task type. call('message', 'Unrecognized task type', 1); @@ -1505,10 +1592,17 @@ sub app_scan($) { my $global_percent = 0; my $i = 0; foreach my $target (@targets) { + if ( !defined($target) + || $target eq '' + || $target =~ /^#/) { + # Ignore empty target or commented one. + next; + } + my @data; my @modules; - $self->{'step'} = STEP_DATABASE_SCAN; + $self->{'step'} = STEP_APP_SCAN; $self->{'c_network_name'} = $target; $self->{'c_network_percent'} = 0; @@ -1524,16 +1618,25 @@ sub app_scan($) { $self->call('update_progress', $global_percent + (10 / (scalar @targets))); # Connect to target. - my $dbObj = PandoraFMS::Recon::Util::enterprise_new( + my $obj = PandoraFMS::Recon::Util::enterprise_new( 'PandoraFMS::Recon::Applications::'.$type, - $self->{'task_data'} + { + %{$self->{'task_data'}}, + 'target' => $target, + 'pa_config' => $self->{'pa_config'}, + 'parent' => $self + }, ); - if (defined($dbObj)) { - if (!$dbObj->is_connected()) { + if (defined($obj)) { + + # Verify if object is connected. If cannot connect to current target + # return with module. + if (!$obj->is_connected()) { call('message', 'Cannot connect to target ' . $target, 3); $global_percent += $global_step; $self->{'c_network_percent'} = 90; + # Update progress $self->call('update_progress', $global_percent + (90 / (scalar @targets))); $self->{'summary'}->{'not_alive'} += 1; @@ -1545,74 +1648,51 @@ sub app_scan($) { }; } else { - my $dbObjCfg = $dbObj->get_config(); + # + # $results is always a hash with: + # @modules => 'global' modules. + # @data => { + # 'agent_data' => {} + # 'module_data' => [] + # } + my $results; - $self->{'summary'}->{'discovered'} += 1; - $self->{'summary'}->{'alive'} += 1; + # Scan connected obj. + if ( $self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL + || $self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE) { - push @modules, { - name => $type . ' connection', - type => 'generic_proc', - data => 1, - description => $type . ' availability' - }; + # Database. + $results = $self->database_scan($type, $obj, $global_percent, \@targets); - # Analyze. - $self->{'step'} = STEP_STATISTICS; - $self->{'c_network_percent'} = 30; - $self->call('update_progress', $global_percent + (30 / (scalar @targets))); - $self->{'c_network_name'} = $dbObj->get_host(); + } elsif ($self->{'task_data'}->{'type'} == DISCOVERY_APP_SAP) { - # Retrieve connection statistics. - # Retrieve uptime statistics - # Retrieve query stats - # Retrieve connections - # Retrieve innodb - # Retrieve cache - $self->{'c_network_percent'} = 50; - $self->call('update_progress', $global_percent + (50 / (scalar @targets))); - push @modules, $dbObj->get_statistics(); + # SAP scan + $results = $obj->scan(); - # Custom queries. - $self->{'step'} = STEP_CUSTOM_QUERIES; - $self->{'c_network_percent'} = 80; - $self->call('update_progress', $global_percent + (80 / (scalar @targets))); - push @modules, $dbObj->execute_custom_queries(); + } - if (defined($dbObjCfg->{'scan_databases'}) - && "$dbObjCfg->{'scan_databases'}" eq "1") { - # Skip database scan in Oracle tasks - next if $self->{'type'} == DISCOVERY_APP_ORACLE; + # Add results. + if (ref($results) eq 'HASH') { + if (defined($results->{'modules'})) { + push @modules, $results->{'modules'}; + } - my $__data = $dbObj->scan_databases(); - - if (ref($__data) eq "ARRAY") { - if (defined($dbObjCfg->{'agent_per_database'}) - && $dbObjCfg->{'agent_per_database'} == 1) { - # Agent per database detected. - push @data, @{$__data}; - } else { - # Merge modules into engine agent. - my @_modules = map { - map { $_ } @{$_->{'module_data'}} - } @{$__data}; - - push @modules, @_modules; - } + if (defined($results->{'data'})) { + push @data, $results->{'data'}; } } } # Put engine agent at the beginning of the list. - my $version = $dbObj->get_version(); - unshift @data,{ + my $version = $obj->get_version(); + unshift @data, { 'agent_data' => { - 'agent_name' => $dbObj->get_agent_name(), + 'agent_name' => $obj->get_agent_name(), 'os' => $type, 'os_version' => (defined($version) ? $version : 'Discovery'), 'interval' => $self->{'task_data'}->{'interval_sweep'}, 'id_group' => $self->{'task_data'}->{'id_group'}, - 'address' => $dbObj->get_host(), + 'address' => $obj->get_host(), 'description' => '', }, 'module_data' => \@modules, @@ -1621,7 +1701,7 @@ sub app_scan($) { $self->call('create_agents', \@data); # Destroy item. - undef($dbObj); + undef($obj); } $global_percent += $global_step; @@ -1657,9 +1737,11 @@ sub deploy_scan($) { ); if (!$deployer) { + # Failed to initialize, check Cloud credentials or anything. call('message', 'Unable to initialize PandoraFMS::Recon::Deployer', 3); } else { + # Let deployer object manage scan. $deployer->scan(); } @@ -1682,13 +1764,16 @@ sub scan($) { $self->call('update_progress', 1); if (defined($self->{'task_data'})) { - if ($self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL - || $self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE) { - # Database scan. + if ( $self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL + || $self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE + || $self->{'task_data'}->{'type'} == DISCOVERY_APP_SAP) { + + # Application scan. return $self->app_scan(); } if ($self->{'task_data'}->{'type'} == DISCOVERY_CLOUD_AWS_RDS) { + # Cloud scan. return $self->cloud_scan(); } diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index 3a3e1904a0..05adbf79d1 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -110,6 +110,7 @@ our @EXPORT = qw( is_offline to_number clean_blank + credential_store_get_key pandora_sendmail pandora_trash_ascii enterprise_hook @@ -487,6 +488,33 @@ sub pandora_daemonize { # Pandora other General functions | # -------------------------------------------+ +######################################################################## +# SUB credential_store_get_key +# Retrieve all information related to target identifier. +# param1 - config hash +# param2 - dbh link +# param3 - string identifier +######################################################################## +sub credential_store_get_key($$$) { + my ($pa_config, $dbh, $identifier) = @_; + + my $sql = 'SELECT * FROM tcredential_store WHERE identifier = ?'; + my $key = PandoraFMS::DB::get_db_single_row($dbh, $sql, $identifier); + + return { + 'username' => PandoraFMS::Core::pandora_output_password( + $pa_config, + $key->{'username'} + ), + 'password' => PandoraFMS::Core::pandora_output_password( + $pa_config, + $key->{'password'} + ), + 'extra_1' => $key->{'extra_1'}, + 'extra_2' => $key->{'extra_2'}, + }; + +} ######################################################################## # SUB pandora_sendmail diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 058a7a201f..d40fca28bc 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.740 -%define release 191113 +%define release 191118 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 1cc4ce0412..d827011000 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.740 -%define release 191113 +%define release 191118 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 34b1a6479c..56d2225910 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.740" -PI_BUILD="191113" +PI_BUILD="191118" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 7ae1717f78..76b393698b 100644 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -34,7 +34,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.740 PS191113"; +my $version = "7.0NG.740 PS191118"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index f45897efe6..76e267b8ac 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.740 PS191113"; +my $version = "7.0NG.740 PS191118"; # save program name for logging my $progname = basename($0);