instancier : déchiffrer la voûte pour ansible-inventory (exit 4)

Une voûte chiffrée group_vars/all/vault.yml fait échouer
ansible-inventory --list (comparaison du plan) sans mot de passe →
« Appliquer le plan » cassé dès qu'une voûte existe. instancier utilise
maintenant ~/.config/setops-vault-pass si ANSIBLE_VAULT_PASSWORD_FILE
n'est pas déjà fourni. Validé : plus d'exit 4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-07-01 22:17:45 -04:00
parent 27b8f51f15
commit 937ac700b9
2 changed files with 15 additions and 2 deletions

View file

@ -15,6 +15,12 @@
- **Compteur « vivantes »** dans l'en-tête (depuis la sonde), à côté de actifs/planifiés.
### Corrigé
- **Une voûte chiffrée cassait `instancier` / « Appliquer le plan ».** `ansible-inventory
--list` (utilisé pour la comparaison sémantique du plan) tente de déchiffrer
`group_vars/all/vault.yml` et échoue sans mot de passe (`exit 4`) — alors que
l'opération est structurelle, sans secret. `instancier` utilise désormais
automatiquement le fichier conventionnel `~/.config/setops-vault-pass` (si
`ANSIBLE_VAULT_PASSWORD_FILE` n'est pas déjà défini).
- **Secrets des rôles non câblés à la voûte (échafaudage manquant).** Les rôles à
secrets déclaraient `serveur_X_password: ""` avec, en commentaire seulement, la
variable de voûte attendue (`{{ vault_X }}`) — sans mapping réel. Résultat : remplir

View file

@ -114,8 +114,15 @@ def ecrire(path: Path = GENERE) -> None:
def _resolu(fichier: Path) -> tuple[dict, dict]:
sortie = subprocess.run(["ansible-inventory", "-i", str(fichier), "--list"],
capture_output=True, text=True, check=True).stdout
cmd = ["ansible-inventory", "-i", str(fichier), "--list"]
# Une voute chiffree (group_vars/all/vault.yml) fait echouer ansible-inventory sans
# mot de passe (exit 4). Si ANSIBLE_VAULT_PASSWORD_FILE n'est pas deja fourni, on
# tente le fichier conventionnel Set-OPS ~/.config/setops-vault-pass.
if not os.environ.get("ANSIBLE_VAULT_PASSWORD_FILE"):
conv = Path.home() / ".config" / "setops-vault-pass"
if conv.is_file():
cmd += ["--vault-password-file", str(conv)]
sortie = subprocess.run(cmd, capture_output=True, text=True, check=True).stdout
data = json.loads(sortie)
hostvars = data.get("_meta", {}).get("hostvars", {})
groupes: dict = {}