Skip to content

Commit

Permalink
Add support for setting passwords on Windows Server and utilize QEMU …
Browse files Browse the repository at this point in the history
…Guest Agent for setting passwords on Linux
  • Loading branch information
AnushK-Fro authored Nov 10, 2024
1 parent bdc9c41 commit c431a7b
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 11 deletions.
71 changes: 71 additions & 0 deletions app/Jobs/Server/SyncWindowsSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
namespace Convoy\Jobs\Server;

use Convoy\Models\Server;
use Convoy\Services\Servers\ServerAuthService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Middleware\SkipIfBatchCancelled;
use Illuminate\Queue\Middleware\WithoutOverlapping;
use Illuminate\Queue\SerializesModels;

class SyncWindowsSettings implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

public int $tries = 15;

public int $timeout = 20;

public function __construct(protected int $serverId, protected string $password)
{
//
}

public function middleware(): array
{
return [new SkipIfBatchCancelled(), new WithoutOverlapping(
"server.sync-windows-settings#{$this->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();
}
}
61 changes: 61 additions & 0 deletions app/Repositories/Proxmox/Server/ProxmoxGuestAgentRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Convoy\Repositories\Proxmox\Server;

use Convoy\Models\Server;
use Webmozart\Assert\Assert;
use Convoy\Repositories\Proxmox\ProxmoxRepository;
use Convoy\Exceptions\Repository\Proxmox\ProxmoxConnectionException;

class ProxmoxGuestAgentRepository extends ProxmoxRepository
{
/**
* Get Guest Agent status.
*
* @return mixed
*
* @throws ProxmoxConnectionException
*/
public function guestAgentOs()
{
Assert::isInstanceOf($this->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);
}
}
28 changes: 20 additions & 8 deletions app/Services/Servers/ServerAuthService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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']);
}
}
}
}
16 changes: 13 additions & 3 deletions app/Services/Servers/ServerBuildDispatchService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

Expand All @@ -91,4 +101,4 @@ public function getChainedDeleteJobs(Server $server): array
new WaitUntilVmIsDeletedJob($server->id),
];
}
}
}

0 comments on commit c431a7b

Please sign in to comment.