From 59d2d49ba1be7277344983141715e3639a016704 Mon Sep 17 00:00:00 2001 From: Sebastian Serfling Date: Wed, 29 Apr 2026 21:31:39 +0200 Subject: [PATCH] docs: README aktualisiert (Step I, Error Handler, DB-Schema) Co-Authored-By: Claude Sonnet 4.6 --- README.md | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c286af4..bfb4779 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,13 @@ Jeden Tag um **00:11 Uhr** werden alle PBS-Backups auf mehreren Restore-Servern │ │ ├── aktive_datastores_aus_db_holen.my.sql ─ Step F │ │ ├── job_initialisieren_&_backup-queue_...py ─ Step A │ │ ├── alle_freien_restore-server_holen.py ─ Step B -│ │ ├── ssh-credentials_fuer_alle_...py ─ Step G +│ │ ├── ssh_key_versuch.py ─ Step I ← SSH-Key Auth +│ │ ├── ssh-credentials_fuer_alle_...py ─ Step G ← Bitwarden Fallback │ │ ├── script_deployen_&_pbs-datastores_...py ─ Step C │ │ ├── alte_restore-ordner_...py ─ Step H │ │ ├── ersten_restore_pro_server_starten.py ─ Step D -│ │ └── webhook_verarbeiten_&_...py ─ Step E +│ │ ├── webhook_verarbeiten_&_...py ─ Step E +│ │ └── flow_fehler_handler.py ─ failure_module │ ├── backup_restore_report___nextcloud_talk__flow/ ← Täglicher Report (08:00 Uhr) │ ├── folder.meta.yaml │ ├── nextcloud_talk_room.variable.yaml @@ -77,26 +79,60 @@ Windmill (Schedule 00:11 Uhr) --- -## Flow-Ablauf: F → A → B → G → C → H → D → E +## Flow-Ablauf: F → A → B → I → G → C → H → D → E | Step | ID | Sprache | Funktion | |------|----|---------|----------| | F | `f` | MySQL | Aktive Datastores aus DB holen | | A | `a` | Python | Job anlegen, PBS-Snapshots holen, Queue aufbauen (größte zuerst) | | B | `b` | Python | Freie Restore-Server holen | -| G | `g` | Python | SSH-Credentials aus Bitwarden | +| I | `i` | Python | SSH-Key aus DB testen (primäre Auth-Methode) | +| G | `g` | Python | SSH-Credentials aus Bitwarden (Fallback für Server ohne Key) | | C | `c` | Python | Script deployen, PBS-Storages registrieren, Session speichern | | H | `h` | Python | Alte Backup-Ordner auf Backup-Server löschen | | D | `d` | Python | Ersten Restore pro Server starten | | E | `e` | Python | Webhook verarbeiten, nächsten Restore starten | +| — | `failure` | Python | **Error Handler**: Talk-Nachricht + DB-Cleanup bei jedem Flow-Fehler | + +### SSH-Auth Logik (Step I → G) + +Step I liest SSH-Keys aus `bronze.restore.server.ssh_private_key` und testet die Verbindung: +- **Key OK** → Server in `server_creds` eingetragen, Bitwarden wird übersprungen +- **Key fehlt oder schlägt fehl** → Server in `needs_bitwarden` Liste → Step G holt Credentials aus Bitwarden + +Step G ist ein No-Op wenn alle Server per Key authentifiziert wurden. + +### SSH-Key für Server eintragen + +```sql +UPDATE Kunden.`bronze.restore.server` +SET ssh_private_key = '-----BEGIN OPENSSH PRIVATE KEY----- +... +-----END OPENSSH PRIVATE KEY-----', + ssh_key_user = 'root' +WHERE hostname = 'STI-PROX01'; +``` ### Zwei Modi **Schedule-Pfad** (täglich 00:11): -Steps F → A → B → G → C → H → D laufen sequenziell. Step D startet den ersten Restore pro Server per SSH non-blocking und gibt `waiting_for_webhook` zurück. +Steps F → A → B → I → G → C → H → D laufen sequenziell. Step D startet den ersten Restore pro Server per SSH non-blocking. **Webhook-Pfad** (nach jedem `restore.sh`): -Flow-Input enthält `job_uuid` → Step A erkennt Webhook-Aufruf. Steps B–H werden übersprungen. Step E verarbeitet das Ergebnis, schreibt es in die DB und startet sofort das nächste passende Backup auf demselben Server. +Flow-Input enthält `job_uuid` → Step A erkennt Webhook-Aufruf. Steps B–H werden übersprungen. Step E verarbeitet das Ergebnis und startet sofort das nächste Backup auf demselben Server. + +### Error Handler (failure_module) + +Bei jedem Flow-Fehler wird automatisch: +1. Eine Nextcloud Talk Nachricht gesendet: + ``` + 🚨 Backup Restore Flow Fehler + Step: `b` + Fehler: Kein freier Restore-Server verfuegbar! + ``` +2. Der laufende DB-Job auf `failed` gesetzt +3. Alle blockierten Restore-Server freigegeben (`current_job_uuid = NULL`) +4. Session-Einträge des Jobs gelöscht --- @@ -209,6 +245,30 @@ Das Script wird von Step C automatisch auf alle Restore-Server deployed: | min_backup_size_gb | INT | NULL = kein Limit | | script_deployed | TINYINT | Script vorhanden | | script_version | VARCHAR(20) | Aktuelle Script-Version | +| **ssh_private_key** | TEXT | SSH Private Key (RSA/Ed25519/ECDSA) | +| **ssh_key_user** | VARCHAR(64) | SSH-User für Key-Auth (default: root) | + +### `bronze.restore.session` +| Spalte | Typ | Beschreibung | +|--------|-----|--------------| +| job_uuid | VARCHAR(64) | Referenz auf Job | +| hostname | VARCHAR(128) | Server-Hostname | +| ip | VARCHAR(45) | IP-Adresse | +| ssh_user | VARCHAR(64) | SSH-Benutzername | +| ssh_password | VARCHAR(256) | SSH-Passwort (leer bei Key-Auth) | +| **ssh_private_key** | TEXT | SSH Private Key (leer bei Passwort-Auth) | + +> Temporäre Tabelle — wird am Job-Ende oder bei Fehler automatisch bereinigt. + +#### Neue Spalten anlegen +```sql +ALTER TABLE Kunden.`bronze.restore.server` + ADD COLUMN ssh_private_key TEXT, + ADD COLUMN ssh_key_user VARCHAR(64) DEFAULT 'root'; + +ALTER TABLE Kunden.`bronze.restore.session` + ADD COLUMN ssh_private_key TEXT; +``` ---