onQueue('provisioning'); } public function handle(WireguardHub $hub): void { // Derselbe Sperrname wie in ApplyVpnPeer und SyncVpnPeers: ein Abgleich // darf den Hub nicht mitten in dieser Änderung lesen und danach auf das // handeln, was er gesehen hat. Cache::lock('wireguard:hub', 30)->block(10, fn () => $this->apply($hub)); } private function apply(WireguardHub $hub): void { // Der Sollzustand kommt aus der Zeile, nicht aus dem beim Einreihen // festgehaltenen Wert. Ein Wiederholungsversuch nach einem zweiten // Übernahmeversuch trüge sonst den überholten Schlüssel wieder ein. $host = Host::find($this->hostId); if ($host === null || blank($host->wg_pubkey) || blank($host->wg_ip)) { return; } // Erst den neuen Peer aufnehmen, dann den alten entfernen — dazwischen // darf es keinen Moment geben, in dem gar kein Peer eingetragen ist. $hub->addPeer($host->wg_pubkey, $host->wg_ip); if (filled($this->previousPublicKey) && $this->previousPublicKey !== $host->wg_pubkey) { $hub->removePeer($this->previousPublicKey); } } /** * Laut scheitern. * * Der Betreiber hat seine Befehlszeile längst in der Hand; bleibt der Peer * aus, kommt der Tunnel auf der übernommenen Maschine nie hoch, und das * sieht dort aus wie ein Netzproblem. Diese Zeile ist die einzige Stelle, * an der steht, dass es keines war. */ public function failed(?Throwable $e): void { Log::error('Der Tunnel-Peer eines Hosts liess sich nicht eintragen', [ 'host' => $this->hostId, 'exception' => $e?->getMessage(), ]); } }