164 lines
4.2 KiB
PHP
164 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Proxmox;
|
|
|
|
use App\Models\Host;
|
|
|
|
class FakeProxmoxClient implements ProxmoxClient
|
|
{
|
|
public ?Host $host = null;
|
|
|
|
/** @var array<int, array<string, mixed>> */
|
|
public array $nodes = [['node' => 'pve']];
|
|
|
|
/** @var array<string, mixed> */
|
|
public array $status = [
|
|
'cpuinfo' => ['cpus' => 16],
|
|
'memory' => ['total' => 68719476736], // 64 GiB
|
|
'pveversion' => 'pve-manager/8.2.2',
|
|
];
|
|
|
|
/** @var array<int, array<string, mixed>> */
|
|
public array $storage = [
|
|
['storage' => 'local', 'type' => 'dir', 'content' => 'iso,vztmpl,backup', 'total' => 1099511627776],
|
|
['storage' => 'local-lvm', 'type' => 'lvmthin', 'content' => 'images,rootdir', 'total' => 1099511627776], // 1 TiB
|
|
];
|
|
|
|
public function forHost(Host $host): static
|
|
{
|
|
$this->host = $host;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function listNodes(): array
|
|
{
|
|
return $this->nodes;
|
|
}
|
|
|
|
public function nodeStatus(string $node): array
|
|
{
|
|
return $this->status;
|
|
}
|
|
|
|
public function nodeStorage(string $node): array
|
|
{
|
|
return $this->storage;
|
|
}
|
|
|
|
// --- VM lifecycle (deterministic; configurable failure hooks for tests) ---
|
|
|
|
public int $vmidCounter = 100;
|
|
|
|
/** @var array<int, int> */
|
|
public array $clonedVmids = [];
|
|
|
|
/** @var array<int, int> */
|
|
public array $runningVmids = [];
|
|
|
|
/** @var array<int, string> */
|
|
public array $cloudInitCalls = [];
|
|
|
|
/** @var array<int, string> */
|
|
public array $resizeCalls = [];
|
|
|
|
/** @var array<int, string> */
|
|
public array $firewallCalls = [];
|
|
|
|
/** @var array<int, string> recorded guest commands */
|
|
public array $guestCommands = [];
|
|
|
|
/** @var array<string, array{exitcode:int,out-data:string}> */
|
|
private array $guestScripts = [];
|
|
|
|
public int $guestDefaultExit = 0;
|
|
|
|
public string $guestDefaultOut = '';
|
|
|
|
public bool $guestAgentUp = true;
|
|
|
|
public ?string $forceTaskStatus = null; // set to 'running' to force a poll
|
|
|
|
public string $taskExitStatus = 'OK'; // set to a non-OK value to fail a task
|
|
|
|
public function nextVmid(): int
|
|
{
|
|
return $this->vmidCounter++;
|
|
}
|
|
|
|
public function cloneVm(string $node, int $templateVmid, int $newVmid, string $name): string
|
|
{
|
|
$this->clonedVmids[] = $newVmid;
|
|
|
|
return 'UPID:pve:qmclone:'.$newVmid;
|
|
}
|
|
|
|
public function setCloudInit(string $node, int $vmid, array $params): void
|
|
{
|
|
$this->cloudInitCalls[] = $vmid;
|
|
}
|
|
|
|
public function resizeDisk(string $node, int $vmid, string $disk, string $size): void
|
|
{
|
|
$this->resizeCalls[] = $vmid.':'.$disk.':'.$size;
|
|
}
|
|
|
|
public function startVm(string $node, int $vmid): string
|
|
{
|
|
$this->runningVmids[] = $vmid;
|
|
|
|
return 'UPID:pve:qmstart:'.$vmid;
|
|
}
|
|
|
|
public function vmStatus(string $node, int $vmid): array
|
|
{
|
|
return ['status' => in_array($vmid, $this->runningVmids, true) ? 'running' : 'stopped'];
|
|
}
|
|
|
|
public function guestAgentPing(string $node, int $vmid): bool
|
|
{
|
|
return $this->guestAgentUp;
|
|
}
|
|
|
|
public function guestScript(string $substring, int $exitcode, string $out = ''): static
|
|
{
|
|
$this->guestScripts[$substring] = ['exitcode' => $exitcode, 'out-data' => $out];
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function guestExec(string $node, int $vmid, string $command): array
|
|
{
|
|
$this->guestCommands[] = $command;
|
|
|
|
foreach ($this->guestScripts as $substring => $result) {
|
|
if (str_contains($command, $substring)) {
|
|
return $result;
|
|
}
|
|
}
|
|
|
|
return ['exitcode' => $this->guestDefaultExit, 'out-data' => $this->guestDefaultOut];
|
|
}
|
|
|
|
public function guestRan(string $substring): bool
|
|
{
|
|
foreach ($this->guestCommands as $command) {
|
|
if (str_contains($command, $substring)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function taskStatus(string $node, string $upid): array
|
|
{
|
|
return ['status' => $this->forceTaskStatus ?? 'stopped', 'exitstatus' => $this->taskExitStatus];
|
|
}
|
|
|
|
public function applyFirewall(string $node, int $vmid, array $rules): void
|
|
{
|
|
$this->firewallCalls[] = (string) $vmid;
|
|
}
|
|
}
|