diff --git a/app/Jobs/Server/SyncWindowsSettings.php b/app/Jobs/Server/SyncWindowsSettings.php new file mode 100644 index 00000000000..71521b21417 --- /dev/null +++ b/app/Jobs/Server/SyncWindowsSettings.php @@ -0,0 +1,71 @@ +serverId}", + )]; + } + + public function handle(ServerAuthService $service): void + { + $server = Server::findOrFail($this->serverId); + + $service->updateWindowsPassword($server, $this->password); + } + + /** + * Determine the time at which the job should retry. + * + * @return \DateTime + */ + public function retryAfter(): \DateTime + { + return now()->addSeconds(20); + } + + /** + * Determine the time at which the job should timeout. + * + * @return \DateTime + */ + public function retryUntil(): \DateTime + { + return now()->addSeconds($this->timeout * $this->tries); + } + + /** + * Handle a job failure. + * + * @return void + */ + public function failed(): void + { + // Mark the job as completed + $this->delete(); + } +} \ No newline at end of file diff --git a/app/Repositories/Proxmox/Server/ProxmoxGuestAgentRepository.php b/app/Repositories/Proxmox/Server/ProxmoxGuestAgentRepository.php new file mode 100644 index 00000000000..d9752f5f2b4 --- /dev/null +++ b/app/Repositories/Proxmox/Server/ProxmoxGuestAgentRepository.php @@ -0,0 +1,61 @@ +server, Server::class); + + $response = $this->getHttpClient() + ->withUrlParameters([ + 'node' => $this->node->cluster, + 'server' => $this->server->vmid, + ]) + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/get-osinfo') + ->json(); + + return $this->getData($response); + } + + /** + * Update Guest Agent password for Administrator user. + * + * @param string $password + * @return mixed + * + * @throws ProxmoxConnectionException + */ + public function updateGuestAgentPassword(string $username, string $password) + { + Assert::isInstanceOf($this->server, Server::class); + + $params = [ + 'username' => $username, + 'password' => $password, + ]; + + $response = $this->getHttpClient() + ->withUrlParameters([ + 'node' => $this->node->cluster, + 'server' => $this->server->vmid, + ]) + ->post('/api2/json/nodes/{node}/qemu/{server}/agent/set-user-password', $params) + ->json(); + + return $this->getData($response); + } +} \ No newline at end of file diff --git a/app/Services/Servers/ServerAuthService.php b/app/Services/Servers/ServerAuthService.php index 590948888e1..e53f2defad6 100644 --- a/app/Services/Servers/ServerAuthService.php +++ b/app/Services/Servers/ServerAuthService.php @@ -4,20 +4,32 @@ use Convoy\Models\Server; use Convoy\Repositories\Proxmox\Server\ProxmoxConfigRepository; +use Convoy\Repositories\Proxmox\Server\ProxmoxGuestAgentRepository; class ServerAuthService { - public function __construct(private ProxmoxConfigRepository $configRepository) + public function __construct(private ProxmoxConfigRepository $configRepository, private ProxmoxGuestAgentRepository $guestAgentRepository) { } public function updatePassword(Server $server, string $password) { - // if (!empty($password)) { - $this->configRepository->setServer($server)->update(['cipassword' => $password]); - // } else { - // $this->configRepository->setServer($server)->update(['delete' => 'cipassword']); - // } + try { + $OsInfo = $this->guestAgentRepository->setServer($server)->guestAgentOs(); + if (str_contains($OsInfo["result"]["name"], "Windows")) { + $username = "Administrator"; + } else { + $username = "root"; + } + $this->guestAgentRepository->setServer($server)->updateGuestAgentPassword($username, $password); + $this->configRepository->setServer($server)->update(['cipassword' => $password]); + } catch (\Exception $e) { + $this->configRepository->setServer($server)->update(['cipassword' => $password]); + } + } + + public function updateWindowsPassword(Server $server, string $password) { + $this->guestAgentRepository->setServer($server)->updateGuestAgentPassword("Administrator", $password); } public function getSSHKeys(Server $server) @@ -29,10 +41,10 @@ public function getSSHKeys(Server $server) public function updateSSHKeys(Server $server, ?string $keys) { - if (! empty($keys)) { + if (!empty($keys)) { $this->configRepository->setServer($server)->update(['sshkeys' => rawurlencode($keys)]); } else { $this->configRepository->setServer($server)->update(['delete' => 'sshkeys']); } } -} +} \ No newline at end of file diff --git a/app/Services/Servers/ServerBuildDispatchService.php b/app/Services/Servers/ServerBuildDispatchService.php index 528d81e78fb..bf2e4a312d7 100644 --- a/app/Services/Servers/ServerBuildDispatchService.php +++ b/app/Services/Servers/ServerBuildDispatchService.php @@ -15,6 +15,7 @@ use Convoy\Jobs\Server\SendPowerCommandJob; use Convoy\Jobs\Server\WaitUntilVmIsCreatedJob; use Convoy\Jobs\Server\WaitUntilVmIsDeletedJob; +use Convoy\Jobs\Server\SyncWindowsSettings; use Convoy\Data\Server\Deployments\ServerDeploymentData; class ServerBuildDispatchService @@ -67,11 +68,20 @@ private function getChainedBuildJobs(ServerDeploymentData $deployment): array ]; } - if (! empty($deployment->account_password)) { + $startOnce = false; + + // TODO: Readd the start_on_completion check + + if (!empty($deployment->account_password)) { $jobs[] = new UpdatePasswordJob($deployment->server->id, $deployment->account_password); + if (str_contains($deployment->template->name, "Windows")) { + $jobs[] = new SendPowerCommandJob($deployment->server->id, PowerAction::START); + $startOnce = true; + $jobs[] = new SyncWindowsSettings($deployment->server->id, $deployment->account_password); + } } - if ($deployment->start_on_completion) { + if (!$startOnce) { $jobs[] = new SendPowerCommandJob($deployment->server->id, PowerAction::START); } @@ -91,4 +101,4 @@ public function getChainedDeleteJobs(Server $server): array new WaitUntilVmIsDeletedJob($server->id), ]; } -} +} \ No newline at end of file