Set-OPS-Public/scripts/tests/test_relais_du_site.py
Daniel Allaire 92a396b3fe forge du site : ses courriels partent, par le relais du site
La forge nommait infra-mail-01 en dur comme relais : une machine de
locataire, absente du site. Elle derive maintenant son relais du groupe
serveur_postfix. Le relais du site admet les machines dont un role declare
un flux vers lui, lues dans le registre des flux (aujourd'hui la forge).

Deploye au site ; un courriel de mot de passe oublie est arrive et a servi.
Aussi : forge-comptes ne compte plus de changement en mode plan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:57:43 -04:00

65 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""La forge du site trouve son relais de courriel, et le relais la laisse passer.
POURQUOI (2026-10-12). « Mot de passe oublie » sur la forge du site n'a jamais remis un
courriel. Deux defauts, chacun suffisant :
1. `serveur_forgejo_smtp` valait `infra-mail-01.<domaine>` en dur : la machine des boites
d'un locataire, absente du site ;
2. le relais du site (`mynetworks`) n'admettait que sa boucle locale.
"""
from __future__ import annotations
import sys
from pathlib import Path
RACINE = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(RACINE / "scripts"))
import site_inventaire as si # noqa: E402
from resoudre_flux import charger_flux # noqa: E402
def main() -> int:
echecs: list[str] = []
# 1. La forge ne nomme plus de machine : elle lit le groupe du relais.
defauts = (RACINE / "roles/serveur_forgejo/defaults/main.yml").read_text(encoding="utf-8")
ligne = next((l for l in defauts.splitlines() if l.startswith("serveur_forgejo_smtp:")), "")
bloc = defauts[defauts.find(ligne):].split("\n\n")[0]
if "infra-mail-01" in bloc or "groups['serveur_postfix']" not in bloc:
echecs.append("serveur_forgejo_smtp ne derive pas du groupe `serveur_postfix`")
# 2. Le relais admet les emetteurs declares, et eux seuls (pur).
serveurs = {"forge": {"ip": "10.0.33.11"}, "edge": {"ip": "10.0.37.11"},
"mon": {"ip": "10.0.36.11"}, "vieille": {"ip": "10.0.33.99", "etat": "retire"}}
groupes = {"forge": {"serveur_forgejo"}, "edge": {"serveur_nginx"},
"mon": {"serveur_postfix", "serveur_icinga"}, "vieille": {"serveur_forgejo"}}
obtenu = si.reseaux_confiance_relais(serveurs, lambda n: groupes[n], charger_flux()).split()
if obtenu != ["127.0.0.0/8", "[::1]/128", "10.0.33.11/32"]:
echecs.append(f"reseaux_confiance_relais = {obtenu}, attendu boucle + la forge seule")
# 3. Sur le site monte, s'il l'est : la machine du relais admet sa forge.
try:
inv = si.inventaire()
except Exception: # noqa: BLE001 — aucun site monte : la partie pure suffit
inv = {}
hv = (inv.get("_meta") or {}).get("hostvars") or {}
relais = (inv.get("serveur_postfix") or {}).get("hosts") or []
forges = (inv.get("serveur_forgejo") or {}).get("hosts") or []
for r in relais:
confiance = str((hv.get(r) or {}).get("serveur_postfix_reseaux_confiance") or "").split()
for f in forges:
ip = f"{(hv.get(f) or {}).get('ansible_host')}/32"
if ip not in confiance:
echecs.append(f"{r} n'admet pas sa forge {f} ({ip}) : {confiance}")
for e in echecs:
print(f"ECHEC : {e}")
if not echecs:
print(f"OK : la forge lit son relais ; le relais admet ses emetteurs declares"
f"{' (site monte verifie)' if relais else ''}.")
return 1 if echecs else 0
if __name__ == "__main__":
raise SystemExit(main())