diff --git a/CHANGELOG.md b/CHANGELOG.md index f73ae76..634d942 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ émet la config Cisco-like du réseau convergé — **VLANs + SVIs (passerelles) + ACLs d'isolation inter-tenant** — dérivée des nomenclatures, jamais saisie à la main (toujours synchrone avec le plan). One-shot précédemment ; maintenant reproductible. +- **GUI : vue « Réseau » (devis switch) + bouton Copier.** Nouvel onglet lecture seule qui + affiche le devis `make devis-reseau` (VLANs + SVIs + ACLs), via `GET /api/devis-reseau`, avec + un bouton **Copier** (prêt à coller sur le switch). Un opérateur génère et transmet la config + sans CLI. - **GUI : erreurs de déploiement en LANGAGE CLAIR.** Quand une action (créer/vérifier/déployer) échoue, le GUI n'oblige plus à lire le dump Ansible : un encadré résume les tâches en erreur — **étape · hôte · type · message clair** — avec un bouton **« Copier »** (pour transmettre le diff --git a/scripts/inventory_gui.py b/scripts/inventory_gui.py index 6ffbe43..d332af1 100644 --- a/scripts/inventory_gui.py +++ b/scripts/inventory_gui.py @@ -20,6 +20,7 @@ from urllib.parse import urlparse import yaml +import devis_reseau from inventory_rules import ( GROUPE_HOTES_ACTIFS, GROUPE_HOTES_PLANIFIES, @@ -916,6 +917,8 @@ HTML = r""" .re-hote { color: var(--teal); font-weight: 700; } .re-type { color: var(--muted); font-size: 11px; } .re-msg { background: var(--surface-3); border-radius: 6px; padding: 4px 8px; margin-top: 3px; font-family: ui-monospace, monospace; font-size: 11.5px; white-space: pre-wrap; word-break: break-word; } + /* Devis réseau (config switch) */ + .devis-reseau { margin: 8px 0 0; padding: 12px 14px; background: var(--surface-3); border-radius: 8px; font-family: ui-monospace, monospace; font-size: 11.5px; line-height: 1.5; white-space: pre; overflow: auto; max-height: calc(100vh - 210px); }
@@ -933,6 +936,7 @@ HTML = r""" + @@ -1152,6 +1156,7 @@ HTML = r""" document.getElementById('btn-vue-domaines').classList.toggle('on', v === 'domaines'); document.getElementById('btn-vue-flux').classList.toggle('on', v === 'flux'); document.getElementById('btn-vue-couches').classList.toggle('on', v === 'couches'); + document.getElementById('btn-vue-reseau').classList.toggle('on', v === 'reseau'); dessinerGrilles(); dessinerDetail(); // le panneau droit reflète la sélection de la vue courante majIndicateurSauvegarde(); @@ -1176,6 +1181,7 @@ HTML = r""" if (vuePrincipale === 'domaines') { dessinerDomaines(); return; } if (vuePrincipale === 'flux') { dessinerFlux(); return; } if (vuePrincipale === 'couches') { dessinerCouches(); return; } + if (vuePrincipale === 'reseau') { dessinerReseau(); return; } dessinerServeurs(); } @@ -1191,6 +1197,10 @@ HTML = r"""meta/flux.yml des rôles, puis make flux.ip-miroir (VLAN = 1000 + index×10 + zone, unique sur le trunk).make devis-reseau. À adapter à ta plateforme (NX-OS/IOS-XE, HSRP, route par défaut vers OPNsense, port de trunk).${echapper(devisReseauTexte)}