clusev/app/Livewire/Servers/Show.php

113 lines
3.6 KiB
PHP

<?php
namespace App\Livewire\Servers;
use App\Models\Server;
use App\Services\FleetService;
use Livewire\Attributes\Layout;
use Livewire\Attributes\On;
use Livewire\Attributes\Title;
use Livewire\Component;
use Throwable;
#[Layout('layouts.app')]
#[Title('Server-Details — Clusev')]
class Show extends Component
{
/** Route-model-bound by uuid (R11). */
public Server $server;
public bool $connected = false;
public array $volumes = [];
public array $interfaces = [];
public array $hardening = [];
public array $sshKeys = [];
/**
* Pull a live snapshot over SSH and persist identity/metrics onto the row.
* On any failure (no credential, unreachable) the page renders an offline
* state from the last persisted values instead of crashing.
*/
public function mount(FleetService $fleet): void
{
try {
$snap = $fleet->snapshot($this->server);
$id = $snap['identity'];
$rootUsed = collect($snap['volumes'])->firstWhere('mount', '/')['used'] ?? $this->server->disk;
$this->server->forceFill([
'cpu' => $snap['metrics']['cpu'],
'mem' => $snap['metrics']['mem'],
'disk' => $rootUsed,
'os' => $id['os'],
'hostname' => $id['hostname'],
'uptime' => $id['uptime'],
'status' => 'online',
'last_seen_at' => now(),
'specs' => [
'cores' => $id['cores'],
'ram_gb' => $id['ram_gb'],
'disk_gb' => $id['disk_gb'],
'arch' => $id['arch'],
'kernel' => $id['kernel'],
'virt' => $id['virt'],
],
])->save();
$this->volumes = $snap['volumes'];
$this->interfaces = $snap['interfaces'];
$this->hardening = $snap['hardening'];
$this->sshKeys = $snap['sshKeys'];
$this->connected = true;
} catch (Throwable) {
$this->connected = false;
if ($this->server->status !== 'offline') {
$this->server->forceFill(['status' => 'offline'])->save();
}
}
}
/**
* Revoke an SSH key (R5): opens the confirm modal, which writes the
* AuditEvent and re-dispatches `keyRemoved`. SSH layer removal lands later.
*/
public function confirmKeyRemoval(string $fingerprint, string $comment): void
{
$this->dispatch('openModal',
component: 'modals.confirm-action',
arguments: [
'heading' => 'SSH-Schlüssel entfernen',
'body' => "Der Schlüssel „{$comment}“ verliert den Zugang zu {$this->server->name}.",
'confirmLabel' => 'Entfernen',
'danger' => true,
'icon' => 'trash',
'auditAction' => 'ssh_key.remove',
'auditTarget' => "{$comment} · {$this->server->name}",
'serverId' => $this->server->id,
'event' => 'keyRemoved',
'params' => ['fingerprint' => $fingerprint],
'notify' => "Schlüssel „{$comment}“ entfernt.",
],
);
}
/** Applies the confirmed key removal (optimistic until SSH layer lands). */
#[On('keyRemoved')]
public function removeKey(string $fingerprint): void
{
$this->sshKeys = array_values(array_filter(
$this->sshKeys,
fn (array $k): bool => $k['fingerprint'] !== $fingerprint,
));
}
public function render()
{
return view('livewire.servers.show');
}
}