From 72c3ac6007f120236b421496d308bd5a4bed87ac Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Sun, 21 Jun 2026 20:47:44 -0400 Subject: [PATCH] Consolider le flux operationnel des inventaires --- AGENTS.md | 5 ++- CHANGELOG.md | 16 ++++++++ Makefile | 21 +++++++--- README.md | 10 ++++- docs/nomenclature-vm.md | 12 ++++++ docs/vm-lifecycle.md | 16 ++++++-- inventories/lab/hosts.yml | 6 --- inventories/production/hosts.yml | 4 -- scripts/inventory_gui.py | 40 +++++++++++++----- scripts/inventory_host.py | 70 ++++++++++++++++++++++++++++---- scripts/inventory_rules.py | 22 ++++++++++ 11 files changed, 180 insertions(+), 42 deletions(-) create mode 100644 scripts/inventory_rules.py diff --git a/AGENTS.md b/AGENTS.md index 407abd3..8140cac 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -256,7 +256,7 @@ Les cibles d'exploitation des VM doivent privilégier les groupes : ```text make deployer HOTE=web-01 make deployer-groupe GROUPE=serveurs_debian -make appliquer GROUPE=serveurs_debian +make hote-planifier HOTE=obs-01 VMID=94101 GROUPES="serveurs_debian serveurs_durcis serveurs_prometheus" ``` Éviter les cibles parallèles qui réappliquent les mêmes rôles par couche, par exemple `make socle`, `make durcissement`, `make converger` ou `make deployer-vm`. @@ -336,7 +336,8 @@ clients_ldap clients_supervision clients_metriques serveurs_web -serveurs_bases_donnees +serveurs_postgresql +serveurs_prometheus ``` Ne pas cibler `all` par défaut pour un playbook qui ne s'applique pas réellement à tous les hôtes. diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e0da0d..be5d5fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # CHANGELOG — Set-OPS +## 2026-06-22 + +### Ajouté +- Ajout de `make hote-planifier` pour renseigner un hôte, son VMID et ses groupes sans création ni déploiement immédiat. +- Ajout de `scripts/inventory_rules.py` pour centraliser les règles partagées entre la gestion CLI et l'interface locale d'inventaire. + +### Modifié +- Renforcement de la validation d'inventaire : + - un hôte doit être soit planifié, soit actif, mais pas les deux ; + - un hôte actif doit avoir `ansible_host` ; + - un hôte doit porter au moins un groupe opérationnel ; + - les VMID dupliqués sont refusés. +- Conservation du VMID dans l'inventaire lors de `make creer-vm` et `make hote-ajouter`. +- Alignement de l'aide Makefile et de la documentation sur le flux opérateur : planifier, activer/créer, déployer. +- Retrait des groupes génériques obsolètes `serveurs_bases_donnees` et `serveurs_supervision` au profit des groupes de services précis. + ## 2026-06-21 ### Ajouté diff --git a/Makefile b/Makefile index 2a85933..115f17f 100644 --- a/Makefile +++ b/Makefile @@ -95,12 +95,14 @@ aide: @printf '%s\n' ' make config' @printf '%s\n' '' @printf '%s\n' 'Hotes' + @printf '%s\n' ' Planifier un hote sans le deployer:' + @printf '%s\n' ' make hote-planifier HOTE=obs-01 VMID=94101 GROUPES="serveurs_debian serveurs_durcis serveurs_prometheus serveurs_loki"' @printf '%s\n' ' Remettre un hote en conformite selon ses groupes:' @printf '%s\n' ' make deployer HOTE=web-01' @printf '%s\n' ' Afficher un hote:' @printf '%s\n' ' make hote-afficher HOTE=web-01' @printf '%s\n' ' Ajouter un hote existant:' - @printf '%s\n' ' make hote-ajouter HOTE=web-01 ADRESSE_IP=192.168.12.101 GROUPES="serveurs_debian serveurs_durcis"' + @printf '%s\n' ' make hote-ajouter HOTE=web-01 VMID=99101 ADRESSE_IP=192.168.12.101 GROUPES="serveurs_debian serveurs_durcis"' @printf '%s\n' ' Modifier ses groupes:' @printf '%s\n' ' make hote-groupes HOTE=web-01 GROUPES="serveurs_debian serveurs_durcis"' @printf '%s\n' ' Diagnostiquer:' @@ -109,8 +111,6 @@ aide: @printf '%s\n' 'Groupes' @printf '%s\n' ' Appliquer un groupe complet:' @printf '%s\n' ' make deployer-groupe GROUPE=serveurs_debian' - @printf '%s\n' ' Rejouer directement le playbook d un groupe:' - @printf '%s\n' ' make appliquer GROUPE=serveurs_debian' @printf '%s\n' ' Convention:' @printf '%s\n' ' groupe serveurs_debian -> playbooks/groupes/serveurs_debian.yml' @printf '%s\n' '' @@ -173,7 +173,7 @@ syntaxe-proxmox: ansible-runtime .PHONY: verifier verifier: lint inventaire-verifier syntaxe -.PHONY: inventaire hote-ajouter hote-groupes hote-afficher appliquer deployer deployer-groupe cloner-vm creer-vm config inventaire-ui inventaire-verifier inventaire-lister inventaire-graphe inventaire-hote inventaire-lab inventaire-production +.PHONY: inventaire hote-planifier hote-ajouter hote-groupes hote-afficher appliquer deployer deployer-groupe cloner-vm creer-vm config inventaire-ui inventaire-verifier inventaire-lister inventaire-graphe inventaire-hote inventaire-lab inventaire-production inventaire: inventaire-production config: @@ -187,7 +187,16 @@ hote-ajouter: ansible-runtime printf '%s\n' 'Refus: relancer avec HOTE=nom_hote ADRESSE_IP=adresse_ip.'; \ exit 2; \ fi - python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) ajouter --hote $(HOTE) --adresse-ip $(ADRESSE_IP) --utilisateur-ansible $(UTILISATEUR_ANSIBLE) --groupes "$(GROUPES)" --dossier-playbooks $(DOSSIER_PLAYBOOKS_GROUPES) + python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) ajouter --hote $(HOTE) --adresse-ip $(ADRESSE_IP) --utilisateur-ansible $(UTILISATEUR_ANSIBLE) --vmid "$(VMID)" --groupes "$(GROUPES)" --dossier-playbooks $(DOSSIER_PLAYBOOKS_GROUPES) + $(MAKE) inventaire-verifier + $(MAKE) hote-afficher HOTE="$(HOTE)" FICHIER_INVENTAIRE="$(FICHIER_INVENTAIRE)" + +hote-planifier: ansible-runtime + @if [[ -z "$(HOTE)" ]]; then \ + printf '%s\n' 'Refus: relancer avec HOTE=nom_hote GROUPES="groupe1 groupe2".'; \ + exit 2; \ + fi + python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) ajouter --hote $(HOTE) --vmid "$(VMID)" --groupes "$(GROUPES)" --dossier-playbooks $(DOSSIER_PLAYBOOKS_GROUPES) $(MAKE) inventaire-verifier $(MAKE) hote-afficher HOTE="$(HOTE)" FICHIER_INVENTAIRE="$(FICHIER_INVENTAIRE)" @@ -307,7 +316,7 @@ creer-vm: exit 2; \ fi $(MAKE) cloner-vm HOTE="$(HOTE)" VMID_MODELE="$(VMID_MODELE)" VMID="$(VMID)" NOEUD_PROXMOX="$(NOEUD_PROXMOX)" STOCKAGE_PROXMOX="$(STOCKAGE_PROXMOX)" FORMAT_DISQUE="$(FORMAT_DISQUE)" TAILLE_DISQUE="$(TAILLE_DISQUE)" DISQUE_PROXMOX="$(DISQUE_PROXMOX)" ADRESSE_IP="$(ADRESSE_IP)" CIDR="$(CIDR)" PASSERELLE="$(PASSERELLE)" DNS="$(DNS)" DHCP="$(DHCP)" CIUSER="$(CIUSER)" CLE_SSH_PUBLIQUE="$(CLE_SSH_PUBLIQUE)" PONT_PROXMOX="$(PONT_PROXMOX)" VLAN="$(VLAN)" DEMARRER="$(DEMARRER)" CLONE_COMPLET="$(CLONE_COMPLET)" - $(MAKE) hote-ajouter HOTE="$(HOTE)" ADRESSE_IP="$(ADRESSE_IP)" GROUPES="$(GROUPES)" FICHIER_INVENTAIRE="$(FICHIER_INVENTAIRE)" + $(MAKE) hote-ajouter HOTE="$(HOTE)" ADRESSE_IP="$(ADRESSE_IP)" VMID="$(VMID)" GROUPES="$(GROUPES)" FICHIER_INVENTAIRE="$(FICHIER_INVENTAIRE)" inventaire-verifier: ansible-runtime ansible-inventory -i $(INVENTAIRE_LAB) --list > /dev/null diff --git a/README.md b/README.md index a7b677e..234a5fc 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,16 @@ Ouvrir l'interface locale de gestion d'inventaire : make inventaire-ui ``` +Planifier une VM sans la créer ni la déployer : + +```bash +make hote-planifier HOTE=obs-01 VMID=94101 GROUPES="serveurs_debian serveurs_durcis serveurs_prometheus serveurs_loki" +``` + Ajouter une VM à l'inventaire production et l'associer aux groupes qui détermineront sa configuration : ```bash -make hote-ajouter HOTE=web-01 ADRESSE_IP=192.168.12.101 GROUPES="serveurs_debian serveurs_durcis" +make hote-ajouter HOTE=web-01 VMID=99101 ADRESSE_IP=192.168.12.101 GROUPES="serveurs_debian serveurs_durcis" make hote-groupes HOTE=web-01 GROUPES="serveurs_debian serveurs_durcis" ``` @@ -117,3 +123,5 @@ Déployer ou remettre en conformité un groupe : ```bash make deployer-groupe GROUPE=serveurs_debian ``` + +Les déploiements de groupes ciblent automatiquement les hôtes actifs seulement. diff --git a/docs/nomenclature-vm.md b/docs/nomenclature-vm.md index e330542..7062ab8 100644 --- a/docs/nomenclature-vm.md +++ b/docs/nomenclature-vm.md @@ -61,6 +61,18 @@ Les hôtes prévus mais non encore déployés sont placés dans `hotes_planifies Les hôtes réellement joignables par Ansible sont placés dans `hotes_actifs`. +Planifier un hôte : + +```bash +make hote-planifier HOTE=obs-01 VMID=94101 GROUPES="serveurs_debian serveurs_durcis serveurs_prometheus serveurs_loki" +``` + +Activer un hôte existant ou déjà cloné : + +```bash +make hote-ajouter HOTE=obs-01 VMID=94101 ADRESSE_IP=192.168.12.141 GROUPES="serveurs_debian serveurs_durcis serveurs_prometheus serveurs_loki" +``` + Les déploiements groupés limitent automatiquement l'exécution à : ```text diff --git a/docs/vm-lifecycle.md b/docs/vm-lifecycle.md index 8aaf4eb..6bee7ee 100644 --- a/docs/vm-lifecycle.md +++ b/docs/vm-lifecycle.md @@ -100,6 +100,10 @@ Cloud-init ne remplace pas Ansible pour la configuration réelle du serveur. Une VM déployée doit être placée dans les groupes d'inventaire qui décrivent l'état voulu. +Les hôtes prévus mais non créés restent dans `hotes_planifies`. + +Les hôtes joignables par Ansible sont dans `hotes_actifs`. + Chaque groupe opérationnel doit avoir un playbook homonyme : ```text @@ -114,14 +118,16 @@ web-01 dans serveurs_debian -> applique le socle Debian web-01 dans serveurs_durcis -> applique le durcissement commun ``` -Un groupe sans playbook ne doit pas être assigné à une VM de production tant que son rôle n'est pas implémenté. +Un groupe sans playbook ne doit pas être assigné à une VM de production. + +Un playbook de groupe peut être un contrat temporaire sans rôle tant que le service n'est pas encore implémenté. Il doit rester idempotent et explicite. ## 6. Socle Debian Le groupe `serveurs_debian` maintient les composants de base : ```bash -make appliquer GROUPE=serveurs_debian +make deployer-groupe GROUPE=serveurs_debian ``` ## 7. Hardening commun @@ -129,7 +135,7 @@ make appliquer GROUPE=serveurs_debian Le groupe `serveurs_durcis` maintient les couches de sécurité communes : ```bash -make appliquer GROUPE=serveurs_durcis +make deployer-groupe GROUPE=serveurs_durcis ``` L'accès SSH par mot de passe est désactivé dès le socle. L'activation de nftables doit rester dépendante des règles réseau propres au rôle du serveur. @@ -139,7 +145,7 @@ L'accès SSH par mot de passe est désactivé dès le socle. L'activation de nft Pour une VM déjà clonée et démarrée : ```bash -make hote-ajouter HOTE=web-01 ADRESSE_IP=192.168.12.101 GROUPES="serveurs_debian serveurs_durcis" +make hote-ajouter HOTE=web-01 VMID=99101 ADRESSE_IP=192.168.12.101 GROUPES="serveurs_debian serveurs_durcis" make deployer HOTE=web-01 ``` @@ -159,6 +165,8 @@ Pour converger un groupe complet : make deployer-groupe GROUPE=serveurs_debian ``` +Cette commande limite le playbook au croisement entre le groupe demandé et `hotes_actifs`. + ## 9. Variables template et conformité Les variables du template servent à construire le golden template dans `inventories/lab/group_vars/modeles_vm.yml`. diff --git a/inventories/lab/hosts.yml b/inventories/lab/hosts.yml index 3393077..eb8e21a 100644 --- a/inventories/lab/hosts.yml +++ b/inventories/lab/hosts.yml @@ -16,11 +16,5 @@ all: serveurs_web: hosts: {} - serveurs_bases_donnees: - hosts: {} - - serveurs_supervision: - hosts: {} - hotes_proxmox: hosts: {} diff --git a/inventories/production/hosts.yml b/inventories/production/hosts.yml index 18d3e7e..73f240e 100644 --- a/inventories/production/hosts.yml +++ b/inventories/production/hosts.yml @@ -74,10 +74,6 @@ all: web-02: ansible_host: 192.168.12.102 ansible_user: ansible - serveurs_bases_donnees: - hosts: {} - serveurs_supervision: - hosts: {} serveurs_keycloak: hosts: idm-01: {} diff --git a/scripts/inventory_gui.py b/scripts/inventory_gui.py index 3972518..af499d4 100644 --- a/scripts/inventory_gui.py +++ b/scripts/inventory_gui.py @@ -11,12 +11,17 @@ from urllib.parse import urlparse import yaml +from inventory_rules import ( + GROUPE_HOTES_ACTIFS, + GROUPE_HOTES_PLANIFIES, + GROUPES_ETAT_HOTE, + est_groupe_operationnel, + groupes_operationnels_connus, +) RACINE = Path(__file__).resolve().parents[1] INVENTAIRE_DEFAUT = RACINE / "inventories/production/hosts.yml" DOSSIER_PLAYBOOKS_GROUPES = RACINE / "playbooks/groupes" -GROUPES_OPERATIONNELS_PREFIXES = ("serveurs_", "clients_") -GROUPES_ETAT = ("hotes_actifs", "hotes_planifies") def charger_yaml(path: Path) -> dict: @@ -41,9 +46,7 @@ def enfants(data: dict) -> dict: def groupes_disponibles(data: dict) -> list[str]: - groupes = set(enfants(data)) - groupes.update(playbook.stem for playbook in DOSSIER_PLAYBOOKS_GROUPES.glob("*.yml")) - return sorted(group for group in groupes if group.startswith(GROUPES_OPERATIONNELS_PREFIXES)) + return groupes_operationnels_connus(enfants(data), DOSSIER_PLAYBOOKS_GROUPES) def variables_hote(data: dict, hote: str) -> dict: @@ -65,15 +68,21 @@ def liste_hotes(data: dict) -> list[dict]: for nom in sorted(noms): groupes = [] etat = "planifie" + visible = False for groupe, groupe_data in enfants(data).items(): if nom not in groupe_data.get("hosts", {}): continue - if groupe == "hotes_actifs": + if groupe == GROUPE_HOTES_ACTIFS: etat = "actif" - elif groupe in GROUPES_ETAT: + visible = True + elif groupe in GROUPES_ETAT_HOTE: + visible = True continue - elif groupe.startswith(GROUPES_OPERATIONNELS_PREFIXES): + elif est_groupe_operationnel(groupe): groupes.append(groupe) + visible = True + if not visible: + continue variables = variables_hote(data, nom) hotes.append( { @@ -114,8 +123,8 @@ def donnees_hote(hote: dict) -> dict: def construire_inventaire(payload: dict, groupes_connus: list[str]) -> dict: enfants_data: dict = { "modeles_vm": {"hosts": {}}, - "hotes_actifs": {"hosts": {}}, - "hotes_planifies": {"hosts": {}}, + GROUPE_HOTES_ACTIFS: {"hosts": {}}, + GROUPE_HOTES_PLANIFIES: {"hosts": {}}, } for groupe in groupes_connus: enfants_data.setdefault(groupe, {"hosts": {}}) @@ -126,7 +135,7 @@ def construire_inventaire(payload: dict, groupes_connus: list[str]) -> dict: if not nom: continue variables = donnees_hote(hote) - groupe_etat = "hotes_actifs" if hote.get("etat") == "actif" else "hotes_planifies" + groupe_etat = GROUPE_HOTES_ACTIFS if hote.get("etat") == "actif" else GROUPE_HOTES_PLANIFIES enfants_data[groupe_etat]["hosts"][nom] = variables for groupe in hote.get("groupes", []): if groupe not in groupes_connus: @@ -138,6 +147,7 @@ def construire_inventaire(payload: dict, groupes_connus: list[str]) -> dict: def valider_payload(payload: dict, groupes_connus: list[str]) -> None: noms: set[str] = set() + vmids: dict[str, str] = {} for hote in payload.get("hotes", []): nom = str(hote.get("nom", "")).strip() if not nom: @@ -145,12 +155,20 @@ def valider_payload(payload: dict, groupes_connus: list[str]) -> None: if nom in noms: raise ValueError(f"Hote en double: {nom}") noms.add(nom) + if hote.get("etat") == "actif" and not str(hote.get("adresse_ip", "")).strip(): + raise ValueError(f"Hote actif sans adresse IP: {nom}") groupes = hote.get("groupes", []) if not groupes: raise ValueError(f"Aucun groupe operationnel pour: {nom}") inconnus = sorted(set(groupes) - set(groupes_connus)) if inconnus: raise ValueError(f"Groupes inconnus pour {nom}: {', '.join(inconnus)}") + vmid = str(hote.get("vmid", "")).strip() + if not vmid: + continue + if vmid in vmids: + raise ValueError(f"VMID en double: {vmid} pour {vmids[vmid]} et {nom}") + vmids[vmid] = nom HTML = r""" diff --git a/scripts/inventory_host.py b/scripts/inventory_host.py index 845b224..5314ea7 100644 --- a/scripts/inventory_host.py +++ b/scripts/inventory_host.py @@ -9,11 +9,12 @@ import sys import yaml - -GROUPES_OPERATIONNELS_PREFIXES = ("serveurs_", "clients_") -GROUPE_HOTES_ACTIFS = "hotes_actifs" -GROUPE_HOTES_PLANIFIES = "hotes_planifies" -GROUPES_ETAT_HOTE = {GROUPE_HOTES_ACTIFS, GROUPE_HOTES_PLANIFIES} +from inventory_rules import ( + GROUPE_HOTES_ACTIFS, + GROUPE_HOTES_PLANIFIES, + GROUPES_ETAT_HOTE, + est_groupe_operationnel, +) def charger_inventaire(path: Path) -> dict: @@ -61,6 +62,13 @@ def variables_hote(data: dict, host: str) -> dict: return merged +def tous_les_hotes(data: dict) -> list[str]: + hosts: set[str] = set() + for group_data in enfants(data).values(): + hosts.update(group_data.get("hosts", {})) + return sorted(hosts) + + def groupes_hote(data: dict, host: str) -> list[str]: groups: list[str] = [] for group, group_data in enfants(data).items(): @@ -74,12 +82,21 @@ def retirer_hote_de_tous_les_groupes(data: dict, host: str) -> None: group_data.get("hosts", {}).pop(host, None) -def ajouter_hote(data: dict, host: str, groups: list[str], ip: str | None, ansible_user: str | None) -> None: +def ajouter_hote( + data: dict, + host: str, + groups: list[str], + ip: str | None, + ansible_user: str | None, + vmid: str | None, +) -> None: vars_for_host = variables_hote(data, host) if ip: vars_for_host["ansible_host"] = ip if ansible_user: vars_for_host["ansible_user"] = ansible_user + if vmid: + vars_for_host["proxmox_vmid"] = int(vmid) if vmid.isdigit() else vmid for group in groups: assurer_groupe(data, group)["hosts"][host] = dict(vars_for_host) @@ -87,6 +104,9 @@ def ajouter_hote(data: dict, host: str, groups: list[str], ip: str | None, ansib if ip: assurer_groupe(data, GROUPE_HOTES_ACTIFS)["hosts"][host] = dict(vars_for_host) assurer_groupe(data, GROUPE_HOTES_PLANIFIES)["hosts"].pop(host, None) + else: + assurer_groupe(data, GROUPE_HOTES_PLANIFIES)["hosts"][host] = dict(vars_for_host) + assurer_groupe(data, GROUPE_HOTES_ACTIFS)["hosts"].pop(host, None) def definir_groupes_hote(data: dict, host: str, groups: list[str]) -> None: @@ -136,7 +156,7 @@ def afficher_playbooks_hote(data: dict, host: str, playbook_dir: Path) -> None: playbooks: list[Path] = [] for group in groups: - if not group.startswith(GROUPES_OPERATIONNELS_PREFIXES): + if not est_groupe_operationnel(group): continue playbook = playbook_dir / f"{group}.yml" if playbook.exists(): @@ -161,6 +181,36 @@ def verifier_hote_actif(data: dict, host: str) -> None: raise ValueError(f"Hote non actif dans l'inventaire: {host}") +def verifier_coherence_hotes(data: dict) -> None: + vmids: dict[str, str] = {} + + for host in tous_les_hotes(data): + groups = groupes_hote(data, host) + state_groups = [group for group in groups if group in GROUPES_ETAT_HOTE] + operational_groups = [group for group in groups if est_groupe_operationnel(group)] + vars_for_host = variables_hote(data, host) + + if not state_groups and not operational_groups: + continue + if len(state_groups) != 1: + raise ValueError( + f"{host} doit appartenir exactement a un groupe d'etat: " + f"{GROUPE_HOTES_ACTIFS} ou {GROUPE_HOTES_PLANIFIES}" + ) + if not operational_groups: + raise ValueError(f"{host} doit appartenir a au moins un groupe operationnel.") + if GROUPE_HOTES_ACTIFS in state_groups and not vars_for_host.get("ansible_host"): + raise ValueError(f"{host} est actif mais n'a pas ansible_host.") + + vmid = vars_for_host.get("proxmox_vmid") + if vmid in (None, ""): + continue + vmid_key = str(vmid) + if vmid_key in vmids and vmids[vmid_key] != host: + raise ValueError(f"VMID en double: {vmid_key} pour {vmids[vmid_key]} et {host}") + vmids[vmid_key] = host + + def verifier_playbooks_groupes(data: dict, playbook_dir: Path) -> None: missing_playbooks: list[str] = [] @@ -168,7 +218,7 @@ def verifier_playbooks_groupes(data: dict, playbook_dir: Path) -> None: hosts = group_data.get("hosts", {}) if not hosts: continue - if not group.startswith(GROUPES_OPERATIONNELS_PREFIXES): + if not est_groupe_operationnel(group): continue playbook = playbook_dir / f"{group}.yml" if not playbook.exists(): @@ -178,6 +228,8 @@ def verifier_playbooks_groupes(data: dict, playbook_dir: Path) -> None: missing = ", ".join(sorted(missing_playbooks)) raise ValueError(f"Playbook de groupe manquant pour: {missing}") + verifier_coherence_hotes(data) + def main() -> int: parser = argparse.ArgumentParser(description="Gere les hotes d'un inventaire Ansible statique Set-OPS.") @@ -190,6 +242,7 @@ def main() -> int: add_parser.add_argument("--groupes", required=True) add_parser.add_argument("--adresse-ip") add_parser.add_argument("--utilisateur-ansible") + add_parser.add_argument("--vmid") add_parser.add_argument("--dossier-playbooks", type=Path) groups_parser = subparsers.add_parser("definir-groupes", help="Remplace l'appartenance aux groupes pour un hote.") @@ -225,6 +278,7 @@ def main() -> int: analyser_groupes(args.groupes), args.adresse_ip, args.utilisateur_ansible, + args.vmid, ) if args.dossier_playbooks: verifier_playbooks_groupes(data, args.dossier_playbooks) diff --git a/scripts/inventory_rules.py b/scripts/inventory_rules.py new file mode 100644 index 0000000..799ce1d --- /dev/null +++ b/scripts/inventory_rules.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +"""Regles partagees pour les inventaires statiques Set-OPS.""" + +from __future__ import annotations + +from pathlib import Path + + +GROUPES_OPERATIONNELS_PREFIXES = ("serveurs_", "clients_") +GROUPE_HOTES_ACTIFS = "hotes_actifs" +GROUPE_HOTES_PLANIFIES = "hotes_planifies" +GROUPES_ETAT_HOTE = {GROUPE_HOTES_ACTIFS, GROUPE_HOTES_PLANIFIES} + + +def est_groupe_operationnel(groupe: str) -> bool: + return groupe.startswith(GROUPES_OPERATIONNELS_PREFIXES) + + +def groupes_operationnels_connus(enfants: dict, dossier_playbooks: Path) -> list[str]: + groupes = set(enfants) + groupes.update(playbook.stem for playbook in dossier_playbooks.glob("*.yml")) + return sorted(groupe for groupe in groupes if est_groupe_operationnel(groupe))