From c431a7b617c983066ede9a1c471ba6c677182937 Mon Sep 17 00:00:00 2001 From: Anush <33168386+AnushK-Fro@users.noreply.github.com> Date: Sat, 9 Nov 2024 20:57:28 -0500 Subject: [PATCH 1/3] Add support for setting passwords on Windows Server and utilize QEMU Guest Agent for setting passwords on Linux --- app/Jobs/Server/SyncWindowsSettings.php | 71 +++++++++++++++++++ .../Server/ProxmoxGuestAgentRepository.php | 61 ++++++++++++++++ app/Services/Servers/ServerAuthService.php | 28 +++++--- .../Servers/ServerBuildDispatchService.php | 16 ++++- 4 files changed, 165 insertions(+), 11 deletions(-) create mode 100644 app/Jobs/Server/SyncWindowsSettings.php create mode 100644 app/Repositories/Proxmox/Server/ProxmoxGuestAgentRepository.php 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 From 3c6200ca7dad14b5a80e9e768a1295e5e8d31545 Mon Sep 17 00:00:00 2001 From: Anush <33168386+AnushK-Fro@users.noreply.github.com> Date: Sat, 9 Nov 2024 21:06:26 -0500 Subject: [PATCH 2/3] Increases pagination limit to 999999 for IP Addresses --- app/Http/Controllers/Admin/AddressPools/AddressController.php | 2 +- app/Http/Controllers/Admin/Nodes/AddressController.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Admin/AddressPools/AddressController.php b/app/Http/Controllers/Admin/AddressPools/AddressController.php index e2c4f2409e1..5f287fc98e1 100644 --- a/app/Http/Controllers/Admin/AddressPools/AddressController.php +++ b/app/Http/Controllers/Admin/AddressPools/AddressController.php @@ -48,7 +48,7 @@ public function index(Request $request, AddressPool $addressPool) AllowedFilter::exact('server_id')->nullable(), ], ) - ->paginate(min($request->query('per_page', 50), 100))->appends( + ->paginate(min($request->query('per_page', 50), 999999))->appends( $request->query(), ); diff --git a/app/Http/Controllers/Admin/Nodes/AddressController.php b/app/Http/Controllers/Admin/Nodes/AddressController.php index c7bd5afb942..ff633ec02b3 100644 --- a/app/Http/Controllers/Admin/Nodes/AddressController.php +++ b/app/Http/Controllers/Admin/Nodes/AddressController.php @@ -25,7 +25,7 @@ public function index(Request $request, Node $node) new FiltersAddressWildcard(), ), AllowedFilter::exact('server_id')->nullable()], ) - ->paginate(min($request->query('per_page', 50), 100))->appends( + ->paginate(min($request->query('per_page', 50), 999999))->appends( $request->query(), ); From 059a6557a2a2b8ed5435c6c12db3f2678bd56ae5 Mon Sep 17 00:00:00 2001 From: Anush <33168386+AnushK-Fro@users.noreply.github.com> Date: Sun, 10 Nov 2024 11:00:28 -0500 Subject: [PATCH 3/3] Fixes problem with test not passing --- app/Services/Servers/ServerAuthService.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/Services/Servers/ServerAuthService.php b/app/Services/Servers/ServerAuthService.php index e53f2defad6..7c2caac9070 100644 --- a/app/Services/Servers/ServerAuthService.php +++ b/app/Services/Servers/ServerAuthService.php @@ -16,12 +16,15 @@ public function updatePassword(Server $server, string $password) { try { $OsInfo = $this->guestAgentRepository->setServer($server)->guestAgentOs(); - if (str_contains($OsInfo["result"]["name"], "Windows")) { - $username = "Administrator"; - } else { - $username = "root"; + if (is_array($OsInfo) && isset($OsInfo["result"]["name"])) { + if (str_contains($OsInfo["result"]["name"], "Windows")) { + $username = "Administrator"; + } else { + $username = "root"; + } + + $this->guestAgentRepository->setServer($server)->updateGuestAgentPassword($username, $password); } - $this->guestAgentRepository->setServer($server)->updateGuestAgentPassword($username, $password); $this->configRepository->setServer($server)->update(['cipassword' => $password]); } catch (\Exception $e) { $this->configRepository->setServer($server)->update(['cipassword' => $password]);