docs, docker : interface web (serve), variables, compose web + CLI

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015a8P6WMRPeqdpd5VCh6jAy
This commit was merged in pull request #1.
This commit is contained in:
claude BotandClaude Opus 5.5 committed 2026-10-13 16:13:02 +02:00
1 parent 0cac77e63f
commit 5561bcfcf9
3 files changed
+110 -18

No files matched your search

+64 -10
View File
@@ -4,9 +4,10 @@ Synchronisation d'une partie de la configuration d'un cluster Proxmox VE 9.x
« référence » vers N clusters « clients », via l'API PVE et des tokens API.
Sens unique référence → clients. Pas de VM, pas de disques.
**État : phase 0 (CLI).** Export, diff et apply en YAML pour les options datacenter
et le SDN (zones VLAN/VXLAN, VNets, subnets). Testé contre un faux serveur PVE ;
**pas encore testé sur les clusters de labo.**
**État : phases 0 à 2.** CLI (export, diff et apply en YAML) et interface web
(écarts par client, dry-run et synchronisation par objet, par client ou global, journal,
audit) pour les options datacenter et le SDN (zones VLAN/VXLAN, VNets, subnets).
Testé contre un faux serveur PVE ; **pas encore testé sur les clusters de labo.**
## Périmètre
@@ -71,12 +72,59 @@ docker compose run --rm confsync check
docker compose run --rm confsync apply -confirm
```
## Interface web
```sh
go run ./cmd/pve-confsync serve -demo # démo : faux clusters PVE, http://localhost:8080
docker compose up -d confsync-web # production : données dans le volume /data
```
Le mode démo démarre une référence PVE 9.1, deux clients avec des écarts (dont un mapping
manquant, bloquant) et un cluster PVE 8 refusé. Comptes `admin`, `operateur` et `lecteur`,
mot de passe `confsync-demo`.
- **Écarts** : une carte par cluster (version, compteurs à créer / modifier / erreurs /
hors référence), puis les objets du client choisi ; le détail d'un objet montre pour
chaque champ la politique, la valeur de référence, le mapping, la valeur actuelle et
la valeur après synchro.
- **Dry-run / Synchroniser** par objet (avec ses dépendances : zone et vnet parents à
créer), par client ou global. La synchronisation passe toujours par un dry-run : le
serveur recalcule le plan et refuse s'il a changé depuis (empreinte du plan). Avec des
changements SDN, il faut taper le nom du client (celui de la référence en global).
Une seule synchronisation à la fois, suivie étape par étape.
- **Journal** des dry-runs et synchronisations (plans, étapes, résultats) et **Audit**
(connexions, actions, modifications des paramètres ; admin).
- **Paramètres** : clusters (test d'accès et des droits, TLS, mapping et politiques par
client), types synchronisés, sélection, politiques, suppression (désactivée par défaut),
utilisateurs locaux, import / export YAML (format de la CLI), compte, apparence.
Rôles : `admin` (tout), `operator` (dry-run et synchronisation), `viewer` (lecture).
Les comptes locaux restent disponibles même avec OIDC.
| Variable | Défaut | Rôle |
|---|---|---|
| `LISTEN` | `:8080` | adresse d'écoute |
| `DATA_DIR` | `/data` | base SQLite, `secret.key`, `session.key` |
| `CONFSYNC_SECRET_KEY` / `_FILE` | `DATA_DIR/secret.key` (créée) | clé AES-256 (hex ou base64) des secrets en base |
| `CONFSYNC_ADMIN_USER`, `CONFSYNC_ADMIN_PASSWORD` / `_FILE` | `admin`, aléatoire (journalisé une fois) | premier administrateur, base vide |
| `CONFSYNC_IMPORT` | | YAML de la CLI importé si la base n'a aucun cluster |
| `AUTH_LOCAL` | `true` | comptes locaux |
| `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET` / `_FILE`, `OIDC_REDIRECT_URL` | | OIDC (code + PKCE) ; `OIDC_REDIRECT_URL` complète, par ex. `https://confsync.example.org/auth/callback` |
| `OIDC_SCOPES`, `OIDC_GROUPS_CLAIM` | `openid profile email`, `groups` | ajouter le scope qui fournit les groupes chez l'IdP |
| `OIDC_ADMIN_GROUP`, `OIDC_OPERATOR_GROUP`, `OIDC_DEFAULT_ROLE` | `viewer` | rôle d'après les groupes |
| `SESSION_TTL` | `12h` | durée des sessions |
| `CONFSYNC_DEMO` | `false` | mode démo |
## Sécurité
- Secrets des tokens : jamais dans le YAML (`token_secret` en clair est refusé) ; lus depuis
une variable d'environnement (`token_secret_env`) ou un fichier (`token_secret_file`,
secret docker). Ils ne sont ni affichés ni journalisés. Le chiffrement au repos arrive avec
le stockage SQLite (phase 1).
secret docker). Ils ne sont ni affichés ni journalisés. Dans l'interface, ils sont chiffrés en base
(AES-256-GCM, clé hors base) et jamais renvoyés au navigateur ; l'export YAML les remplace
par `token_secret_env`.
- Interface : mots de passe PBKDF2-SHA256 (600 000 itérations), cookie de session signé
(HttpOnly, SameSite=Lax, Secure derrière HTTPS) invalidé au changement de mot de passe,
en-tête `X-Confsync` exigé sur les écritures (CSRF), CSP sans script ni style en ligne.
- TLS : `fingerprint` (pinning SHA-256 du certificat, adapté aux certificats auto-signés PVE),
`ca_file`, ou `insecure: true` réservé au labo.
- Tokens (privilege separation activée, l'ACL doit être posée sur l'utilisateur et le token) :
@@ -99,7 +147,12 @@ un droit.
## Arborescence
```
cmd/pve-confsync/ CLI (check, export, diff, apply)
cmd/pve-confsync/ CLI (check, export, diff, apply, serve)
internal/service/ analyse pour l'UI : lecture parallèle, plans, lignes de diff par champ
internal/store/ SQLite : clusters (secrets chiffrés), paramètres, utilisateurs, journal, audit
internal/server/ HTTP : auth locale + OIDC, rôles, API, jobs de synchronisation
internal/demo/ faux clusters du mode démo
web/ UI embarquée (index.html, app.js, style.css, login.html)
internal/pve/ client API : token, TLS, form-encoding, version, tâches
internal/pve/pvetest/ faux serveur PVE 9.x pour les tests
internal/model/ objets génériques, snapshot YAML, valeurs canoniques
@@ -111,18 +164,19 @@ docs/api-pve.md routes et schémas vérifiés dans les sources PVE
Tests : `go test ./...` (bout en bout contre le faux serveur : synchro complète, mapping
manquant, rollback sur erreur, refus de PVE 8, prune et ordre de suppression, forme
canonique des options datacenter, CLI dry-run/apply/export).
canonique des options datacenter, CLI dry-run/apply/export ; sélection d'objets et dépendances ; chiffrement, utilisateurs ;
serveur de bout en bout : rôles, CSRF, dry-run, empreinte périmée, confirmation SDN, apply).
## Phasage
0. **CLI** export / diff / apply YAML (options datacenter, tags, SDN). ← ici
0. **CLI** export / diff / apply YAML (options datacenter, tags, SDN).
1. UI lecture seule : clusters, diff visuel par client. Ergonomie reprise de Logstream
(`web/index.html`, `style.css`, `app.js`, `login.html`, auth locale + OIDC, audit) ;
SQLite (clusters, profils, mappings, historique, audit), secrets chiffrés.
2. UI d'action : Dry-run / Synchroniser (par objet, par client, global), journal des exécutions.
2. UI d'action : Dry-run / Synchroniser (par objet, par client, global), journal des exécutions. ← ici
3. Planification, détection de dérive en lecture seule, notifications.
## Reste à faire avant la phase 1
## Reste à faire
- Valider sur les deux clusters de labo : forme réelle des réponses (`nodes`, `dhcp-range`,
booléens), comportement de `PUT /cluster/options` avec `delete`.