SHELL := /usr/bin/env bash export ANSIBLE_HOME ?= $(CURDIR)/.ansible export ANSIBLE_LOCAL_TEMP ?= $(CURDIR)/.ansible/tmp export ANSIBLE_SSH_CONTROL_PATH_DIR ?= $(CURDIR)/.ansible/cp export ANSIBLE_SSH_ARGS ?= -F /dev/null -o ControlMaster=no export SETOPS_INSTANCE ?= instance # Inventaire de l'instance : un seul par instance dans le modèle « séparation par # instance ». Détection rétro-compatible : principal > production > lab. # Surchargeable : make … SETOPS_INVENTAIRE=chemin/hosts.yml SETOPS_INVENTAIRE ?= $(firstword $(wildcard $(SETOPS_INSTANCE)/inventories/principal/hosts.yml) $(wildcard $(SETOPS_INSTANCE)/inventories/production/hosts.yml) $(SETOPS_INSTANCE)/inventories/principal/hosts.yml) export SETOPS_INVENTAIRE # Inventaire « modèle » (construction du golden template) : lab > principal > production. INVENTAIRE_LAB ?= $(firstword $(wildcard $(SETOPS_INSTANCE)/inventories/lab/hosts.yml) $(wildcard $(SETOPS_INSTANCE)/inventories/principal/hosts.yml) $(SETOPS_INSTANCE)/inventories/production/hosts.yml) INVENTAIRE_PRODUCTION ?= $(SETOPS_INVENTAIRE) FICHIER_INVENTAIRE ?= $(SETOPS_INVENTAIRE) FICHIER_DEPENDANCES ?= docs/dependances-groupes.yml GROUPE_MODELE ?= modeles_vm GROUPE_DEBIAN ?= serveur_debian GROUPE_HOTES_ACTIFS ?= hotes_actifs LIMITE ?= $(GROUPE_DEBIAN) HOTE ?= ADRESSE_IP ?= GROUPES ?= $(GROUPE_DEBIAN) GROUPE ?= $(GROUPE_DEBIAN) UTILISATEUR_ANSIBLE ?= ansible VMID_MODELE ?= VMID ?= NOEUD_PROXMOX ?= STOCKAGE_PROXMOX ?= FORMAT_DISQUE ?= TAILLE_DISQUE ?= DISQUE_PROXMOX ?= CIDR ?= 24 PASSERELLE ?= DNS ?= DHCP ?= false CIUSER ?= CLE_SSH_PUBLIQUE ?= PONT_PROXMOX ?= VLAN ?= DEMARRER ?= CLONE_COMPLET ?= CONFIRMER ?= false VERIFICATION ?= false DIFF ?= false ETIQUETTES ?= SAUTER_ETIQUETTES ?= VARIABLES ?= OPTIONS_PLAYBOOK := ifneq ($(LIMITE),) OPTIONS_PLAYBOOK += --limit $(LIMITE) endif ifeq ($(VERIFICATION),true) OPTIONS_PLAYBOOK += --check endif ifeq ($(DIFF),true) OPTIONS_PLAYBOOK += --diff endif ifneq ($(ETIQUETTES),) OPTIONS_PLAYBOOK += --tags $(ETIQUETTES) endif ifneq ($(SAUTER_ETIQUETTES),) OPTIONS_PLAYBOOK += --skip-tags $(SAUTER_ETIQUETTES) endif ifneq ($(VARIABLES),) OPTIONS_PLAYBOOK += -e $(VARIABLES) endif PLAYBOOK_PREPARER_MODELE := playbooks/modeles_vm/debian13_proxmox_preparer.yml PLAYBOOK_VERIFIER_MODELE := playbooks/modeles_vm/debian13_proxmox_verifier.yml PLAYBOOK_NETTOYER_MODELE := playbooks/modeles_vm/debian13_proxmox_nettoyer.yml PLAYBOOK_VERIFIER_HOTE := playbooks/maintenance/verifier_hote_debian.yml PLAYBOOK_PROXMOX_CLONER_VM := playbooks/proxmox/cloner_vm_debian.yml DOSSIER_PLAYBOOKS_GROUPES := playbooks/groupes .DEFAULT_GOAL := aide .PHONY: ansible-runtime ansible-runtime: @mkdir -p "$(ANSIBLE_LOCAL_TEMP)" @mkdir -p "$(ANSIBLE_SSH_CONTROL_PATH_DIR)" .PHONY: _instance-requise _instance-requise: @if [[ ! -f "$(SETOPS_INSTANCE)/plan/serveurs.yml" ]]; then \ printf '%s\n' "Aucune instance configuree : '$(SETOPS_INSTANCE)/plan' introuvable."; \ printf '%s\n' "Demarre avec QUICKSTART.md. En bref :"; \ printf '%s\n' " cp -r exemples/modeles/ ../mon-instance && ln -s ../mon-instance instance"; \ printf '%s\n' " modeles disponibles : $$(ls exemples/modeles 2>/dev/null | grep -v '\.md' | tr '\n' ' ')"; \ exit 2; \ fi .PHONY: aide aide: @printf '%s\n' 'Set-OPS — moteur d ecosystemes numeriques souverains' @printf '%s\n' '' @printf '%s\n' 'Nouveau ? -> QUICKSTART.md (de zero a ton ecosysteme sur Proxmox)' @printf '%s\n' 'Flux: editer le plan -> make instancier -> make instancier-appliquer -> make deployer' @printf '%s\n' '' @printf '%s\n' 'VM' @printf '%s\n' ' Creer une VM (VMID/IP/VLAN/passerelle lus dans le plan):' @printf '%s\n' ' make creer-vm HOTE=web-frontal-01' @printf '%s\n' ' Cloner seulement, sans passer par le plan:' @printf '%s\n' ' make cloner-vm HOTE=web-frontal-01 VMID=95301 VLAN=15 ADRESSE_IP=10.0.2.31 PASSERELLE=10.0.2.1' @printf '%s\n' ' Configurer Proxmox et le Vault API (parametres: docs/config-proxmox.md):' @printf '%s\n' ' make config' @printf '%s\n' '' @printf '%s\n' 'Hotes' @printf '%s\n' ' Planifier/modifier un hote: editer le plan, puis regenerer:' @printf '%s\n' ' editer instance/plan/serveurs.yml (ou la vue Serveurs du GUI)' @printf '%s\n' ' make instancier-appliquer' @printf '%s\n' ' Verifier un deploiement a blanc (dry-run):' @printf '%s\n' ' make verifier-deploiement HOTE=web-frontal-01' @printf '%s\n' ' Remettre un hote en conformite selon ses groupes:' @printf '%s\n' ' make deployer HOTE=web-frontal-01' @printf '%s\n' ' Afficher un hote:' @printf '%s\n' ' make hote-afficher HOTE=web-frontal-01' @printf '%s\n' ' Diagnostiquer:' @printf '%s\n' ' make verifier-hote LIMITE=web-frontal-01' @printf '%s\n' '' @printf '%s\n' 'Groupes' @printf '%s\n' ' Appliquer un groupe complet:' @printf '%s\n' ' make deployer-groupe GROUPE=serveur_debian' @printf '%s\n' ' Convention:' @printf '%s\n' ' groupe serveur_debian -> playbooks/groupes/serveur_debian.yml' @printf '%s\n' '' @printf '%s\n' 'Ecosysteme complet (orchestrateur)' @printf '%s\n' ' Ordre de deploiement (couches + graphe):' @printf '%s\n' ' make site-verifier # valide la coherence couches/graphe' @printf '%s\n' ' python3 scripts/orchestrer.py ordre' @printf '%s\n' ' (Re)generer playbooks/site.yml ordonne:' @printf '%s\n' ' make site' @printf '%s\n' ' CONFIGURER la flotte existante, couche par couche (2b, VM deja creees):' @printf '%s\n' ' make deployer-tout CONFIRMER=true # (MODE_CHECK=1 pour un essai a blanc idempotent)' @printf '%s\n' ' CREER toutes les VM du plan (2a, clone Proxmox):' @printf '%s\n' ' make flotte-creer CONFIRMER=true' @printf '%s\n' ' RECONSTRUIRE from-zero = creer les VM PUIS deployer (2a+2b, VM inexistantes):' @printf '%s\n' ' make reconstruire CONFIRMER=true # alias: make myDay CONFIRMER=true' @printf '%s\n' '' @printf '%s\n' 'Flux reseau (pare-feu / audit)' @printf '%s\n' ' Matrice d audit + apercus nftables resolus (NON actives):' @printf '%s\n' ' make flux # -> docs/registre-flux.md + instance/flux-genere/*.nft' @printf '%s\n' ' make flux-verifier # valide schema + coherence de matrice' @printf '%s\n' '' @printf '%s\n' 'Wiki pedagogique' @printf '%s\n' ' Publier wiki/ dans le wiki Forgejo (source versionnee -> vue browsable):' @printf '%s\n' ' make wiki-publier WIKI_REMOTE=https://forge.//.wiki.git' @printf '%s\n' '' @printf '%s\n' 'Inventaires' @printf '%s\n' ' Graphe de production:' @printf '%s\n' ' make inventaire' @printf '%s\n' ' Graphe explicite:' @printf '%s\n' ' make inventaire-graphe FICHIER_INVENTAIRE=$(SETOPS_INSTANCE)/inventories/production/hosts.yml' @printf '%s\n' ' Verifier les inventaires:' @printf '%s\n' ' make inventaire-verifier' @printf '%s\n' ' Lister les donnees brutes:' @printf '%s\n' ' make inventaire-lister' @printf '%s\n' ' Interface locale de gestion:' @printf '%s\n' ' make inventaire-ui' @printf '%s\n' '' @printf '%s\n' 'Modele Debian 13 Proxmox' @printf '%s\n' ' Construire et verifier:' @printf '%s\n' ' make preparer-modele' @printf '%s\n' ' make verifier-modele' @printf '%s\n' ' Nettoyage final protege:' @printf '%s\n' ' make nettoyer-modele CONFIRMER=true' @printf '%s\n' '' @printf '%s\n' 'Validation' @printf '%s\n' ' make syntaxe' @printf '%s\n' ' make lint' @printf '%s\n' ' make verifier' @printf '%s\n' '' @printf '%s\n' 'Variables frequentes' @printf '%s\n' ' HOTE=web-frontal-01 GROUPE=serveur_debian GROUPES="serveur_debian serveur_durci"' @printf '%s\n' ' VMID=95301 VLAN=15 ADRESSE_IP=10.0.2.31 PASSERELLE=10.0.2.1' @printf '%s\n' ' FICHIER_INVENTAIRE=$(SETOPS_INSTANCE)/inventories/production/hosts.yml FICHIER_DEPENDANCES=docs/dependances-groupes.yml CONFIRMER=true' .PHONY: lint lint: ansible-runtime ansible-lint .PHONY: syntaxe syntaxe-modele syntaxe-nettoyage syntaxe-verification-modele syntaxe-verification-hote syntaxe-groupes syntaxe-proxmox syntaxe: syntaxe-modele syntaxe-verification-modele syntaxe-nettoyage syntaxe-verification-hote syntaxe-groupes syntaxe-proxmox syntaxe-modele: ansible-runtime ansible-playbook -i $(INVENTAIRE_LAB) $(PLAYBOOK_PREPARER_MODELE) --syntax-check syntaxe-verification-modele: ansible-runtime ansible-playbook -i $(INVENTAIRE_LAB) $(PLAYBOOK_VERIFIER_MODELE) --syntax-check syntaxe-nettoyage: ansible-runtime ansible-playbook -i $(INVENTAIRE_LAB) $(PLAYBOOK_NETTOYER_MODELE) --syntax-check syntaxe-verification-hote: ansible-runtime ansible-playbook -i $(INVENTAIRE_PRODUCTION) $(PLAYBOOK_VERIFIER_HOTE) --syntax-check syntaxe-groupes: ansible-runtime @for playbook in $(DOSSIER_PLAYBOOKS_GROUPES)/*.yml; do \ ansible-playbook -i $(INVENTAIRE_PRODUCTION) "$$playbook" --syntax-check; \ done syntaxe-proxmox: ansible-runtime ansible-playbook -i localhost, $(PLAYBOOK_PROXMOX_CLONER_VM) --syntax-check .PHONY: test test: python3 scripts/tests/test_inventory_host.py .PHONY: verifier verifier: lint test inventaire-verifier site-verifier flux-verifier syntaxe python3 scripts/prouver.py --verifier # Harnais de preuve : rejoue les preuves automatisables du registre et ecrit # docs/audit/preuve-.md (piece justificative horodatee, rejouable). # `make verifier` l'appelle en mode --verifier (preuves seules, aucun rapport ecrit). .PHONY: prouver prouver: ansible-runtime _instance-requise python3 scripts/prouver.py .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 instance-utiliser instance-courante inventaire: inventaire-production # Bascule le symlink 'instance' vers un autre dépôt d'instance (séparation par # instance : prod vs bac à sable). Ex. : make instance-utiliser NOM=OPS-Chezlepro-lab instance-utiliser: @if [[ -z "$(NOM)" ]]; then printf '%s\n' "Usage: make instance-utiliser NOM= (ex. OPS-Chezlepro-lab)"; exit 2; fi @if [[ ! -d "../$(NOM)" ]]; then printf '%s\n' "Introuvable: ../$(NOM)"; exit 2; fi @if [[ -e instance && ! -L instance ]]; then printf '%s\n' "Refus: 'instance' existe et n'est pas un symlink."; exit 2; fi @rm -f instance && ln -s "../$(NOM)" instance @printf 'instance -> %s\n' "$$(readlink instance)" instance-courante: @printf 'instance -> %s\n' "$$(readlink instance 2>/dev/null || echo '(non monté)')" config: python3 scripts/config_proxmox.py inventaire-ui: _instance-requise python3 scripts/inventory_gui.py --inventaire $(FICHIER_INVENTAIRE) hote-ajouter hote-planifier hote-groupes: @printf '%s\n' 'Cible depreciee: l inventaire est GENERE depuis le plan, il ne s edite plus a la main.' @printf '%s\n' 'Declare ou modifie l hote dans instance/plan/serveurs.yml (ou la vue Serveurs du GUI), puis :' @printf '%s\n' ' make instancier-appliquer' @printf '%s\n' '(creer-vm lit desormais VMID/IP/VLAN/passerelle directement dans l inventaire genere.)' @exit 2 hote-afficher: ansible-runtime @if [[ -z "$(HOTE)" ]]; then \ printf '%s\n' 'Refus: relancer avec HOTE=nom_hote.'; \ exit 2; \ fi python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) afficher --hote $(HOTE) appliquer: ansible-runtime @if [[ -z "$(GROUPE)" ]]; then \ printf '%s\n' 'Refus: relancer avec GROUPE=nom_groupe.'; \ exit 2; \ fi @if [[ ! -f "$(DOSSIER_PLAYBOOKS_GROUPES)/$(GROUPE).yml" ]]; then \ printf '%s\n' 'Refus: aucun playbook pour ce groupe: $(DOSSIER_PLAYBOOKS_GROUPES)/$(GROUPE).yml'; \ exit 2; \ fi python3 scripts/inventory_host.py --inventaire $(INVENTAIRE_PRODUCTION) --dependances $(FICHIER_DEPENDANCES) verifier-dependances-groupe --groupe $(GROUPE) ansible-playbook -i $(INVENTAIRE_PRODUCTION) "$(DOSSIER_PLAYBOOKS_GROUPES)/$(GROUPE).yml" --limit '$(GROUPE):&$(GROUPE_HOTES_ACTIFS)' deployer: _instance-requise @set -e; \ if [[ -z "$(HOTE)" ]]; then \ printf '%s\n' 'Refus: relancer avec HOTE=nom_hote.'; \ exit 2; \ fi; \ python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) verifier-actif --hote $(HOTE); \ python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) --dependances $(FICHIER_DEPENDANCES) verifier-dependances-hote --hote $(HOTE); \ playbooks="$$(python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) playbooks --hote $(HOTE) --dossier-playbooks $(DOSSIER_PLAYBOOKS_GROUPES))"; \ if [[ -z "$$playbooks" ]]; then \ printf '%s\n' 'Refus: aucun playbook applicable pour HOTE=$(HOTE).'; \ exit 2; \ fi; \ vault_chiffre="$$(grep -rlsIF '$$ANSIBLE_VAULT' $(dir $(INVENTAIRE_PRODUCTION))group_vars 2>/dev/null | head -1 || true)"; \ if [[ -n "$$vault_chiffre" && -z "$${ANSIBLE_VAULT_PASSWORD_FILE:-}" ]]; then \ if [[ -t 0 ]]; then \ read -r -s -p 'Mot de passe du vault Ansible: ' mdp; echo; \ vf="$$(mktemp)"; printf '%s' "$$mdp" > "$$vf"; chmod 600 "$$vf"; \ export ANSIBLE_VAULT_PASSWORD_FILE="$$vf"; \ trap 'rm -f "$$vf"' EXIT; \ else \ printf '%s\n' 'Refus: vault chiffre detecte mais aucun mot de passe (entree non interactive). Fournir ANSIBLE_VAULT_PASSWORD_FILE ou le champ vault de la GUI.'; \ exit 2; \ fi; \ fi; \ $(MAKE) _verifier-acces-hote LIMITE="$(HOTE)"; \ $(MAKE) _verifier-privileges-hote LIMITE="$(HOTE)"; \ for playbook in $$playbooks; do \ ansible-playbook -i $(INVENTAIRE_PRODUCTION) "$$playbook" --limit "$(HOTE)"; \ done; \ $(MAKE) verifier-hote LIMITE="$(HOTE)" .PHONY: site site-verifier deployer-tout site: ansible-runtime python3 scripts/orchestrer.py ecrire ansible-playbook -i $(INVENTAIRE_PRODUCTION) playbooks/site.yml --syntax-check site-verifier: python3 scripts/orchestrer.py verifier .PHONY: flux flux-verifier flux: ansible-runtime python3 scripts/resoudre_flux.py registre python3 scripts/resoudre_flux.py nftables .PHONY: devis-reseau devis-reseau: ansible-runtime ## Devis switch (VLANs/SVIs/ACLs) du reseau converge, derive des nomenclatures python3 scripts/devis_reseau.py flux-verifier: python3 scripts/resoudre_flux.py verifier .PHONY: valider valider: ansible-runtime ansible-playbook -i $(INVENTAIRE_PRODUCTION) playbooks/valider.yml .PHONY: wiki-publier wiki-publier: @set -e; \ if [[ -z "$(WIKI_REMOTE)" ]]; then \ printf '%s\n' 'Refus: URL du wiki Forgejo requise.'; \ printf '%s\n' 'Ex: make wiki-publier WIKI_REMOTE=https://forge.//.wiki.git'; \ exit 2; \ fi; \ src="$(CURDIR)/wiki"; \ tmp="$$(mktemp -d)"; \ trap 'rm -rf "$$tmp"' EXIT; \ printf '%s\n' "Clonage du wiki: $(WIKI_REMOTE)"; \ if ! git clone --quiet --depth 1 "$(WIKI_REMOTE)" "$$tmp/wiki"; then \ printf '%s\n' 'Echec du clone (URL ou acces ?). Le wiki doit exister (creer une 1re page dans Forgejo).'; \ exit 1; \ fi; \ find "$$tmp/wiki" -maxdepth 1 -name '*.md' -delete; \ for f in "$$src"/*.md; do \ bn="$$(basename "$$f")"; \ [[ "$$bn" == "README.md" ]] && continue; \ cp "$$f" "$$tmp/wiki/$$bn"; \ done; \ cd "$$tmp/wiki"; \ if [[ -z "$$(git status --porcelain)" ]]; then \ printf '%s\n' 'Wiki deja a jour (aucun changement).'; \ exit 0; \ fi; \ git add -A; \ sha="$$(git -C "$(CURDIR)" rev-parse --short HEAD 2>/dev/null || echo inconnu)"; \ git commit --quiet -m "Publication du wiki depuis le depot (source: $$sha)"; \ git push --quiet; \ printf '%s\n' 'Wiki publie.' deployer-tout: _instance-requise @set -e; \ if [[ "$(CONFIRMER)" != "true" ]]; then \ printf '%s\n' 'Refus: deploiement ORCHESTRE de TOUTE la flotte (action impactante).'; \ printf '%s\n' 'Relancer avec CONFIRMER=true. Astuce: tester d abord en idempotent avec MODE_CHECK=1.'; \ exit 2; \ fi; \ python3 scripts/orchestrer.py verifier; \ python3 scripts/orchestrer.py ecrire; \ vault_chiffre="$$(grep -rlsIF '$$ANSIBLE_VAULT' $(dir $(INVENTAIRE_PRODUCTION))group_vars 2>/dev/null | head -1 || true)"; \ if [[ -n "$$vault_chiffre" && -z "$${ANSIBLE_VAULT_PASSWORD_FILE:-}" ]]; then \ if [[ -t 0 ]]; then \ read -r -s -p 'Mot de passe du vault Ansible: ' mdp; echo; \ vf="$$(mktemp)"; printf '%s' "$$mdp" > "$$vf"; chmod 600 "$$vf"; \ export ANSIBLE_VAULT_PASSWORD_FILE="$$vf"; \ trap 'rm -f "$$vf"' EXIT; \ else \ printf '%s\n' 'Refus: vault chiffre detecte mais aucun mot de passe (entree non interactive). Fournir ANSIBLE_VAULT_PASSWORD_FILE ou le champ vault de la GUI.'; \ exit 2; \ fi; \ fi; \ $(MAKE) _verifier-acces-hote LIMITE="$(GROUPE_HOTES_ACTIFS)"; \ $(MAKE) _verifier-privileges-hote LIMITE="$(GROUPE_HOTES_ACTIFS)"; \ mode="$$([[ -n "$(MODE_CHECK)" ]] && printf -- '--check --diff' || true)"; \ ansible-playbook -i $(INVENTAIRE_PRODUCTION) playbooks/site.yml --limit "$(GROUPE_HOTES_ACTIFS)" $$mode # --- Reconstruction from-zero : creer TOUTES les VM (2a) puis deployer (2b) --- .PHONY: flotte-creer flotte-creer: _instance-requise @set -e; \ if [[ "$(CONFIRMER)" != "true" ]]; then \ printf '%s\n' 'Refus: creation de TOUTES les VM actives du plan (clone Proxmox).'; \ printf '%s\n' 'Relancer avec CONFIRMER=true.'; \ exit 2; \ fi; \ hotes="$$(python3 scripts/inventory_host.py --inventaire $(INVENTAIRE_PRODUCTION) lister-actifs)"; \ if [[ -z "$$hotes" ]]; then printf '%s\n' 'Refus: aucun hote actif dans le plan.'; exit 2; fi; \ for h in $$hotes; do \ printf '\n=== Creation VM: %s ===\n' "$$h"; \ $(MAKE) creer-vm HOTE="$$h"; \ done; \ printf '\nToutes les VM actives sont creees.\n' .PHONY: _attendre-flotte _attendre-flotte: ansible-runtime @set -e; \ max="$${ATTENTE_MAX:-600}"; deadline=$$(( $$(date +%s) + max )); \ printf 'Attente que la flotte reponde en SSH (max %ss)...\n' "$$max"; \ until ansible -i $(INVENTAIRE_PRODUCTION) $(GROUPE_HOTES_ACTIFS) -m ping -e ansible_become=false >/dev/null 2>&1; do \ if (( $$(date +%s) > deadline )); then printf 'Timeout: flotte injoignable apres %ss.\n' "$$max"; exit 1; fi; \ sleep 10; \ done; \ printf 'Flotte joignable.\n' .PHONY: reconstruire reconstruire: _instance-requise @set -e; \ if [[ "$(CONFIRMER)" != "true" ]]; then \ printf '%s\n' 'Refus: RECONSTRUCTION — cree les VM manquantes (2a) PUIS deploie tout (2b).'; \ printf '%s\n' 'Idempotent : une VM deja presente est sautee (clone par nom), le deploiement converge.'; \ printf '%s\n' 'Relancer avec CONFIRMER=true.'; \ exit 2; \ fi; \ $(MAKE) flotte-creer CONFIRMER=true; \ $(MAKE) _attendre-flotte; \ $(MAKE) deployer-tout CONFIRMER=true # « Go ahead, make my day. » — LE bouton rouge : alias de reconstruire (Clint Eastwood). # Cree toutes les VM puis deploie tout, en une commande. Garde CONFIRMER=true. .PHONY: myDay myDay: reconstruire deployer-groupe: @if [[ -z "$(GROUPE)" ]]; then \ printf '%s\n' 'Refus: relancer avec GROUPE=nom_groupe.'; \ exit 2; \ fi $(MAKE) appliquer GROUPE="$(GROUPE)" .PHONY: verifier-deploiement verifier-deploiement: ansible-runtime @set -e; \ if [[ -z "$(HOTE)" ]]; then \ printf '%s\n' 'Refus: relancer avec HOTE=nom_hote.'; \ exit 2; \ fi; \ python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) verifier-actif --hote $(HOTE); \ python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) --dependances $(FICHIER_DEPENDANCES) verifier-dependances-hote --hote $(HOTE); \ playbooks="$$(python3 scripts/inventory_host.py --inventaire $(FICHIER_INVENTAIRE) playbooks --hote $(HOTE) --dossier-playbooks $(DOSSIER_PLAYBOOKS_GROUPES))"; \ if [[ -z "$$playbooks" ]]; then \ printf '%s\n' 'Refus: aucun playbook applicable pour HOTE=$(HOTE).'; \ exit 2; \ fi; \ vault_chiffre="$$(grep -rlsIF '$$ANSIBLE_VAULT' $(dir $(INVENTAIRE_PRODUCTION))group_vars 2>/dev/null | head -1 || true)"; \ if [[ -n "$$vault_chiffre" && -z "$${ANSIBLE_VAULT_PASSWORD_FILE:-}" ]]; then \ if [[ -t 0 ]]; then \ read -r -s -p 'Mot de passe du vault Ansible: ' mdp; echo; \ vf="$$(mktemp)"; printf '%s' "$$mdp" > "$$vf"; chmod 600 "$$vf"; \ export ANSIBLE_VAULT_PASSWORD_FILE="$$vf"; \ trap 'rm -f "$$vf"' EXIT; \ else \ printf '%s\n' 'Refus: vault chiffre detecte mais aucun mot de passe (entree non interactive). Fournir ANSIBLE_VAULT_PASSWORD_FILE ou le champ vault de la GUI.'; \ exit 2; \ fi; \ fi; \ for playbook in $$playbooks; do \ ansible-playbook -i $(INVENTAIRE_PRODUCTION) "$$playbook" --limit "$(HOTE)" --check --diff; \ done cloner-vm: ansible-runtime @if [[ -z "$(HOTE)" || -z "$(VMID)" ]]; then \ printf '%s\n' 'Refus: relancer avec HOTE=nom VMID=id_clone.'; \ exit 2; \ fi @if [[ -z "$(VLAN)" ]]; then \ printf '%s\n' 'Refus: relancer avec VLAN=id_vlan.'; \ exit 2; \ fi @if ! [[ "$(VLAN)" =~ ^[0-9]+$$ ]] || (( 10#$(VLAN) < 1 || 10#$(VLAN) > 4094 )); then \ printf '%s\n' 'Refus: VLAN doit etre un nombre entre 1 et 4094.'; \ exit 2; \ fi @if [[ -n "$(CLE_SSH_PUBLIQUE)" && ! -f "$(CLE_SSH_PUBLIQUE)" ]]; then \ printf '%s\n' 'Refus: cle publique SSH introuvable: $(CLE_SSH_PUBLIQUE)'; \ exit 2; \ fi @if [[ "$(DHCP)" != "true" && ( -z "$(ADRESSE_IP)" || -z "$(CIDR)" || -z "$(PASSERELLE)" ) ]]; then \ printf '%s\n' 'Refus: fournir ADRESSE_IP, CIDR et PASSERELLE, ou utiliser DHCP=true.'; \ exit 2; \ fi @ipconfig='ip=dhcp'; \ if [[ "$(DHCP)" != "true" ]]; then \ ipconfig='ip=$(ADRESSE_IP)/$(CIDR),gw=$(PASSERELLE)'; \ fi; \ extra_vars=( \ -e proxmox_clone_nom="$(HOTE)" \ -e proxmox_clone_vmid="$(VMID)" \ -e proxmox_clone_ipconfig0="$$ipconfig" \ ); \ [[ -n "$(VMID_MODELE)" ]] && extra_vars+=( -e proxmox_clone_vmid_modele="$(VMID_MODELE)" ); \ [[ -n "$(NOEUD_PROXMOX)" ]] && extra_vars+=( -e proxmox_clone_noeud="$(NOEUD_PROXMOX)" ); \ [[ -n "$(STOCKAGE_PROXMOX)" ]] && extra_vars+=( -e proxmox_clone_stockage="$(STOCKAGE_PROXMOX)" ); \ [[ -n "$(FORMAT_DISQUE)" ]] && extra_vars+=( -e proxmox_clone_format="$(FORMAT_DISQUE)" ); \ [[ -n "$(CLONE_COMPLET)" ]] && extra_vars+=( -e proxmox_clone_complet="$(CLONE_COMPLET)" ); \ [[ -n "$(TAILLE_DISQUE)" ]] && extra_vars+=( -e proxmox_clone_taille_disque="$(TAILLE_DISQUE)" ); \ [[ -n "$(COEURS)" ]] && extra_vars+=( -e proxmox_clone_coeurs="$(COEURS)" ); \ [[ -n "$(MEMOIRE)" ]] && extra_vars+=( -e proxmox_clone_memoire="$(MEMOIRE)" ); \ [[ -n "$(DISQUE_PROXMOX)" ]] && extra_vars+=( -e proxmox_clone_disque="$(DISQUE_PROXMOX)" ); \ [[ -n "$(DNS)" ]] && extra_vars+=( -e proxmox_clone_dns="$(DNS)" ); \ [[ -n "$(CIUSER)" ]] && extra_vars+=( -e proxmox_clone_ciuser="$(CIUSER)" ); \ [[ -n "$(CLE_SSH_PUBLIQUE)" ]] && extra_vars+=( -e proxmox_clone_cle_publique_fichier="$(CLE_SSH_PUBLIQUE)" ); \ [[ -n "$(PONT_PROXMOX)" ]] && extra_vars+=( -e proxmox_clone_pont="$(PONT_PROXMOX)" ); \ extra_vars+=( -e proxmox_clone_vlan="$(VLAN)" ); \ [[ -n "$(DEMARRER)" ]] && extra_vars+=( -e proxmox_clone_demarrer="$(DEMARRER)" ); \ vault_args=(); \ vault_file=""; \ for d in lab principal production; do \ for gv in group_vars/all/vault.yml group_vars/proxmox.vault.yml; do \ f="$(SETOPS_INSTANCE)/inventories/$$d/$$gv"; \ [[ -f "$$f" ]] && vault_file="$$f" && break 2; \ done; \ done; \ if [[ -n "$$vault_file" && -f "$$vault_file" ]]; then \ read -r premiere_ligne < "$$vault_file" || true; \ case "$$premiere_ligne" in \ '$$ANSIBLE_VAULT'*) \ if [[ -z "$${ANSIBLE_VAULT_PASSWORD_FILE:-}" ]]; then \ vault_args+=( --ask-vault-pass ); \ fi; \ ;; \ esac; \ fi; \ ansible-playbook -i localhost, $(PLAYBOOK_PROXMOX_CLONER_VM) "$${vault_args[@]}" "$${extra_vars[@]}" creer-vm: _instance-requise @set -e; \ if [[ -z "$(HOTE)" ]]; then \ printf '%s\n' 'Refus: relancer avec HOTE=nom_hote (declare dans le plan).'; \ exit 2; \ fi; \ params="$$(python3 scripts/inventory_host.py --inventaire $(INVENTAIRE_PRODUCTION) parametres-proxmox --hote $(HOTE))"; \ eval "$$params"; \ $(MAKE) cloner-vm \ HOTE="$(HOTE)" \ VMID="$$SETOPS_VMID" \ ADRESSE_IP="$$SETOPS_IP" \ CIDR="$$SETOPS_CIDR" \ PASSERELLE="$$SETOPS_PASSERELLE" \ VLAN="$$SETOPS_VLAN" \ STOCKAGE_PROXMOX="$${SETOPS_STOCKAGE:-$(STOCKAGE_PROXMOX)}" \ TAILLE_DISQUE="$${SETOPS_DISQUE:-$(TAILLE_DISQUE)}" \ COEURS="$${SETOPS_COEURS:-$(COEURS)}" \ MEMOIRE="$${SETOPS_MEMOIRE:-$(MEMOIRE)}" \ NOEUD_PROXMOX="$${SETOPS_NOEUD:-$(NOEUD_PROXMOX)}" \ VMID_MODELE="$(VMID_MODELE)" \ FORMAT_DISQUE="$(FORMAT_DISQUE)" \ DISQUE_PROXMOX="$(DISQUE_PROXMOX)" \ DNS="$(DNS)" \ DHCP="$(DHCP)" \ CIUSER="$(CIUSER)" \ CLE_SSH_PUBLIQUE="$(CLE_SSH_PUBLIQUE)" \ PONT_PROXMOX="$(PONT_PROXMOX)" \ DEMARRER="$(DEMARRER)" \ CLONE_COMPLET="$(CLONE_COMPLET)" inventaire-verifier: ansible-runtime _instance-requise ansible-inventory -i $(INVENTAIRE_LAB) --list > /dev/null ansible-inventory -i $(INVENTAIRE_PRODUCTION) --list > /dev/null python3 scripts/inventory_host.py --inventaire $(INVENTAIRE_PRODUCTION) verifier-playbooks --dossier-playbooks $(DOSSIER_PLAYBOOKS_GROUPES) python3 scripts/inventory_host.py --inventaire $(INVENTAIRE_PRODUCTION) --dependances $(FICHIER_DEPENDANCES) verifier-dependances --dossier-playbooks $(DOSSIER_PLAYBOOKS_GROUPES) python3 scripts/verifier_gui.py python3 scripts/serveurs.py verifier python3 scripts/applications.py verifier python3 scripts/bases_donnees.py verifier python3 scripts/domaines.py verifier .PHONY: bases bases-verifier domaines domaines-verifier applications applications-verifier applications-bootstrap serveurs serveurs-verifier serveurs-bootstrap serveurs: python3 scripts/serveurs.py lister serveurs-verifier: python3 scripts/serveurs.py verifier serveurs-bootstrap: python3 scripts/serveurs.py bootstrap .PHONY: instancier instancier-appliquer instancier: _instance-requise python3 scripts/instancier.py generer python3 scripts/instancier.py comparer instancier-appliquer: _instance-requise python3 scripts/instancier.py appliquer $(if $(FORCE),--force) bases: python3 scripts/bases_donnees.py lister bases-verifier: python3 scripts/bases_donnees.py verifier domaines: python3 scripts/domaines.py lister domaines-verifier: python3 scripts/domaines.py verifier applications: python3 scripts/applications.py lister applications-verifier: python3 scripts/applications.py verifier applications-bootstrap: python3 scripts/applications.py bootstrap inventaire-lister: ansible-runtime ansible-inventory -i $(FICHIER_INVENTAIRE) --list inventaire-graphe: ansible-runtime ansible-inventory -i $(FICHIER_INVENTAIRE) --graph inventaire-hote: ansible-runtime @if [[ -z "$(HOTE)" ]]; then \ printf '%s\n' 'Refus: relancer avec HOTE=nom_hote.'; \ exit 2; \ fi ansible-inventory -i $(FICHIER_INVENTAIRE) --host $(HOTE) inventaire-lab: $(MAKE) inventaire-graphe FICHIER_INVENTAIRE="$(INVENTAIRE_LAB)" inventaire-production: $(MAKE) inventaire-graphe FICHIER_INVENTAIRE="$(INVENTAIRE_PRODUCTION)" .PHONY: _verifier-acces-modele _verifier-privileges-modele preparer-modele verifier-modele nettoyer-modele _verifier-acces-modele: ansible-runtime ansible -i $(INVENTAIRE_LAB) $(GROUPE_MODELE) -m ping -e ansible_become=false _verifier-privileges-modele: ansible-runtime ansible -i $(INVENTAIRE_LAB) $(GROUPE_MODELE) -b -m command -a "whoami" preparer-modele: ansible-runtime _verifier-acces-modele _verifier-privileges-modele ansible-playbook -i $(INVENTAIRE_LAB) $(PLAYBOOK_PREPARER_MODELE) verifier-modele: ansible-runtime ansible-playbook -i $(INVENTAIRE_LAB) $(PLAYBOOK_VERIFIER_MODELE) nettoyer-modele: ansible-runtime @if [[ "$(CONFIRMER)" != "true" ]]; then \ printf '%s\n' 'Refus: relancer avec CONFIRMER=true pour le nettoyage final du modele.'; \ exit 2; \ fi ansible-playbook -i $(INVENTAIRE_LAB) $(PLAYBOOK_NETTOYER_MODELE) -e template_cleanup_confirm=true .PHONY: _verifier-acces-hote _verifier-privileges-hote faits verifier-hote _verifier-acces-hote: ansible-runtime ansible -i $(INVENTAIRE_PRODUCTION) $(LIMITE) -m ping -e ansible_become=false _verifier-privileges-hote: ansible-runtime ansible -i $(INVENTAIRE_PRODUCTION) $(LIMITE) -b -m command -a "whoami" faits: ansible-runtime ansible -i $(INVENTAIRE_PRODUCTION) $(LIMITE) -m setup -a "filter=ansible_distribution*" verifier-hote: ansible-runtime ansible-playbook -i $(INVENTAIRE_PRODUCTION) $(PLAYBOOK_VERIFIER_HOTE) $(OPTIONS_PLAYBOOK)