115 lines
4.3 KiB
PHP
115 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Admin;
|
|
|
|
use App\Models\Host;
|
|
use App\Support\HostEnrolment;
|
|
use App\Support\HostTakeoverCommand;
|
|
use LivewireUI\Modal\ModalComponent;
|
|
|
|
/**
|
|
* Stellt die Übernahme-Befehlszeile für einen bestehenden Host neu aus.
|
|
*
|
|
* Es gab sie bis hierher genau EINMAL: auf der Seite direkt nach dem Anlegen.
|
|
* Wer sie dort nicht kopierte — oder wem sie wegbrach, wie beim
|
|
* WireGuard-Fehler bis 1.3.80 — hatte danach einen Host in der Liste, für den
|
|
* es keinen Weg zu einer Befehlszeile mehr gab. Ein zweites Anlegen scheitert
|
|
* an der eindeutigen IP, also blieb nur Entfernen und von vorn.
|
|
*
|
|
* `HostTakeoverCommand` behauptet in seinem Kopfkommentar, die Zeile werde „an
|
|
* zwei Stellen gezeigt (beim Anlegen und beim Neuausstellen eines Codes)". Das
|
|
* Zweite gab es nie — ein Kommentar, der eine Absicht beschreibt und wie eine
|
|
* Beschreibung des Gebauten klingt.
|
|
*
|
|
* Bestätigt wird VOR dem Ausstellen (R23), denn der bisherige Code wird dabei
|
|
* wertlos: eine Maschine, die gerade im Rettungssystem arbeitet, verlöre ihren
|
|
* Ausweis mitten im Lauf.
|
|
*/
|
|
class ReissueTakeover extends ModalComponent
|
|
{
|
|
public string $uuid;
|
|
|
|
public string $name = '';
|
|
|
|
/** Null, solange nur gefragt wird. Gesetzt heißt: ausgestellt, hier steht sie. */
|
|
public ?string $command = null;
|
|
|
|
/** Gesetzt, wenn nicht ausgestellt wurde — und warum. */
|
|
public ?string $refusal = null;
|
|
|
|
/**
|
|
* Nur vor der Übernahme: angelegt, mitten in der Übernahme, gescheitert.
|
|
*
|
|
* Für einen laufenden Host wäre eine neue Befehlszeile kein Angebot,
|
|
* sondern eine Falle: sie setzt die Maschine neu auf.
|
|
*
|
|
* `disabled` gehört NICHT dazu, obwohl es danach aussieht (Codex P1).
|
|
* Es ist der Wartungszustand eines längst laufenden Hosts —
|
|
* `HostDetail::toggleMaintenance()` schaltet aktiv → disabled, um ihn aus
|
|
* der Platzierung zu nehmen. Wer einen Host zum Warten stilllegt, bekäme
|
|
* sonst einen Knopf angeboten, der seine Produktionsmaschine neu aufsetzt.
|
|
*/
|
|
public const ELIGIBLE = ['pending', 'onboarding', 'error'];
|
|
|
|
/**
|
|
* Eine Stelle für die Bedingung, gefragt von der Ansicht UND von `issue()`.
|
|
*
|
|
* Zwei Fassungen davon liefen auseinander, sobald jemand eine ändert — und
|
|
* die, die dann noch gilt, ist die in der Ansicht, also gar keine.
|
|
*/
|
|
public static function eligible(Host $host): bool
|
|
{
|
|
return in_array($host->status, self::ELIGIBLE, true);
|
|
}
|
|
|
|
public function mount(string $uuid): void
|
|
{
|
|
$this->uuid = $uuid;
|
|
$this->name = Host::query()->where('uuid', $uuid)->value('name') ?? '';
|
|
}
|
|
|
|
/**
|
|
* Ein Modal ist ohne die Route-Middleware der Seite erreichbar (R20) und
|
|
* prüft die Berechtigung deshalb selbst — hier besonders, weil in der
|
|
* Antwort ein privater WireGuard-Schlüssel steht.
|
|
*/
|
|
public function issue(): void
|
|
{
|
|
$this->authorize('hosts.manage');
|
|
|
|
$host = Host::query()->where('uuid', $this->uuid)->firstOrFail();
|
|
|
|
// Der Knopf steht nur bei passendem Zustand — aber ein Modal, das offen
|
|
// blieb, während der Host aktiv wurde, ruft diese Methode trotzdem, und
|
|
// eine Livewire-Methode ist ohnehin von außen aufrufbar. Die
|
|
// Sichtbarkeit eines Knopfes ist keine Prüfung (Codex P1): sonst
|
|
// tauschte das hier den Schlüssel einer laufenden Maschine und schnitte
|
|
// sie aus dem Tunnel.
|
|
if (! self::eligible($host)) {
|
|
$this->refusal = __('hosts.reissue.not_eligible');
|
|
|
|
return;
|
|
}
|
|
|
|
// Dieselbe Prüfung wie in der Ansicht, aus demselben Grund (Codex P2).
|
|
// Sonst wird ein gültiger Code entwertet und dafür eine Zeile
|
|
// ausgegeben, der die Tunnel-Angaben fehlen — genau die kaputte Zeile,
|
|
// vor der die Warnung daneben steht.
|
|
if (HostTakeoverCommand::missingSettings() !== []) {
|
|
$this->refusal = __('hosts.takeover.missing_title');
|
|
|
|
return;
|
|
}
|
|
|
|
$this->refusal = null;
|
|
$this->command = HostTakeoverCommand::for($host, HostEnrolment::issueWithKeys($host));
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.admin.reissue-takeover', [
|
|
'missingSettings' => HostTakeoverCommand::missingSettings(),
|
|
]);
|
|
}
|
|
}
|