Preuve complète (16/16) + détail P16 lisible #2
2 changed files with 20 additions and 4 deletions
|
|
@ -7,7 +7,7 @@
|
|||
> [`docs/audit/affirmations.md`](affirmations.md).
|
||||
|
||||
- **Instance** : `instance` — inventaire `instance/inventories/principal/hosts.yml`
|
||||
- **Verdict** : ✅ CONFORME (15 OK · 0 echec · 1 saute)
|
||||
- **Verdict** : ✅ CONFORME (16 OK · 0 echec · 0 saute)
|
||||
|
||||
## Preuves
|
||||
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
| P13 | Invariants structurels/doctrinaux | AFF-015, AFF-022, AFF-037, AFF-038, AFF-062 | ✅ OK | LICENSE, socle dossier, pas de couches paralleles, SSH clef-only, nftables off : OK. |
|
||||
| P14 | Pas de chemin lab/ code en dur | AFF-097 | ✅ OK | Aucun chemin instance/inventories/lab/group_vars code en dur. |
|
||||
| P15 | Modele public socle valide | AFF-022, AFF-099 | ✅ OK | Modele public socle : domaines/serveurs/applications/bases valides. |
|
||||
| P16 | Inventaire Ansible complet (--list) | AFF-030 | ⚪ SAUTE | Voute chiffree sans ANSIBLE_VAULT_PASSWORD_FILE (prerequis AFF-026). |
|
||||
| P16 | Inventaire Ansible complet (--list) | AFF-030 | ✅ OK | 14 hotes, 29 groupes (inventaire dechiffre et parse). |
|
||||
|
||||
## Couverture des affirmations ✅ du registre
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ Usage :
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime as _dt
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
|
@ -178,6 +179,22 @@ def preuve_pas_lab_code_en_dur() -> tuple[bool, str]:
|
|||
return True, "Aucun chemin instance/inventories/lab/group_vars code en dur."
|
||||
|
||||
|
||||
def preuve_inventaire_ansible() -> tuple[bool, str]:
|
||||
"""`ansible-inventory --list` : l'inventaire (voute dechiffree) se parse (AFF-030)."""
|
||||
r = subprocess.run(["ansible-inventory", "-i", INV, "--list"],
|
||||
cwd=RACINE, capture_output=True, text=True, timeout=600)
|
||||
if r.returncode != 0:
|
||||
sortie = (r.stdout + r.stderr).strip().splitlines()
|
||||
return False, f"rc={r.returncode} : {sortie[-1] if sortie else ''}"
|
||||
try:
|
||||
data = json.loads(r.stdout)
|
||||
except ValueError:
|
||||
return True, "inventaire liste (JSON non parse)."
|
||||
n_hotes = len((data.get("_meta") or {}).get("hostvars") or {})
|
||||
n_groupes = len([k for k in data if k not in ("_meta", "all")])
|
||||
return True, f"{n_hotes} hotes, {n_groupes} groupes (inventaire dechiffre et parse)."
|
||||
|
||||
|
||||
# --- Registre des preuves : (id, titre, refs AFF, executeur) -----------------------
|
||||
#
|
||||
# executeur = liste de commandes argv (toutes doivent renvoyer 0), ou callable -> (ok, detail).
|
||||
|
|
@ -264,8 +281,7 @@ def main() -> int:
|
|||
|
||||
# Preuve conditionnelle : inventaire Ansible complet (necessite la voute).
|
||||
preuve_inv = {"id": "P16", "titre": "Inventaire Ansible complet (--list)",
|
||||
"refs": ["AFF-030"],
|
||||
"cmds": [["ansible-inventory", "-i", INV, "--list"]]}
|
||||
"refs": ["AFF-030"], "func": preuve_inventaire_ansible}
|
||||
liste = list(PREUVES)
|
||||
if _vault_requis_absent():
|
||||
resultats.append((preuve_inv, "SAUTE",
|
||||
|
|
|
|||
Loading…
Reference in a new issue