Agent DNS
- load_config() lit maintenant la section `redis` du config.yaml
(host, port, password, ssl, ssl_ca_cert, ssl_certfile, ssl_keyfile)
→ l'agent ne tombait plus sur localhost:6379 par défaut
- Suppression de retry_on_timeout (déprécié redis-py 6.0)
- Suppression de socket_keepalive_options (clés string invalides)
- int() forcé sur port et db dans run() pour éviter TypeError
- Traceback complet sur fatal error
- get_state: relativize=False → dnspython conserve les FQDN complets
- get_state: parse les enregistrements "; [DISABLED]" pour les inclure
avec active=False dans le state retourné
- _fmt_value: ne ajoute plus le point final sur les noms relatifs
(srvweb → reste srvweb, srvweb.infolix.fr → srvweb.infolix.fr.)
- save_zone_raw: named-checkzone + snapshot (même logique qu'apply_zone)
- gen_certs.sh: REDIS_HOST obligatoire, détection IP vs FQDN pour le SAN
Backend DNS
- _sync_zone_from_state: normalise les noms FQDN → court avant _stable_id
(mail.infolix.fr. → mail pour correspondre à ce qui est en BDD)
- _sync_zone_from_state: active=%s au lieu de COALESCE(active,1)
→ les enregistrements désactivés importés depuis le fichier de zone
sont correctement marqués active=0 en BDD
Frontend
- App.jsx: VITE_API_BASE prioritaire sur localStorage
- validateRecord: accepte les noms relatifs sans point pour CNAME/MX/NS
Snapshots
- Snapshot automatique avant chaque modification de zone (apply_zone + save_zone_raw)
- Stockage dans zones_dir/history/ avec timestamp, purge auto à 20 entrées par zone
- named-checkzone exécuté sur fichier temporaire avant remplacement du fichier réel
- Rollback automatique du snapshot précédent si named-checkzone échoue
- Détection des warnings critiques (MX→IP, CNAME apex) même si returncode=0
Nouvelles routes backend
- GET /dns/zones/{zone}/snapshots — liste des snapshots
- GET /dns/zones/{zone}/snapshots/{name} — contenu d'un snapshot
- POST /dns/zones/{zone}/rollback?snapshot= — restauration + named-checkzone + rndc reload
Nouveaux handlers agent
- list_snapshots, get_snapshot, rollback_zone
Interface DNSManager
- Bouton ⏱ Historique dans la toolbar de zone
- Modale avec liste des snapshots (date formatée)
- Diff inline ▼/▲ par snapshot : lignes ajoutées (vert) / supprimées (rouge)
- Bouton ↩ Restaurer avec confirmation
- Erreur named-checkzone affichée dans la modale Raw au lieu de l'interface principale
- Validation MX/NS/CNAME/PTR : bloque les valeurs pointant vers une IP
Déploiement
- install.sh (serveur principal) et install-agent.sh [dns|mail] (serveurs distants)
- Config Nginx avec restriction IP, SSL, reverse proxy /api/
- VITE_API_BASE via .env.development / .env.production
- Services systemd pour backend et agents
Refactorisation
- Hook useApi centralisé (hooks/useApi.js) — supprime 200 lignes dupliquées
- Helpers backend : get_or_404, _sync_domain_from_state, _sync_zone_from_state, _stable_id
- Constantes de rôles RBAC dans auth.py (ROLE_GLOBAL_ADMIN, etc.)
- handle_apply_domain découpé en _sync_domain_row / _sync_mailboxes / _sync_aliases (169→32 lignes)
- oidc_callback découpé en _exchange_oidc_token / _provision_oidc_user (159→54 lignes)
- Extraction composants : AccountModal, AliasModal, DnssecResultModal, DnssecManageModal
- Suppression MailingLists.jsx (inutilisé)
Corrections
- Notification de connexion différée après validation TOTP
- Création domaine : validation complète avant tout appel API (quota bal > quota global bloqué)
- Création domaine : service Mail non tenté si création DNS échoue
- Alias goto : validation email bloquante (frontend + backend)
- Alias : vérification conflit avec compte mail existant (409)
- delete_domain : notifie l'agent mail pour suppression dans netadmin_mail
- Clés DNSSEC archivées dans key_dir/old/ avant activation et à la suppression de zone
- _get_ds_records : exclut le dossier old/ (évitait la lecture de doublons)
- Modale TOTP : remplace window.confirm par une vraie modale
- "Mon compte" accessible sans rôle
- Suppression champ "Serveur API" de la sidebar