Avant : pve-confsync n'était qu'une CLI (check, export, diff, apply), configurée par un YAML.
Après : pve-confsync serve lance une interface web embarquée (Go embed, SQLite) dont l'ergonomie reprend celle de Logstream. On y voit une carte par cluster, puis les écarts du client choisi, avec le détail champ par champ : politique, référence, mapping, valeur actuelle et valeur après synchro. On peut lancer un dry-run puis synchroniser par objet, par client ou globalement. L'interface tient aussi un journal des exécutions et un audit. serve -demo démarre de faux clusters PVE pour l'essayer sans labo.
Comment
Stockage (internal/store) : SQLite en Go pur (modernc, CGO_ENABLED=0). On y garde les clusters, les paramètres, les utilisateurs, le journal et l'audit.
Les secrets des tokens sont chiffrés en AES-256-GCM. La clé est lue dans CONFSYNC_SECRET_KEY, sinon _FILE, sinon DATA_DIR/secret.key.
Les secrets ne sont jamais renvoyés au navigateur. L'export YAML les remplace par token_secret_env.
Serveur (internal/server) :
Authentification par comptes locaux (PBKDF2-SHA256, 600 000 itérations) et OIDC (code + PKCE, rôle déduit des groupes).
Trois rôles : admin, operator, viewer.
Sessions par cookie signé, invalidé au changement de mot de passe.
Protection CSRF : l'en-tête X-Confsync est exigé sur les écritures. La CSP n'autorise aucun script ni style en ligne.
Synchronisation :
Chaque dry-run est enregistré avec une empreinte du plan. L'apply recalcule le plan et répond 409 si l'empreinte a changé.
Les changements SDN demandent de taper le nom du client, ou celui de la référence pour une synchro globale.
Un seul apply tourne à la fois, en tâche de fond, et chaque étape est écrite dans le journal.
Sélection (engine.Filter) :
Sélectionner un objet ajoute ses dépendances : la zone et le vnet parents à créer, ou les enfants à supprimer d'abord.
Une erreur sur un parent reste bloquante quand on ne sélectionne que l'enfant.
UI (web/) : HTML, CSS et JS sans framework ni build. Elle est en français et en anglais, avec thème clair ou sombre et une mise en page mobile. Les paramètres couvrent les clusters (test d'accès, TLS, mapping et politiques par client), la synchronisation, les utilisateurs, l'import/export YAML, le compte et l'apparence.
Docker : CMD ["serve"] avec un healthcheck. Le compose a un service confsync-web et un service CLI sous le profil cli.
Tests
go vet et go test -race ./... passent. gofmt est propre et le build passe avec CGO_ENABLED=0.
Nouveaux tests :
engine/select_test.go : dépendances, ordre des suppressions, erreurs des parents, empreinte.
store/store_test.go : chiffrement, masquage des secrets, utilisateurs, dernier admin protégé.
server/server_test.go : rôles, CSRF, absence de secret dans les réponses, puis le parcours complet dry-run → refus (bloquant, confirmation, empreinte périmée) → apply → client conforme.
Parcours manuel en Chromium (Playwright) sur le mode démo : aucune erreur JS.
Limites connues
Pas testé sur de vrais clusters PVE, seulement sur le faux serveur.
La synchro globale est bloquée dès qu'un client a une erreur ou est illisible. C'est un choix prudent.
Auth.CheckProvider existe mais n'est pas appelé au démarrage dans serve.go.
clientIP fait confiance à X-Forwarded-For (comme Logstream), à restreindre si le service est exposé sans reverse proxy.
Avant : pve-confsync n'était qu'une CLI (check, export, diff, apply), configurée par un YAML.
Après : `pve-confsync serve` lance une interface web embarquée (Go embed, SQLite) dont l'ergonomie reprend celle de Logstream. On y voit une carte par cluster, puis les écarts du client choisi, avec le détail champ par champ : politique, référence, mapping, valeur actuelle et valeur après synchro. On peut lancer un dry-run puis synchroniser par objet, par client ou globalement. L'interface tient aussi un journal des exécutions et un audit. `serve -demo` démarre de faux clusters PVE pour l'essayer sans labo.
## Comment
- **Stockage** (`internal/store`) : SQLite en Go pur (modernc, CGO_ENABLED=0). On y garde les clusters, les paramètres, les utilisateurs, le journal et l'audit.
- Les secrets des tokens sont chiffrés en AES-256-GCM. La clé est lue dans `CONFSYNC_SECRET_KEY`, sinon `_FILE`, sinon `DATA_DIR/secret.key`.
- Les secrets ne sont jamais renvoyés au navigateur. L'export YAML les remplace par `token_secret_env`.
- **Serveur** (`internal/server`) :
- Authentification par comptes locaux (PBKDF2-SHA256, 600 000 itérations) et OIDC (code + PKCE, rôle déduit des groupes).
- Trois rôles : admin, operator, viewer.
- Sessions par cookie signé, invalidé au changement de mot de passe.
- Protection CSRF : l'en-tête `X-Confsync` est exigé sur les écritures. La CSP n'autorise aucun script ni style en ligne.
- **Synchronisation** :
- Chaque dry-run est enregistré avec une empreinte du plan. L'apply recalcule le plan et répond 409 si l'empreinte a changé.
- Les changements SDN demandent de taper le nom du client, ou celui de la référence pour une synchro globale.
- Un seul apply tourne à la fois, en tâche de fond, et chaque étape est écrite dans le journal.
- **Sélection** (`engine.Filter`) :
- Sélectionner un objet ajoute ses dépendances : la zone et le vnet parents à créer, ou les enfants à supprimer d'abord.
- Une erreur sur un parent reste bloquante quand on ne sélectionne que l'enfant.
- **UI** (`web/`) : HTML, CSS et JS sans framework ni build. Elle est en français et en anglais, avec thème clair ou sombre et une mise en page mobile. Les paramètres couvrent les clusters (test d'accès, TLS, mapping et politiques par client), la synchronisation, les utilisateurs, l'import/export YAML, le compte et l'apparence.
- **Docker** : `CMD ["serve"]` avec un healthcheck. Le compose a un service `confsync-web` et un service CLI sous le profil `cli`.
## Tests
- `go vet` et `go test -race ./...` passent. gofmt est propre et le build passe avec `CGO_ENABLED=0`.
- Nouveaux tests :
- `engine/select_test.go` : dépendances, ordre des suppressions, erreurs des parents, empreinte.
- `store/store_test.go` : chiffrement, masquage des secrets, utilisateurs, dernier admin protégé.
- `server/server_test.go` : rôles, CSRF, absence de secret dans les réponses, puis le parcours complet dry-run → refus (bloquant, confirmation, empreinte périmée) → apply → client conforme.
- Parcours manuel en Chromium (Playwright) sur le mode démo : aucune erreur JS.
## Limites connues
- **Pas testé sur de vrais clusters PVE**, seulement sur le faux serveur.
- La synchro globale est bloquée dès qu'un client a une erreur ou est illisible. C'est un choix prudent.
- `Auth.CheckProvider` existe mais n'est pas appelé au démarrage dans `serve.go`.
- `clientIP` fait confiance à `X-Forwarded-For` (comme Logstream), à restreindre si le service est exposé sans reverse proxy.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_015a8P6WMRPeqdpd5VCh6jAy
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Avant : pve-confsync n'était qu'une CLI (check, export, diff, apply), configurée par un YAML.
Après :
pve-confsync servelance une interface web embarquée (Go embed, SQLite) dont l'ergonomie reprend celle de Logstream. On y voit une carte par cluster, puis les écarts du client choisi, avec le détail champ par champ : politique, référence, mapping, valeur actuelle et valeur après synchro. On peut lancer un dry-run puis synchroniser par objet, par client ou globalement. L'interface tient aussi un journal des exécutions et un audit.serve -demodémarre de faux clusters PVE pour l'essayer sans labo.Comment
internal/store) : SQLite en Go pur (modernc, CGO_ENABLED=0). On y garde les clusters, les paramètres, les utilisateurs, le journal et l'audit.CONFSYNC_SECRET_KEY, sinon_FILE, sinonDATA_DIR/secret.key.token_secret_env.internal/server) :X-Confsyncest exigé sur les écritures. La CSP n'autorise aucun script ni style en ligne.engine.Filter) :web/) : HTML, CSS et JS sans framework ni build. Elle est en français et en anglais, avec thème clair ou sombre et une mise en page mobile. Les paramètres couvrent les clusters (test d'accès, TLS, mapping et politiques par client), la synchronisation, les utilisateurs, l'import/export YAML, le compte et l'apparence.CMD ["serve"]avec un healthcheck. Le compose a un serviceconfsync-webet un service CLI sous le profilcli.Tests
go vetetgo test -race ./...passent. gofmt est propre et le build passe avecCGO_ENABLED=0.engine/select_test.go: dépendances, ordre des suppressions, erreurs des parents, empreinte.store/store_test.go: chiffrement, masquage des secrets, utilisateurs, dernier admin protégé.server/server_test.go: rôles, CSRF, absence de secret dans les réponses, puis le parcours complet dry-run → refus (bloquant, confirmation, empreinte périmée) → apply → client conforme.Limites connues
Auth.CheckProviderexiste mais n'est pas appelé au démarrage dansserve.go.clientIPfait confiance àX-Forwarded-For(comme Logstream), à restreindre si le service est exposé sans reverse proxy.🤖 Generated with Claude Code
https://claude.ai/code/session_015a8P6WMRPeqdpd5VCh6jAy