diff --git a/pandora_console/extras/mr/69.sql b/pandora_console/extras/mr/69.sql index 2be1a25079..63e3a21b32 100644 --- a/pandora_console/extras/mr/69.sql +++ b/pandora_console/extras/mr/69.sql @@ -7712,4 +7712,38 @@ UPDATE `twelcome_tip` SET url = 'https://pandorafms.com/manual/!current/start?id DELETE FROM tconfig WHERE `token` = 'legacy_database_ha'; +-- Add new columns in tdeployment_hosts +ALTER TABLE `tdeployment_hosts` ADD COLUMN `deploy_method` ENUM('SSH', 'HTTP', 'HTTPS') DEFAULT 'SSH'; +ALTER TABLE `tdeployment_hosts` ADD COLUMN `deploy_port` INT UNSIGNED NOT NULL DEFAULT 22; +ALTER TABLE `tdeployment_hosts` ADD COLUMN `server_port` INT UNSIGNED NOT NULL DEFAULT 41121; +ALTER TABLE `tdeployment_hosts` ADD COLUMN `temp_folder` VARCHAR(500) DEFAULT '/tmp'; + +UPDATE + `tdeployment_hosts`, `tconfig_os` +SET + `tdeployment_hosts`.`deploy_method` = 'HTTP', + `tdeployment_hosts`.`deploy_port` = 5985, + `tdeployment_hosts`.`temp_folder` = 'C:\Widnows\Temp' +WHERE + `tdeployment_hosts`.`id_os` = `tconfig_os`.`id_os` AND `tconfig_os`.`name` = 'Windows' AND `tdeployment_hosts`.`deployed` = 0; + +-- Find the name of the foreign key constraint +SELECT @constraint_name := `constraint_name` +FROM `information_schema`.`key_column_usage` +WHERE `table_name` = 'tdeployment_hosts' AND `column_name` = 'id_os'; + +-- Drop the foreign key constraint using dynamic SQL +SET @drop_fk_query = CONCAT('ALTER TABLE `tdeployment_hosts` DROP FOREIGN KEY ', @constraint_name); +PREPARE stmt FROM @drop_fk_query; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +-- Drop unused columns in tdeployment_hosts +ALTER TABLE `tdeployment_hosts` DROP COLUMN `id_os`; +ALTER TABLE `tdeployment_hosts` DROP COLUMN `os_version`; +ALTER TABLE `tdeployment_hosts` DROP COLUMN `arch`; + +-- Update all deployment recon tasks port +UPDATE `trecon_task` SET `field4` = 41121 WHERE `type` = 9; + COMMIT; \ No newline at end of file diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 5d352ebeb1..e3c049d758 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -100,6 +100,26 @@ class DiscoveryTaskList extends HTML // Load styles. parent::run(); + $deploymentCenter = new DeploymentCenter(); + echo $deploymentCenter->loadJS(); + ui_require_css_file('deployment_list'); + + html_print_div( + [ + 'content' => '', + 'id' => 'modal_add_target', + 'class' => 'invisible', + ] + ); + + html_print_div( + [ + 'content' => '', + 'id' => 'modal_deploy_targets', + 'class' => 'invisible', + ] + ); + $this->prepareBreadcrum( [ [ @@ -184,7 +204,7 @@ class DiscoveryTaskList extends HTML } if (is_reporting_console_node() === false) { - $ret2 = $this->showList(__('Host & devices tasks'), [0, 1]); + $ret2 = $this->showList(__('Host & devices tasks'), [0, 1, 9]); $ret2 .= $this->showList(__('Applications tasks'), [3, 4, 5, 10, 11, 12], 'app'); $ret2 .= $this->showList(__('Cloud tasks'), [6, 7, 8, 13, 14], 'cloud'); $ret2 .= $this->showList(__('Custom tasks'), [-1], 'custom'); @@ -874,14 +894,12 @@ class DiscoveryTaskList extends HTML break; case DISCOVERY_DEPLOY_AGENTS: - // Internal deployment task. - $no_operations = true; $data[6] = html_print_image( 'images/osx-terminal@groups.svg', true, ['title' => __('Agent deployment')] ).'  '; - $data[6] .= __('Discovery.Agent.Deployment (legacy)'); + $data[6] .= __('Discovery.Agent.Deployment'); break; case DISCOVERY_APP_MICROSOFT_SQL_SERVER: @@ -1007,6 +1025,7 @@ class DiscoveryTaskList extends HTML && $task['type'] != DISCOVERY_APP_SAP && $task['type'] != DISCOVERY_CLOUD_AWS_RDS && $task['type'] != DISCOVERY_CLOUD_AWS_S3 + && $task['type'] != DISCOVERY_DEPLOY_AGENTS ) { if (check_acl($config['id_user'], 0, 'MR') && (int) $task['type'] !== DISCOVERY_EXTENSION) { $data[9] .= ''; @@ -1066,25 +1085,40 @@ class DiscoveryTaskList extends HTML ).''; } } else { - $url_edit = sprintf( - 'index.php?sec=gservers&sec2=godmode/servers/discovery&%s&task=%d', - $this->getTargetWiz($task, $recon_script_data), - $task['id_rt'] - ); + // Create the url edit. + switch ((int) $task['type']) { + case DISCOVERY_EXTENSION: + $url_edit = ui_get_full_url( + sprintf( + 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=%s&mode=%s&id_task=%s', + $task['section'], + $task['short_name'], + $task['id_rt'], + ) + ); + break; - if ((int) $task['type'] === DISCOVERY_EXTENSION) { - $url_edit = sprintf( - 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=%s&mode=%s&id_task=%s', - $task['section'], - $task['short_name'], - $task['id_rt'], - ); + case DISCOVERY_DEPLOY_AGENTS: + if (empty($task['field1']) === false) { + $url_edit = 'javascript:show_deploy_targets('.$task['id_rt'].')'; + } else { + $url_edit = 'javascript:show_scan_targets('.$task['id_rt'].')'; + } + break; + + default: + $url_edit = ui_get_full_url( + sprintf( + 'index.php?sec=gservers&sec2=godmode/servers/discovery&%s&task=%d', + $this->getTargetWiz($task, $recon_script_data), + $task['id_rt'] + ) + ); + break; } // Check if is a H&D, Cloud or Application or IPAM. - $data[9] .= ''.html_print_image( + $data[9] .= ''.html_print_image( 'images/edit.svg', true, [ diff --git a/pandora_console/include/styles/deployment_list.css b/pandora_console/include/styles/deployment_list.css index e487207b05..746fe82716 100644 --- a/pandora_console/include/styles/deployment_list.css +++ b/pandora_console/include/styles/deployment_list.css @@ -29,6 +29,5 @@ ul.wizard li.flex-indep { } .datatable_filter.content li input[type="text"] { - width: 150px; margin: 0 1em 0 0; } diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 5f5a2bf10c..9b4d2b595a 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -3933,19 +3933,18 @@ CREATE TABLE IF NOT EXISTS `tdeployment_hosts` ( `id` SERIAL, `id_cs` VARCHAR(100), `ip` VARCHAR(100) NOT NULL UNIQUE, - `id_os` INT UNSIGNED DEFAULT 0, - `os_version` VARCHAR(100) DEFAULT '' COMMENT 'OS version in STR format', - `arch` ENUM('x64', 'x86') DEFAULT 'x64', `current_agent_version` VARCHAR(100) DEFAULT '' COMMENT 'String latest installed agent', `target_agent_version_id` BIGINT UNSIGNED, `deployed` BIGINT NOT NULL DEFAULT 0 COMMENT 'When it was deployed', `server_ip` VARCHAR(100) DEFAULT NULL COMMENT 'Where to point target agent', `last_err` TEXT, + `deploy_method` ENUM('SSH', 'HTTP', 'HTTPS') DEFAULT 'SSH', + `deploy_port` INT UNSIGNED NOT NULL DEFAULT 22, + `server_port` INT UNSIGNED NOT NULL DEFAULT 41121, + `temp_folder` VARCHAR(500) DEFAULT '/tmp', PRIMARY KEY (`id`), FOREIGN KEY (`id_cs`) REFERENCES `tcredential_store`(`identifier`) ON UPDATE CASCADE ON DELETE SET NULL, - FOREIGN KEY (`id_os`) REFERENCES `tconfig_os`(`id_os`) - ON UPDATE CASCADE ON DELETE CASCADE, FOREIGN KEY (`target_agent_version_id`) REFERENCES `tagent_repository`(`id`) ON UPDATE CASCADE ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; diff --git a/pandora_server/conf/pandora_server.conf.new b/pandora_server/conf/pandora_server.conf.new index 8dcb2ee0f4..eded19d4db 100644 --- a/pandora_server/conf/pandora_server.conf.new +++ b/pandora_server/conf/pandora_server.conf.new @@ -711,6 +711,9 @@ ncmserver_threads 1 # NCM utility to avoid Net::SSH::Expect issues in multi-threaded environments. ncm_ssh_utility /usr/share/pandora_server/util/ncm_ssh_extension +# Utility to deploy software agents via SSH or WinRM. +agent_deployer_utility /usr/share/pandora_server/util/pandora_agent_deployer + # Pandora FMS Daemon Watchdog execution interval in seconds (PANDORA FMS ENTERPRISE ONLY). ha_interval 30 diff --git a/pandora_server/conf/tentacle_server.conf.new b/pandora_server/conf/tentacle_server.conf.new index a7cec8fd2c..9f0452d82b 100644 --- a/pandora_server/conf/tentacle_server.conf.new +++ b/pandora_server/conf/tentacle_server.conf.new @@ -21,7 +21,7 @@ daemon 1 #insecure 0 # [-i] Filters (regexp:dir;regexp:dir...). -filters .*\.conf:conf;.*\.md5:md5;.*\.zip:collections;.*\.lock:trans;.*\.rcmd:commands +filters .*\.conf:conf;.*\.md5:md5;.*\.zip:collections;.*\.lock:trans;.*\.rcmd:commands;.*\.agent_setup\.exe:agent;.*\.agent_setup\.tar\.gz:agent # [-m] Maximum file size allowed by the server in bytes # max_size 2000000 diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 000a431b5d..68b61e1e9e 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -556,6 +556,8 @@ sub pandora_load_config { $pa_config->{'ncmserver_threads'} = 1; # 7.0.758 $pa_config->{'ncm_ssh_utility'} = '/usr/share/pandora_server/util/ncm_ssh_extension'; # 7.0.758 + $pa_config->{'agent_deployer_utility'} = '/usr/share/pandora_server/util/pandora_agent_deployer'; # 7.0.777 + $pa_config->{"pandora_service_cmd"} = 'service pandora_server'; # 7.0.761 $pa_config->{"tentacle_service_cmd"} = 'service tentacle_serverd'; # 7.0.761 $pa_config->{"tentacle_service_watchdog"} = 1; # 7.0.761 @@ -1337,6 +1339,9 @@ sub pandora_load_config { elsif ($parametro =~ m/^ncm_ssh_utility\s+(.*)/i) { $pa_config->{'ncm_ssh_utility'}= clean_blank($1); } + elsif ($parametro =~ m/^agent_deployer_utility\s+(.*)/i) { + $pa_config->{'agent_deployer_utility'}= clean_blank($1); + } elsif ($parametro =~ m/^ha_file\s(.*)/i) { $pa_config->{'ha_file'} = clean_blank($1); } diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 918d331215..3dc3d44f17 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -148,21 +148,23 @@ sub data_producer ($) { WHERE id_recon_server = ? AND disabled = 0 AND ((utimestamp = 0 AND interval_sweep != 0 OR status = 1) - OR (status < 0 AND interval_sweep > 0 AND (utimestamp + interval_sweep) < UNIX_TIMESTAMP()))', $server_id); + OR (status < 0 AND interval_sweep > 0 AND (utimestamp + interval_sweep) < UNIX_TIMESTAMP()) + OR (status < 0 AND utimestamp = 0 AND interval_sweep = 0))', $server_id); } else { @rows = get_db_rows ($dbh, 'SELECT * FROM trecon_task WHERE (id_recon_server = ? OR id_recon_server NOT IN (SELECT id_server FROM tserver WHERE status = 1 AND server_type = ?)) AND disabled = 0 AND ((utimestamp = 0 AND interval_sweep != 0 OR status = 1) - OR (status < 0 AND interval_sweep > 0 AND (utimestamp + interval_sweep) < UNIX_TIMESTAMP()))', $server_id, DISCOVERYSERVER); + OR (status < 0 AND interval_sweep > 0 AND (utimestamp + interval_sweep) < UNIX_TIMESTAMP()) + OR (status < 0 AND utimestamp = 0 AND interval_sweep = 0))', $server_id, DISCOVERYSERVER); } foreach my $row (@rows) { - # Discovery apps must be fully set up. + # Discovery apps must be fully set up. if ($row->{'type'} == DISCOVERY_APP && $row->{'setup_complete'} != 1) { logger($pa_config, 'Setup for recon app task ' . $row->{'id_app'} . ' not complete.', 10); - next; + next; } # Update task status @@ -313,13 +315,7 @@ sub data_consumer ($$) { # Clean tmp file. if (defined($cnf_extra{'creds_file'}) && -f $cnf_extra{'creds_file'}) { - unlink($cnf_extra{'creds_file'}); - } - - - # Clean one shot tasks - if ($task->{'type'} eq DISCOVERY_DEPLOY_AGENTS) { - db_delete_limit($dbh, ' trecon_task ', ' id_rt = ? ', 1, $task->{'id_rt'}); + unlink($cnf_extra{'creds_file'}); } }; if ($@) { diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 74388cdb06..634b8e2545 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -344,6 +344,8 @@ install () { chmod 2770 $DESTDIR$PANDORA_SPOOL/data_in/commands mkdir $DESTDIR$PANDORA_SPOOL/data_in/discovery 2> /dev/null chmod 2770 $DESTDIR$PANDORA_SPOOL/data_in/discovery + mkdir $DESTDIR$PANDORA_SPOOL/data_in/agent 2> /dev/null + chmod 2770 $DESTDIR$PANDORA_SPOOL/data_in/agent mkdir -p $DESTDIR$PANDORA_LOG 2> /dev/null chown -R pandora:apache $DESTDIR$PANDORA_LOG 2> /dev/null chmod 2774 $DESTDIR$PANDORA_LOG 2> /dev/null @@ -435,6 +437,28 @@ install () { then echo cp $TENTACLE_CFG_FILE_DIST $DESTDIR$TENTACLE_CFG_DIR cp $TENTACLE_CFG_FILE_DIST $DESTDIR$TENTACLE_CFG_DIR + + # Add agents deployment filters if not added yet + filter_changed=0 + tentacle_filters=$(grep -E '^\s*filters\s*.*$' "$DESTDIR$TENTACLE_CFG_FILE" | sed 's/\\/\\\\/g') + if ! [[ $tentacle_filters =~ \.\*\\\\\.agent_setup\\\\\.exe:agent ]] + then + sed -i -e "s/$tentacle_filters/$tentacle_filters;.*\\\\.agent_setup\\\\.exe:agent/" "$DESTDIR$TENTACLE_CFG_FILE" + filter_changed=1 + fi + tentacle_filters=$(grep -E '^\s*filters\s*.*$' "$DESTDIR$TENTACLE_CFG_FILE" | sed 's/\\/\\\\/g') + if ! [[ $tentacle_filters =~ \.\*\\\\\.agent_setup\\\\\.tar\\\\\.gz:agent ]] + then + sed -i -e "s/$tentacle_filters/$tentacle_filters;.*\\\\.agent_setup\\\\.tar\\\\.gz:agent/" "$DESTDIR$TENTACLE_CFG_FILE" + filter_changed=1 + fi + + if [ $filter_changed -eq 1 ] + then + echo "Tentacle filter updated for agent deployment feature." + echo "Please restart 'tentacle_serverd' service." + fi + else echo cp $TENTACLE_CFG_FILE_DIST $DESTDIR$TENTACLE_CFG_FILE cp $TENTACLE_CFG_FILE_DIST $DESTDIR$TENTACLE_CFG_FILE