From 4277b10f55b01c0e3bfb977b7b23b2927487fa17 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 5 Feb 2026 13:09:09 +0100 Subject: [PATCH] Kanbanize Kartenerstellung dokumentiert: Arrival-Rule-Workaround, Board-Struktur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Neuer Abschnitt "Karten erstellen (Aufgaben-Workflow)" mit Workflow A/B - Bekannte Struktur erweitert: Workflows, Columns, Lanes für Board 1 - Pitfalls ergänzt: Arrival Rule, Parent-Link API, linkedCards read-only - Settings und Plans aktualisiert Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 99 ++++- plans/abstract-gathering-tome.md | 64 +++ plans/cheerful-churning-hejlsberg.md | 260 +++++------ plans/crispy-dancing-gray.md | 52 +++ plans/functional-strolling-donut.md | 118 +++++ plans/glittery-enchanting-allen.md | 315 +++++++++++++ plans/groovy-toasting-crayon.md | 15 + plans/hidden-snacking-lighthouse.md | 62 +++ plans/lively-plotting-cosmos.md | 146 ++++++ plans/peppy-prancing-hedgehog.md | 74 ++++ plans/serialized-swimming-corbato.md | 173 ++++++++ plans/silly-waddling-dragonfly.md | 234 ++++++++++ plans/snazzy-riding-eclipse.md | 23 + plans/snuggly-juggling-hoare.md | 152 +++++++ plans/sparkling-sauteeing-clarke.md | 444 +++++++++++++++++++ plans/typed-munching-tarjan-agent-af913fe.md | 63 +++ plans/typed-munching-tarjan.md | 139 ++++++ plans/zany-growing-penguin.md | 97 ++++ plans/zazzy-cooking-pie.md | 63 +++ plans/zesty-finding-harbor.md | 188 ++++++++ settings.json | 14 +- 21 files changed, 2636 insertions(+), 159 deletions(-) create mode 100644 plans/abstract-gathering-tome.md create mode 100644 plans/crispy-dancing-gray.md create mode 100644 plans/functional-strolling-donut.md create mode 100644 plans/glittery-enchanting-allen.md create mode 100644 plans/groovy-toasting-crayon.md create mode 100644 plans/hidden-snacking-lighthouse.md create mode 100644 plans/lively-plotting-cosmos.md create mode 100644 plans/peppy-prancing-hedgehog.md create mode 100644 plans/serialized-swimming-corbato.md create mode 100644 plans/silly-waddling-dragonfly.md create mode 100644 plans/snazzy-riding-eclipse.md create mode 100644 plans/snuggly-juggling-hoare.md create mode 100644 plans/sparkling-sauteeing-clarke.md create mode 100644 plans/typed-munching-tarjan-agent-af913fe.md create mode 100644 plans/typed-munching-tarjan.md create mode 100644 plans/zany-growing-penguin.md create mode 100644 plans/zazzy-cooking-pie.md create mode 100644 plans/zesty-finding-harbor.md diff --git a/CLAUDE.md b/CLAUDE.md index 852d6d8..499d7e0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1000,6 +1000,40 @@ curl -H "apikey: $(cat ~/.config/kanbanize/token)" \ | Board | 1 | Team Infrastruktur | | User | 4 | Robert Wiegand | +**Workflows auf Board 1:** + +| Workflow-ID | Name | Zweck | +|-------------|------|-------| +| 1 | Aufgaben | Operative Tasks (Backlog → ToDo → In Bearbeitung → Erledigt) | +| 2 | Themen | Übergeordnete Themen/Epics, Parent-Karten für Aufgaben | + +**Columns & Lanes — Workflow 1 (Aufgaben):** + +| Column-ID | Name | Section | +|-----------|------|---------| +| 1 | Aufgaben Backlog | Backlog | +| 2 | ToDo | Requested | +| 3 | In Bearbeitung | In Progress | +| 4 | Erledigt | Done | +| 5 | Ready to Archive | Archive | + +| Lane-ID | Name | +|---------|------| +| 1 | Default (Aufgaben) | + +**Columns & Lanes — Workflow 2 (Themen):** + +| Column-ID | Name | Section | +|-----------|------|---------| +| 29 | Themen Backlog | Backlog | +| 8 | Requested | Requested | +| 9 | In Progress | In Progress | +| 10 | Ready to Archive | Done/Archive | + +| Lane-ID | Name | +|---------|------| +| 5 | Default (Themen) | + ### Pflicht-Workflow bei Vinos-Arbeiten **Bei JEDER Arbeit im Kontext `~/Nextcloud/vinos/` MUSS geprüft werden:** @@ -1082,24 +1116,71 @@ curl -s -X PATCH -H "apikey: $(cat ~/.config/kanbanize/token)" \ "https://weinvinosgmbh.kanbanize.com/api/v2/cards/" ``` -**Bekannte Column-IDs (Board 1):** - -| Column-ID | Name | Section | -|-----------|------|---------| -| 1 | Aufgaben Backlog | Backlog | -| 2 | ToDo | Requested | -| 3 | In Bearbeitung | In Progress | -| 4 | Erledigt | Done | -| 5 | Ready to Archive | Archive | +**Column-IDs:** Siehe "Bekannte Struktur" oben für vollständige Auflistung beider Workflows. **Achtung:** Wenn alle Child-Karten einer Parent-Karte auf "Done" stehen, wird die Parent-Karte automatisch mit verschoben. +### Karten erstellen (Aufgaben-Workflow) + +**Hintergrund:** Workflow 1 (Aufgaben) hat eine Arrival Rule, die verlangt, dass jede Karte mit einem Thema (Parent im Themen-Workflow 2) verknüpft ist. Direkte Kartenerstellung in Workflow 1 per API schlägt daher fehl. + +**Workaround:** Karte zunächst in Workflow 2 (Themen) erstellen, Parent-Link setzen, dann nach Workflow 1 verschieben. + +#### Workflow A — Thema existiert bereits + +```bash +# 1. Karte in Workflow 2 erstellen (Themen Backlog) +NEW_ID=$(curl -s -X POST -H "apikey: $(cat ~/.config/kanbanize/token)" \ + -H "Content-Type: application/json" \ + -d '{"board_id": 1, "workflow_id": 2, "lane_id": 5, "column_id": 29, "title": "Neue Aufgabe"}' \ + "https://weinvinosgmbh.kanbanize.com/api/v2/cards" | jq -r '.data.card_id') + +# 2. Parent-Link zum existierenden Thema setzen +curl -s -X PUT -H "apikey: $(cat ~/.config/kanbanize/token)" \ + "https://weinvinosgmbh.kanbanize.com/api/v2/cards/$NEW_ID/parents/" + +# 3. Nach Aufgaben ToDo verschieben + Titel/Owner setzen +curl -s -X PATCH -H "apikey: $(cat ~/.config/kanbanize/token)" \ + -H "Content-Type: application/json" \ + -d '{"workflow_id": 1, "column_id": 2, "lane_id": 1, "owner_user_id": 4}' \ + "https://weinvinosgmbh.kanbanize.com/api/v2/cards/$NEW_ID" +``` + +#### Workflow B — Thema existiert noch nicht + +```bash +# 1. Thema in Workflow 2 erstellen +THEMA_ID=$(curl -s -X POST -H "apikey: $(cat ~/.config/kanbanize/token)" \ + -H "Content-Type: application/json" \ + -d '{"board_id": 1, "workflow_id": 2, "lane_id": 5, "column_id": 29, "title": "Neues Thema"}' \ + "https://weinvinosgmbh.kanbanize.com/api/v2/cards" | jq -r '.data.card_id') + +# 2. Kind-Karte in Workflow 2 erstellen +CHILD_ID=$(curl -s -X POST -H "apikey: $(cat ~/.config/kanbanize/token)" \ + -H "Content-Type: application/json" \ + -d '{"board_id": 1, "workflow_id": 2, "lane_id": 5, "column_id": 29, "title": "Aufgabe zum Thema"}' \ + "https://weinvinosgmbh.kanbanize.com/api/v2/cards" | jq -r '.data.card_id') + +# 3. Parent-Link setzen +curl -s -X PUT -H "apikey: $(cat ~/.config/kanbanize/token)" \ + "https://weinvinosgmbh.kanbanize.com/api/v2/cards/$CHILD_ID/parents/$THEMA_ID" + +# 4. Kind-Karte nach Aufgaben ToDo verschieben +curl -s -X PATCH -H "apikey: $(cat ~/.config/kanbanize/token)" \ + -H "Content-Type: application/json" \ + -d '{"workflow_id": 1, "column_id": 2, "lane_id": 1, "owner_user_id": 4}' \ + "https://weinvinosgmbh.kanbanize.com/api/v2/cards/$CHILD_ID" +``` + ### Pitfalls - **Kommentare können NICHT gelöscht werden** — weder via API noch UI. Workaround: Inhalt durch `.` ersetzen - **`\n` wird komplett ignoriert** — immer `
` verwenden - **Markdown wird NICHT gerendert** — kein `##`, `**`, `-` etc. - **`type` ist immer `plain`** — kann nicht auf `html` gesetzt werden, HTML wird trotzdem gerendert +- **Arrival Rule auf Workflow 1** blockiert direkte Kartenerstellung per API — Workaround: Karte in Workflow 2 erstellen, Parent setzen, dann nach Workflow 1 verschieben (siehe "Karten erstellen") +- **Parent-Link Endpunkt:** `PUT /cards/{id}/parents/{parent_id}` — nicht POST, nicht PATCH. Entfernen: `DELETE /cards/{id}/parents/{parent_id}` +- **`linkedCards` Sub-Resource ist read-only** — nur GET, keine Manipulation darüber möglich. Parent/Child-Links über `/parents/` und `/children/` Endpunkte verwalten ### In die Task-Abschluss-Checkliste integriert diff --git a/plans/abstract-gathering-tome.md b/plans/abstract-gathering-tome.md new file mode 100644 index 0000000..10430cc --- /dev/null +++ b/plans/abstract-gathering-tome.md @@ -0,0 +1,64 @@ +# Plan: Spam-Learning für Grommunio auf srvmailgw03 konfigurieren + +## Ziel + +Das bestehende Spam-Learning-Script auf srvmailgw03 (`/home/skripte/spam_learning.py`) um Grommunio-IMAP-Accounts erweitern, sodass auch Junk-Mails aus Grommunio für SpamAssassin-Training genutzt werden. + +## Voraussetzungen (bereits erfüllt) + +- IMAP auf srvmail01 für `robert.wiegand@egonetix.de` und `bestellungen@egonetix.de` aktiviert (privilegeBits) +- Gleiche LDAP-Credentials wie Kopano +- SSH-Zugriff auf srvmailgw03 (10.0.0.37) + +## Schritte + +### 1. Bestandsaufnahme auf srvmailgw03 + +- SSH auf srvmailgw03 +- `/home/skripte/spam_learning.py` lesen und verstehen +- `/home/skripte/wrapper.sh` lesen +- Cronjob-Konfiguration prüfen (`crontab -l`) +- Prüfen wie Credentials gespeichert sind (im Script, Config-Datei, Environment?) + +### 2. IMAP-Konnektivität testen + +- Von srvmailgw03 aus IMAP-Verbindung zu srvmail01 (10.0.0.23:993) testen +- Login mit `robert.wiegand@egonetix.de` verifizieren +- Junk-Ordner `Junk-E-Mail` identifizieren und auflisten + +### 3. Script anpassen + +- Grommunio-Accounts zur Konfiguration hinzufügen: + - Server: `10.0.0.23` (srvmail01), Port 993 (IMAPS) + - Account 1: `robert.wiegand@egonetix.de`, Ordner: `Junk-E-Mail` + - Account 2: `bestellungen@egonetix.de`, Ordner: `Junk-E-Mail` +- Beachten: Grommunio nutzt `Junk-E-Mail` (Bindestrich), Kopano nutzt `Junk E-Mail` (Leerzeichen) +- Credentials: Gleiche LDAP-Passwörter wie für die Kopano-Accounts + +### 4. Testen + +- Script manuell ausführen (Testlauf) +- Log prüfen (`/var/log/pmg-spam-learning.log`) +- Verifizieren: Mails werden gelesen, an sa-learn übergeben, dann gelöscht + +### 5. Dokumentation aktualisieren + +- README.md im grommunio-Repo: Spam-Learning-Abschnitt verifizieren/aktualisieren +- `infrastructure/hosts/srvmailgw03.md`: Grommunio-Accounts bestätigen + +## Kritische Dateien + +| Datei | Server | Aktion | +|-------|--------|--------| +| `/home/skripte/spam_learning.py` | srvmailgw03 | Anpassen | +| `/home/skripte/wrapper.sh` | srvmailgw03 | Prüfen | +| `/var/log/pmg-spam-learning.log` | srvmailgw03 | Verifizieren | +| `README.md` | lokal (grommunio-Repo) | Aktualisieren | +| `infrastructure/hosts/srvmailgw03.md` | lokal | Aktualisieren | + +## Verifikation + +1. Manueller Testlauf des Scripts auf srvmailgw03 +2. Log-Ausgabe zeigt erfolgreiche IMAP-Verbindung zu srvmail01 +3. Junk-Mails (falls vorhanden) werden verarbeitet und gelöscht +4. Cronjob bleibt unverändert (Script wird bereits täglich um 01:00 ausgeführt) diff --git a/plans/cheerful-churning-hejlsberg.md b/plans/cheerful-churning-hejlsberg.md index fc77d3b..e07465d 100644 --- a/plans/cheerful-churning-hejlsberg.md +++ b/plans/cheerful-churning-hejlsberg.md @@ -1,136 +1,71 @@ -# Plan: Fix Flaw 1 (Service Unavailable) + Flaw 2 (Theme Layout) +# Plan: Keycloak Theme CSS Fix — Alle Login-Seiten -## Flaw 1: "Service Unavailable" nach OIDC-Login +## Status -### Diagnose +- ~~Flaw 1 (Service Unavailable)~~: **ERLEDIGT** — Ursache war das Files-Plugin, vom User deaktiviert +- **Flaw 2 (Theme Layout)**: Offen — CSS-Fix war unvollständig, PatternFly-Overrides fehlen -**Symptom:** Nach erfolgreichem Keycloak-Login zeigt grommunio-web "Unknown error - Service Unavailable". +## Problem-Analyse (aus 4 Screenshots) -**Log-Evidenz:** -``` -zcore[25984]: rhost=[] user= zs_logon_token rejected: Token did not validate -``` +### Screenshot 1 — Username-Eingabe +- Logo "egonetix / IT Solutions" + "Log in" Titel LINKS neben der Card, kaum lesbar +- Card enthält nur: Username-Feld, Sign In Button, Passkey-Hint -**Wichtig:** `user=` ist LEER -- zcore kann keinen User aus dem Token extrahieren. +### Screenshot 2 — Passkey Login +- "Passkey Login" Text LINKS, kaum lesbar +- Card enthält nur: Username, "Sign in with Passkey" Button, "Try Another Way" -**Was funktioniert:** -- PHP OIDC-Flow: `login() returned 0 (NOERROR)` -- Keycloak-Auth OK -- bearer_pubkey: Korrekt, gleicher Key wie Keycloak, lesbar für gromox-User -- keycloak.json: Korrekt konfiguriert mit `realm-public-key` und `principal-attribute` -- Alle Services: nginx, php-fpm, gromox-http, gromox-zcore laufen +### Screenshot 3 — Login-Methode wählen +- "Select login method" Text LINKS, kaum lesbar +- Card enthält: Username, Passkey-Button, Password-Button -**Vermutete Ursache:** Die PHP-Schicht (grommunio-web) authentifiziert sich erfolgreich bei Keycloak, aber wenn sie den Bearer-Token an gromox-zcore weiterreicht (`mapi_logon_token()`), schlaegt die Token-Validierung in zcore fehl. Der leere `user=` deutet darauf hin, dass zcore den Token nicht parsen oder die Claims nicht extrahieren kann. +### Screenshot 4 — Passwort-Eingabe +- **Mehrere Cards übereinandergestapelt!** +- Eine Card zeigt "robert.wiegand", eine andere das Passwort-Feld +- "Try Another Way" außerhalb beider Cards -### Schritt 1: gromox-zcore Neustart + Live-Test +## Root Cause -```bash -ssh root@10.0.0.23 'systemctl restart gromox-zcore && sleep 2 && systemctl status gromox-zcore --no-pager' -``` +PatternFly v5 `.pf-v5-c-login__main` nutzt intern **CSS Grid** mit grid-template-areas. Das egonetix CSS setzt `display: flex` OHNE `!important`, wodurch PatternFly's Grid gewinnt. Die Kinder (header, body, footer) werden in separate Grid-Areas platziert statt als Flex-Column innerhalb einer Card. -Dann im Browser einloggen und sofort Logs pruefen: -```bash -ssh root@10.0.0.23 'journalctl -u gromox-zcore --since "1 min ago" --no-pager' -``` +Zusätzlich fehlen Grid-Overrides für `.pf-v5-c-login__container` und PatternFly-Transparenz-Regeln für Footer und innere Wrapper. -### Schritt 2: JWT-Token aus Keycloak dekodieren +## Betroffene Datei -Ein Token von Keycloak holen und die Claims pruefen: -```bash -# Token holen (Resource Owner Password Grant fuer Test) -TOKEN=$(curl -s -X POST "https://auth.egonetix.de/realms/egonetix/protocol/openid-connect/token" \ - -d "grant_type=password" \ - -d "client_id=grommunio" \ - -d "username=robert.wiegand@egonetix.de" \ - -d "password=" | jq -r '.access_token') +`/home/icke/keycloak/themes/egonetix/login/resources/css/egonetix.css` auf srvdocker02 (10.0.0.48) -# Token dekodieren (ohne Signatur-Check) -echo "$TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq . -``` +## Fix: CSS-Änderungen -Pruefen ob folgende Claims vorhanden: -- `iss` = `https://auth.egonetix.de/realms/egonetix` -- `aud` = enthaelt `grommunio` oder `account` -- `preferred_username` = `robert.wiegand@egonetix.de` -- `sub` = UUID des Users -- `azp` = `grommunio` - -### Schritt 3: gromox-zcore Debug-Logging erhoehen - -```bash -ssh root@10.0.0.23 'sed -i "s/log_level=6/log_level=1/" /etc/gromox/zcore.cfg && systemctl restart gromox-zcore' -``` - -Log-Level 1 = maximales Logging. Nach Test zuruecksetzen auf 6. - -### Schritt 4: PHP MAPI Token-Uebergabe pruefen - -Pruefen was genau grommunio-web an zcore uebergibt: -```bash -ssh root@10.0.0.23 'grep -n "logon_token\|mapi_logon\|bearer\|zs_logon" /usr/share/php-mapi/class.keycloak.php /usr/share/grommunio-web/server/includes/core/*.php 2>/dev/null' -``` - -### Schritt 5: Direct Access Grants pruefen - -Falls `grant_type=password` nicht erlaubt ist (Public Client), per Browser-DevTools: -1. https://mail.egonetix.de oeffnen -2. DevTools Network-Tab -3. Login durchfuehren -4. Token-Exchange-Request finden und access_token kopieren -5. Manuell dekodieren - -### Schritt 6: Fix anwenden - -Basierend auf Diagnose -- moegliche Fixes: - -**A) Token-Claim-Problem:** Keycloak Mapper anpassen (preferred_username muss E-Mail enthalten) -**B) Audience-Problem:** Keycloak Client Scope anpassen -**C) gromox-Config:** Fehlende Config-Option in zcore.cfg/http.cfg -**D) PHP-Code:** grommunio-web uebergibt falsches Token-Format an zcore - ---- - -## Flaw 2: Keycloak Theme Layout kaputt - -### Diagnose - -**Screenshot-Analyse (Auswahl_2145.jpg):** -- Berg-Hintergrund: OK -- Login-Card (weiss/glassmorphism): Rechts positioniert, OK -- **Logo "egonetix" + "IT SOLUTIONS":** LINKS neben der Card, halb verdeckt -- **"Log in" Titel:** LINKS unter dem Logo, ausserhalb der Card -- Nur Formularfelder (Username, Button, Passkey-Hint) sind IN der Card - -**Root Cause:** Keycloak v2 template.ftl rendert den DOM so: - -```html - -``` - -**Das CSS** applied Card-Styling NUR auf `.pf-v5-c-login__main-body`, NICHT auf den Parent `.pf-v5-c-login__main`. Deshalb sind Logo und Titel AUSSERHALB der visuellen Card. - -### Theme-Dateien (auf srvdocker02) - -| Datei | Pfad | -|-------|------| -| CSS | `/home/icke/keycloak/themes/egonetix/login/resources/css/egonetix.css` | -| login.ftl | `/home/icke/keycloak/themes/egonetix/login/login.ftl` | -| login-username.ftl | `/home/icke/keycloak/themes/egonetix/login/login-username.ftl` | -| logout-confirm.ftl | `/home/icke/keycloak/themes/egonetix/login/logout-confirm.ftl` | -| theme.properties | `/home/icke/keycloak/themes/egonetix/login/theme.properties` | - -### Fix: CSS umstrukturieren - -**Kern-Aenderung:** Card-Styling von `.pf-v5-c-login__main-body` auf `.pf-v5-c-login__main` verschieben. +### Änderung 1 — Layout-Section: PatternFly-Grid killen +Ersetze den bestehenden Layout-Block: ```css -/* Card auf den PARENT anwenden (umschliesst Header + Body) */ +/* === Layout === */ +.pf-v5-c-login, +.login-pf { + background: transparent !important; + min-height: 100vh; + display: flex !important; + align-items: center !important; + justify-content: center !important; +} + +.pf-v5-c-login__container { + display: flex !important; + align-items: center !important; + justify-content: center !important; + width: 100% !important; + max-width: none !important; + grid-template-columns: unset !important; + grid-template-rows: unset !important; +} +``` + +### Änderung 2 — Card-Section: `!important` auf alle Display/Grid-Properties + +Ersetze den Card-Block: +```css +/* === Card (Glassmorphism) === */ .pf-v5-c-login__main { background: var(--ego-card-background) !important; backdrop-filter: var(--ego-card-backdrop) !important; @@ -142,14 +77,28 @@ Basierend auf Diagnose -- moegliche Fixes: width: var(--ego-card-width) !important; max-width: 90vw !important; margin: 0 auto !important; + /* Kill PatternFly grid, force flex column */ + display: flex !important; + flex-direction: column !important; + align-items: center !important; + grid-template-columns: unset !important; + grid-template-rows: unset !important; + grid-template-areas: unset !important; } +``` -/* Kinder transparent machen (kein doppelter Card-Effekt) */ +### Änderung 3 — Children-Section: Footer + Grid-Area-Overrides hinzufügen + +Ersetze den Children-Block (`.pf-v5-c-login__main-footer` und `grid-column/grid-row` fehlten): +```css +/* === Children transparent (no double card) === */ .pf-v5-c-login__main-header, .pf-v5-c-login__main-body, +.pf-v5-c-login__main-footer, #kc-form, #kc-content-wrapper, -#kc-form-wrapper { +#kc-form-wrapper, +#kc-header-wrapper { background: transparent !important; box-shadow: none !important; border: none !important; @@ -158,41 +107,66 @@ Basierend auf Diagnose -- moegliche Fixes: border-radius: 0 !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important; + /* Kill PatternFly grid-area assignments */ + grid-column: unset !important; + grid-row: unset !important; } ``` -**Zusaetzlich:** `.pf-v5-c-login__main` Layout korrigieren: +### Änderung 4 — Neue Regel: PatternFly-interne Card-Elemente transparent + +Hinzufügen nach Children-Block: ```css -.pf-v5-c-login__main { - display: flex; - flex-direction: column; - align-items: center; +/* === Kill PatternFly card styling inside login === */ +.pf-v5-c-login__main .pf-v5-c-card, +.pf-v5-c-login__main .pf-v5-c-card__body, +.pf-v5-c-login__main fieldset, +.pf-v5-c-login__main legend { + background: transparent !important; + box-shadow: none !important; + border: none !important; + padding: 0 !important; } ``` -### Schritt-fuer-Schritt +### Änderung 5 — Page-Title-Regel erweitern -1. **egonetix.css** auf srvdocker02 editieren: - - Card-Styling von `#kc-form, .pf-v5-c-login__main-body, #kc-content-wrapper, #kc-form-wrapper` entfernen - - Card-Styling auf `.pf-v5-c-login__main` setzen - - Alle Kinder (header, body, form-wrapper) transparent machen - - Layout-Anpassung: `.pf-v5-c-login__main` als flex-column +Ersetze den Title-Block mit breiterer Abdeckung: +```css +/* === Page Title === */ +#kc-page-title, +.pf-v5-c-login__main-header h1, +.pf-v5-c-login__main-header-desc, +h1#kc-page-title, +h1.pf-v5-c-title { + text-align: center !important; + font-size: 18px !important; + font-weight: 600 !important; + color: var(--ego-text-primary) !important; + margin: 0 0 var(--ego-spacing-lg) 0 !important; + padding: 0 !important; + width: 100% !important; +} +``` -2. **Keycloak-Cache leeren** (Theme-Aenderungen erfordern Cache-Clear oder Restart): - ```bash - ssh root@10.0.0.48 'docker restart keycloak' - ``` +## Deployment -3. **Browser-Test:** https://auth.egonetix.de/realms/egonetix/account -> Logo + Titel + Formular alle IN der Card +```bash +# 1. CSS lokal editieren und per SCP deployen +scp egonetix.css root@10.0.0.48:/home/icke/keycloak/themes/egonetix/login/resources/css/egonetix.css ---- - -## Reihenfolge - -1. **Flaw 2 zuerst** (Theme-Fix) -- CSS-Aenderung auf srvdocker02, schnell verifizierbar -2. **Flaw 1 danach** (Service Unavailable) -- erfordert iteratives Debugging auf srvmail01 +# 2. Keycloak neustarten (Theme-Cache leeren) +ssh root@10.0.0.48 'docker restart keycloak' +``` ## Verifikation -- **Flaw 2:** Browser -> https://mail.egonetix.de -> Keycloak-Login-Seite zeigt Logo + Titel INNERHALB der Card -- **Flaw 1:** Browser -> Login -> kein "Service Unavailable" Dialog, Mailbox oeffnet sich +Alle 4 Seiten im Inkognito-Fenster testen: + +| Seite | Was prüfen | +|-------|-----------| +| Username-Eingabe | Logo + "Log in" INNERHALB der Card, zentriert | +| Passkey Login | "Passkey Login" Titel INNERHALB der Card | +| Login-Methode wählen | "Select login method" Titel INNERHALB der Card | +| Passwort-Eingabe | NUR EINE Card, Passwort-Feld darin, kein Stacking | +| Responsive (Handy) | Card füllt Bildschirm, kein Overflow | diff --git a/plans/crispy-dancing-gray.md b/plans/crispy-dancing-gray.md new file mode 100644 index 0000000..3c8ebbf --- /dev/null +++ b/plans/crispy-dancing-gray.md @@ -0,0 +1,52 @@ +# Plan: Aufräumen + Kanbanize-Workflow dokumentieren + +## Teil 1: Test-Karte 13515 aufräumen + +1. Parent-Link entfernen: `DELETE /api/v2/cards/13515/parents/13458` +2. Zurück nach Ready to Archive (Workflow 2): `PATCH /api/v2/cards/13515` → `{"workflow_id": 2, "column_id": 10, "lane_id": 5}` + +## Teil 2: Kanbanize-Kartenerstellung in CLAUDE.md dokumentieren + +Neuer Abschnitt **"### Karten erstellen (Aufgaben-Workflow)"** nach dem bestehenden Abschnitt "Karten verschieben" (Zeile 1095) einfügen. + +### Inhalt des neuen Abschnitts + +Dokumentiert den 3-Schritt-Workflow, der die Arrival Rule auf Board 1 / Workflow 1 umgeht. Gilt ausschließlich für das Vinos-Board (Board 1, `weinvinosgmbh.kanbanize.com`) — wird als Unter-Abschnitt im bestehenden Vinos-Kanbanize-Block eingefügt: + +**Hintergrund:** Workflow 1 (Aufgaben) hat eine Arrival Rule, die verlangt, dass jede Karte mit einem Thema (Parent im Themen-Workflow 2) verknüpft ist. Direkte Kartenerstellung in Workflow 1 per API ist daher nicht möglich. + +**Workflow A — Thema existiert bereits:** + +1. Karte in Workflow 2 erstellen: `POST /api/v2/cards` mit `workflow_id: 2, lane_id: 5, column_id: 29` +2. Parent-Link setzen: `PUT /api/v2/cards/{new_id}/parents/{parent_id}` +3. Nach Aufgaben ToDo verschieben: `PATCH /api/v2/cards/{new_id}` mit `workflow_id: 1, column_id: 2, lane_id: 1` +4. Titel/Beschreibung/Owner setzen: `PATCH /api/v2/cards/{new_id}` (kann mit Schritt 3 kombiniert werden) + +**Workflow B — Thema existiert noch nicht:** + +1. Thema in Workflow 2 erstellen: `POST /api/v2/cards` mit `workflow_id: 2, lane_id: 5, column_id: 29` +2. Kind-Karte in Workflow 2 erstellen: `POST /api/v2/cards` (gleiche Parameter) +3. Parent-Link setzen: `PUT /api/v2/cards/{child_id}/parents/{theme_id}` +4. Kind-Karte nach Aufgaben ToDo verschieben: `PATCH /api/v2/cards/{child_id}` mit `workflow_id: 1, column_id: 2, lane_id: 1` +5. Titel/Beschreibung/Owner auf beiden Karten setzen + +Ergänzung der **Bekannte Struktur**-Tabelle (Zeile 995) um Workflows, Lanes und Columns beider Workflows. + +Ergänzung der **Pitfalls** (Zeile 1097) um: +- Arrival Rule auf Workflow 1 blockiert direkte Kartenerstellung per API +- Parent-Link Endpunkt: `PUT /cards/{id}/parents/{parent_id}` (nicht POST/PATCH) +- `linkedCards` Sub-Resource ist read-only (nur GET) + +### Betroffene Datei + +- `~/dotfiles/claude_settings/CLAUDE.md` (Zeile ~1076-1102) + +## Teil 3: Auto-Memory aktualisieren + +Kanbanize-Workflow-Erkenntnisse in `/home/rwiegand/.claude/projects/-home-rwiegand-Nextcloud-vinos-zabbix/memory/MEMORY.md` festhalten. + +## Verifizierung + +- Karte 13515: `GET /api/v2/cards/13515/parents` → leer, Column = 10 (Ready to Archive) +- Thema 13458: `GET /api/v2/cards/13458` → `linked_cards` enthält nur 13459 + 13516 (nicht mehr 13515) +- CLAUDE.md: Neuer Abschnitt vorhanden, Settings-Sync nach Gitea gepusht diff --git a/plans/functional-strolling-donut.md b/plans/functional-strolling-donut.md new file mode 100644 index 0000000..0526cc7 --- /dev/null +++ b/plans/functional-strolling-donut.md @@ -0,0 +1,118 @@ +# Plan: CIFS-Mount-Monitoring für srv-nu-ftp01 + +## Ziel + +Auf srv-nu-ftp01 alle CIFS-Mounts überwachen, die nach `//vinos.local/DFS/Workflows/` zeigen. Sobald ein Mountpoint nicht aktiv ist, soll Zabbix alarmieren. + +## Aktueller Stand + +- UserParameters wurden eingetragen, aber **Agent startet nicht** (exit code 1) +- Ursache: Discovery-Zeile über 2 Zeilen umgebrochen → `missing assignment operator` in Zeile 325 +- Die Status-Zeile (`cifs.mount.status[*]`) ist OK + +## Ist-Zustand fstab + +**18 aktive Mounts** (ohne auskommentierte) nach `//vinos.local/DFS/Workflows/`: +- 12× Artikelbilder (gleiche Quelle, verschiedene User-Home-Verzeichnisse) +- Reporting/DWH → `/mnt/Workflows/Reporting/DWH` +- Shop-Filialinfos → `/home/filialinfos/Shop-Filialinfos` +- econda → `/mnt/google_analytics` + `/home/srv-db03/google_analytics` +- sovendus → `/home/sovendus/upload` +- emarsys → `/home/emarsys/upload` +- hubspot → `/home/hubspot/upload` +- Pin-eBrief → `/mnt/Workflows/Pin-eBrief` +- KWK-Export → `/home/kwk-export/KWK-Export` + +## Ansatz: Script-File + UserParameters + +Die Inline-awk-Variante ist zu lang (~200 Zeichen) und bricht beim Kopieren um. Stattdessen ein minimales Discovery-Script. + +## Schritte + +### 1. Agent-Config fixen (DRINGEND - Agent ist down!) + +Die kaputten Zeilen 324-325 entfernen/ersetzen. Neue Config: + +``` +UserParameter=cifs.mount.discovery,/etc/zabbix/scripts/cifs_mount_discovery.sh +UserParameter=cifs.mount.status[*],findmnt "$1" >/dev/null 2>&1 && echo 1 || echo 0 +``` + +### 2. Discovery-Script erstellen + +Script nach `/home/vinosadmin/cifs_mount_discovery.sh` schreiben (kein root-Zugriff als vinosadmin). +User verschiebt es manuell nach `/etc/zabbix/scripts/cifs_mount_discovery.sh` und setzt `chmod +x`. + +```bash +#!/bin/bash +grep -i '//vinos.local/DFS/Workflows' /etc/fstab \ + | grep -v '^\s*#' \ + | awk 'BEGIN{printf "["} NR>1{printf ","} {printf "{\"{#MOUNTPOINT}\":\"%s\",\"{#REMOTE}\":\"%s\"}",$2,$1} END{printf "]"}' +``` + +### 3. Agent neustarten und testen + +```bash +systemctl restart zabbix-agent2 +systemctl status zabbix-agent2 +``` + +Test: +```bash +# Lokal +/etc/zabbix/scripts/cifs_mount_discovery.sh +findmnt /home/fluent/artikelbilder >/dev/null 2>&1 && echo 1 || echo 0 + +# Via Agent (von srv-monitor02) +zabbix_get -s srv-nu-ftp01 -k 'cifs.mount.discovery' +zabbix_get -s srv-nu-ftp01 -k 'cifs.mount.status[/home/fluent/artikelbilder]' +``` + +### 4. Host-ID ermitteln + +Via Zabbix API: `host.get` mit `search: {name: "ftp01"}` + +### 5. Zabbix LLD via API konfigurieren + +**a) Discovery Rule** (`discoveryrule.create`) +- Name: `CIFS DFS/Workflows Mount Discovery` +- Key: `cifs.mount.discovery` +- Type: Zabbix Agent (passive/active je nach Config) +- Update Interval: `1h` + +**b) Item Prototype** (`itemprototype.create`) +- Name: `CIFS Mount Status: {#MOUNTPOINT}` +- Key: `cifs.mount.status[{#MOUNTPOINT}]` +- Type: Zabbix Agent +- Value Type: Numeric (unsigned) +- Update Interval: `5m` + +**c) Trigger Prototype** (`triggerprototype.create`) +- Name: `CIFS Mount {#MOUNTPOINT} nicht aktiv (Remote: {#REMOTE})` +- Expression: `last(/HOST/cifs.mount.status[{#MOUNTPOINT}])=0` +- Severity: High + +### 6. Dokumentation + +- `zabbix/hosts.md`: srv-nu-ftp01 Abschnitt mit Host-ID, UserParameters, SSH-Befehlen +- `zabbix/README.md`: Host-ID in Schnellreferenz + +## Kritische Dateien + +| Datei (auf srv-nu-ftp01) | Aktion | +|---------------------------|--------| +| `/etc/zabbix/zabbix_agent2.conf` | Zeilen 324-325 fixen → 2 saubere UserParameter-Zeilen | +| `/etc/zabbix/scripts/cifs_mount_discovery.sh` | Neu erstellen (4 Zeilen) | + +| Datei (lokal) | Aktion | +|----------------|--------| +| `zabbix/hosts.md` | srv-nu-ftp01 ergänzen | +| `zabbix/README.md` | Host-ID ergänzen | + +## Verifikation + +1. `systemctl status zabbix-agent2` → active (running) +2. `zabbix_get -s srv-nu-ftp01 -k 'cifs.mount.discovery'` → JSON mit 18 Mountpoints +3. `zabbix_get -s srv-nu-ftp01 -k 'cifs.mount.status[/home/fluent/artikelbilder]'` → `1` +4. Zabbix UI: Discovery Rule ausführen → 18 Items + 18 Trigger angelegt +5. Optional: Test-Unmount → Trigger feuert diff --git a/plans/glittery-enchanting-allen.md b/plans/glittery-enchanting-allen.md new file mode 100644 index 0000000..2a2119b --- /dev/null +++ b/plans/glittery-enchanting-allen.md @@ -0,0 +1,315 @@ +# n8n Security Update: 1.123.5 → 2.3.4 + +## Executive Summary + +**Kritikalität:** Hoch - CVE-2025-68668 (CVSS 9.9) ist nur in 2.0.0+ gefixt +**Downtime:** ~5-10 Minuten (PostgreSQL Auto-Migration + Container Rebuild) +**Risiko:** Niedrig - keine Breaking Changes in Workflows gefunden +**Ziel-Version:** 2.3.4 (aktuelle Stable, nicht 2.0.0 wegen Bug-Fixes) + +--- + +## Sicherheitsrisiko-Bewertung + +### Status der 4 CVEs in aktueller Version 1.123.5 + +| CVE | CVSS | Status in 1.123.5 | Risiko | +|-----|------|-------------------|--------| +| **CVE-2026-21858** "Ni8mare" | 10.0 | ✅ GEFIXT (1.121.0) | Unauthenticated RCE über Webhooks | +| **CVE-2026-21877** | 10.0 | ✅ GEFIXT (1.121.3) | Authenticated RCE via Git Node | +| **CVE-2025-68613** | 10.0 | ✅ GEFIXT (1.122.0) | Authenticated Expression Injection | +| **CVE-2025-68668** | 9.9 | ❌ **NICHT GEFIXT** | Python Sandbox Bypass → RCE | + +**Fazit:** CVE-2025-68668 erfordert zwingend Update auf 2.0.0+ + +--- + +## Breaking Changes Analyse + +### ✅ Keine kritischen Breaking Changes + +- **Start Nodes:** Nicht verwendet (alle Workflows nutzen manualTrigger/cron/emailReadImap) +- **Code Nodes:** Kein `process.env` Zugriff (N8N_BLOCK_ENV_ACCESS_IN_NODE=true ist ab 2.0 default) +- **Python Code Nodes:** Nicht verwendet (nur JavaScript Code Nodes) +- **Binary Data Mode:** Keine deprecated Configs + +### ⚠️ Funktionstest erforderlich + +**3 Workflows mit LangChain/OpenAI Integration:** +- `gebuehrenfrei_live.json` +- `instabank_current.json` +- `tfbank_current.json` + +**Verwendung:** AI-gestützte Extraktion von Zahlungsinformationen (Fälligkeitsdatum, IBAN, BIC, Betrag) + +**Nodes:** +- `@n8n/n8n-nodes-langchain.agent` (v1.1) +- `@n8n/n8n-nodes-langchain.lmChatOpenAi` (v1) +- `@n8n/n8n-nodes-langchain.memoryBufferWindow` (v1) + +**Aktion:** Nach Update AI-Extraktion manuell testen + +--- + +## Update-Plan + +### Phase 1: Pre-Update Backup + +**Kritisch:** PostgreSQL-Datenbank enthält alle Workflows, Credentials, Execution History + +```bash +# 1. Auf srvdocker02 per SSH +ssh root@10.0.0.48 + +# 2. PostgreSQL Backup erstellen +cd /home/icke/n8n +docker exec postgres-n8n pg_dump -U n8n n8n > "backup-$(date +%Y%m%d-%H%M%S).sql" + +# 3. Backup komprimieren und sichern +gzip backup-*.sql +ls -lh backup-*.sql.gz + +# 4. Optional: Volume-Backup (enthält auch n8n-Files) +tar -czf "n8n-volumes-$(date +%Y%m%d-%H%M%S).tar.gz" /home/icke/n8n_pg/ +``` + +**Backup-Dateien auf Laptop kopieren (Sicherheitskopie):** +```bash +# Von Laptop aus +scp root@10.0.0.48:/home/icke/n8n/backup-*.sql.gz ~/Nextcloud/egonetix/n8n/backups/ +``` + +--- + +### Phase 2: Update durchführen + +**Datei:** `/home/rwiegand/Nextcloud/egonetix/n8n/Dockerfile.n8n-curl` + +**Änderung:** +```dockerfile +# Alt: +FROM n8nio/n8n:1.123.5 + +# Neu: +FROM n8nio/n8n:2.3.4 +``` + +**Rebuild + Restart:** +```bash +# Auf srvdocker02 +cd /home/icke/n8n + +# Container stoppen +docker compose down + +# Rebuild mit neuer Version (dauert ~2-3 Minuten) +docker compose up -d --build + +# Logs überwachen (PostgreSQL Auto-Migration) +docker compose logs -f n8n-new +``` + +**Erwartete Log-Ausgaben:** +- `Running migrations...` (PostgreSQL Schema-Migration) +- `Migration XYZ successful` +- `n8n ready on 0.0.0.0:5678` + +**Abbruchkriterium:** Wenn Fehler in Logs → sofort `docker compose down` und Rollback + +--- + +### Phase 3: Verifikation + +#### 3.1 Web-UI Zugriff prüfen + +```bash +# Von Laptop +curl -I https://flow.egonetix.de/ +# Erwartung: HTTP 200 oder 302 (Redirect zu Login) +``` + +**Browser-Test:** +- https://flow.egonetix.de/ öffnen +- Login mit Owner-Account +- Dashboard sollte laden + +#### 3.2 Workflows prüfen + +**In Web-UI:** +1. Workflows-Liste öffnen +2. Status der aktiven Workflows prüfen: + - `gebuehrenfrei_live` → aktiv? + - `instabank_current` → aktiv? + - `tfbank_current` → aktiv? + +#### 3.3 LangChain/OpenAI Integration testen + +**Pro Workflow (gebuehrenfrei_live, instabank_current, tfbank_current):** + +1. Workflow öffnen in Editor +2. "Execute Workflow" klicken (manueller Trigger) +3. **Input:** Test-E-Mail mit Kreditkarten-Rechnung +4. **Erwartete Ausgabe:** + - AI Agent extrahiert: Fälligkeitsdatum, IBAN, BIC, Betrag + - Nextcloud Deck Karte wird erstellt (`/home/node/create_card_from_ai.sh`) +5. **Logs prüfen:** + ```bash + docker compose logs n8n-new | grep -i "openai\|langchain\|error" + ``` + +**Falls AI-Extraktion fehlschlägt:** +- Workflow-Logs in Web-UI prüfen +- OpenAI API-Key noch gültig? (in Workflow Credentials) +- Rate Limits überschritten? + +#### 3.4 IMAP-Trigger testen + +**Workflows mit Email-Trigger:** +- Warten auf nächste eingehende Kreditkarten-E-Mail +- Oder: Manuell Test-E-Mail an IMAP-Account senden +- Prüfen ob Workflow automatisch triggert + +#### 3.5 Version bestätigen + +```bash +# In Container +docker exec n8n-new n8n --version +# Erwartung: 2.3.4 +``` + +**In Web-UI:** +- Settings → About → Version sollte "2.3.4" zeigen + +--- + +### Phase 4: Rollback (falls nötig) + +**Nur wenn kritische Fehler auftreten:** + +```bash +# 1. Container stoppen +cd /home/icke/n8n +docker compose down + +# 2. Dockerfile zurücksetzen +# In /home/rwiegand/Nextcloud/egonetix/n8n/Dockerfile.n8n-curl: +FROM n8nio/n8n:1.123.5 + +# 3. Rebuild mit alter Version +docker compose up -d --build + +# 4. Falls DB korrupt: Backup einspielen +docker exec -i postgres-n8n psql -U n8n n8n < backup-TIMESTAMP.sql +``` + +**Wichtig:** Rollback nur bis max. 1 Stunde nach Update - danach könnten neue Workflows/Executions verloren gehen! + +--- + +## Post-Update Maßnahmen + +### Dokumentation aktualisieren + +**Datei:** `/home/rwiegand/Nextcloud/egonetix/n8n/README.md` + +**Abschnitt "Upgrade n8n" aktualisieren:** +```markdown +### Upgrade n8n +Edit `Dockerfile.n8n-curl` and change version: +```dockerfile +FROM n8nio/n8n:2.3.4 # Change version here (aktuell: 2.3.4, Stand: 2026-02-04) +``` +Then rebuild: +```bash +docker compose up -d --build +``` + +**Hinweis:** Breaking Changes zwischen 1.x und 2.x beachten: +- Start Nodes entfernt (verwende manualTrigger stattdessen) +- Python Sandbox sicherer (CVE-2025-68668 gefixt) +- PostgreSQL Schema-Migration läuft automatisch (Backup vorher!) +``` + +### Infrastructure-Dokumentation + +**Datei:** `~/Nextcloud/egonetix/infrastructure/hosts/srvdocker02.md` + +**Neuer Abschnitt unter "Docker Containers":** +```markdown +## Wichtige Updates + +### n8n Security Update (2026-02-04) +- **Version:** 1.123.5 → 2.3.4 +- **Grund:** CVE-2025-68668 (Python Sandbox RCE, CVSS 9.9) +- **Downtime:** ~8 Minuten +- **Migration:** PostgreSQL Schema automatisch migriert +- **Tests:** LangChain/OpenAI Integration erfolgreich getestet +- **Commit:** [commit-hash] +``` + +### Git Commit + +```bash +cd ~/Nextcloud/egonetix/n8n +git add Dockerfile.n8n-curl README.md +git commit -m "Security Update: n8n 1.123.5 → 2.3.4 (CVE-2025-68668) + +- Update Dockerfile.n8n-curl auf n8n:2.3.4 +- Behebt CVE-2025-68668 (Python Sandbox Bypass, CVSS 9.9) +- PostgreSQL Schema-Migration erfolgreich +- LangChain/OpenAI Workflows getestet und funktional +- Breaking Changes: keine in unserer Konfiguration + +Co-Authored-By: Claude Haiku 4.5 " +git push origin main +``` + +--- + +## Kritische Dateien + +| Datei | Änderung | +|-------|----------| +| `Dockerfile.n8n-curl` | Zeile 1: `FROM n8nio/n8n:1.123.5` → `FROM n8nio/n8n:2.3.4` | +| `README.md` | Abschnitt "Upgrade n8n" erweitern mit Breaking Changes Hinweis | + +**Keine Änderungen nötig:** +- `docker-compose.yml` (Environment-Variablen bleiben unverändert) +- `scripts/*.sh` (Custom Scripts kompatibel) +- Workflow-Files (keine Start Nodes, kein process.env) + +--- + +## Verification Checklist + +Nach Abschluss des Updates: + +- [ ] PostgreSQL Backup erstellt und gesichert +- [ ] `docker compose logs` zeigt keine Errors +- [ ] Web-UI unter https://flow.egonetix.de/ erreichbar +- [ ] Login funktioniert +- [ ] Workflows-Liste zeigt alle Workflows +- [ ] 3 LangChain Workflows manuell getestet: + - [ ] `gebuehrenfrei_live` - AI-Extraktion funktioniert + - [ ] `instabank_current` - AI-Extraktion funktioniert + - [ ] `tfbank_current` - AI-Extraktion funktioniert +- [ ] IMAP-Trigger aktiv (bei nächster E-Mail testen) +- [ ] `n8n --version` zeigt 2.3.4 +- [ ] README.md aktualisiert +- [ ] `infrastructure/hosts/srvdocker02.md` aktualisiert +- [ ] Git Commit erstellt und gepusht +- [ ] Backup-Files können gelöscht werden (nach 1 Woche Betrieb) + +--- + +## Geschätzte Zeiten + +| Phase | Dauer | +|-------|-------| +| Backup | 2-3 Minuten | +| Update (Dockerfile Edit + Rebuild) | 3-5 Minuten | +| Verifikation (Web-UI + Workflows) | 5-10 Minuten | +| Dokumentation | 3-5 Minuten | +| **Gesamt** | **15-25 Minuten** | + +**Downtime:** Nur während Container-Restart (~5 Minuten) diff --git a/plans/groovy-toasting-crayon.md b/plans/groovy-toasting-crayon.md new file mode 100644 index 0000000..43c503a --- /dev/null +++ b/plans/groovy-toasting-crayon.md @@ -0,0 +1,15 @@ +# CRIF #13461 - Untersuchungsergebnis + +## Status: Kein Handlungsbedarf + +Die Untersuchung hat ergeben, dass der Fix vom 02.02 (Commit `1f2bd4c`) **korrekt funktioniert**: + +- Item 99026 hat Intervall `15m;0/1-7,00:00-02:30` (bestätigt via API) +- Letzte Nacht (02.→03.02): Keine Checks zwischen 00:00 und 02:30 +- Kein Trigger-Event, keine Alerts seit dem Fix +- User hatte die Daten verwechselt - die Meldungen kamen vom 02.02 01:45 (vor dem Fix) + +## Optionale Aktion + +- Kanbanize #13461: Bestätigungskommentar posten dass der Fix verifiziert ist +- Karte auf "Erledigt" verschieben (falls gewünscht) diff --git a/plans/hidden-snacking-lighthouse.md b/plans/hidden-snacking-lighthouse.md new file mode 100644 index 0000000..9c4193c --- /dev/null +++ b/plans/hidden-snacking-lighthouse.md @@ -0,0 +1,62 @@ +# Plan: Dokumentation nach VPN-Analyse aktualisieren + +## Kontext + +Während der Analyse des VPN-Timeouts (flow.wvits.de nicht erreichbar über Client-VPN) wurden folgende Erkenntnisse gewonnen: + +- **gw-nu-wan01** hat ein direktes DMZ-VLAN-Interface (igb0.811, IP 10.10.81.14) +- **srv-revproxy01** hat gw-nu-wan01 als Default-Gateway (10.10.81.14), NICHT gw-nu-dmz02 +- Admin-VPN (10.250.0.0/24): `pass to any` → funktioniert +- Client-VPN (10.250.1.0/24): Firewall-Regel für 10.10.81.4:443 wurde hinzugefügt (Easy Rule), 10.10.81.4 in OpenVPN "IPv4 Local Networks" ergänzt +- srv-revproxy01 Routing: `10.10.10.0/24` und `10.10.254.0/24` via gw-nu-dmz02 (10.10.81.1), alles andere via gw-nu-wan01 + +## Zu aktualisierende Dateien + +### 1. `infrastructure/hosts/gw-nu-wan01.md` + +Aktuell nur Stub mit TODOs. Erweitern um: +- Netzwerk-Interfaces: igb0.811 (10.10.81.14, DMZ VLAN) hinzufügen +- VPN-Server dokumentieren: Admin-VPN (server6, 10.250.0.0/24, Port 1300), Client-VPN (server8, 10.250.1.0/24) +- VPN-Firewall-Regeln: Admin hat `to any`, Client hat spezifische Ziel-Regeln +- Client-VPN Firewall-Regel: `10.250.1.0/24 → 10.10.81.4:443` (Easy Rule, bereits umgesetzt) +- OpenVPN Client-VPN: 10.10.81.4 in "IPv4 Local Networks" ergänzt (bereits umgesetzt) +- Abhängigkeiten aktualisieren: srv-revproxy01 hängt von gw-nu-wan01 ab (Default-GW) +- DNS-Push: 10.10.10.111, 10.10.10.222, domain vinos.local + +### 2. `infrastructure/hosts/srv-revproxy01.md` + +Ergänzen: +- Routing-Tabelle: Default-GW ist 10.10.81.14 (gw-nu-wan01), nicht gw-nu-dmz02 +- Abhängigkeiten: gw-nu-wan01 als Default-Gateway hinzufügen +- Firewall-Abschnitt: WuV_VPN_Admin (10.250.0.0/24) fehlt in der Liste der erlaubten Netze + +### 3. `infrastructure/dependencies.md` + +n8n-Mermaid-Diagramm aktualisieren: +- gw-nu-wan01 als VPN-Gateway hinzufügen (zwischen VPN-Client und srv-revproxy01) +- VPN-Client-Pfad: VPN → gw-nu-wan01 → DMZ → srv-revproxy01 +- Impact-Tabelle: gw-nu-wan01-Ausfall = VPN-Clients erreichen DMZ nicht +- Referenz-Tabelle: gw-nu-wan01 hinzufügen + +### 4. `n8n/README.md` + +VPN-Voraussetzungen (Zeile 191-198) erweitern: +- 4. Voraussetzung: Firewall auf gw-nu-wan01 erlaubt VPN → DMZ:443 — Status: ✅ Erledigt (Admin: `to any`, Client: Easy Rule 10.250.1.0/24 → 10.10.81.4:443) +- 5. Voraussetzung: 10.10.81.4 in OpenVPN "IPv4 Local Networks" — Status: ✅ Erledigt (beide VPN-Server) +- Abhängigkeiten-Tabelle: gw-nu-wan01 hinzufügen (VPN-Gateway, Default-GW für srv-revproxy01) + +## Reihenfolge + +1. gw-nu-wan01.md aktualisieren (Kernfund) +2. srv-revproxy01.md aktualisieren (Routing + Abhängigkeit) +3. dependencies.md aktualisieren (Diagramm + Impact) +4. n8n README.md aktualisieren (VPN-Voraussetzungen) +5. Alles committen und pushen (n8n-Repo + infrastructure-Repo) +6. Pflicht-Checkliste durchlaufen (Verifikation, Settings-Sync, Kanbanize) + +## Verifikation + +- Alle Markdown-Links prüfen (relative Pfade zwischen hosts/) +- Mermaid-Diagramm Knoten gegen Referenz-Tabelle abgleichen +- IPs/Netze konsistent zwischen README, srv-revproxy01.md und dependencies.md +- Zweiter Review-Pass gemäß CLAUDE.md diff --git a/plans/lively-plotting-cosmos.md b/plans/lively-plotting-cosmos.md new file mode 100644 index 0000000..abaec3f --- /dev/null +++ b/plans/lively-plotting-cosmos.md @@ -0,0 +1,146 @@ +# Plan: flow.wvits.de intern erreichbar machen + +## Ziel + +`flow.wvits.de` soll aus ausgewählten internen Netzen voll erreichbar sein (inkl. Formulare, Signup). Externe Zugriffe bleiben auf Webhooks beschränkt. + +| Netz | Subnet | Zugriff | +|------|--------|---------| +| Admin-Netz | 10.10.254.0/24 | Voller Zugriff | +| Bodega Client | 10.20.20.0/24 | Voller Zugriff | +| Admin-VPN | 10.250.0.0/24 | Voller Zugriff | +| WuV VPN | 10.250.1.0/24 | Voller Zugriff | +| gw-web02 | 10.10.81.12 | Voller Zugriff | +| Extern | alles andere | Nur Webhooks | + +## Verifizierte Diagnose + +### Problem 1: Firewall gw-nu-dmz02 blockiert + +**Getestet:** +- srv-docker01 (10.10.10.24) → DMZ: **durchkommt** (EasyRule für diesen einzelnen Host) +- srv-docker02 (10.10.10.81) → DMZ: **TIMEOUT** (kein Firewall-Eintrag für Subnet) + +**Aktuelle Firewall-Regeln zu srv-revproxy01 (10.10.81.4):** + +| Quelle | Alias | Port | Status | +|--------|-------|------|--------| +| 10.10.254.0/24 | NET_NU_ADMIN | SSH, 80, 81, 443, 8443 | ✅ vorhanden | +| 10.250.1.0/24 | WuV_VPN_Client | 443 | ✅ vorhanden | +| 10.250.0.0/24 | WuV_VPN_Admin | 443 | ✅ vorhanden | +| 10.20.20.0/24 | NET_BD_CLIENT | 443 | ✅ vorhanden | +| 10.10.10.24 | (EasyRule) | alle | ✅ nur einzelner Host | +| 10.10.10.0/24 | — | — | Nicht benötigt | +| 10.10.0.0/24 | LAN__NETWORK | — | Nicht benötigt | +| 10.20.0.0/24 | — | — | Nicht benötigt | + +**Existierende Aliases (relevant):** +- `WebGatewayNets`: 10.10.10.0/24, 10.10.12.0/27, 10.10.20.0/24, 10.10.40.0/24, 10.10.254.0/24 +- `LAN__NETWORK`: 10.10.0.0/24 +- `WebGateways`: 10.10.81.10, 10.10.81.11, 10.10.81.12 + +### Problem 2: nginx allow/deny blockiert + +**Getestet:** +- srv-docker01 (10.10.10.24) → Webhook-Pfad: **funktioniert** (n8n antwortet) +- srv-docker01 (10.10.10.24) → Signup-Pfad: **403 Forbidden** +- nginx-Log bestätigt: `client: 10.10.10.24, access forbidden by rule` + +**Aktuelle allow/deny im non-webhook Location-Block:** +```nginx +allow 10.10.81.12; # gw-web02 +deny all; +# Auskommentiert: 10.10.254.0/24, 10.20.20.0/24, 10.250.1.0/24 +``` + +--- + +## Lösung + +### Schritt 1: Firewall gw-nu-dmz02 — Regeln hinzufügen (User macht das) + +Auf pfsense Web-UI von gw-nu-dmz02: Firewall-Regeln auf **em1 (LAN)** prüfen/ergänzen. + +**Benötigte Regeln zu srv_revproxy01 (10.10.81.4) Port 443:** + +| Quelle | Alias vorhanden? | Regel vorhanden? | Aktion | +|--------|-------------------|------------------|--------| +| 10.10.254.0/24 | `NET_NU_ADMIN` ✅ | ✅ HTTPS erlaubt | Keine Änderung | +| 10.20.20.0/24 | `NET_BD_CLIENT` ✅ | ✅ HTTPS erlaubt | Keine Änderung | +| 10.250.0.0/24 | `WuV_VPN_Admin` ✅ | ✅ HTTPS erlaubt | Keine Änderung | +| 10.250.1.0/24 | `WuV_VPN_Client` ✅ | ✅ HTTPS erlaubt | Keine Änderung | + +Alle benötigten Netze haben bereits Firewall-Regeln. **Keine Firewall-Änderung nötig.** + +Die EasyRule für 10.10.10.24 (srv-docker01) bleibt bestehen (wird für NPM → DMZ benötigt). + +### Schritt 2: nginx.conf anpassen + +**Datei:** `/home/vinosadmin/n8n-reverse-proxy/nginx.conf` auf srv-revproxy01 +**Zugang:** `ssh -J sshtest@10.10.254.201 vinosadmin@srv-revproxy01` + +**Änderung im Location-Block `location /77ba0b14e9ccd5521a0ec1867332378c/`:** + +Ersetze: +```nginx +#allow 10.10.254.0/24; # Admin-Netz +#allow 10.20.20.0/24; # Bodega Client Netz +#allow 10.250.1.0/24; # VPN Client Netz +allow 10.10.81.12; # gw-web02 +deny all; +``` + +Durch: +```nginx +allow 10.10.254.0/24; # Admin-Netz +allow 10.20.20.0/24; # Bodega Client Netz +allow 10.250.0.0/24; # Admin-VPN +allow 10.250.1.0/24; # WuV VPN Client Netz +allow 10.10.81.12; # gw-web02 +deny all; +``` + +Nur Bodega-Clients + Admin/VPN. Keine breiten Netz-Freigaben (10.10.0.0/24, 10.20.0.0/24, 10.10.10.0/24). + +**Container neu starten:** +```bash +cd /home/vinosadmin/n8n-reverse-proxy && docker compose restart +``` + +### Schritt 3: Testen + +```bash +# Von srv-docker02 (10.10.10.81) — derzeit geblockt durch Firewall: +ssh vinosadmin@srv-docker02 "curl -sk --connect-timeout 5 -w 'HTTP %{http_code}\n' \ + 'https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/signup'" +# Erwartet: HTTP 200 oder 302 (statt Timeout) + +# Von srv-docker01 (10.10.10.24) — derzeit geblockt durch nginx: +ssh vinosadmin@srv-docker01 "curl -sk --connect-timeout 5 -w 'HTTP %{http_code}\n' \ + 'https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/signup'" +# Erwartet: HTTP 200 oder 302 (statt 403) + +# Webhook weiterhin funktionsfähig: +ssh vinosadmin@srv-docker01 "curl -sk --connect-timeout 5 -w 'HTTP %{http_code}\n' \ + 'https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/webhook-test/test'" +# Erwartet: HTTP 404 (n8n: webhook nicht aktiv — ok) +``` + +--- + +## Betroffene Systeme + +| System | Zugang | Änderung | +|--------|--------|----------| +| gw-nu-dmz02 | pfsense Web-UI | Keine Änderung nötig (Regeln existieren bereits) | +| srv-revproxy01 | SSH via cli-rwe02 | nginx.conf: allow-Regeln erweitern | + +## Verifiziert (keine Änderung nötig) + +| Prüfpunkt | Status | +|-----------|--------| +| DNS Split (flow.wvits.de → 10.10.81.4) | ✅ funktioniert (srv-docker01, srv-docker02) | +| real_ip Modul (nginx sieht echte Client-IP) | ✅ bestätigt in nginx-Logs | +| Webhook-Pfade (allow all) | ✅ funktioniert von srv-docker01 | +| NPM-Routing zu nginx Container | ✅ funktioniert | +| Route vom Servernetz zur DMZ | ✅ Route existiert (via 10.10.10.1 → 10.10.0.81) | diff --git a/plans/peppy-prancing-hedgehog.md b/plans/peppy-prancing-hedgehog.md new file mode 100644 index 0000000..661fba0 --- /dev/null +++ b/plans/peppy-prancing-hedgehog.md @@ -0,0 +1,74 @@ +# Plan: Leverage auf 5x auf srvdocker02 deployen + +## Kontext + +- **Server:** srvdocker02 (10.0.0.48 / srvdocker02.egonetix.lan) +- **Projekt-Pfad:** `/home/icke/traderv4` +- **Container:** `trading-bot-v4` +- **.env** wird als Volume gemountet (`./.env:/app/.env`), daher reicht ein Container-Restart + +## Schritte + +### 1. SSH auf srvdocker02, .env sichern +```bash +ssh root@10.0.0.48 +cd /home/icke/traderv4 +cp .env .env.backup-$(date +%Y%m%d_%H%M%S) +``` + +### 2. Leverage-Werte in .env aendern + +| Variable | Alt | Neu | +|----------|-----|-----| +| `LEVERAGE` | 10 | **5** | +| `BASE_LEVERAGE` | 10 | **5** | +| `STACK_LEVERAGE` | 10 | **5** | +| `MAX_LEVERAGE_TOTAL` | 20 | **10** | +| `HIGH_QUALITY_LEVERAGE` | 10 | **5** | +| `LOW_QUALITY_LEVERAGE` | 10 | **5** | +| `SOLANA_LEVERAGE` | 10 | **5** | + +Per `sed` auf dem Server: +```bash +sed -i 's/^LEVERAGE=10$/LEVERAGE=5/' .env +sed -i 's/^BASE_LEVERAGE=10$/BASE_LEVERAGE=5/' .env +sed -i 's/^STACK_LEVERAGE=10$/STACK_LEVERAGE=5/' .env +sed -i 's/^MAX_LEVERAGE_TOTAL=20$/MAX_LEVERAGE_TOTAL=10/' .env +sed -i 's/^HIGH_QUALITY_LEVERAGE=10$/HIGH_QUALITY_LEVERAGE=5/' .env +sed -i 's/^LOW_QUALITY_LEVERAGE=10$/LOW_QUALITY_LEVERAGE=5/' .env +sed -i 's/^SOLANA_LEVERAGE=10$/SOLANA_LEVERAGE=5/' .env +``` + +### 3. Container neu starten +```bash +docker compose restart trading-bot +``` +Kein Rebuild noetig - .env wird als Volume gemountet und beim Start neu gelesen. + +### 4. Verifizieren +```bash +# Container laeuft? +docker ps | grep trading-bot-v4 + +# Leverage-Werte pruefen +grep -E "LEVERAGE" .env + +# Logs: Startup-Meldungen mit Leverage? +docker logs --tail=30 trading-bot-v4 + +# Health-Check +curl -s http://localhost:3001/api/health +``` + +## Hinweis: Git-Sync separat + +Die lokalen Git-Aenderungen (copilot-instructions.md Verschiebung, .gitignore) werden hier NICHT gepullt, da `git rm --cached .env` die Server-.env beim Pull loeschen wuerde. Git-Sync auf dem Server muss separat mit .env-Backup erfolgen. + +## Verifikation + +- [ ] SSH-Zugang funktioniert +- [ ] .env Backup erstellt +- [ ] Alle 7 Leverage-Werte geaendert +- [ ] Container neugestartet +- [ ] Health-Check OK +- [ ] Logs zeigen korrekten Start diff --git a/plans/serialized-swimming-corbato.md b/plans/serialized-swimming-corbato.md new file mode 100644 index 0000000..cc45846 --- /dev/null +++ b/plans/serialized-swimming-corbato.md @@ -0,0 +1,173 @@ +# Fix: OAuth Callback 403 Forbidden - WEBHOOK_URL und BASE_URL fehlen Prefix + +## Aktuelle Situation (Stand 2026-02-05) + +**Problem:** OAuth-Callback zu `flow.wvits.de/rest/oauth2-credential/callback` schlägt mit **403 Forbidden** fehl. + +**Screenshot zeigt:** Callback-URL hat **KEINEN Prefix** → nginx blockt mit 403. + +## Root Cause Analyse + +### Gefundene Probleme: + +1. ✅ **WEBHOOK_URL ohne Prefix** (Hauptursache) + ```yaml + # docker-compose.yml auf srv-docker02 + # WEBHOOK_URL=https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/ # ← Auskommentiert! + WEBHOOK_URL=https://flow.wvits.de/ # ← Aktiv, OHNE Prefix + ``` + → OAuth-Callbacks gehen zu `/rest/oauth2-credential/callback` statt `/PREFIX/rest/oauth2-credential/callback` + +2. ✅ **N8N_EDITOR_BASE_URL fehlt** + ```yaml + # N8N_EDITOR_BASE_URL=https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/ # ← Auskommentiert + ``` + → n8n nutzt Fallback (`N8N_PROTOCOL + N8N_HOST`), aber ohne Prefix + → UI-Redirects, WebSocket-URLs, Asset-Loading könnten fehlschlagen + +3. ⚠️ **nginx blockt alles ohne Prefix** + ```nginx + # /home/vinosadmin/n8n-reverse-proxy/nginx.conf auf srv-revproxy01 + location / { return 403; } # ← Catch-All blockt + ``` + → Nur Requests unter `/77ba0b14e9ccd5521a0ec1867332378c/` werden weitergeleitet + +4. ℹ️ **NPM Asset-Cache existiert** (kein direktes Problem, aber Pitfall) + - Cache-Key: `$host$request_uri` (ohne Client-IP) + - Könnte 403-Responses cachen wenn externer Client Assets abruft + - Aktuell: Cache leer, kein Problem + +5. ℹ️ **Custom Certificates Mount-Error** (kein Problem für OAuth) + - `/opt/custom-certificates` Access denied + - Betrifft nur HTTPS zu internen Services mit Custom CA + - SMTP ist unverschlüsselt (SSL=false), kein Impact + +## Fix-Plan + +### Schritt 1: n8n docker-compose.yml korrigieren (srv-docker02) + +**SSH:** `ssh vinosadmin@srv-docker02` + +**Datei:** `/home/vinosadmin/n8n/docker-compose.yml` + +**Änderungen:** + +```yaml +# 1. WEBHOOK_URL mit Prefix aktivieren (Zeile ~31) +# WEBHOOK_URL=https://flow.wvits.de/ +WEBHOOK_URL=https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/ + +# 2. N8N_EDITOR_BASE_URL mit Prefix hinzufügen (nach N8N_PROXY_HOPS) +N8N_EDITOR_BASE_URL=https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/ +``` + +**Begründung:** +- `WEBHOOK_URL`: n8n nutzt diese für OAuth-Callback-URLs und Webhook-Generierung +- `N8N_EDITOR_BASE_URL`: n8n nutzt diese für UI-Redirects, WebSocket-URLs, Asset-Pfade + +### Schritt 2: Container neu starten + +```bash +cd /home/vinosadmin/n8n +docker compose down +docker compose up -d +``` + +**Warum `down` statt `restart`?** +- Environment-Variablen werden nur beim `up` neu eingelesen +- `restart` behält alte Env-Vars bei + +### Schritt 3: Verifikation + +**A) Container-Status prüfen:** +```bash +docker compose ps +docker compose logs -f n8n-main | head -20 +``` + +**B) Environment-Variablen verifizieren:** +```bash +docker exec n8n-n8n-main-1 env | grep -E "(WEBHOOK_URL|EDITOR_BASE_URL)" +``` + +Erwartete Ausgabe: +``` +WEBHOOK_URL=https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/ +N8N_EDITOR_BASE_URL=https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/ +``` + +**C) OAuth-Flow testen:** +1. n8n UI öffnen: `https://flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/` +2. Credentials → Microsoft Teams account 2 → "Connect my account" +3. Microsoft-Login → Callback sollte zu `/PREFIX/rest/oauth2-credential/callback` gehen +4. Erfolgreich: "Connected" - Credential ist authorisiert + +**D) Nginx-Logs prüfen (falls 403):** +```bash +# Auf srv-revproxy01 +ssh -J sshtest@10.10.254.201 vinosadmin@srv-revproxy01 +docker logs --tail 50 n8n-reverse-proxy-nginx-1 2>&1 | grep oauth +``` + +### Schritt 4 (Optional): NPM-Cache leeren + +Falls nach dem Fix immer noch Probleme auftreten: +```bash +# Auf srv-revproxy01 +ssh -J sshtest@10.10.254.201 vinosadmin@srv-revproxy01 +docker exec npm sh -c 'rm -rf /var/lib/nginx/cache/public/*' +docker exec npm nginx -s reload +``` + +## Geänderte Dateien + +| Datei | Host | Änderung | +|-------|------|----------| +| `/home/vinosadmin/n8n/docker-compose.yml` | srv-docker02 | WEBHOOK_URL + N8N_EDITOR_BASE_URL mit Prefix | + +## Sicherheit & Impact + +**Was ändert sich:** +- OAuth-Callbacks gehen nun zu `/PREFIX/rest/oauth2-credential/callback` (mit Prefix) +- nginx leitet alle `/PREFIX/*` Requests weiter (bestehende IP-Kontrolle bleibt) +- Keine Änderungen an Firewall-Regeln oder nginx-Config + +**Keine Regression:** +- Bestehende Webhooks (UPS-Workflow) unverändert: `/PREFIX/webhook/*` +- Interner Zugang via n8n.vinos.de weiterhin funktional +- Externe Webhooks weiterhin erlaubt (`allow all` in Webhook-Block) + +## Troubleshooting + +### Falls OAuth immer noch 403: + +**A) Callback-URL prüfen:** +```bash +# Browser DevTools → Network Tab → OAuth-Redirect URL ansehen +# Sollte sein: flow.wvits.de/77ba0b14e9ccd5521a0ec1867332378c/rest/oauth2-credential/callback +# NICHT: flow.wvits.de/rest/oauth2-credential/callback +``` + +**B) Container-Logs prüfen:** +```bash +docker compose logs n8n-main | grep -i webhook +``` + +**C) nginx-Logs prüfen:** +```bash +# Auf srv-revproxy01 +docker logs --tail 100 n8n-reverse-proxy-nginx-1 2>&1 | grep "403\|oauth" +``` + +### Falls SPA nicht lädt (weiße Seite): + +**NPM-Cache leeren** (gecachte 403-Responses): +```bash +# Auf srv-revproxy01 +docker exec npm sh -c 'rm -rf /var/lib/nginx/cache/public/*' +docker exec npm nginx -s reload +``` + +**Browser-Cache leeren:** +- Ctrl+Shift+R (Hard Reload) +- Oder Incognito-Fenster diff --git a/plans/silly-waddling-dragonfly.md b/plans/silly-waddling-dragonfly.md new file mode 100644 index 0000000..528f649 --- /dev/null +++ b/plans/silly-waddling-dragonfly.md @@ -0,0 +1,234 @@ +# Plan: VMware-Alarme mit VM-Namen in Zabbix anzeigen + +## Problem + +Die Operational Data bei VMware-Alarm-Triggern zeigt `alarm-127.group-d1` (interner vSphere-Key) statt des VM-Namens. Man sieht nicht, WELCHE VM ein Problem hat. + +## Ursache + +- `vmware.alarms.get[url]` sammelt Alarme auf **Datacenter-Ebene** (entity `group-d1` = Root) +- Das Alarm-JSON enthält **kein** Entity-/VM-Name-Feld +- Der Trigger-Prototype hat **leere opdata** → Zabbix zeigt den lastvalue (= den nutzlosen Key) +- Das VMware Guest Template hat **keine Alarm-Discovery** (auch nicht in der neusten Version 7.4-1 auf GitHub) + +## Lösung: Per-VM Alarm-Discovery zum VMware Guest Template hinzufügen + +`vmware.vm.alarms.get[url, uuid]` existiert als Item-Key in Zabbix 7.0 — wird nur nicht im Template verwendet. Wenn wir Alarm-Discovery auf die VMware Guest Hosts bringen, erscheinen Alarm-Trigger direkt auf dem jeweiligen VM-Host. **Der Host-Name im Dashboard IST der VM-Name** → Problem gelöst. + +### Warum das funktioniert + +vSphere feuert Alarme auf **zwei Ebenen**: +1. **Datacenter-Level:** Gesamtstatus ("irgendwo gibt es ein Backup-Problem") → aktueller Zustand +2. **Entity-Level (VM/Host):** Alarm auf der spezifischen VM die das Problem hat → was wir brauchen + +`vmware.vm.alarms.get` liefert die Entity-Level Alarme pro VM. + +## Schritte + +### Schritt 0: Template-Backup (PFLICHT, VOR jeder Änderung) + +Vollständige Exports beider VMware-Templates via Zabbix API als JSON-Backup. Enthält ALLE Objekte: Items, Triggers, Discovery Rules, Item-/Trigger-Prototypen, Tags, Preprocessing, Macros, Dependencies. + +**a) VMware Guest Template (10174) — wird geändert:** +``` +configuration.export format=json options.templates=[10174] +→ ~/Nextcloud/vinos/zabbix/backups/vmware-guest-template-10174-backup.json +``` + +**b) VMware Template (10173) — opdata-Änderung:** +``` +configuration.export format=json options.templates=[10173] +→ ~/Nextcloud/vinos/zabbix/backups/vmware-template-10173-backup.json +``` + +**c) Verifizierung der Backups:** +- Dateigröße prüfen (sollte mehrere KB sein) +- JSON-Validität prüfen (`python3 -m json.tool`) +- Stichprobe: Tags im Backup vorhanden? (grep nach "tags") +- Stichprobe: Trigger-Prototypen im Backup? (grep nach "trigger_prototypes") + +**Restore bei Problemen:** +``` +configuration.import format=json source=[Dateiinhalt] rules.templates.updateExisting=true +``` + +**Backups werden ins Git committed** (`zabbix/backups/`) damit sie versioniert und jederzeit wiederherstellbar sind. + +### Schritt 1: Quick-Fix — opdata auf bestehendem Trigger-Prototype verbessern + +**Template-Ebene** (VMware Template ID 10173): +- Trigger-Prototype ID `54450` → `opdata` setzen auf `{#VMWARE.ALARMS.STATUS}` +- Zeigt dann "red"/"yellow" statt "alarm-127.group-d1" +- Betrifft alle 5 entdeckten Alarme auf srv-nu-vcenter01 + +**API-Call:** +``` +triggerprototype.update: triggerid=54450, opdata="{#VMWARE.ALARMS.STATUS}" +``` + +### Schritt 2: Validierung — Per-VM Alarme testen + +**Bevor wir das Template ändern**, prüfen ob `vmware.vm.alarms.get` pro VM funktioniert: + +1. Temporäres Test-Item auf einer VM erstellen (z.B. SRV-DATA01, Host-ID 10893): + - Key: `vmware.vm.alarms.get[{$VMWARE.URL},{$VMWARE.VM.UUID}]` + - Type: Simple Check + - Value Type: Text + - History: 1h +2. Warten bis Daten kommen (1-2 Min) +3. Prüfen ob der Backup-Alarm in den per-VM Daten auftaucht +4. Test-Item wieder löschen + +**Mögliche Ergebnisse:** +- JSON enthält den Alarm → weiter mit Schritt 3 +- JSON ist leer → Backup-Alarm feuert nur auf Datacenter-Ebene, Schritt 3 bringt für diesen speziellen Alarm nichts + +### Schritt 3: Neues Template "VMware Guest Alarms" erstellen (PARALLEL, nicht am Original) + +**Strategie:** Statt das Original-Template (10174) zu modifizieren, erstellen wir ein **separates Template** mit nur der Alarm-Discovery. Dieses wird zusätzlich zu "VMware Guest" auf die VM-Hosts gelinkt. + +**Vorteile:** +- Original "VMware Guest" bleibt 100% unverändert +- Bei Problemen: Template unlinken → alle Alarm-Items sofort weg +- Nachbesserungen am neuen Template ohne Risiko +- Bei Zabbix-Update wird das Original-Template aktualisiert, unser Custom-Template bleibt + +**Template-Name:** `VMware Guest Alarms` +**Host Group:** Gleiche wie VMware Guest (wird beim Linken automatisch zugewiesen) + +**a) Template erstellen:** +``` +template.create: + host: "VMware Guest Alarms" + name: "VMware Guest Alarms" + description: "Per-VM Alarm-Discovery für VMware Guest Hosts. + Ergänzt das Standard VMware Guest Template um Alarm-Monitoring. + Benötigt Macros {$VMWARE.URL} und {$VMWARE.VM.UUID} vom VMware Guest Template." + groups: [{groupid: }] +``` + +**b) Master-Item (Simple Check):** +``` +item.create: + hostid: [neues Template] + name: "Get VM alarms" + key: vmware.vm.alarms.get[{$VMWARE.URL},{$VMWARE.VM.UUID}] + type: Simple Check (3) + value_type: Text (4) + history: 0 + delay: 0 (VMware Collector) +``` + +**c) Discovery Rule (Dependent):** +``` +discoveryrule.create: + hostid: [neues Template] + name: "VMware VM alarm discovery" + key: vmware.vm.alarms.discovery + type: Dependent (18) + master_itemid: [Get VM alarms Item] + lifetime: 0 + LLD Macro Paths: + {#VMWARE.ALARMS.DESC} → $.description + {#VMWARE.ALARMS.KEY} → $.key + {#VMWARE.ALARMS.NAME} → $.name + {#VMWARE.ALARMS.STATUS} → $.overall_status +``` + +**d) Item-Prototype (Dependent):** +``` +itemprototype.create: + ruleid: [Discovery Rule] + hostid: [neues Template] + name: "{#VMWARE.ALARMS.NAME}" + key: vmware.vm.alarms.status["{#VMWARE.ALARMS.KEY}"] + type: Dependent (18) + master_itemid: [Get VM alarms Item] + value_type: Character (1) + preprocessing: + 1. JSONPath: $.[?(@.key == "{#VMWARE.ALARMS.KEY}")].key.first() + error_handler: set value to -1 + 2. Throttling: 1h +``` + +**e) Trigger-Prototype:** +``` +triggerprototype.create: + description: "VMware VM: {#VMWARE.ALARMS.NAME}" ← "VM:" um von vCenter-Level zu unterscheiden + expression: last(/VMware Guest Alarms/vmware.vm.alarms.status["{#VMWARE.ALARMS.KEY}"])<>-1 + opdata: "{#VMWARE.ALARMS.STATUS}" + priority: 0 (Not classified) ← gleich wie vCenter-Level Trigger + comments: "{#VMWARE.ALARMS.DESC}" + tags: [{"tag": "scope", "value": "notice"}] +``` + +**Tag-Kontext:** Das Notification-System basiert auf Tags wie `Meldung_Webhook_*` / `Meldung_Mail_*` (siehe notifications.md). Der `scope=notice` Tag kommt vom Template. Spezifische Routing-Tags (`Meldung_*`) werden bei Bedarf nachträglich auf entdeckte Trigger gesetzt — nicht auf dem Prototype. + +### Schritt 3b: Template auf VMware Guest Hosts linken + +**Erst auf einem Test-Host:** +1. Template "VMware Guest Alarms" auf SRV-DATA01 (10893) linken +2. Warten bis Master-Item Daten liefert (~1-2 Min) +3. LLD abwarten (~5-10 Min) +4. Prüfen ob Alarm-Items erstellt werden + +**Bei Erfolg auf alle VMware Guest Hosts:** +- `host.get` mit `templateids=[10174]` → Liste aller VMware Guest Hosts +- `host.massupdate` mit templates: bestehende + neues Template + +### Schritt 4: Verifizierung + +1. Warten bis LLD auf VMware Guest Hosts läuft (~5-10 Min) +2. Prüfen ob per-VM Alarm-Items erstellt werden +3. Prüfen ob der Backup-Alarm auf der betroffenen VM auftaucht +4. Dashboard-Anzeige prüfen: VM-Name sollte in Host-Spalte stehen + +### Schritt 5: Aufräumen + +- History am Master-Item `vmware.alarms.get` auf vCenter (120476) zurück auf `0` setzen +- Ggf. den Datacenter-Level Alarm-Trigger deaktivieren oder behalten (als Fallback) + +### Schritt 6: Dokumentation + Commits + +- `zabbix/README.md`: VMware Alarm-Monitoring Pattern dokumentieren +- `zabbix/copilot-instructions.md`: Pitfall dokumentieren (opdata leer = zeigt lastvalue) +- Infrastructure: Falls relevant +- Commits in zabbix-Repo + pushen + +## Risiken & Fallbacks + +| Risiko | Auswirkung | Fallback | +|--------|-----------|----------| +| `vmware.vm.alarms.get` liefert keine per-VM Alarme | Backup-Alarm nur auf Datacenter-Ebene | opdata-Fix (Schritt 1) ist trotzdem besser als Status quo | +| Viele neue Items pro VM | Mehr Last auf Zabbix-Server | Items haben 1h Throttling, Master-Item hat `delay=0` (VMware Collector Intervall) | +| Neues Template funktioniert nicht wie erwartet | Falsches/kein Discovery | **Template unlinken** → alle Items/Trigger sofort weg, kein Restrisiko | + +## Rollback-Strategie + +1. **Per-VM Alarms funktionieren nicht:** Template "VMware Guest Alarms" von Hosts unlinken → fertig +2. **opdata-Änderung problematisch:** `triggerprototype.update` opdata zurück auf "" → LLD re-run +3. **Komplett-Rollback:** Template-Backup importieren via `configuration.import` + +## Betroffene Dateien/Objekte + +| Was | ID | Aktion | +|-----|-----|--------| +| VMware Template Trigger-Prototype | 54450 | opdata setzen | +| **NEUES** Template "VMware Guest Alarms" | (wird erstellt) | Alarm-Discovery für VMs | +| VMware Guest Template | 10174 | **NICHT geändert** (nur Backup) | +| Master-Item vCenter (temporär) | 120476 | History zurück auf 0 | +| `zabbix/README.md` | — | Doku ergänzen | + +## Verifizierung + +```bash +# Nach Schritt 2: Test-Item prüfen +item.get hostids=[10893] search={"key_": "vm.alarms"} +history.get itemids=[TEST_ITEM_ID] history=4 + +# Nach Schritt 3: Per-VM Alarm Discovery prüfen +item.get templateids=[10174] search={"key_": "alarm"} +# Auf einem VMware Guest Host: +item.get hostids=[10893] search={"key_": "alarm"} +trigger.get hostids=[10893] search={"description": "Backup"} +``` diff --git a/plans/snazzy-riding-eclipse.md b/plans/snazzy-riding-eclipse.md new file mode 100644 index 0000000..6642b6e --- /dev/null +++ b/plans/snazzy-riding-eclipse.md @@ -0,0 +1,23 @@ +# Plan: Zertifikat-Doku korrigieren + Evaluierung notieren + +## Korrektur + +Das Zertifikat CN=zabbix_mailboxueberwachung ist **self-signed vom Exchange** (nicht von AD CA SRV-VINOSCA01). Erneuerung erfolgte per Klick in der Exchange Admin Console. + +### Zu korrigierende Stellen + +1. **`README.md`** (Zeile 245): `CA: SRV-VINOSCA01.vinos.local` → `Self-signed (Exchange-lokal)` +2. **`troubleshooting.md`** (Zeile 154): CA-Zeile in Tabelle korrigieren +3. **`troubleshooting.md`** (Zeile 166-177): AD-CA-Erneuerungsschritte durch Exchange-Konsole-Erneuerung ersetzen +4. **`troubleshooting.md`**: Evaluierungshinweis ergänzen — Zertifikat ggf. überflüssig da `smtp_verify_peer=0` + +### Neue Troubleshooting-Anleitung (ersetzt AD-CA-Schritte) + +Erneuerung per Exchange Admin Console: +1. EAC öffnen → Server → Zertifikate +2. Zertifikat `zabbix_mailboxueberwachung` auswählen → Erneuern +3. Verifizieren per `openssl s_client` + +### Evaluierungshinweis + +> **TODO:** Evaluieren ob das Zertifikat überhaupt benötigt wird. Zabbix verbindet mit `smtp_verify_peer=0` / `smtp_verify_host=0` — das Zertifikat bietet nur opportunistic TLS (Transport-Verschlüsselung) im internen Netz. Alternativen: Plaintext SMTP oder Zertifikatsvalidierung aktivieren. diff --git a/plans/snuggly-juggling-hoare.md b/plans/snuggly-juggling-hoare.md new file mode 100644 index 0000000..1931d78 --- /dev/null +++ b/plans/snuggly-juggling-hoare.md @@ -0,0 +1,152 @@ +# Plan: n8n Workflow — UPS-Rechnungen abholen und weiterleiten + +## Ziel + +Täglicher n8n-Workflow, der UPS-Rechnungsmails aus dem Postfach `vinos-monitoring@mailbox.org` per IMAP abruft, das ZIP-Attachment entpackt und die enthaltenen Rechnungen per SMTP an `rechnung@vinos.de` weiterleitet. + +--- + +## Parameter + +| Parameter | Wert | +|-----------|------| +| Postfach | `vinos-monitoring@mailbox.org` | +| Empfänger | `rechnung@vinos.de` | +| Absender-Filter | `@ups.com` | +| Intervall | Täglich (07:00) | +| Nach Verarbeitung | Mail in Ordner "Verarbeitet" verschieben | +| IMAP-Server | `imap.mailbox.org:993` (SSL/TLS) | +| SMTP-Server | `smtp.mailbox.org:465` (SSL/TLS) | + +--- + +## Voraussetzungen (manuell, vor Workflow-Erstellung) + +### 1. n8n Credentials anlegen (Web-UI) + +In n8n unter **Settings → Credentials → Add Credential**: + +**IMAP-Credential:** +- Typ: **IMAP** +- Host: `imap.mailbox.org` +- Port: `993` +- User: `vinos-monitoring@mailbox.org` +- Passwort: Mailbox.org-Passwort +- SSL/TLS: Ja + +**SMTP-Credential:** +- Typ: **SMTP** +- Host: `smtp.mailbox.org` +- Port: `465` +- User: `vinos-monitoring@mailbox.org` +- Passwort: Mailbox.org-Passwort +- SSL/TLS: Ja + +### 2. Ordner "Verarbeitet" im Postfach anlegen + +Per Webmail auf mailbox.org oder per IMAP-Client einen Ordner `Verarbeitet` erstellen. + +--- + +## Workflow-Aufbau (6 Nodes) + +``` +Schedule Trigger → Email Read (IMAP) → IF (hat ZIP-Attachment?) + → Compression (Decompress) → Send Email (SMTP) + → IMAP Move to Folder +``` + +### Node 1: Schedule Trigger +- **Typ:** `n8n-nodes-base.scheduleTrigger` +- **Konfiguration:** Täglich um 07:00 Uhr (`0 7 * * *`) + +### Node 2: Email Read (IMAP) +- **Typ:** `n8n-nodes-base.emailReadImap` +- **Postfach:** `vinos-monitoring@mailbox.org` +- **Ordner:** INBOX +- **Filter:** Ungelesene Mails +- **Attachments:** Herunterladen aktiviert +- **Credential:** IMAP (mailbox.org) + +### Node 3: IF — Hat ZIP-Attachment? +- **Typ:** `n8n-nodes-base.if` +- **Bedingung:** Binary-Daten vorhanden UND Dateiname endet auf `.zip` +- **Zweck:** Nur Mails mit ZIP-Anhang verarbeiten + +### Node 4: Compression — ZIP entpacken +- **Typ:** `n8n-nodes-base.compression` +- **Operation:** Decompress +- **Input:** Binary-Feld des ZIP-Attachments +- **Output:** Entpackte Dateien als Binary-Daten + +### Node 5: Send Email (SMTP) +- **Typ:** `n8n-nodes-base.sendEmail` (oder `n8n-nodes-base.emailSend`) +- **Von:** `vinos-monitoring@mailbox.org` +- **An:** `rechnung@vinos.de` +- **Betreff:** `UPS-Rechnung` + Datum aus Original-Mail +- **Body:** Kurzer Hinweistext (z.B. "Anbei die entpackte UPS-Rechnung") +- **Attachments:** Entpackte Dateien aus Node 4 +- **Credential:** SMTP (mailbox.org) + +### Node 6: IMAP — Mail verschieben +- **Typ:** `n8n-nodes-base.emailReadImap` (oder HTTP-Request an IMAP) +- **Operation:** Mail als gelesen markieren + in Ordner "Verarbeitet" verschieben +- **Hinweis:** n8n hat keine native "IMAP Move"-Operation — ggf. per Code-Node (IMAP-Befehl MOVE) oder als "gelesen markieren" vereinfachen + +--- + +## Bekannte Einschränkung: IMAP Move + +n8n's IMAP-Node kann Mails lesen, aber das Verschieben in einen anderen Ordner ist nicht nativ unterstützt. Optionen: + +1. **Nur als gelesen markieren** — einfachste Lösung, Node 2 liest dann nur ungelesene +2. **Code-Node mit IMAP-Bibliothek** — per JavaScript direkt IMAP MOVE ausführen +3. **HTTP-Request an Mailbox.org API** — falls vorhanden + +**Empfehlung:** Option 1 (als gelesen markieren) für den Start. "Nur ungelesene lesen" verhindert Doppelverarbeitung zuverlässig. + +--- + +## Umsetzung + +### Schritt 1: Workflow-Grundgerüst via API erstellen +- POST an `https://flow.wvits.de/api/v1/workflows` +- 5-6 Nodes (je nach IMAP-Move-Lösung) +- Credentials als Platzhalter (in UI verknüpfen) + +### Schritt 2: Credentials in n8n-UI verknüpfen +- IMAP-Credential den Email-Read-Nodes zuweisen +- SMTP-Credential dem Send-Email-Node zuweisen + +### Schritt 3: Testlauf +- Test-Mail mit ZIP-Anhang an `vinos-monitoring@mailbox.org` senden +- Workflow manuell in der UI ausführen +- Prüfen: ZIP entpackt? Mail bei `rechnung@vinos.de` angekommen? + +### Schritt 4: Workflow aktivieren +- `POST /api/v1/workflows/{id}/activate` + +--- + +## Verifikation + +1. **API-Test:** `GET /api/v1/workflows/{id}` — Node-Struktur prüfen +2. **Manueller Testlauf:** In n8n-UI "Execute Workflow" +3. **Prüfpunkte:** + - [ ] IMAP-Verbindung zu mailbox.org funktioniert + - [ ] Ungelesene Mails werden abgerufen + - [ ] ZIP-Attachment wird erkannt und gefiltert + - [ ] ZIP wird entpackt, Dateien korrekt + - [ ] SMTP-Versand an rechnung@vinos.de funktioniert + - [ ] Entpackte Dateien sind als Attachment in der Mail + - [ ] Verarbeitete Mail wird als gelesen markiert +4. **Fehlerfall:** Mail ohne ZIP → IF-Node filtert korrekt + +--- + +## Dateien + +| Datei | Zweck | +|-------|-------| +| `/home/rwiegand/Nextcloud/vinos/n8n/.env` | API-Key + Base-URL (vorhanden) | +| `/home/rwiegand/Nextcloud/vinos/n8n/README.md` | Projekt-Doku (Update nach Abschluss) | diff --git a/plans/sparkling-sauteeing-clarke.md b/plans/sparkling-sauteeing-clarke.md new file mode 100644 index 0000000..b1d465e --- /dev/null +++ b/plans/sparkling-sauteeing-clarke.md @@ -0,0 +1,444 @@ +# Plan: Vinos/clawd — Governance & Skills Repository + +## Ziel + +Vinos-spezifisches Governance-Repository anlegen mit Skills, Standards und Workflows — analog zu Egonetix/clawd, aber angepasst für Vinos-Infrastruktur. + +**Kontext:** Heute kam ein Fall (BCC-Mail-Routing bei Egonetix) wo Monitoring vergessen wurde → Ausfall 8,5h unbemerkt. Für Vinos existiert nur eine generische CLAUDE.md Anweisung (29.01., Zeile 638-667), die leicht übersehen wird. Egonetix hat ein vollständiges Governance-System aufgebaut (`Egonetix/clawd.git`) mit Skills, Quality Gates und erzwungenen Workflows. + +**Entscheidung:** Trennung pro Kunde mit gemeinsamer Grundstruktur — Vinos bekommt eigenes clawd-Repo, basierend auf Egonetix-Vorlage, aber angepasst. + +--- + +## Bestehende Vinos-Infrastruktur (Basis) + +### Gitea-Organisation "Vinos" + +| Repo | Status | Beschreibung | +|------|--------|--------------| +| `Vinos/infrastructure.git` | ✅ Existiert | Landkarte, hosts/, dependencies.md, Mermaid-Diagramme | +| `Vinos/zabbix.git` | ✅ Existiert | Zabbix-Server-Doku, API, Troubleshooting | +| `Vinos/n8n.git` | ✅ Existiert | Workflow-Automation, komplexe Netzwerk-Architektur | +| `Vinos/srv-job01.git` | ❌ Lokal | Windows Task-Server (sollte gepusht werden) | +| `Vinos/clawd.git` | ❌ NEU | Governance, Skills, Standards (dieses Repo) | + +### Dokumentierte Hosts (8 Stück) + +- srv-docker01 (10.10.10.24) - Docker + NPM intern +- srv-docker02 (10.10.10.81) - Docker + n8n +- srv-revproxy01 (10.10.81.4) - Reverse Proxy DMZ +- gw-nu-dmz02 (10.10.81.1 / 10.10.0.81) - DMZ Segment-Router +- cli-rwe02 (10.10.254.201) - SSH-Sprungserver +- srv-job01 (10.10.10.42) - Windows Task-Server +- srv-monitor02 - Zabbix Monitoring +- gw-nu-wan01 - WAN/VPN Gateway + +### Vinos-Netze + +**Wichtig:** Vinos hat NICHT 172.20.20.0/24 (User-Korrektur), sondern mehrere verschiedene Netze: +- 10.10.10.0/24 - LAN +- 10.10.81.0/24 - DMZ +- 10.10.254.0/24 - Management +- Weitere Netze noch zu dokumentieren + +→ In der ersten Version KEINE Netzwerk-Spezifikation im Skill (kann später ergänzt werden) + +### Bestehendes Monitoring-Beispiel (exzellent!) + +`~/Nextcloud/vinos/srv-job01/C_Tasks/dhl_premiumadress/`: +- **MONITORING.md** (237 Zeilen) - WAS überwachen, Items, Trigger, Schwellwerte +- **ZABBIX_IMPLEMENTATION_GUIDE.md** (415 Zeilen) - WIE implementieren in Zabbix + +**Das ist bereits die perfekte Arbeitsteilung!** Zeigt dass das Konzept schon angewendet wurde, aber nicht als globaler Standard erzwungen ist. + +--- + +## Ziel-Struktur: Vinos/clawd + +``` +~/Nextcloud/vinos/clawd/ +├── README.md # Einstieg, Übersicht +├── skills/ +│ ├── monitoring/ +│ │ └── SKILL.md # Monitoring-Requirements (Basis: Egonetix) +│ ├── infra/ # (später) +│ ├── mail/ # (später) +│ └── assistant/ # (später) +├── team/ +│ ├── STANDARDS.md # Vinos-spezifische Arbeitsstandards +│ ├── WORKFLOW-POLICY.md # Change-Management-Workflow +│ └── post-mortems/ # (leer, für künftige Incidents) +├── reports/ +│ └── monitoring-gap-vinos.md # Gap-Analyse für Vinos (optional, später) +├── scripts/ # (später, ggf. Monitoring-Helper) +└── references/ + └── dhl-monitoring-example.md # Verweis auf srv-job01/dhl als Referenz +``` + +**Gitea Remote:** `ssh://git@gitea.egonetix.de:222/Vinos/clawd.git` + +--- + +## Was übernehmen? Was anpassen? + +### Übernehmen von Egonetix/clawd: + +| Datei | Was übernehmen | +|-------|----------------| +| `skills/monitoring/SKILL.md` | Grundstruktur, Workflow (4 Schritte), Check-Typen, Schwellwerte, Szenarien-Template | +| `team/STANDARDS.md` | Change-Management-Workflow (7 Schritte), Pre-/During-/Post-Change-Pflichten, Monitoring-Pflicht | +| `team/WORKFLOW-POLICY.md` | Delegation-Regeln, Sub-Agent-Accountability | + +### Anpassen für Vinos: + +| Aspekt | Egonetix | Vinos (angepasst) | +|--------|----------|-------------------| +| **Netzwerk** | 10.0.0.0/24 explizit genannt | WEGLASSEN (mehrere Netze, noch nicht vollständig dokumentiert) | +| **Zabbix-URL** | http://10.0.0.48:8092 | https://zabbix.vinos.de (gleiche Instanz, anderer Zugang) | +| **Task-Tracking** | Gitea Cards | Kanbanize (weinvinosgmbh.kanbanize.com) | +| **Beispiele** | BCC-Mail-Routing (srv-docker02, srv-mail01) | DHL-Monitoring (srv-job01) + generische Szenarien | +| **Ansprechpartner** | Harry | [Vinos-spezifisch, noch zu klären] | +| **Host-Namen** | srvdocker02, srvrevproxy02 | srv-docker02, srv-revproxy01 | +| **Gültigkeit** | egonetix + vinos | Nur Vinos | + +--- + +## Implementierungsplan + +### Phase 1: Repo-Setup + +**1.1 Lokales Repo erstellen** + +```bash +cd ~/Nextcloud/vinos +mkdir clawd +cd clawd +git init +git branch -M main +``` + +**1.2 Basis-Struktur anlegen** + +```bash +mkdir -p skills/monitoring +mkdir -p team/post-mortems +mkdir -p reports +mkdir -p scripts +mkdir -p references +``` + +**1.3 README.md erstellen** + +```markdown +# Vinos — Governance & Skills + +Zentrale Dokumentation für Arbeitsstandards, Skills und Workflows für Kunde **Vinos**. + +## Struktur + +| Verzeichnis | Inhalt | +|-------------|--------| +| `skills/` | Wiederverwendbare Skills (monitoring, infra, mail, etc.) | +| `team/` | Arbeitsstandards, Workflows, Post-Mortems | +| `reports/` | Gap-Analysen, Reviews | +| `references/` | Referenz-Beispiele aus der Praxis | + +## Skills + +- [monitoring](skills/monitoring/SKILL.md) — Monitoring-Anforderungen definieren (PFLICHT) + +## Standards + +- [STANDARDS.md](team/STANDARDS.md) — Verbindliche Arbeitsregeln +- [WORKFLOW-POLICY.md](team/WORKFLOW-POLICY.md) — Change-Management-Workflow + +## Quick Links + +- [Vinos Infrastructure](../infrastructure/) — Host-Übersichten, Abhängigkeiten +- [Zabbix](../zabbix/) — Monitoring-Server-Dokumentation +- [Gitea Organisation](https://gitea.egonetix.de/Vinos) +``` + +**1.4 Gitea-Repo erstellen** + +```bash +curl -X POST -H "Authorization: token $(cat ~/.config/gitea/token)" \ + -H "Content-Type: application/json" \ + -d '{ + "name":"clawd", + "description":"Governance, Skills und Arbeitsstandards für Vinos", + "private":false, + "auto_init":false + }' \ + "https://gitea.egonetix.de/api/v1/orgs/Vinos/repos" +``` + +**1.5 Remote hinzufügen und pushen** + +```bash +cd ~/Nextcloud/vinos/clawd +git remote add origin ssh://git@gitea.egonetix.de:222/Vinos/clawd.git +git add README.md +git commit -m "Initial commit: Vinos/clawd Repo-Struktur" +git push -u origin main +``` + +--- + +### Phase 2: Monitoring-Skill erstellen + +**2.1 Egonetix-Skill als Basis kopieren** + +```bash +cp /tmp/clawd/skills/monitoring/SKILL.md ~/Nextcloud/vinos/clawd/skills/monitoring/SKILL.md +``` + +**2.2 Anpassungen vornehmen** + +| Zeile | Was ändern | Von (Egonetix) | Zu (Vinos) | +|-------|------------|----------------|------------| +| 2-3 | Description | "...new systems AND changes..." | Gleich lassen (gilt auch für Vinos) | +| 8-9 | Hintergrund | Mail-Ausfall 2026-02-01 | Gleich lassen (zeigt Ursprung) + Hinweis "Gilt für Vinos seit 2026-02-02" | +| 386-392 | Gültigkeit | "egonetix + Remote ST / vinos" | **Neu:** Nur Vinos, Netzwerk-Info weglassen | +| 136 | Bezug | "Kanban-Card, Task-Beschreibung" | **Kanbanize-Card** explizit erwähnen | +| 159 | Alerting | "Telegram/Email" | Gleich lassen (Kanäle noch zu klären) | +| 203-230, 232-260, 262-294, 296-334, 336-366 | Szenarien 1-5 | Egonetix-Host-Namen | Generisch halten ODER Vinos-Host-Namen (srv-docker02 statt srvdocker02) | +| 370-380 | Bekannte Lücken | Egonetix Gap-Analyse | **Neu:** Verweis auf Vinos-spezifische Lücken (optional, später Gap-Analyse) | +| 396-402 | Referenzen | Egonetix-Reports | **Neu:** Verweis auf DHL-Monitoring-Beispiel | + +**2.3 Neue Gültigkeit-Sektion (Zeile 386-392 ersetzen)** + +```markdown +## Gültigkeit + +Dieser Skill gilt für die **Vinos-Infrastruktur**. + +**Zabbix-Instanz:** https://zabbix.vinos.de (gleiche Instanz wie Egonetix) + +**Netze:** Vinos nutzt mehrere Netze (10.10.10.0/24 LAN, 10.10.81.0/24 DMZ, 10.10.254.0/24 Management, weitere). Details siehe [infrastructure/netzwerk/](../../infrastructure/netzwerk/). + +**Task-Tracking:** Kanbanize (weinvinosgmbh.kanbanize.com) — technische Doku in Gitea, Aufgaben-Management in Kanbanize. +``` + +**2.4 Neue Referenzen-Sektion (Zeile 396-402 ersetzen)** + +```markdown +## Referenzen + +- `../references/dhl-monitoring-example.md` — Verweis auf DHL-Monitoring (srv-job01) als Vinos-spezifisches Beispiel +- `skills/infra/SKILL.md` — Infrastruktur-Management (TODO) +- `skills/mail/SKILL.md` — Mail-Infrastruktur (TODO) +- `team/STANDARDS.md` — Verbindliche Arbeitsstandards, Abschnitt 9 +``` + +**2.5 Referenz-Beispiel erstellen** + +`references/dhl-monitoring-example.md`: + +```markdown +# DHL-Monitoring — Referenz-Beispiel + +Dieses Beispiel zeigt die perfekte Arbeitsteilung zwischen System-Agent und Zabbix-Spezialist. + +## Was ist das? + +DHL Premium Address ist ein automatisierter File-Transfer auf srv-job01 (Windows Task-Server). Die Monitoring-Dokumentation ist ein exzellentes Beispiel für: +- WAS überwachen (System-Agent-Perspektive) +- WIE implementieren (Zabbix-Spezialist-Perspektive) + +## Dokumente + +| Datei | Zweck | Zeilen | +|-------|-------|--------| +| [MONITORING.md](../../srv-job01/C_Tasks/dhl_premiumadress/MONITORING.md) | **WAS**: Items, Trigger, Schwellwerte, Dashboard-Widgets | 237 | +| [ZABBIX_IMPLEMENTATION_GUIDE.md](../../srv-job01/C_Tasks/dhl_premiumadress/ZABBIX_IMPLEMENTATION_GUIDE.md) | **WIE**: Schritt-für-Schritt Zabbix-Konfiguration | 415 | + +## Warum ist das ein gutes Beispiel? + +✅ **Klare Arbeitsteilung:** +- System-Agent: Definiert WAS überwacht werden soll (Check-Typen, Schwellwerte, Alert-Bedingungen) +- Zabbix-Spezialist: Implementiert WIE es in Zabbix umgesetzt wird (Items, Trigger, API-Calls) + +✅ **Konkrete Schwellwerte:** +- Warning: >50 Mails in Queue +- Critical: >200 Mails in Queue +- Zeitfenster: Alerts nur nach 08:00 (nach Scheduled Tasks) + +✅ **Vollständiger Kontext:** +- Scheduled Tasks erklärt +- Log-Locations dokumentiert +- Troubleshooting-Szenarien vorbereitet + +✅ **Quality Gate:** +- Trigger mit Tags (`Meldung_Webhook_IFS-Meldungen`) +- Recovery-Expressions definiert +- Manual Close erlaubt + +## Nutzen als Template + +Wenn du ein neues System/Service implementierst, nutze diese Dokumente als Template: +1. Kopiere die Struktur von MONITORING.md +2. Passe die Items/Trigger an dein System an +3. Erstelle ein ZABBIX_IMPLEMENTATION_GUIDE.md für den Zabbix-Spezialisten + +**Das erfüllt exakt den Monitoring-Skill-Workflow!** +``` + +--- + +### Phase 3: Team-Standards erstellen + +**3.1 Egonetix STANDARDS.md als Basis kopieren** + +```bash +cp /tmp/clawd/team/STANDARDS.md ~/Nextcloud/vinos/clawd/team/STANDARDS.md +``` + +**3.2 Anpassungen vornehmen** + +| Abschnitt | Was ändern | +|-----------|------------| +| Header (Zeile 1-5) | Datum auf 2026-02-02, Genehmigung durch [Vinos-Ansprechpartner] | +| 1.1 Dokumentation lesen (Zeile 18-22) | Pfad anpassen: `/root/Nextcloud/egonetix/` → `~/Nextcloud/vinos/` | +| 1.4 Genehmigung (Zeile 34-36) | Ansprechpartner anpassen (statt "Harry" → Vinos-spezifisch) | +| 3.3 Monitoring-Pflicht (Zeile 62-69) | Gleich lassen, Verweis auf Abschnitt 9 bleibt | +| 9 Monitoring-Pflicht (Zeile 162-203) | Verweis auf `skills/monitoring/SKILL.md` bleibt, Beispiel-Paths anpassen | + +**3.3 Neue Header-Sektion** + +```markdown +# Team-Standards — Verbindliche Arbeitsregeln + +**Gültig ab:** 2026-02-02 +**Anlass:** Monitoring-Gap (Egonetix Mail-Incident 2026-02-01) → auch für Vinos relevant +**Genehmigt durch:** [Vinos-Ansprechpartner, TODO] +``` + +**3.4 WORKFLOW-POLICY.md erstellen** + +Übernehmen von Egonetix, minimale Anpassungen: +- Pfade: `/root/Nextcloud/egonetix/` → `~/Nextcloud/vinos/` +- Ansprechpartner: "Harry" → Vinos-spezifisch + +--- + +### Phase 4: Weitere Dateien (optional, später) + +**Nicht in dieser Phase:** +- reports/monitoring-gap-vinos.md — kann später erstellt werden (analog zu Egonetix Gap-Analyse) +- scripts/ — Monitoring-Helper-Scripts, Token-Watchdog (bei Bedarf) +- skills/infra/, skills/mail/ — weitere Skills nach Bedarf + +**Fokus:** Nur Monitoring-Skill + Standards in dieser ersten Version. + +--- + +### Phase 5: Integration in CLAUDE.md + +**5.1 CLAUDE.md erweitern (globale Anweisung)** + +Nach Zeile 667 (Ende von "PFLICHT: Monitoring-Abgleich") einfügen: + +```markdown +**Für Vinos-Projekte gilt zusätzlich:** + +Der vollständige Monitoring-Workflow ist im **Monitoring-Skill** definiert: +- `~/Nextcloud/vinos/clawd/skills/monitoring/SKILL.md` + +Dieser Skill MUSS bei jeder Infrastruktur-Arbeit aufgerufen werden (analog zu verification-before-completion). Details siehe Skill-Dokumentation. +``` + +**5.2 Session-Start Hook anpassen (optional)** + +Falls Hook existiert: Bei `~/Nextcloud/vinos/` auch `clawd/` Skills laden. + +--- + +### Phase 6: Erste Commits + +**6.1 Alle Dateien committen** + +```bash +cd ~/Nextcloud/vinos/clawd +git add -A +git commit -m "Add: Monitoring-Skill, Team-Standards, DHL-Referenz + +- skills/monitoring/SKILL.md: Basierend auf Egonetix, angepasst für Vinos +- team/STANDARDS.md: Arbeitsstandards mit Change-Management-Workflow +- team/WORKFLOW-POLICY.md: Delegation und Accountability +- references/dhl-monitoring-example.md: srv-job01 DHL als Vorbild + +Basis: Egonetix/clawd (Commit 9c1cac8) +" +``` + +**6.2 Pushen** + +```bash +git push origin main +``` + +**6.3 CLAUDE.md committen und pushen** + +```bash +cd ~/dotfiles/claude_settings +git add CLAUDE.md +git commit -m "Add: Verweis auf Vinos/clawd Monitoring-Skill" +git push origin main +``` + +--- + +## Verifikation + +Nach Abschluss prüfen: + +- [ ] `Vinos/clawd.git` existiert auf Gitea +- [ ] Lokales Repo: `~/Nextcloud/vinos/clawd/` vorhanden +- [ ] `skills/monitoring/SKILL.md` existiert (angepasst für Vinos) +- [ ] `team/STANDARDS.md` existiert (Vinos-spezifisch) +- [ ] `references/dhl-monitoring-example.md` verweist korrekt auf srv-job01 +- [ ] README.md im Root verlinkt alle Strukturen +- [ ] Alle Dateien committet und gepusht +- [ ] CLAUDE.md erweitert (Verweis auf Vinos-Skill) +- [ ] Test: In `~/Nextcloud/vinos/` eine neue Session starten → Skill sollte verfügbar sein (manuelle Prüfung) + +--- + +## Nächste Schritte (nach dieser Phase, nicht Teil des Plans) + +- Gap-Analyse für Vinos durchführen → `reports/monitoring-gap-vinos.md` +- srv-job01 auf Gitea pushen (lokal vorhanden, fehlt auf Gitea) +- Weitere Skills nach Bedarf erstellen (infra, mail) +- Post-Mortems bei künftigen Incidents dokumentieren + +--- + +## Kritische Dateien + +| Datei | Zeilen (ca.) | Beschreibung | +|-------|--------------|--------------| +| `skills/monitoring/SKILL.md` | ~400 | Monitoring-Requirements-Workflow (Basis: Egonetix, angepasst) | +| `team/STANDARDS.md` | ~200 | Arbeitsstandards mit Monitoring-Pflicht | +| `team/WORKFLOW-POLICY.md` | ~50 | Delegation und Workflow-Regeln | +| `references/dhl-monitoring-example.md` | ~80 | Verweis auf DHL-Monitoring als Vinos-Beispiel | +| `README.md` | ~40 | Einstieg ins Repo | +| `~/.claude/CLAUDE.md` | +10 | Verweis auf Vinos-Skill hinzufügen | + +--- + +## Entscheidungen (geklärt) + +| Frage | Entscheidung | +|-------|--------------| +| Egonetix-Skill übernehmen oder neu schreiben? | Übernehmen + anpassen (Grundstruktur bleibt) | +| Netzwerk-Spezifikation in Skill? | NEIN (mehrere Netze, noch nicht vollständig dokumentiert) | +| BCC-Mail-Routing-Beispiel für Vinos? | NEIN (war Egonetix, nicht Vinos) | +| DHL-Monitoring-Beispiel nutzen? | JA (exzellentes Vinos-Beispiel, referenzieren) | +| Kanbanize erwähnen? | JA (explizit als Task-Tracking-System) | +| Gap-Analyse jetzt erstellen? | NEIN (später, nicht Teil dieser Phase) | +| srv-job01 auf Gitea pushen? | NEIN (später, nicht Teil dieser Phase) | + +--- + +**Dieser Plan ist fertig zur Umsetzung.** diff --git a/plans/typed-munching-tarjan-agent-af913fe.md b/plans/typed-munching-tarjan-agent-af913fe.md new file mode 100644 index 0000000..59708a3 --- /dev/null +++ b/plans/typed-munching-tarjan-agent-af913fe.md @@ -0,0 +1,63 @@ +# Plan: Update srvclawdbot01.md for OpenClaw (Clawdbot) + Telegram + +## Target File +`/home/rwiegand/Nextcloud/egonetix/infrastructure/hosts/srvclawdbot01.md` + +## Changes Overview + +### 1. Header Table (Line 8) +**Change:** Update `Funktion` from `Claude Remote Agent` to `Claude Remote Agent + OpenClaw Bot` + +### 2. Services Table (Lines 18-22) +**Change:** Add a new row for the Telegram Bot service after the existing entries: +``` +| clawdbot-gateway | 18789 | OpenClaw Telegram Bot (@egomol_bot) | +``` + +### 3. New Section "## OpenClaw / Clawdbot" (after line 123, i.e. after the Claude Remote Agent section ends) +**Change:** Insert a complete new section with: +- Website link, npm package info, bot name +- Komponenten table (5 paths) +- Channels table (Telegram, active) +- Service-Verwaltung code block (systemctl --user commands, clawdbot CLI) +- Gateway info (Port 18789, loopback, token auth, dashboard URL) + +### 4. Ressourcen Section (Lines 125-130) +**Change:** Keep existing values (RAM 2 GB, Disk 8 GB) - no modification needed. + +### 5. Abhängigkeiten Section (Lines 11-14) +**Change:** Add two new dependencies: +- **Telegram API** (api.telegram.org) - fuer Bot-Kommunikation +- **Anthropic API** (api.anthropic.com) - fuer Claude Model + +## Resulting File Structure + +``` +# srvclawdbot01 - Claude Remote Agent Server + (header table with updated Funktion) + +## Abhängigkeiten + (existing + 2 new API dependencies) + +## Services + (existing + clawdbot-gateway row) + +## Claude Remote Agent + (all existing content unchanged) + +## OpenClaw / Clawdbot <-- NEW SECTION + (website, npm, bot info) + ### Komponenten <-- NEW + ### Channels <-- NEW + ### Service-Verwaltung <-- NEW + ### Gateway <-- NEW + +## Ressourcen + (unchanged) + +## Postfix Konfiguration + (unchanged) +``` + +## No Content Removed +All existing sections and content are preserved. Only additions and one field update (Funktion). diff --git a/plans/typed-munching-tarjan.md b/plans/typed-munching-tarjan.md new file mode 100644 index 0000000..d380710 --- /dev/null +++ b/plans/typed-munching-tarjan.md @@ -0,0 +1,139 @@ +# Plan: moltbot Arbeitsumgebung einrichten + +## Ziel + +moltbot (@egomol_bot) soll genauso arbeiten wie die CLI-Sessions: Infrastructure-Doku pflegen, Server verwalten, Repos committen/pushen. Dafür braucht er CLAUDE.md, SSH-Zugriff auf alle Server, und Gitea-Zugang. + +## Ausgangslage (srvclawdbot01) + +- Clawdbot läuft, Telegram-Channel OK, Pairing abgeschlossen +- SSH-Key existiert: `/root/.ssh/id_rsa` (root@srvclawdbot01) +- Gitea (gitea.egonetix.de:222) ist in known_hosts +- **Fehlt:** CLAUDE.md, SSH-Zugriff auf Infra-Server, Repos geklont, Gitea-Key, Verzeichnisstruktur + +## Schritte + +### 1. CLAUDE.md deployen + +**Datei:** `/root/.claude/CLAUDE.md` auf srvclawdbot01 + +```bash +scp /home/rwiegand/dotfiles/claude_settings/CLAUDE.md root@10.0.0.61:/root/.claude/CLAUDE.md +``` + +Claude Code CLI liest diese Datei automatisch als globale Instruktionen. 1:1 Kopie. + +### 2. Verzeichnisstruktur anlegen + +Gleiche Struktur wie auf dem Laptop, damit CLAUDE.md-Pfade funktionieren: + +```bash +ssh root@10.0.0.61 "mkdir -p /root/Nextcloud/egonetix" +``` + +### 3. SSH-Key auf alle Server verteilen + +Den existierenden Key `/root/.ssh/id_rsa.pub` auf alle Server kopieren: + +| Server | IP | User | +|--------|----|------| +| srvhost04 | 95.216.112.133 | root | +| srvdc01 | 10.0.0.21 | root | +| srvdocker02 | 10.0.0.29 | root | +| srvmail01 | 10.0.0.23 | root | +| srvmailgw03 | 10.0.0.37 | root | +| srvrevproxy02 | 10.0.0.29 | root | +| srvfs01 | ? | root | +| gwnue01 | 10.0.0.1 | root | +| gw-st01 | 172.20.20.1 | root | + +**Methode:** Vom Laptop aus den Public Key lesen und per SSH auf jeden Server verteilen: +```bash +PUBKEY=$(ssh root@10.0.0.61 "cat /root/.ssh/id_rsa.pub") +for host in srvhost04 srvdc01 srvdocker02 srvmail01 srvmailgw03 srvrevproxy02 srvfs01 gwnue01; do + ssh root@$host "echo '$PUBKEY' >> /root/.ssh/authorized_keys && sort -u -o /root/.ssh/authorized_keys /root/.ssh/authorized_keys" +done +``` + +### 4. Known Hosts populieren + +Vom Server aus alle Hosts einmal kontaktieren, damit SSH nicht nach Fingerprints fragt: + +```bash +ssh root@10.0.0.61 "for h in 10.0.0.21 10.0.0.23 10.0.0.29 10.0.0.37 95.216.112.133 10.0.0.1 172.20.20.1; do + ssh-keyscan -H \$h >> /root/.ssh/known_hosts 2>/dev/null +done +sort -u -o /root/.ssh/known_hosts /root/.ssh/known_hosts" +``` + +### 5. Gitea SSH-Key hinterlegen + +Public Key als Deploy-Key oder User-Key in Gitea registrieren: + +```bash +PUBKEY=$(ssh root@10.0.0.61 "cat /root/.ssh/id_rsa.pub") +curl -X POST -H "Authorization: token $(cat ~/.config/gitea/token)" \ + -H "Content-Type: application/json" \ + -d "{\"title\":\"moltbot (srvclawdbot01)\",\"key\":\"$PUBKEY\"}" \ + https://gitea.egonetix.de/api/v1/user/keys +``` + +### 6. Repos klonen + +Infrastructure-Repo und relevante Repos auf srvclawdbot01 klonen: + +```bash +ssh root@10.0.0.61 " + cd /root/Nextcloud/egonetix + git clone ssh://git@gitea.egonetix.de:222/Egonetix/infrastructure.git +" +``` + +Optional weitere Repos (zabbix, claude-remote-agent) je nach Bedarf. + +### 7. dotfiles/claude_settings klonen + +Damit moltbot die Settings-Sync Pflicht erfüllen kann: + +```bash +ssh root@10.0.0.61 " + mkdir -p /root/dotfiles + cd /root/dotfiles + git clone ssh://git@gitea.egonetix.de:222/root/claude_settings.git +" +``` + +### 8. Gitea Token auf Server hinterlegen + +```bash +ssh root@10.0.0.61 "mkdir -p /root/.config/gitea" +scp /home/rwiegand/.config/gitea/token root@10.0.0.61:/root/.config/gitea/token +``` + +### 9. tea CLI installieren (optional) + +Falls `~/bin/tea` auf dem Server gewünscht ist für Gitea-Interaktion. + +### 10. Git-Config auf Server setzen + +```bash +ssh root@10.0.0.61 " + git config --global user.name 'moltbot' + git config --global user.email 'moltbot@egonetix.de' +" +``` + +## Verifikation + +1. `ssh root@10.0.0.61 "cat /root/.claude/CLAUDE.md | head -5"` — CLAUDE.md vorhanden +2. `ssh root@10.0.0.61 "ssh root@10.0.0.21 hostname"` — SSH zu srvdc01 funktioniert +3. `ssh root@10.0.0.61 "cd /root/Nextcloud/egonetix/infrastructure && git pull"` — Repo-Zugriff OK +4. `ssh root@10.0.0.61 "cd /root/dotfiles/claude_settings && git pull"` — Settings-Repo OK +5. moltbot in Telegram bitten: "Lies die README von infrastructure und sag mir was drin steht" +6. moltbot bitten: "Prüfe den Status von srvdocker02 per SSH" + +## Offene Punkte + +- IPs von srvfs01 und srvrevproxy02 verifizieren (aus Host-Dateien) +- gw-st01 (172.20.20.1) ist nur über VPN erreichbar — prüfen ob srvclawdbot01 VPN-Routing hat +- Entscheidung: Soll moltbot eine eigene Git-Identity bekommen (moltbot@egonetix.de) oder die gleiche wie der User? diff --git a/plans/zany-growing-penguin.md b/plans/zany-growing-penguin.md new file mode 100644 index 0000000..3cd7653 --- /dev/null +++ b/plans/zany-growing-penguin.md @@ -0,0 +1,97 @@ +# Document Model Selection Strategy in CLAUDE.md + +## Goal +Create a clear, non-ambiguous rule for model selection (Haiku vs Sonnet vs Opus) that balances token costs with quality, avoiding false economies where cheaper models lead to more expensive debugging cycles. + +## Key Insight from Discussion +Using Haiku for execution with Opus for error recovery is likely **more expensive** in practice because: +- Context loss between models +- Opus must do blind forensics on Haiku's errors +- Error recovery costs more tokens than doing it right the first time + +## Model Characteristics + +### Haiku (claude-haiku-4-5) +- **Speed**: Fastest +- **Cost**: Cheapest per token +- **Best for**: Truly trivial, zero-risk tasks +- **Risk**: Higher error rate, weaker context understanding + +### Sonnet (claude-sonnet-4-5) +- **Speed**: Medium +- **Cost**: Medium (~3x Haiku) +- **Best for**: Most standard tasks, the "default choice" +- **Risk**: Good balance of speed/quality + +### Opus (claude-opus-4-5) +- **Speed**: Slower +- **Cost**: Highest (~5x Haiku) +- **Best for**: Complex tasks, deep debugging, critical systems +- **Risk**: Lowest error rate, best context understanding + +## Proposed Decision Tree + +``` +TASK COMPLEXITY: + +1. Is this trivial? (git status, typo fix, read a single file) + → HAIKU + +2. Is this a standard task with a plan? + Default: OPUS plans AND executes (one shot, no context loss) + + Exception: SONNET executes if BOTH: + - Plan is super-straightforward (mechanical steps, no decisions) + - AND error probability is very low (documented, tested system) + +3. Complex/risky tasks? + → OPUS (always) +``` + +**Core Principle:** Avoid model switches mid-task. Context loss costs more than using Opus from start. + +**Why Opus for execution too?** +- Real-world execution rarely matches the plan exactly +- Opus can adapt on-the-fly without re-planning overhead +- Token-efficient when you factor in error recovery costs + +## Critical Files +- `~/.claude/CLAUDE.md` - Global instructions to update + +## Implementation Plan + +1. **Add new section to CLAUDE.md** after "Mandatory Workflow" + - Title: "Model Selection Strategy" + - Decision tree with concrete examples + - Anti-patterns (what NOT to do) + +2. **Document these rules:** + - **Default: Opus plans AND executes** (one shot, no context loss) + - **Sonnet**: Only for execution when plan is super-straightforward AND low error risk + - **Haiku**: Only for truly trivial read-only tasks + - **Never mix models mid-task** - context loss costs more than using Opus from start + +3. **Include real examples:** + - **Haiku**: `git status`, reading a single file, checking if a file exists + - **Sonnet** (rare exception): Executing a well-tested deployment script when plan is 100% mechanical + - **Opus** (default): Host scans, documentation, SSH operations, service restarts, debugging, anything with potential for surprises + +4. **Add anti-pattern:** + - ❌ "Opus plans, Sonnet/Haiku executes, Opus fixes errors" → Context loss costs more tokens + - ❌ "Save tokens by using cheaper models" → False economy, error recovery is expensive + - ✅ "Opus plans AND executes in one shot" → No context loss, adapts on-the-fly + - ✅ "Only use Haiku for truly trivial read-only tasks" + +## Verification +- Read the updated CLAUDE.md section +- Verify the decision tree is unambiguous +- Check that examples are concrete, not vague +- User confirms it's no longer "schwammig" + +## Decision Made +After discussion, the strategy is: +- **Opus as default** for planning AND execution (one shot, no context loss) +- **Sonnet only as rare exception** when plan is 100% mechanical AND low error risk +- **Haiku only for trivial read-only** operations + +Rationale: Context loss between models costs more tokens than using Opus from start. Real-world execution rarely matches plans exactly. diff --git a/plans/zazzy-cooking-pie.md b/plans/zazzy-cooking-pie.md new file mode 100644 index 0000000..eedfefb --- /dev/null +++ b/plans/zazzy-cooking-pie.md @@ -0,0 +1,63 @@ +# Plan: Monitor-Auswahl im RDP Client + +## Problem + +`_get_best_monitor_selection(count)` wählt automatisch die N linkesten Monitore. +Bei 3 Monitoren (Laptop + 2 Extern) wird bei "2 Monitors" immer Laptop + 1 Extern gewählt, +statt der gewünschten 2 Externen. + +## Lösung: "Custom..." Option mit Checkbox-Dialog + +Eine neue Option "Custom..." im Multi-Monitor-Dropdown, die einen Dialog öffnet, +in dem der User per Checkbox auswählt, welche Monitore genutzt werden sollen. +Die Auswahl wird pro Verbindung in `monitor_ids` gespeichert. + +## Änderungen in `rdp_client.py` + +### 1. Neue Methode: `_get_monitor_details()` +- Ruft `xfreerdp /monitor-list` auf +- Gibt Liste mit Monitor-Infos zurück: `[{id, name, resolution, position, is_primary}]` +- Ergänzt um xrandr-Ausgabenamen (DP-3-1, eDP-1, etc.) für bessere Lesbarkeit + +### 2. Neuer Dialog: Monitor-Auswahl-Dialog +- Wird geöffnet wenn "Custom..." im Dropdown gewählt wird +- Zeigt alle verfügbaren Monitore mit Checkboxen: + ``` + [x] Monitor 0: DP-3-1 1920x1080 +3840+60 + [ ] Monitor 1: eDP-1 1920x1200 +0+0 (primary) + [x] Monitor 2: DP-3-2 1920x1080 +1920+60 + ``` +- Mindestens 1 Monitor muss ausgewählt sein +- OK/Cancel Buttons + +### 3. Dropdown-Optionen erweitern (`_get_multimon_options()`) +- Neue Option `"Custom..."` am Ende hinzufügen (vor Span) +- Optionen: `["No", "2 Monitors", "3 Monitors", "Custom...", "All Monitors", "Span"]` + +### 4. Connection-Editor anpassen (Zeile ~1441) +- Wenn "Custom..." gewählt wird → Dialog öffnen +- Ausgewählte Monitor-IDs in `monitor_ids` speichern (z.B. `"0,2"`) +- Label neben Dropdown zeigt aktuelle Auswahl: "Monitors: 0, 2" + +### 5. Verbindungsaufbau anpassen (Zeile ~930-966) +- Neuer Case für `multimon == "Custom..."`: + ```python + elif multimon == "Custom...": + monitor_list = conn.get("monitor_ids", "0") + cmd.append("/multimon") + cmd.append(f"/monitors:{monitor_list}") + ``` + +### 6. Details-Anzeige anpassen (Zeile ~721) +- Bei "Custom..." zusätzlich die gespeicherten Monitor-IDs anzeigen + +## Betroffene Datei + +- `/home/rwiegand/Nextcloud/entwicklung/Werkzeuge/rdp_client.py` + +## Verifikation + +1. Script starten: `python3 rdp_client.py` +2. Verbindung bearbeiten → "Custom..." wählen → Dialog prüfen +3. Monitore 0 und 2 auswählen → Speichern +4. Verbindung starten → prüfen ob `xfreerdp /multimon /monitors:0,2` aufgerufen wird diff --git a/plans/zesty-finding-harbor.md b/plans/zesty-finding-harbor.md new file mode 100644 index 0000000..64f2694 --- /dev/null +++ b/plans/zesty-finding-harbor.md @@ -0,0 +1,188 @@ +# Plan: CRIF Nächtliche False-Positive Problemmeldungen beheben + +## Problem + +**Kanbanize-Ticket:** #13461 - "VAE-Meldungen erhält jede Nacht Nachricht über CRIF" + +**Symptome:** +- Jede Nacht kommt eine Zabbix-Problemmeldung zum CRIF-Export +- Problem löst sich nach ca. 15 Minuten automatisch +- Die Zeiten sind sehr unregelmäßig + +**Betroffener Trigger:** +- TriggerID: 44829 +- Name: `processing_backup_monitoring_hours_crif` +- Host: SRV-JOB01 +- Kategorie: Interface/CRIF + +## Hintergrund + +Laut Dokumentation (troubleshooting.md:151-164): +- **Ablauf:** NAV erstellt Export → Scheduled Task (02:00) lädt zu CRIF FTP hoch → Dateien werden ins Backup-Verzeichnis verschoben +- **Trigger-Funktion:** Prüft ob Dateien jünger als 1 Tag im `\\vinos.local\sys\nav\interfaces\CRIFBuergel\backup` Ordner existieren +- **Häufige Ursache:** NAV Aufgabenwarteschlange läuft nicht (aber hier löst sich das Problem selbst → kein echter Fehler) + +## Hypothese (BESTÄTIGT durch Phase 1) + +**VERIFIZIERTE FAKTEN:** +- Trigger 44829 auf SRV-JOB01 überwacht CRIF-Backup (korrekt dokumentiert) +- Item: `processing_backup_monitoring_hours_crif` (Trapper-Type, empfängt Werte) +- Events feuern um ~01:15-01:45 CET (nicht 02:00!) +- Scheduled Task "Transfer-FilesWinSCP" läuft um 02:00 +- **ABER:** Backup-Dateien landen schon um 01:07-01:41 (vorher!) + +**Erkannte Ursache:** +Es gibt einen **ANDEREN Prozess** der die Backup-Dateien um ~01:00-01:30 erstellt (vermutlich NAV/Business Central Export). Der 02:00 Task ist nur der **Transfer**, nicht die Erstellung. + +Der Trigger prüft um ~01:30 und findet zu dem Zeitpunkt noch keine neuen Dateien (Export läuft noch), dann sind sie 15-45 Min später fertig → Auto-Recovery. + +**Problem:** Timing zwischen NAV-Export (unregelmäßig 01:07-01:41) und Monitoring-Check (~01:30) ist zu eng. + +## Implementierungsplan + +### Phase 1: Diagnose & Datensammlung ✅ ABGESCHLOSSEN + +**Ergebnisse:** + +**Trigger 44829 (verifiziert via Opus-Agent):** +- Host: SRV-JOB01 (hostid 10636) +- Item: 99026 "processing_backup_monitoring_hours_crif" (Trapper-Type) +- Expression: `{86644}=1` (feuert wenn Item-Wert = 1) +- Tags: IFS-Meldungen, VAE-Meldungen, fts + +**Event-Pattern (7 Tage):** +- Häufigkeit: 5 Events in 7 Tagen (täglich nachts) +- Timing: 01:15-01:45 CET +- Dauer bis Recovery: 15-45 Min (Durchschnitt: 36 Min) +- 100% Auto-Recovery + +**Scheduled Task "Transfer-FilesWinSCP":** +- Läuft um: 02:00:00 täglich +- Dauer: 2-3 Sekunden +- LastTaskResult: 0 (erfolgreich) + +**KRITISCHER FUND: Timing-Diskrepanz** +- Backup-Dateien landen: 01:07-01:41 (unregelmäßig!) +- Scheduled Task läuft: 02:00 (zu spät!) +- → Es gibt einen ANDEREN Prozess der die Dateien erstellt + +**Hypothese bestätigt:** NAV/Business Central erstellt Exports um ~01:00-01:30, Transfer-Task transportiert sie um 02:00. Trigger prüft während der Export-Erstellung läuft. + +### Phase 2: Lösungsansatz entwickeln + +**EMPFOHLENE LÖSUNG (basierend auf Phase 1):** + +**Option A: Monitoring-Check-Timing verschieben** ⭐ BESTE LÖSUNG +- **Problem:** Check läuft während NAV-Export (01:15-01:45) +- **Lösung:** Item-Update-Intervall so setzen dass Check NACH Export läuft (z.B. 02:30 oder 03:00) +- **Vorteil:** Einfach, keine False-Positives mehr +- **Nachteil:** Erkennt Probleme erst 1-2h später + +**Option B: Grace Period / Hysteresis einbauen** +- **Problem:** Export braucht 15-45 Min aber Trigger ist ungeduldig +- **Lösung:** Trigger feuert erst wenn 2-3 Checks in Folge fehlschlagen (z.B. "no data for 2 hours") +- **Vorteil:** Erkennt echte Ausfälle vs. temporäre Export-Phasen +- **Nachteil:** Komplexere Trigger-Logic + +**Option C: Maintenance Window** +- **Problem:** Nächtliche Wartung/Export = False-Positive +- **Lösung:** Maintenance Window 01:00-02:00 CET +- **Vorteil:** Sauber, professionell +- **Nachteil:** Echte Ausfälle in diesem Fenster werden nicht gemeldet + +**Option D: NAV-Export-Prozess finden und direkt überwachen** +- **Problem:** Wir überwachen Backup-Dateien, nicht den Prozess +- **Lösung:** NAV Aufgabenwarteschlange direkt überwachen (siehe troubleshooting.md:160 "Häufigste Ursache: NAV läuft nicht") +- **Vorteil:** Root-Cause-Monitoring statt Symptom-Monitoring +- **Nachteil:** Erfordert NAV-Zugriff und neue Items + +**EMPFEHLUNG:** Kombination A + B +1. Check-Timing auf 02:30 verschieben (nach Export UND Transfer) +2. Hysteresis: "Problem erst wenn 2 Checks (30 Min) fehlschlagen" +3. Damit: False-Positives weg + echte Ausfälle erkannt + +### Phase 3: Fix implementieren (Option A - Check-Timing verschieben) + +**Ziel:** Item-Update-Intervall so setzen dass Check NACH NAV-Export + Transfer läuft. + +**Schritte:** + +1. **Item 99026 Details abrufen:** + - Aktuelles Update-Intervall prüfen + - Type = Trapper → Werte werden gepusht, kein Poll-Intervall + - → Das Script das die Werte pusht muss gefunden werden + +2. **Monitoring-Script finden:** + - Auf SRV-JOB01: Scheduled Task der das Item befüllt + - Wahrscheinlich: PowerShell-Script das Backup-Ordner prüft + - Task-Name vermutlich: "Zabbix*CRIF*" oder ähnlich + - Pfad vermutlich: `C:\Skripte\` oder `C:\Tasks\` + +3. **Scheduled Task anpassen:** + - Backup der Task-Definition erstellen + - Task-Zeitplan von aktuell (vermutlich 01:30) auf **02:30** verschieben + - Begründung: NAV-Export läuft 01:07-01:41, Transfer 02:00, Check danach um 02:30 + +4. **Dokumentation aktualisieren:** + - `troubleshooting.md` Abschnitt "CRIF Bürgel Export-Monitoring" ergänzen + - Neues Timing dokumentieren + - Begründung für Änderung festhalten + +5. **Verifikation:** + - Morgen (03.02.2026) um ~02:30 Events prüfen + - Bestätigen: Kein False-Positive mehr + - 3-5 Nächte beobachten + +### Phase 4: Dokumentation & Abschluss + +1. **Troubleshooting.md aktualisieren:** + - Abschnitt "CRIF Bürgel Export-Monitoring" erweitern + - Fix und Erkenntnisse dokumentieren + - Pitfall hinzufügen falls relevant + +2. **README.md aktualisieren:** + - Trigger-ID Eintrag aktualisieren falls Name/Beschreibung geändert + +3. **Kanbanize-Kommentar erstellen:** + - Problemdokumentation nach Template + - User-Freigabe einholen bevor gepostet wird + +4. **Git Commit:** + - Dokumentationsänderungen committen + - Aussagekräftige Commit-Message + +## User-Entscheidung + +✅ Option A gewählt: Monitoring-Check-Timing verschieben +- Check-Zeit von ~01:30 auf 02:30 verschieben +- Damit läuft Check NACH NAV-Export (01:07-01:41) UND Transfer-Task (02:00) + +## Risiken & Überlegungen + +- **Kein Produktions-Impact:** CRIF-Export läuft, nur Monitoring ist zu sensitiv +- **Vorsicht:** Schwellwert nicht zu hoch setzen, sonst übersehen wir echte Ausfälle +- **Testing:** Idealerweise würden wir 2-3 Nächte beobachten nach dem Fix + +## Verification Strategy + +**Sofort nach Fix:** +1. Scheduled Task Status prüfen: NextRunTime = 02:30? +2. Task manuell triggern um zu testen + +**Nächste Nacht (03.02.2026):** +1. Um ~02:35: Zabbix Events prüfen +2. Bestätigen: Kein neues Problem-Event +3. Bestätigen: Item-Wert = 0 (OK) + +**Langfristig (3-5 Nächte):** +1. Event-Historie beobachten +2. Bestätigen: Keine False-Positives mehr +3. Optional: NAV-Export simuliert ausfallen lassen um zu testen ob echter Alarm käme + +## Success Criteria + +- [ ] Trigger 44829 feuert nicht mehr jede Nacht +- [ ] Wenn CRIF-Export tatsächlich fehlt, wird er trotzdem erkannt +- [ ] User erhält keine nächtlichen Problemmeldungen mehr +- [ ] Dokumentation ist aktualisiert +- [ ] Kanbanize-Kommentar erstellt und User-approved diff --git a/settings.json b/settings.json index 15ec8f4..e2d0bde 100644 --- a/settings.json +++ b/settings.json @@ -1,11 +1,4 @@ { - "statusLine": { - "type": "command", - "command": "$HOME/.claude/statusline-command.sh" - }, - "enabledPlugins": { - "superpowers@claude-plugins-official": true - }, "hooks": { "SessionStart": [ { @@ -18,5 +11,12 @@ ] } ] + }, + "statusLine": { + "type": "command", + "command": "$HOME/.claude/statusline-command.sh" + }, + "enabledPlugins": { + "superpowers@claude-plugins-official": true } }