administration : nftables et Proxmox admettent les memes sources
Le devis Proxmox ne lisait que nftables_admin_ssh ; nftables y ajoutait le tunnel du locataire. Filtre par Proxmox, Technolibre refusait le SSH de son propre tunnel. Une derivation, tunnel_admin_de, pour les deux. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8804d67dbf
commit
67fd3ab6b7
3 changed files with 33 additions and 12 deletions
|
|
@ -477,8 +477,15 @@ def admin_de(nom_instance: str) -> list[str]:
|
|||
data = yaml.safe_load(fichier.read_text(encoding="utf-8")) or {}
|
||||
if isinstance(data, dict) and data.get("nftables_admin_ssh"):
|
||||
src = data["nftables_admin_ssh"]
|
||||
return [str(s) for s in src] if isinstance(src, list) else [str(src)]
|
||||
return []
|
||||
recus = [str(s) for s in src] if isinstance(src, list) else [str(src)]
|
||||
return sorted(set(recus) | set(_tunnel_de(nom_instance)))
|
||||
return sorted(set(_tunnel_de(nom_instance)))
|
||||
|
||||
|
||||
def _tunnel_de(nom_instance: str) -> list[str]:
|
||||
"""Le tunnel du locataire : MEME derivation que nftables (`tunnel_admin_de`)."""
|
||||
from inventory_rules import tunnel_admin_de
|
||||
return tunnel_admin_de(DOSSIER_INSTANCES / nom_instance)
|
||||
|
||||
|
||||
def admin_tous_tenants() -> list[str]:
|
||||
|
|
|
|||
|
|
@ -751,6 +751,28 @@ def reseau_vpn_locataire(index: int) -> str:
|
|||
return f"10.{int(index)}.29.0/24"
|
||||
|
||||
|
||||
def tunnel_admin_de(base: Path) -> list[str]:
|
||||
"""Le reseau du tunnel d'administration d'UN locataire (dossier `base`), ou [].
|
||||
|
||||
UNE SEULE DERIVATION, DEUX CONSOMMATEURS (2026-09-28). nftables (dans les VM) et le
|
||||
pare-feu de Proxmox (devant elles) doivent admettre les MEMES sources d'administration.
|
||||
nftables ajoutait ce tunnel a l'intrant `nftables_admin_ssh` ; le devis Proxmox, lui,
|
||||
ne lisait que l'intrant. Filtre par Proxmox, Technolibre refusait donc le SSH venu de
|
||||
son propre tunnel, que ses machines, elles, acceptaient.
|
||||
|
||||
AUCUN PAIR ACTIF, AUCUNE SOURCE : ouvrir le SSH a un tunnel que personne n'emprunte
|
||||
n'apporterait rien, sinon une porte.
|
||||
"""
|
||||
try:
|
||||
pairs = charger_acces(base / "plan" / "acces.yml").get("acces_admin_vpn") or {}
|
||||
index = charger_nomenclature(base / "plan" / "nomenclature.yml").get("index")
|
||||
except (OSError, ValueError):
|
||||
return []
|
||||
actifs = [n for n, c in pairs.items()
|
||||
if isinstance(c, dict) and str(c.get("etat", "present")) == "present"]
|
||||
return [reseau_vpn_locataire(index)] if (actifs and index is not None) else []
|
||||
|
||||
|
||||
def port_vpn_locataire(index: int) -> int:
|
||||
return 52000 + int(index)
|
||||
|
||||
|
|
|
|||
|
|
@ -238,16 +238,8 @@ def _tunnel_admin_locataire() -> list[str]:
|
|||
AUCUN PAIR, AUCUNE SOURCE : declarer un reseau que personne n'emprunte ouvrirait le SSH
|
||||
de toutes ses machines a un tunnel qui n'existe pas.
|
||||
"""
|
||||
from inventory_rules import charger_acces, charger_nomenclature, reseau_vpn_locataire
|
||||
base = INSTANCE
|
||||
try:
|
||||
pairs = charger_acces(base / "plan" / "acces.yml").get("acces_admin_vpn") or {}
|
||||
index = charger_nomenclature(base / "plan" / "nomenclature.yml").get("index")
|
||||
except (OSError, ValueError):
|
||||
return []
|
||||
actifs = [n for n, c in pairs.items()
|
||||
if isinstance(c, dict) and str(c.get("etat", "present")) == "present"]
|
||||
return [reseau_vpn_locataire(index)] if (actifs and index is not None) else []
|
||||
from inventory_rules import tunnel_admin_de
|
||||
return tunnel_admin_de(INSTANCE)
|
||||
|
||||
|
||||
def _ip_par_hote(data: dict) -> dict[str, str]:
|
||||
|
|
|
|||
Loading…
Reference in a new issue