alliance-boreale/docs/architecture/scripts_migration.sh
Dan Allaire e704e1cc39
Some checks failed
CI / yaml-lint (push) Has been cancelled
CI / ssot-export (push) Has been cancelled
CI / tests (push) Has been cancelled
CI / docs (push) Has been cancelled
normes et nomenclature mnémotechnique
2025-10-21 11:09:16 -04:00

1248 lines
No EOL
34 KiB
Bash

#!/bin/bash
################################################################################
# Scripts de Migration et d'Audit - Nomenclature v2.0
# L'Alliance Boréale
#
# Version: 1.0
# Date: 21 octobre 2025
# Licence: AGPL-3.0
#
# DESCRIPAM_FILE="/etc/alliance-boreale/ipam.txt"
DNS_OUTPUT="/var/lib/alliance-boreale/dns-records.zone"
INVENTORY_OUTPUT="/var/lib/alliance-boreale/inventory.yml"
CONFIG
# Créer répertoires de travail
mkdir -p /var/lib/alliance-boreale
mkdir -p /var/log/alliance-boreale
# Source configuration dans les scripts
echo "source /etc/alliance-boreale/nomenclature.conf" >> ~/.bashrc
echo "✅ Configuration créée: /etc/alliance-boreale/nomenclature.conf"
echo "✅ Répertoires créés: /var/lib/alliance-boreale"
echo ""
echo "Scripts installés:"
echo " - audit-nomenclature.sh"
echo " - generate-dns-records.sh"
echo " - generate-inventory.sh"
echo " - migrate-vm.sh"
echo " - validate-vmid.sh"
echo " - allocate-ip.sh"
echo ""
echo "Usage:"
echo " audit-nomenclature.sh # Audit de conformité"
echo " generate-dns-records.sh # Génération DNS"
echo " generate-inventory.sh # Génération inventaire"
echo " migrate-vm.sh <src> <dst> <nom> <ip> # Migration VM"
echo " validate-vmid.sh <vmid> # Validation VMID"
echo " allocate-ip.sh <tenant-id> # Allocation IP"
echo ""
echo "======================================================"
echo "Installation terminée!"
echo "======================================================"
INSTALL
chmod +x /usr/local/bin/install-nomenclature-tools.sh
################################################################################
# DOCUMENTATION
################################################################################
cat > /usr/local/share/doc/nomenclature-v2-scripts.md << 'DOC'
# Documentation Scripts Nomenclature v2.0
## L'Alliance Boréale
## Installation
```bash
# Exécuter le script d'installation
sudo /usr/local/bin/install-nomenclature-tools.sh
# Ou installer manuellement
sudo cp *.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/*.sh
```
## Configuration
Fichier: `/etc/alliance-boreale/nomenclature.conf`
```bash
MEMBER_ID="czp"
DNS_DOMAIN="alliance-boreale.ca"
IPAM_FILE="/etc/alliance-boreale/ipam.txt"
```
## Scripts Disponibles
### 1. audit-nomenclature.sh
**Description:** Audit complet de conformité des VMs au standard v2.0
**Usage:**
```bash
audit-nomenclature.sh
```
**Sortie:**
- Rapport console avec couleurs
- CSV détaillé: `/tmp/audit-nomenclature-YYYYMMDD-HHMMSS.csv`
- Exit code: 0 si conforme, 1 si non-conforme
**Exemple:**
```bash
$ audit-nomenclature.sh
======================================================
AUDIT DE CONFORMITÉ - NOMENCLATURE v2.0
Membre: czp
Date: 2025-10-21 14:30:00
======================================================
✅ CONFORME | VMID: 02001 | Nom: czp-infra-dns-master-prod-01 | IP: 10.0.2.10
❌ NON CONFORME | VMID: 104 | Nom: old-vm-web | IP: 10.50.100.5
→ VMID invalide; Nom invalide; IP invalide;
======================================================
RÉSUMÉ
======================================================
Total VMs : 25
Conformes : 20
Non conformes : 5
Taux de conformité: 80.0%
======================================================
```
### 2. generate-dns-records.sh
**Description:** Génère les enregistrements DNS zone file à partir de Proxmox
**Usage:**
```bash
generate-dns-records.sh > dns-records.zone
```
**Variables:**
```bash
MEMBER="czp" # ID membre
DNS_DOMAIN="alliance-boreale.ca" # Domaine
DNS_OUTPUT="/tmp/dns-records-${MEMBER}.zone" # Fichier sortie
```
**Exemple:**
```bash
$ generate-dns-records.sh
; DNS Records for czp.alliance-boreale.ca
; Generated on Mon Oct 21 14:30:00 2025
; Standard Nomenclature v2.0
; ======================================================
; INFRASTRUCTURE (Couches 1-4)
; ======================================================
dns-master.infra.czp.alliance-boreale.ca. IN A 10.0.2.10
dns-slave1.infra.czp.alliance-boreale.ca. IN A 10.0.2.11
ansible.infra.czp.alliance-boreale.ca. IN A 10.0.1.10
git.infra.czp.alliance-boreale.ca. IN A 10.0.1.20
; ======================================================
; TENANTS (Couches 5-8)
; ======================================================
web.t001.czp.alliance-boreale.ca. IN A 10.0.10.1
db.t001.czp.alliance-boreale.ca. IN A 10.0.10.2
```
### 3. generate-inventory.sh
**Description:** Génère l'inventaire Ansible YAML à partir de Proxmox
**Usage:**
```bash
generate-inventory.sh
```
**Sortie:** `/tmp/inventory-${MEMBER}.yml`
**Exemple:**
```bash
$ generate-inventory.sh
Inventaire généré: /tmp/inventory-czp.yml
$ cat /tmp/inventory-czp.yml
---
# Ansible Inventory - czp
# Generated on Mon Oct 21 14:30:00 2025
all:
vars:
member_id: czp
domain: alliance-boreale.ca
children:
infrastructure:
children:
layer_2:
hosts:
dns-master.infra.czp.alliance-boreale.ca:
ansible_host: 10.0.2.10
vmid: 02001
layer: 2
service: dns-master
environment: prod
```
### 4. migrate-vm.sh
**Description:** Migre une VM vers le nouveau standard (VMID, nom, IP)
**Usage:**
```bash
migrate-vm.sh <vmid-source> <vmid-dest> <nouveau-nom> <nouvelle-ip>
```
**Options:**
```bash
DRY_RUN=true # Mode simulation (pas de changement réel)
```
**Exemple:**
```bash
# Simulation
$ DRY_RUN=true migrate-vm.sh 104 10001 czp-t001-web-prod-01 10.0.10.1
# Migration réelle
$ migrate-vm.sh 104 10001 czp-t001-web-prod-01 10.0.10.1
======================================================
MIGRATION VM - NOMENCLATURE v2.0
======================================================
VMID source : 104
VMID dest : 10001
Nouveau nom : czp-t001-web-prod-01
Nouvelle IP : 10.0.10.1
Mode simulation: false
======================================================
État actuel:
Nom: old-vm-web
IP : 10.50.100.5
Nouvel état:
Nom: czp-t001-web-prod-01
IP : 10.0.10.1
Continuer? (oui/non): oui
Étapes de migration:
1. Création backup...
✓ Backup créé
2. Arrêt de la VM...
✓ VM arrêtée
3. Clonage vers nouveau VMID...
✓ VM clonée
4. Configuration nouvelle IP...
✓ IP configurée dans Proxmox
⚠ ATTENTION: Modifier aussi l'IP dans la VM
5. Démarrage nouvelle VM...
✓ VM démarrée
======================================================
MIGRATION TERMINÉE
======================================================
Prochaines étapes MANUELLES:
1. Vérifier que la VM démarre correctement
2. Connecter à la VM et changer l'IP
3. Tester la connectivité réseau
4. Créer l'entrée DNS
5. Mettre à jour l'inventaire Ansible
6. Une fois validé: qm destroy 104
```
### 5. validate-vmid.sh
**Description:** Valide qu'un VMID respecte le standard v2.0
**Usage:**
```bash
validate-vmid.sh <vmid>
```
**Exemples:**
```bash
$ validate-vmid.sh 02001
✅ VMID VALIDE
Type: Infrastructure
Couche: 2
Type service: 00
Instance: 01
Description: Couche 2 - Réseau
$ validate-vmid.sh 10001
✅ VMID VALIDE
Type: Tenant
Tenant ID: 001
Instance: 01
$ validate-vmid.sh 99999
❌ VMID INVALIDE
Format attendu:
Infrastructure: 0CTTII (ex: 02001)
Tenant: TTTII (ex: 10001)
```
### 6. allocate-ip.sh
**Description:** Alloue la prochaine IP disponible pour un tenant
**Usage:**
```bash
allocate-ip.sh <tenant-id>
```
**Fichier IPAM:** `/etc/alliance-boreale/ipam.txt`
**Exemple:**
```bash
$ allocate-ip.sh 001
✅ IP DISPONIBLE: 10.0.10.1
Pour allouer cette IP:
echo "001 10.0.10.1 2025-10-21 10001" >> /etc/alliance-boreale/ipam.txt
$ allocate-ip.sh 002
Tenant 002 a déjà des IPs allouées:
002 10.0.10.10 2025-10-20 20001
002 10.0.10.11 2025-10-20 20002
✅ IP DISPONIBLE: 10.0.10.12
```
## Workflow de Migration Complet
### Étape 1: Audit Initial
```bash
# Générer rapport de conformité
audit-nomenclature.sh
# Identifier les VMs non conformes
grep "NON CONFORME" /tmp/audit-nomenclature-*.csv
```
### Étape 2: Planification
```bash
# Pour chaque VM non conforme, déterminer:
# - Nouveau VMID (validate-vmid.sh)
# - Nouveau nom
# - Nouvelle IP (allocate-ip.sh si tenant)
# Exemple de plan:
cat > migration-plan.txt << EOF
# Plan de Migration - Nomenclature v2.0
VMID_SRC | VMID_DST | Nom Actuel | Nouveau Nom | IP Actuelle | Nouvelle IP
---------|----------|-----------------|--------------------------------|--------------|-------------
104 | 10001 | old-vm-web | czp-t001-web-prod-01 | 10.50.100.5 | 10.0.10.1
105 | 10011 | web-api | czp-t001-api-prod-01 | 10.50.100.6 | 10.0.10.3
200 | 04001 | ansible-server | czp-infra-ansible-ctrl-prod-01| 10.0.1.100 | 10.0.1.10
EOF
```
### Étape 3: Migration par Lots
```bash
# Lot 1: VMs non-critiques (dev/staging)
DRY_RUN=true migrate-vm.sh 104 10001 czp-t001-web-prod-01 10.0.10.1
# Valider sortie, puis:
migrate-vm.sh 104 10001 czp-t001-web-prod-01 10.0.10.1
# Lot 2: Services d'infrastructure
migrate-vm.sh 200 04001 czp-infra-ansible-ctrl-prod-01 10.0.1.10
# Lot 3: Services critiques (planifier fenêtre maintenance)
migrate-vm.sh 100 02001 czp-infra-dns-master-prod-01 10.0.2.10
```
### Étape 4: Validation Post-Migration
```bash
# Vérifier conformité
audit-nomenclature.sh
# Régénérer DNS
generate-dns-records.sh > /var/lib/alliance-boreale/dns-records.zone
# Régénérer inventaire
generate-inventory.sh
# Tester connectivité
ansible all -m ping -i /var/lib/alliance-boreale/inventory.yml
```
### Étape 5: Nettoyage
```bash
# Supprimer anciennes VMs (après validation complète)
qm destroy 104
qm destroy 105
qm destroy 200
# Archiver anciens backups
mv /var/lib/vz/dump/vzdump-qemu-104-*.zst /backup/archive/
```
## Automatisation
### Cron Job - Audit Quotidien
```bash
# /etc/cron.daily/audit-nomenclature
#!/bin/bash
/usr/local/bin/audit-nomenclature.sh > /var/log/alliance-boreale/audit-$(date +%Y%m%d).log 2>&1
```
### Cron Job - Génération DNS Hebdomadaire
```bash
# /etc/cron.weekly/generate-dns
#!/bin/bash
/usr/local/bin/generate-dns-records.sh > /var/lib/alliance-boreale/dns-records.zone
/usr/local/bin/generate-inventory.sh
```
## Intégration CI/CD
### GitLab CI - Validation Pre-Deployment
```yaml
# .gitlab-ci.yml
stages:
- validate
validate_vmid:
stage: validate
script:
- validate-vmid.sh ${NEW_VMID}
only:
- merge_requests
```
## Troubleshooting
### Problème: Audit échoue
```bash
# Vérifier que qm est accessible
qm list
# Vérifier permissions
ls -la /usr/local/bin/audit-nomenclature.sh
# Exécuter en mode debug
bash -x /usr/local/bin/audit-nomenclature.sh
```
### Problème: Migration échoue
```bash
# Vérifier espace disque
df -h
# Vérifier état VM source
qm status <vmid-source>
# Consulter logs Proxmox
tail -f /var/log/pve/tasks/active
```
### Problème: IP déjà allouée
```bash
# Consulter IPAM
cat /etc/alliance-boreale/ipam.txt
# Rechercher IP spécifique
grep "10.0.10.1" /etc/alliance-boreale/ipam.txt
# Forcer allocation nouvelle plage
# Éditer manuellement ipam.txt
```
## Support
**Documentation complète:** https://docs.alliance-boreale.ca/nomenclature-v2
**Dépôt Git:** https://forge.alliance-boreale.ca/tools/nomenclature-scripts
**Contact:** technique@alliance-boreale.ca
---
**Licence:** AGPL-3.0
**Version:** 1.0
**Dernière mise à jour:** 21 octobre 2025
DOC
################################################################################
# FIN DU FICHIER
################################################################################
echo ""
echo "======================================================"
echo "SCRIPTS DE MIGRATION ET D'AUDIT - v1.0"
echo "L'Alliance Boréale"
echo "======================================================"
echo ""
echo "✅ 6 scripts créés:"
echo " 1. audit-nomenclature.sh"
echo " 2. generate-dns-records.sh"
echo " 3. generate-inventory.sh"
echo " 4. migrate-vm.sh"
echo " 5. validate-vmid.sh"
echo " 6. allocate-ip.sh"
echo ""
echo "✅ Script d'installation créé:"
echo " - install-nomenclature-tools.sh"
echo ""
echo "✅ Documentation créée:"
echo " - /usr/local/share/doc/nomenclature-v2-scripts.md"
echo ""
echo "Pour installer:"
echo " sudo bash install-nomenclature-tools.sh"
echo ""
echo "======================================================"TION:
# Collection de scripts pour auditer et migrer les VMs vers le standard v2.0
#
# SCRIPTS INCLUS:
# 1. audit-nomenclature.sh - Audit de conformité
# 2. generate-dns-records.sh - Génération enregistrements DNS
# 3. generate-inventory.sh - Génération inventaire Ansible
# 4. migrate-vm.sh - Migration d'une VM
# 5. validate-vmid.sh - Validation format VMID
# 6. allocate-ip.sh - Allocation IP tenant
################################################################################
################################################################################
# SCRIPT 1: audit-nomenclature.sh
# Vérifie la conformité des VMs au standard v2.0
################################################################################
cat > /usr/local/bin/audit-nomenclature.sh << 'AUDIT_SCRIPT'
#!/bin/bash
# audit-nomenclature.sh - Audit de conformité nomenclature v2.0
set -euo pipefail
# Configuration
MEMBER_ID="${MEMBER_ID:-czp}"
REPORT_FILE="/tmp/audit-nomenclature-$(date +%Y%m%d-%H%M%S).txt"
REPORT_CSV="/tmp/audit-nomenclature-$(date +%Y%m%d-%H%M%S).csv"
# Couleurs
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Compteurs
TOTAL=0
CONFORME=0
NON_CONFORME=0
echo "======================================================"
echo "AUDIT DE CONFORMITÉ - NOMENCLATURE v2.0"
echo "Membre: ${MEMBER_ID}"
echo "Date: $(date)"
echo "======================================================"
echo ""
# En-tête CSV
echo "VMID,Nom,IP,Conforme_VMID,Conforme_Nom,Conforme_IP,Statut_Global,Commentaires" > "$REPORT_CSV"
# Fonction de validation VMID
validate_vmid() {
local vmid=$1
# Infrastructure: 0[1-4][0-9]{3}
if [[ $vmid =~ ^0[1-4][0-9]{3}$ ]]; then
echo "infra"
return 0
fi
# Tenant: [1-9][0-9]{4}
if [[ $vmid =~ ^[1-9][0-9]{4}$ ]]; then
echo "tenant"
return 0
fi
echo "invalid"
return 1
}
# Fonction de validation nom
validate_name() {
local name=$1
local vmid_type=$2
if [ "$vmid_type" = "infra" ]; then
# Format: <membre>-infra-<type>-<env>-<instance>
if [[ $name =~ ^[a-z]+-infra-[a-z0-9-]+-[a-z]+-[0-9]{2}$ ]]; then
return 0
fi
elif [ "$vmid_type" = "tenant" ]; then
# Format: <membre>-t[0-9]{3}-<type>-<env>-<instance>
if [[ $name =~ ^[a-z]+-t[0-9]{3}-[a-z0-9-]+-[a-z]+-[0-9]{2}$ ]]; then
return 0
fi
fi
return 1
}
# Fonction de validation IP
validate_ip() {
local ip=$1
local vmid_type=$2
if [ "$vmid_type" = "infra" ]; then
# Infrastructure: 10.0.0.0 - 10.0.23.255
if [[ $ip =~ ^10\.0\.(0|1|2|20|21|22|23)\. ]]; then
return 0
fi
elif [ "$vmid_type" = "tenant" ]; then
# Tenant: 10.0.10.0/23 ou 10.0.128.0/17
if [[ $ip =~ ^10\.0\.(10|11)\. ]] || [[ $ip =~ ^10\.0\.(12[8-9]|1[3-9][0-9]|2[0-4][0-9]|25[0-5])\. ]]; then
return 0
fi
fi
return 1
}
# Boucle sur toutes les VMs
for vmid in $(qm list | awk 'NR>1 {print $1}'); do
TOTAL=$((TOTAL + 1))
# Récupérer les informations
name=$(qm config "$vmid" 2>/dev/null | grep "^name:" | awk '{print $2}' || echo "NO_NAME")
ip=$(qm config "$vmid" 2>/dev/null | grep "ipconfig0" | sed 's/.*ip=\([^,/]*\).*/\1/' || echo "NO_IP")
# Validation
vmid_type=$(validate_vmid "$vmid" || echo "invalid")
conforme_vmid="NON"
conforme_nom="NON"
conforme_ip="NON"
statut="❌ NON CONFORME"
commentaires=""
if [ "$vmid_type" != "invalid" ]; then
conforme_vmid="OUI"
else
commentaires="${commentaires}VMID invalide; "
fi
if validate_name "$name" "$vmid_type"; then
conforme_nom="OUI"
else
commentaires="${commentaires}Nom invalide; "
fi
if validate_ip "$ip" "$vmid_type"; then
conforme_ip="OUI"
else
commentaires="${commentaires}IP invalide; "
fi
# Statut global
if [ "$conforme_vmid" = "OUI" ] && [ "$conforme_nom" = "OUI" ] && [ "$conforme_ip" = "OUI" ]; then
statut="✅ CONFORME"
CONFORME=$((CONFORME + 1))
else
NON_CONFORME=$((NON_CONFORME + 1))
fi
# Affichage
if [ "$statut" = "✅ CONFORME" ]; then
echo -e "${GREEN}${statut}${NC} | VMID: $vmid | Nom: $name | IP: $ip"
else
echo -e "${RED}${statut}${NC} | VMID: $vmid | Nom: $name | IP: $ip"
echo -e " ${YELLOW}→ ${commentaires}${NC}"
fi
# Export CSV
echo "$vmid,$name,$ip,$conforme_vmid,$conforme_nom,$conforme_ip,$statut,$commentaires" >> "$REPORT_CSV"
done
echo ""
echo "======================================================"
echo "RÉSUMÉ"
echo "======================================================"
echo "Total VMs : $TOTAL"
echo -e "${GREEN}Conformes : $CONFORME${NC}"
echo -e "${RED}Non conformes : $NON_CONFORME${NC}"
echo ""
echo "Taux de conformité: $(awk "BEGIN {printf \"%.1f\", ($CONFORME/$TOTAL)*100}")%"
echo ""
echo "Rapport détaillé: $REPORT_CSV"
echo "======================================================"
# Exit code basé sur conformité
if [ "$NON_CONFORME" -gt 0 ]; then
exit 1
else
exit 0
fi
AUDIT_SCRIPT
chmod +x /usr/local/bin/audit-nomenclature.sh
################################################################################
# SCRIPT 2: generate-dns-records.sh
# Génère les enregistrements DNS à partir de l'inventaire Proxmox
################################################################################
cat > /usr/local/bin/generate-dns-records.sh << 'DNS_SCRIPT'
#!/bin/bash
# generate-dns-records.sh - Génération enregistrements DNS
set -euo pipefail
# Configuration
MEMBER="${MEMBER_ID:-czp}"
DOMAIN="${DNS_DOMAIN:-alliance-boreale.ca}"
OUTPUT_FILE="${DNS_OUTPUT:-/tmp/dns-records-${MEMBER}.zone}"
echo "; DNS Records for ${MEMBER}.${DOMAIN}"
echo "; Generated on $(date)"
echo "; Standard Nomenclature v2.0"
echo ""
# Infrastructure (Couches 1-4)
echo "; ======================================================"
echo "; INFRASTRUCTURE (Couches 1-4)"
echo "; ======================================================"
for vmid in $(qm list | grep -E "0[1-4][0-9]{3}" | awk '{print $1}'); do
name=$(qm config "$vmid" 2>/dev/null | grep "^name:" | awk '{print $2}' || continue)
ip=$(qm config "$vmid" 2>/dev/null | grep "ipconfig0" | sed 's/.*ip=\([^,/]*\).*/\1/' || continue)
# Extraire le service du nom
# Format: <membre>-infra-<type>-<env>-<instance>
if [[ $name =~ ^[a-z]+-infra-([a-z0-9-]+)-([a-z]+)-([0-9]{2})$ ]]; then
service="${BASH_REMATCH[1]}"
env="${BASH_REMATCH[2]}"
instance="${BASH_REMATCH[3]}"
# Nom DNS complet
if [ "$env" = "prod" ]; then
dns_name="${service}.infra.${MEMBER}.${DOMAIN}."
else
dns_name="${service}-${env}.infra.${MEMBER}.${DOMAIN}."
fi
echo "$dns_name IN A $ip"
fi
done
echo ""
# Tenants (Couches 5-8)
echo "; ======================================================"
echo "; TENANTS (Couches 5-8)"
echo "; ======================================================"
for vmid in $(qm list | grep -E "^[1-9][0-9]{4}$" | awk '{print $1}'); do
name=$(qm config "$vmid" 2>/dev/null | grep "^name:" | awk '{print $2}' || continue)
ip=$(qm config "$vmid" 2>/dev/null | grep "ipconfig0" | sed 's/.*ip=\([^,/]*\).*/\1/' || continue)
# Extraire tenant et service du nom
# Format: <membre>-t<tenant-id>-<type>-<env>-<instance>
if [[ $name =~ ^[a-z]+-(t[0-9]{3})-([a-z0-9-]+)-([a-z]+)-([0-9]{2})$ ]]; then
tenant="${BASH_REMATCH[1]}"
service="${BASH_REMATCH[2]}"
env="${BASH_REMATCH[3]}"
instance="${BASH_REMATCH[4]}"
# Nom DNS complet
if [ "$env" = "prod" ]; then
dns_name="${service}.${tenant}.${MEMBER}.${DOMAIN}."
else
dns_name="${service}-${env}.${tenant}.${MEMBER}.${DOMAIN}."
fi
echo "$dns_name IN A $ip"
fi
done
echo ""
echo "; ======================================================"
echo "; END OF DNS RECORDS"
echo "; ======================================================"
DNS_SCRIPT
chmod +x /usr/local/bin/generate-dns-records.sh
################################################################################
# SCRIPT 3: generate-inventory.sh
# Génère l'inventaire Ansible à partir de Proxmox
################################################################################
cat > /usr/local/bin/generate-inventory.sh << 'INVENTORY_SCRIPT'
#!/bin/bash
# generate-inventory.sh - Génération inventaire Ansible YAML
set -euo pipefail
# Configuration
MEMBER="${MEMBER_ID:-czp}"
DOMAIN="${DNS_DOMAIN:-alliance-boreale.ca}"
OUTPUT_FILE="${INVENTORY_OUTPUT:-/tmp/inventory-${MEMBER}.yml}"
cat > "$OUTPUT_FILE" << YAML_HEADER
---
# Ansible Inventory - ${MEMBER}
# Generated on $(date)
# Standard Nomenclature v2.0
all:
vars:
member_id: ${MEMBER}
domain: ${DOMAIN}
children:
infrastructure:
vars:
category: infrastructure
children:
YAML_HEADER
# Générer les groupes par couche
for layer in 1 2 3 4; do
echo " layer_${layer}:" >> "$OUTPUT_FILE"
echo " hosts:" >> "$OUTPUT_FILE"
has_hosts=false
for vmid in $(qm list | grep -E "^0${layer}[0-9]{3}$" | awk '{print $1}'); do
name=$(qm config "$vmid" 2>/dev/null | grep "^name:" | awk '{print $2}' || continue)
ip=$(qm config "$vmid" 2>/dev/null | grep "ipconfig0" | sed 's/.*ip=\([^,/]*\).*/\1/' || continue)
if [[ $name =~ ^[a-z]+-infra-([a-z0-9-]+)-([a-z]+)-([0-9]{2})$ ]]; then
service="${BASH_REMATCH[1]}"
env="${BASH_REMATCH[2]}"
dns_name="${service}.infra.${MEMBER}.${DOMAIN}"
cat >> "$OUTPUT_FILE" << YAML_HOST
${dns_name}:
ansible_host: ${ip}
vmid: ${vmid}
layer: ${layer}
service: ${service}
environment: ${env}
YAML_HOST
has_hosts=true
fi
done
if [ "$has_hosts" = false ]; then
echo " {}" >> "$OUTPUT_FILE"
fi
echo "" >> "$OUTPUT_FILE"
done
# Générer les groupes tenants
echo " tenants:" >> "$OUTPUT_FILE"
echo " vars:" >> "$OUTPUT_FILE"
echo " category: tenant" >> "$OUTPUT_FILE"
echo " children:" >> "$OUTPUT_FILE"
# Trouver tous les tenants uniques
tenant_ids=$(qm list | grep -E "^[1-9][0-9]{4}$" | awk '{print $1}' | while read vmid; do
name=$(qm config "$vmid" 2>/dev/null | grep "^name:" | awk '{print $2}' || continue)
if [[ $name =~ -(t[0-9]{3})- ]]; then
echo "${BASH_REMATCH[1]}"
fi
done | sort -u)
for tenant_id in $tenant_ids; do
echo " tenant_${tenant_id}:" >> "$OUTPUT_FILE"
echo " vars:" >> "$OUTPUT_FILE"
echo " tenant_id: ${tenant_id}" >> "$OUTPUT_FILE"
echo " hosts:" >> "$OUTPUT_FILE"
has_hosts=false
for vmid in $(qm list | grep -E "^[1-9][0-9]{4}$" | awk '{print $1}'); do
name=$(qm config "$vmid" 2>/dev/null | grep "^name:" | awk '{print $2}' || continue)
if [[ $name =~ -(${tenant_id})-([a-z0-9-]+)-([a-z]+)-([0-9]{2})$ ]]; then
ip=$(qm config "$vmid" 2>/dev/null | grep "ipconfig0" | sed 's/.*ip=\([^,/]*\).*/\1/' || continue)
service="${BASH_REMATCH[2]}"
env="${BASH_REMATCH[3]}"
dns_name="${service}.${tenant_id}.${MEMBER}.${DOMAIN}"
cat >> "$OUTPUT_FILE" << YAML_HOST
${dns_name}:
ansible_host: ${ip}
vmid: ${vmid}
tenant: ${tenant_id}
service: ${service}
environment: ${env}
YAML_HOST
has_hosts=true
fi
done
if [ "$has_hosts" = false ]; then
echo " {}" >> "$OUTPUT_FILE"
fi
echo "" >> "$OUTPUT_FILE"
done
echo "Inventaire généré: $OUTPUT_FILE"
INVENTORY_SCRIPT
chmod +x /usr/local/bin/generate-inventory.sh
################################################################################
# SCRIPT 4: migrate-vm.sh
# Migre une VM vers le nouveau standard
################################################################################
cat > /usr/local/bin/migrate-vm.sh << 'MIGRATE_SCRIPT'
#!/bin/bash
# migrate-vm.sh - Migration d'une VM vers nomenclature v2.0
set -euo pipefail
# Configuration
MEMBER_ID="${MEMBER_ID:-czp}"
DRY_RUN="${DRY_RUN:-false}"
# Couleurs
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
usage() {
echo "Usage: $0 <vmid-source> <vmid-dest> <nouveau-nom> <nouvelle-ip>"
echo ""
echo "Exemple:"
echo " $0 104 10001 czp-t001-web-prod-01 10.0.10.1"
echo ""
echo "Options:"
echo " DRY_RUN=true - Mode simulation (pas de changement)"
exit 1
}
# Vérification arguments
if [ $# -ne 4 ]; then
usage
fi
VMID_SRC="$1"
VMID_DST="$2"
NEW_NAME="$3"
NEW_IP="$4"
echo "======================================================"
echo "MIGRATION VM - NOMENCLATURE v2.0"
echo "======================================================"
echo "VMID source : $VMID_SRC"
echo "VMID dest : $VMID_DST"
echo "Nouveau nom : $NEW_NAME"
echo "Nouvelle IP : $NEW_IP"
echo "Mode simulation: $DRY_RUN"
echo "======================================================"
echo ""
# Vérifier que la VM source existe
if ! qm status "$VMID_SRC" &>/dev/null; then
echo -e "${RED}ERREUR: VM $VMID_SRC n'existe pas${NC}"
exit 1
fi
# Vérifier que la VM dest n'existe pas
if qm status "$VMID_DST" &>/dev/null; then
echo -e "${RED}ERREUR: VM $VMID_DST existe déjà${NC}"
exit 1
fi
# Récupérer info actuelle
OLD_NAME=$(qm config "$VMID_SRC" | grep "^name:" | awk '{print $2}')
OLD_IP=$(qm config "$VMID_SRC" | grep "ipconfig0" | sed 's/.*ip=\([^,/]*\).*/\1/')
echo -e "${YELLOW}État actuel:${NC}"
echo " Nom: $OLD_NAME"
echo " IP : $OLD_IP"
echo ""
echo -e "${GREEN}Nouvel état:${NC}"
echo " Nom: $NEW_NAME"
echo " IP : $NEW_IP"
echo ""
# Demander confirmation
if [ "$DRY_RUN" != "true" ]; then
read -p "Continuer? (oui/non): " confirm
if [ "$confirm" != "oui" ]; then
echo "Migration annulée"
exit 0
fi
fi
echo ""
echo "Étapes de migration:"
echo ""
# Étape 1: Backup
echo "1. Création backup..."
if [ "$DRY_RUN" != "true" ]; then
vzdump "$VMID_SRC" --mode snapshot --compress zstd --storage local
echo -e "${GREEN} ✓ Backup créé${NC}"
else
echo -e "${YELLOW} [SIMULATION] Backup créé${NC}"
fi
# Étape 2: Arrêter la VM
echo "2. Arrêt de la VM..."
if [ "$DRY_RUN" != "true" ]; then
qm shutdown "$VMID_SRC" || qm stop "$VMID_SRC"
sleep 5
echo -e "${GREEN} ✓ VM arrêtée${NC}"
else
echo -e "${YELLOW} [SIMULATION] VM arrêtée${NC}"
fi
# Étape 3: Cloner avec nouveau VMID
echo "3. Clonage vers nouveau VMID..."
if [ "$DRY_RUN" != "true" ]; then
qm clone "$VMID_SRC" "$VMID_DST" --name "$NEW_NAME" --full
echo -e "${GREEN} ✓ VM clonée${NC}"
else
echo -e "${YELLOW} [SIMULATION] VM clonée${NC}"
fi
# Étape 4: Changer l'IP
echo "4. Configuration nouvelle IP..."
if [ "$DRY_RUN" != "true" ]; then
# Modifier la config réseau Proxmox
qm set "$VMID_DST" --ipconfig0 "ip=${NEW_IP}/24,gw=10.0.0.1"
echo -e "${GREEN} ✓ IP configurée dans Proxmox${NC}"
echo -e "${YELLOW} ⚠ ATTENTION: Modifier aussi l'IP dans la VM (après démarrage)${NC}"
else
echo -e "${YELLOW} [SIMULATION] IP configurée${NC}"
fi
# Étape 5: Démarrer la nouvelle VM
echo "5. Démarrage nouvelle VM..."
if [ "$DRY_RUN" != "true" ]; then
qm start "$VMID_DST"
echo -e "${GREEN} ✓ VM démarrée${NC}"
else
echo -e "${YELLOW} [SIMULATION] VM démarrée${NC}"
fi
echo ""
echo "======================================================"
echo "MIGRATION TERMINÉE"
echo "======================================================"
echo ""
echo "Prochaines étapes MANUELLES:"
echo "1. Vérifier que la VM démarre correctement"
echo "2. Connecter à la VM et changer l'IP dans /etc/network/interfaces"
echo "3. Tester la connectivité réseau"
echo "4. Créer l'entrée DNS: ${NEW_NAME%.prod-*}.infra.${MEMBER_ID}.alliance-boreale.ca"
echo "5. Mettre à jour l'inventaire Ansible"
echo "6. Mettre à jour le monitoring"
echo "7. Une fois validé, supprimer l'ancienne VM: qm destroy $VMID_SRC"
echo ""
MIGRATE_SCRIPT
chmod +x /usr/local/bin/migrate-vm.sh
################################################################################
# SCRIPT 5: validate-vmid.sh
# Valide le format d'un VMID
################################################################################
cat > /usr/local/bin/validate-vmid.sh << 'VALIDATE_SCRIPT'
#!/bin/bash
# validate-vmid.sh - Validation format VMID
set -euo pipefail
usage() {
echo "Usage: $0 <vmid>"
echo ""
echo "Valide qu'un VMID respecte le standard v2.0"
echo ""
echo "Exemples:"
echo " $0 02001 # Infrastructure Couche 2"
echo " $0 10001 # Tenant 001"
exit 1
}
if [ $# -ne 1 ]; then
usage
fi
VMID="$1"
# Infrastructure: 0[1-4][0-9]{3}
if [[ $VMID =~ ^0[1-4][0-9]{3}$ ]]; then
layer="${VMID:1:1}"
type="${VMID:2:2}"
instance="${VMID:4:2}"
echo "✅ VMID VALIDE"
echo "Type: Infrastructure"
echo "Couche: $layer"
echo "Type service: $type"
echo "Instance: $instance"
case $layer in
1) echo "Description: Couche 1 - Physique" ;;
2) echo "Description: Couche 2 - Réseau" ;;
3) echo "Description: Couche 3 - Stockage" ;;
4) echo "Description: Couche 4 - Orchestration" ;;
esac
exit 0
fi
# Tenant: [1-9][0-9]{4}
if [[ $VMID =~ ^[1-9][0-9]{4}$ ]]; then
tenant="${VMID:0:3}"
instance="${VMID:3:2}"
echo "✅ VMID VALIDE"
echo "Type: Tenant"
echo "Tenant ID: $tenant"
echo "Instance: $instance"
exit 0
fi
# Invalide
echo "❌ VMID INVALIDE"
echo ""
echo "Format attendu:"
echo " Infrastructure: 0CTTII (ex: 02001)"
echo " 0 = Infrastructure"
echo " C = Couche (1-4)"
echo " TT = Type (00-99)"
echo " II = Instance (01-99)"
echo ""
echo " Tenant: TTTII (ex: 10001)"
echo " TTT = Tenant ID (001-999)"
echo " II = Instance (01-99)"
exit 1
VALIDATE_SCRIPT
chmod +x /usr/local/bin/validate-vmid.sh
################################################################################
# SCRIPT 6: allocate-ip.sh
# Alloue une IP pour un nouveau tenant
################################################################################
cat > /usr/local/bin/allocate-ip.sh << 'ALLOCATE_SCRIPT'
#!/bin/bash
# allocate-ip.sh - Allocation IP tenant
set -euo pipefail
# Configuration
IPAM_FILE="${IPAM_FILE:-/etc/alliance-boreale/ipam.txt}"
usage() {
echo "Usage: $0 <tenant-id>"
echo ""
echo "Alloue la prochaine IP disponible pour un tenant"
echo ""
echo "Exemple:"
echo " $0 001 # Alloue IP pour tenant 001"
exit 1
}
if [ $# -ne 1 ]; then
usage
fi
TENANT_ID="$1"
# Vérifier format tenant ID
if ! [[ $TENANT_ID =~ ^[0-9]{3}$ ]]; then
echo "ERREUR: Tenant ID doit être au format NNN (ex: 001)"
exit 1
fi
# Créer fichier IPAM si inexistant
if [ ! -f "$IPAM_FILE" ]; then
mkdir -p "$(dirname "$IPAM_FILE")"
echo "# IPAM - Tenant IP Allocation" > "$IPAM_FILE"
echo "# Format: TENANT_ID IP DATE VMID" >> "$IPAM_FILE"
fi
# Vérifier si tenant a déjà des IPs
existing_ips=$(grep "^$TENANT_ID " "$IPAM_FILE" 2>/dev/null || true)
if [ -n "$existing_ips" ]; then
echo "Tenant $TENANT_ID a déjà des IPs allouées:"
echo "$existing_ips"
echo ""
fi
# Trouver prochaine IP disponible dans 10.0.10.0/23
# Stratégie: 10.0.10.0-99 pour tenant 001, 10.0.10.100-199 pour tenant 002, etc.
base_ip_part=$((10 + (${TENANT_ID#0} * 100) / 1000))
base_host=$((((${TENANT_ID#0} % 10) * 100)))
# Trouver prochaine IP libre
for i in {1..99}; do
test_ip="10.0.${base_ip_part}.$((base_host + i))"
# Vérifier si IP déjà allouée
if ! grep -q " ${test_ip} " "$IPAM_FILE" 2>/dev/null; then
echo "✅ IP DISPONIBLE: $test_ip"
echo ""
echo "Pour allouer cette IP:"
echo " echo \"$TENANT_ID $test_ip $(date +%Y-%m-%d) VMID\" >> $IPAM_FILE"
exit 0
fi
done
echo "❌ ERREUR: Aucune IP disponible pour le tenant $TENANT_ID"
echo "Considérer utiliser la plage d'expansion 10.0.128.0/17"
exit 1
ALLOCATE_SCRIPT
chmod +x /usr/local/bin/allocate-ip.sh
################################################################################
# Installation et Configuration
################################################################################
echo "#!/bin/bash" > /usr/local/bin/install-nomenclature-tools.sh
cat >> /usr/local/bin/install-nomenclature-tools.sh << 'INSTALL'
# install-nomenclature-tools.sh - Installation des outils nomenclature v2.0
set -euo pipefail
echo "======================================================"
echo "INSTALLATION OUTILS NOMENCLATURE v2.0"
echo "L'Alliance Boréale"
echo "======================================================"
echo ""
# Vérifier droits root
if [ "$EUID" -ne 0 ]; then
echo "ERREUR: Ce script doit être exécuté en root"
exit 1
fi
# Configuration
read -p "ID du membre (ex: czp): " MEMBER_ID
read -p "Domaine DNS (ex: alliance-boreale.ca): " DNS_DOMAIN
# Créer fichier de configuration
mkdir -p /etc/alliance-boreale
cat > /etc/alliance-boreale/nomenclature.conf << CONFIG
# Configuration Nomenclature v2.0
MEMBER_ID="${MEMBER_ID}"
DNS_DOMAIN="${DNS_DOMAIN}"
IP