Kanbanize Kartenerstellung dokumentiert: Arrival-Rule-Workaround, Board-Struktur
- 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 <noreply@anthropic.com>
This commit is contained in:
64
plans/abstract-gathering-tome.md
Normal file
64
plans/abstract-gathering-tome.md
Normal file
@@ -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)
|
||||
@@ -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=<pw>" | 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
|
||||
<div class="pf-v5-c-login__main">
|
||||
<div class="pf-v5-c-login__main-header"> <-- Header-Section (Logo + Titel)
|
||||
<h1 id="kc-page-title">...</h1>
|
||||
</div>
|
||||
<div class="pf-v5-c-login__main-body"> <-- Body-Section (Formular)
|
||||
...
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
**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 |
|
||||
|
||||
52
plans/crispy-dancing-gray.md
Normal file
52
plans/crispy-dancing-gray.md
Normal file
@@ -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
|
||||
118
plans/functional-strolling-donut.md
Normal file
118
plans/functional-strolling-donut.md
Normal file
@@ -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
|
||||
315
plans/glittery-enchanting-allen.md
Normal file
315
plans/glittery-enchanting-allen.md
Normal file
@@ -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 <noreply@anthropic.com>"
|
||||
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)
|
||||
15
plans/groovy-toasting-crayon.md
Normal file
15
plans/groovy-toasting-crayon.md
Normal file
@@ -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)
|
||||
62
plans/hidden-snacking-lighthouse.md
Normal file
62
plans/hidden-snacking-lighthouse.md
Normal file
@@ -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
|
||||
146
plans/lively-plotting-cosmos.md
Normal file
146
plans/lively-plotting-cosmos.md
Normal file
@@ -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) |
|
||||
74
plans/peppy-prancing-hedgehog.md
Normal file
74
plans/peppy-prancing-hedgehog.md
Normal file
@@ -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
|
||||
173
plans/serialized-swimming-corbato.md
Normal file
173
plans/serialized-swimming-corbato.md
Normal file
@@ -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
|
||||
234
plans/silly-waddling-dragonfly.md
Normal file
234
plans/silly-waddling-dragonfly.md
Normal file
@@ -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: <Templates-Gruppe>}]
|
||||
```
|
||||
|
||||
**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"}
|
||||
```
|
||||
23
plans/snazzy-riding-eclipse.md
Normal file
23
plans/snazzy-riding-eclipse.md
Normal file
@@ -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.
|
||||
152
plans/snuggly-juggling-hoare.md
Normal file
152
plans/snuggly-juggling-hoare.md
Normal file
@@ -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) |
|
||||
444
plans/sparkling-sauteeing-clarke.md
Normal file
444
plans/sparkling-sauteeing-clarke.md
Normal file
@@ -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.**
|
||||
63
plans/typed-munching-tarjan-agent-af913fe.md
Normal file
63
plans/typed-munching-tarjan-agent-af913fe.md
Normal file
@@ -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).
|
||||
139
plans/typed-munching-tarjan.md
Normal file
139
plans/typed-munching-tarjan.md
Normal file
@@ -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?
|
||||
97
plans/zany-growing-penguin.md
Normal file
97
plans/zany-growing-penguin.md
Normal file
@@ -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.
|
||||
63
plans/zazzy-cooking-pie.md
Normal file
63
plans/zazzy-cooking-pie.md
Normal file
@@ -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
|
||||
188
plans/zesty-finding-harbor.md
Normal file
188
plans/zesty-finding-harbor.md
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user