Compare commits
No commits in common. "b4ca67289a9d3a2e7356ed12dcd0bf3a7b793264" and "b5e2edd3de2394711e49540839faf0261db1b037" have entirely different histories.
b4ca67289a
...
b5e2edd3de
2 changed files with 6 additions and 43 deletions
|
|
@ -3,11 +3,6 @@
|
||||||
## 2026-07-07 (soir)
|
## 2026-07-07 (soir)
|
||||||
|
|
||||||
### Ajouté
|
### Ajouté
|
||||||
- **GUI : persistance des journaux d'exécution.** Chaque action lancée depuis l'interface
|
|
||||||
(créer-vm / vérifier / déployer) écrit désormais, **en plus du streaming live**, un journal
|
|
||||||
horodaté `<instance>/logs/<hôte>-<action>-<date>.log` (gitignoré). Bonus : si le navigateur se
|
|
||||||
déconnecte, l'exécution **continue** et le journal est capturé jusqu'au bout (au lieu d'être
|
|
||||||
interrompue) — utile pour un déploiement qu'on ne veut pas voir avorter à la fermeture d'un onglet.
|
|
||||||
- **GUI : vues « Flux » et « Couches » (lecture seule).** Deux nouveaux onglets rendent visibles
|
- **GUI : vues « Flux » et « Couches » (lecture seule).** Deux nouveaux onglets rendent visibles
|
||||||
dans l'interface deux registres jusque-là en ligne de commande seulement : **Flux** = la matrice
|
dans l'interface deux registres jusque-là en ligne de commande seulement : **Flux** = la matrice
|
||||||
d'audit réseau (rôle · sens · port · pair · chiffrement coloré · raison, depuis les `meta/flux.yml`),
|
d'audit réseau (rôle · sens · port · pair · chiffrement coloré · raison, depuis les `meta/flux.yml`),
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import secrets
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
|
||||||
import threading
|
import threading
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -102,26 +101,12 @@ INTRANTS_CLES_INTERDITES = {
|
||||||
}
|
}
|
||||||
# Rappel en lecture seule (jamais de valeur) : secrets a fournir via Ansible Vault.
|
# Rappel en lecture seule (jamais de valeur) : secrets a fournir via Ansible Vault.
|
||||||
SECRETS_ATTENDUS = [
|
SECRETS_ATTENDUS = [
|
||||||
# Accès Proxmox (proxmox.vault.yml)
|
|
||||||
"proxmox_api_token_id", "proxmox_api_token_secret",
|
"proxmox_api_token_id", "proxmox_api_token_secret",
|
||||||
# PKI (step-ca)
|
|
||||||
"vault_step_ca_password", "vault_step_ca_provisioner_password",
|
"vault_step_ca_password", "vault_step_ca_provisioner_password",
|
||||||
# Identité (LDAP / Keycloak)
|
|
||||||
"vault_openldap_admin", "vault_ldap_sssd", "vault_keycloak_admin",
|
"vault_openldap_admin", "vault_ldap_sssd", "vault_keycloak_admin",
|
||||||
# Bases de données
|
"vault_postgresql_keycloak", "vault_bd_keycloak", "vault_forgejo_admin",
|
||||||
"vault_postgresql_keycloak", "vault_bd_keycloak", "vault_bd_forgejo",
|
"vault_forgejo_secret_key", "vault_forgejo_internal_token", "vault_bd_forgejo",
|
||||||
"vault_bd_icingadb", "vault_bd_nextcloud",
|
"vault_grafana_admin", "vault_redis", "vault_bd_icingadb",
|
||||||
# Forge (Forgejo)
|
|
||||||
"vault_forgejo_admin", "vault_forgejo_secret_key", "vault_forgejo_internal_token",
|
|
||||||
# Observabilité / cache
|
|
||||||
"vault_grafana_admin", "vault_redis",
|
|
||||||
# Applications (admin)
|
|
||||||
"vault_nextcloud_admin",
|
|
||||||
# Secrets OIDC des clients SSO (un par app fédérée)
|
|
||||||
"vault_grafana_oidc", "vault_forgejo_oidc", "vault_icingaweb2_oidc",
|
|
||||||
"vault_nextcloud_oidc", "vault_oauth2_cookie",
|
|
||||||
# Sauvegarde (restic hors-nœud)
|
|
||||||
"vault_restic_password", "vault_backup_ssh_privkey",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Garde-fous des executions (verifier / deployer) depuis l'interface.
|
# Garde-fous des executions (verifier / deployer) depuis l'interface.
|
||||||
|
|
@ -2054,7 +2039,6 @@ class Gestionnaire(BaseHTTPRequestHandler):
|
||||||
self.repondre_json(409, {"erreur": "Une execution est deja en cours."})
|
self.repondre_json(409, {"erreur": "Une execution est deja en cours."})
|
||||||
return
|
return
|
||||||
fichier_vault = None
|
fichier_vault = None
|
||||||
journal = None
|
|
||||||
try:
|
try:
|
||||||
cible = {"deployer": "deployer", "pousser": "deployer",
|
cible = {"deployer": "deployer", "pousser": "deployer",
|
||||||
"creer": "creer-vm"}.get(mode, "verifier-deploiement")
|
"creer": "creer-vm"}.get(mode, "verifier-deploiement")
|
||||||
|
|
@ -2068,14 +2052,7 @@ class Gestionnaire(BaseHTTPRequestHandler):
|
||||||
self.send_header("Content-Type", "text/plain; charset=utf-8")
|
self.send_header("Content-Type", "text/plain; charset=utf-8")
|
||||||
self.send_header("Cache-Control", "no-cache")
|
self.send_header("Cache-Control", "no-cache")
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
# Persistance : un journal horodaté par exécution, en plus du streaming live.
|
self._ecrire_flux(f"$ make {cible} HOTE={hote}\n\n")
|
||||||
dossier_logs = self.inventaire.parents[2] / "logs"
|
|
||||||
dossier_logs.mkdir(parents=True, exist_ok=True)
|
|
||||||
chemin_log = dossier_logs / f"{hote}-{cible}-{time.strftime('%Y%m%dT%H%M%S')}.log"
|
|
||||||
journal = open(chemin_log, "w", encoding="utf-8")
|
|
||||||
entete = f"$ make {cible} HOTE={hote}\n\n"
|
|
||||||
journal.write(entete)
|
|
||||||
self._ecrire_flux(entete)
|
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
["make", cible, f"HOTE={hote}"],
|
["make", cible, f"HOTE={hote}"],
|
||||||
cwd=str(RACINE), env=env,
|
cwd=str(RACINE), env=env,
|
||||||
|
|
@ -2084,11 +2061,8 @@ class Gestionnaire(BaseHTTPRequestHandler):
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
for ligne in proc.stdout:
|
for ligne in proc.stdout:
|
||||||
journal.write(ligne)
|
|
||||||
if not self._ecrire_flux(ligne):
|
if not self._ecrire_flux(ligne):
|
||||||
# Navigateur déconnecté : on continue à journaliser jusqu'au bout.
|
proc.terminate()
|
||||||
for reste in proc.stdout:
|
|
||||||
journal.write(reste)
|
|
||||||
break
|
break
|
||||||
finally:
|
finally:
|
||||||
rc = proc.wait()
|
rc = proc.wait()
|
||||||
|
|
@ -2103,14 +2077,8 @@ class Gestionnaire(BaseHTTPRequestHandler):
|
||||||
marquer_serveur_actif(hote)
|
marquer_serveur_actif(hote)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
journal.write(f"\n__FIN__ rc={rc}\n")
|
self._ecrire_flux(f"\n__FIN__ rc={rc}\n")
|
||||||
self._ecrire_flux(f"\n[journal : {os.path.relpath(chemin_log, RACINE)}]\n__FIN__ rc={rc}\n")
|
|
||||||
finally:
|
finally:
|
||||||
if journal:
|
|
||||||
try:
|
|
||||||
journal.close()
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
if fichier_vault:
|
if fichier_vault:
|
||||||
try:
|
try:
|
||||||
os.remove(fichier_vault)
|
os.remove(fichier_vault)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue