feat(benachrichtigung): E-Mail und Webhook bei Drift und Ablauf (#028)
Drift, ablaufende und abgelaufene Schluessel, unerreichbare Hosts und geaenderte Host-Keys sollen auffallen, ohne dass jemand taeglich in die Oberflaeche schaut. Versand per SMTP (Microsoft 365, STARTTLS) und per Webhook mit HMAC-Signatur, eingestellt unter /einstellungen. Die Anlaesse liest der Worker aus der Datenbank, statt sie im Abgleich auszuloesen: der Abgleich-Ablauf bleibt unberuehrt, und ein verpasster Lauf holt sich der naechste. Ein Versandprotokoll (Zustellung) mit Anlass-Fingerabdruck verhindert Doppelmeldungen und haelt Fehlschlaege fuer begrenzte Wiederholungen fest. Taeglich eine Zusammenfassung, geaenderte Host-Keys im Fuenf-Minuten-Takt sofort. Versand und Testnachricht laufen im Worker, damit der Webprozess keinen Weg zu Mailserver oder Webhook-Ziel braucht. Passwort und Geheimnis liegen nur verschluesselt in der Datenbank; die Seite zeigt "gesetzt". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+29
-1
@@ -5,11 +5,14 @@ import { alleHostsAbgleichen } from "@/server/services/abgleich";
|
||||
import {
|
||||
WARTESCHLANGE,
|
||||
ZEITPLAN_ABGLEICH,
|
||||
ZEITPLAN_MELDUNG,
|
||||
ZEITPLAN_MELDUNG_TAKT,
|
||||
warteschlangeHolen,
|
||||
type VorgangsJob,
|
||||
} from "@/server/vorgaenge/warteschlange";
|
||||
import { vorgangAusfuehren } from "@/worker/ausfuehren";
|
||||
import { abholungenAufraeumen } from "@/worker/ablaeufe/privatekey";
|
||||
import { taktVersenden, zusammenfassungVersenden } from "@/worker/benachrichtigung/versand";
|
||||
import { deploymentKeySicherstellen } from "@/worker/geheimnisse";
|
||||
import { HANDLER } from "@/worker/handler";
|
||||
|
||||
@@ -61,7 +64,32 @@ async function starten(): Promise<void> {
|
||||
console.log(`Zeitplan: ${anzahl} Abgleich(e) eingereiht.`);
|
||||
});
|
||||
|
||||
console.log(`sshkv-worker ${VERSION} bereit (Abgleich: ${zeitplan}).`);
|
||||
// Benachrichtigungen (#028): taeglich die Zusammenfassung, alle fuenf Minuten geaenderte
|
||||
// Host-Keys (dringend) und faellige Wiederholungen. Fehler nur ins Log – das
|
||||
// Versandprotokoll haelt fest, was nachzuholen ist.
|
||||
const meldung = process.env["SSHKV_MELDUNG_CRON"]?.trim() || "0 7 * * *";
|
||||
const melden = (lauf: () => Promise<{ gesendet: number; fehlgeschlagen: number }>) => async () => {
|
||||
const bilanz = await lauf().catch((fehler: unknown) => {
|
||||
console.error("Benachrichtigung:", fehler instanceof Error ? fehler.message : fehler);
|
||||
return null;
|
||||
});
|
||||
if (bilanz && bilanz.gesendet + bilanz.fehlgeschlagen > 0)
|
||||
console.log(`Benachrichtigung: ${bilanz.gesendet} gesendet, ${bilanz.fehlgeschlagen} fehlgeschlagen.`);
|
||||
};
|
||||
await boss.createQueue(ZEITPLAN_MELDUNG);
|
||||
await boss.schedule(ZEITPLAN_MELDUNG, meldung, null, { tz: "Europe/Berlin" });
|
||||
await boss.work(
|
||||
ZEITPLAN_MELDUNG,
|
||||
melden(() => zusammenfassungVersenden()),
|
||||
);
|
||||
await boss.createQueue(ZEITPLAN_MELDUNG_TAKT);
|
||||
await boss.schedule(ZEITPLAN_MELDUNG_TAKT, "*/5 * * * *", null, { tz: "Europe/Berlin" });
|
||||
await boss.work(
|
||||
ZEITPLAN_MELDUNG_TAKT,
|
||||
melden(() => taktVersenden()),
|
||||
);
|
||||
|
||||
console.log(`sshkv-worker ${VERSION} bereit (Abgleich: ${zeitplan}, Meldungen: ${meldung}).`);
|
||||
|
||||
const beenden = async (signal: string) => {
|
||||
console.log(`${signal} empfangen, beende laufende Vorgänge …`);
|
||||
|
||||
Reference in New Issue
Block a user