onQueue('provisioning'); } public function handle(WireguardHub $hub): void { $snapshots = $hub->peers(); $now = now(); // hosts.wg_pubkey => host id, so pipeline-created peers show up // under their host name instead of as an unknown key. $hostsByKey = Host::query() ->whereNotNull('wg_pubkey') ->pluck('id', 'wg_pubkey'); foreach ($snapshots as $publicKey => $snapshot) { $peer = VpnPeer::withTrashed()->where('public_key', $publicKey)->first(); // Revoked, yet still on the hub: the removal never landed. Retry it // rather than adopting the peer back into the console — otherwise a // failed removal quietly becomes a live access again. if ($peer?->trashed()) { ApplyVpnPeer::dispatch($publicKey, null, false); continue; } $hostId = $hostsByKey[$publicKey] ?? null; $observed = [ 'present' => true, 'endpoint' => $snapshot->endpoint, 'last_handshake_at' => $snapshot->latestHandshake, 'rx_bytes' => $snapshot->rxBytes, 'tx_bytes' => $snapshot->txBytes, 'observed_at' => $now, ]; if ($peer === null) { VpnPeer::create($observed + [ 'public_key' => $publicKey, // Fall back to the dump's allowed-ips for peers that were // never created through the console. 'allowed_ip' => strtok($snapshot->allowedIps, '/') ?: $snapshot->allowedIps, 'host_id' => $hostId, 'name' => $hostId !== null ? (Host::find($hostId)?->name ?? __('vpn.unknown_peer')) : __('vpn.unknown_peer'), 'enabled' => true, ]); continue; } // Never overwrite `enabled`: that is the operator's intent, and a // peer being present only says the hub has not caught up yet. $peer->update($observed + ['host_id' => $peer->host_id ?? $hostId]); } $seen = array_keys($snapshots); VpnPeer::query() ->whereNotIn('public_key', $seen) ->update(['present' => false, 'observed_at' => $now]); // A tombstone whose peer is gone from the hub has done its job. VpnPeer::onlyTrashed()->whereNotIn('public_key', $seen)->forceDelete(); } }