# Filtrage des Playbooks par Compatibilité Host/Group ## Vue d'ensemble Le système de filtrage des playbooks permet de s'assurer que seuls les playbooks compatibles avec un hôte ou un groupe spécifique peuvent être exécutés. Cette fonctionnalité est basée sur le champ `hosts` défini dans chaque playbook Ansible. ## Fonctionnement ### Champ `hosts` dans les Playbooks Chaque playbook Ansible définit un champ `hosts` qui spécifie sur quels hôtes ou groupes il peut être exécuté : ```yaml --- - name: Backup Serveurs Proxmox Configuration files hosts: role_proxmox # ← Ce playbook ne peut s'exécuter que sur le groupe role_proxmox become: true tasks: # ... ``` ### Règles de Compatibilité Le système applique les règles suivantes pour déterminer la compatibilité : 1. **`hosts: all`** → Compatible avec tous les hôtes et groupes 2. **`hosts: role_proxmox`** → Compatible avec : - Le groupe `role_proxmox` lui-même - Tous les hôtes membres du groupe `role_proxmox` - Les sous-groupes dont tous les hôtes sont dans `role_proxmox` 3. **`hosts: server.home`** → Compatible uniquement avec : - L'hôte `server.home` - Les groupes contenant cet hôte ### Exemples #### Exemple 1 : Playbook Proxmox ```yaml # backup-proxmox-config.yml hosts: role_proxmox ``` **Compatible avec :** - ✅ Groupe `role_proxmox` - ✅ Hôte `ali2v.xeon.home` (membre de role_proxmox) - ✅ Hôte `hp.nas.home` (membre de role_proxmox) **Non compatible avec :** - ❌ Hôte `raspi.4gb.home` (membre de role_sbc, pas de role_proxmox) - ❌ Groupe `env_homelab` (contient des hôtes hors de role_proxmox) #### Exemple 2 : Playbook Universal ```yaml # health-check.yml hosts: all ``` **Compatible avec :** - ✅ Tous les hôtes - ✅ Tous les groupes - ✅ `all` ## API Endpoints ### 1. Lister les Playbooks (avec filtrage optionnel) ```http GET /api/ansible/playbooks?target={host_ou_groupe} ``` **Paramètres :** - `target` (optionnel) : Nom de l'hôte ou du groupe pour filtrer les playbooks compatibles **Exemple sans filtre :** ```bash curl -H "X-API-Key: your-key" http://localhost:8000/api/ansible/playbooks ``` **Réponse :** ```json { "playbooks": [ { "name": "backup-proxmox-config", "filename": "backup-proxmox-config.yml", "hosts": "role_proxmox", "category": "backup", "subcategory": "configuration", "description": "Backup Serveurs Proxmox Configuration files" }, { "name": "health-check", "filename": "health-check.yml", "hosts": "all", "category": "monitoring", "subcategory": "health" } ], "filter": null } ``` **Exemple avec filtre :** ```bash curl -H "X-API-Key: your-key" \ "http://localhost:8000/api/ansible/playbooks?target=role_proxmox" ``` **Réponse :** ```json { "playbooks": [ { "name": "backup-proxmox-config", "filename": "backup-proxmox-config.yml", "hosts": "role_proxmox", "category": "backup" }, { "name": "health-check", "filename": "health-check.yml", "hosts": "all", "category": "monitoring" } ], "filter": "role_proxmox" } ``` ### 2. Exécuter un Playbook (avec validation) ```http POST /api/ansible/execute ``` **Corps de la requête :** ```json { "playbook": "backup-proxmox-config.yml", "target": "ali2v.xeon.home", "extra_vars": {}, "check_mode": false } ``` **Validation automatique :** - ✅ Si compatible : le playbook s'exécute - ❌ Si incompatible : erreur HTTP 400 avec message explicatif **Exemple d'erreur :** ```json { "detail": "Le playbook 'backup-proxmox-config.yml' (hosts: role_proxmox) n'est pas compatible avec la cible 'raspi.4gb.home'. Ce playbook ne peut être exécuté que sur: role_proxmox" } ``` ### 3. Créer un Schedule (avec validation) ```http POST /api/schedules ``` **Corps de la requête :** ```json { "name": "Backup Proxmox Quotidien", "playbook": "backup-proxmox-config.yml", "target": "role_proxmox", "target_type": "group", "schedule_type": "recurring", "recurrence": { "type": "daily", "time": "02:00" } } ``` **Validation automatique :** - Vérifie que le playbook existe - Vérifie que la cible (host ou groupe) existe - ✅ **Nouveau :** Vérifie la compatibilité playbook-target ## Utilisation dans l'Interface ### Filtrage Dynamique L'interface peut maintenant : 1. **Afficher uniquement les playbooks compatibles** lors de la sélection d'un hôte/groupe 2. **Empêcher l'exécution** de playbooks incompatibles 3. **Afficher des messages d'erreur clairs** en cas d'incompatibilité ### Exemple de Workflow 1. L'utilisateur sélectionne un hôte : `raspi.4gb.home` 2. L'interface appelle : `GET /api/ansible/playbooks?target=raspi.4gb.home` 3. Seuls les playbooks compatibles sont affichés (pas `backup-proxmox-config.yml`) 4. L'utilisateur ne peut exécuter que les playbooks compatibles ## Implémentation Technique ### Méthodes Ajoutées #### `AnsibleService.get_playbooks()` - Extrait maintenant le champ `hosts` de chaque playbook - Retourne les métadonnées complètes incluant `hosts` #### `AnsibleService.is_target_compatible_with_playbook(target, playbook_hosts)` - Vérifie la compatibilité entre une cible et un champ `hosts` - Gère les cas : `all`, groupes, hôtes, sous-groupes #### `AnsibleService.get_compatible_playbooks(target)` - Filtre tous les playbooks pour ne retourner que ceux compatibles avec la cible ### Points de Validation La validation est effectuée à trois niveaux : 1. **Endpoint de listing** (`GET /api/ansible/playbooks`) : Filtrage optionnel 2. **Endpoint d'exécution** (`POST /api/ansible/execute`) : Validation obligatoire 3. **Endpoint de schedule** (`POST /api/schedules`) : Validation obligatoire ## Tests Un script de test complet est disponible : `test_playbook_filtering.py` ```bash python test_playbook_filtering.py ``` **Résultats attendus :** - ✅ Tous les tests doivent passer (8/8) - Validation des règles de compatibilité - Vérification du filtrage par groupe/hôte ## Migration des Playbooks Existants ### Playbooks avec `hosts: all` Aucune action requise - compatibles avec tout. ### Playbooks spécifiques Vérifier que le champ `hosts` correspond bien aux groupes/hôtes ciblés : ```yaml # Avant (implicite) - name: Mon playbook # hosts non défini ou hosts: all # Après (explicite) - name: Mon playbook hosts: role_proxmox # Spécifier le groupe exact ``` ## Bonnes Pratiques 1. **Définir explicitement le champ `hosts`** dans chaque playbook 2. **Utiliser des groupes** plutôt que des hôtes individuels quand possible 3. **Tester la compatibilité** avant de créer des schedules 4. **Documenter les restrictions** dans la description du playbook ## Dépannage ### Problème : Playbook non disponible pour un hôte **Cause :** Le champ `hosts` du playbook ne correspond pas à l'hôte ou ses groupes **Solution :** 1. Vérifier le champ `hosts` dans le playbook 2. Vérifier l'appartenance de l'hôte aux groupes dans `inventory/hosts.yml` 3. Ajuster soit le playbook, soit l'inventaire ### Problème : Erreur lors de l'exécution **Message :** `Le playbook 'X' n'est pas compatible avec la cible 'Y'` **Solution :** 1. Utiliser l'endpoint de filtrage pour voir les playbooks compatibles 2. Choisir un playbook compatible ou changer la cible ## Références - **Inventaire Ansible :** `ansible/inventory/hosts.yml` - **Playbooks :** `ansible/playbooks/*.yml` - **Code source :** `app/app_optimized.py` (classe `AnsibleService`) - **Tests :** `test_playbook_filtering.py`