pruneVanished($bekannt); $added = 0; foreach ($bekannt as $hostname => $purpose) { $existing = ProxyHost::query()->where('hostname', $hostname)->first(); if ($existing === null) { ProxyHost::create([ 'hostname' => $hostname, 'purpose' => $purpose, 'source' => 'config', ]); $added++; continue; } // Ein von Hand angelegter Name, der inzwischen auch in der Umgebung // steht, bleibt „manual" — sonst verlöre der Betreiber die // Möglichkeit, ihn wieder zu entfernen, ohne je etwas dafür getan // zu haben. if ($existing->isFromConfig() && $existing->purpose !== $purpose) { $existing->forceFill(['purpose' => $purpose])->save(); } } return $added; } /** * Zeilen, die aus der Umgebung kamen und dort nicht mehr stehen. * * Zwei Fälle, und sie brauchen zwei Antworten: * * - Die Zeile hatte NIE ein Zertifikat. Dann war sie ein Fehlgriff — so * kam `127.0.0.1` aus `ADMIN_HOSTS` in die Liste, wo eine nackte IP als * Wiederzugang stehen darf, für die es aber nie ein Zertifikat geben * wird. Sie geht weg; ein dauerhaft roter Eintrag, den niemand beheben * kann, macht die Übersicht unlesbar. * - Die Zeile HAT ein Zertifikat. Dann wird sie zu einem Eintrag von Hand, * statt zu verschwinden. Das Zertifikat läuft ja weiter, und etwas mit * einer laufenden Frist still aus einer Übersicht zu nehmen ist das * Gegenteil einer Übersicht — der Betreiber entfernt sie selbst. * * @param array $bekannt */ private function pruneVanished(array $bekannt): void { $verschwunden = ProxyHost::query() ->where('source', 'config') ->whereNotIn('hostname', array_keys($bekannt)) ->get(); foreach ($verschwunden as $host) { if ($host->hasCertificate()) { $host->forceFill(['source' => 'manual'])->save(); continue; } $host->delete(); } } /** @return array{checked: int, failing: int} */ public function check(): array { $checked = 0; $failing = 0; foreach (ProxyHost::query()->get() as $host) { $result = $this->inspector->inspect($host->hostname); $host->forceFill([ 'certificate_expires_at' => $result['expires_at'], 'certificate_checked_at' => now(), 'certificate_error' => $result['error'], ])->save(); $checked++; if ($result['error'] !== null) { $failing++; } } return ['checked' => $checked, 'failing' => $failing]; } }