feat(ansible-role-remote_users_fact): set remote_users_fact_state default var
This commit is contained in:
@@ -1,6 +1,18 @@
|
||||
# remote_users_fact
|
||||
|
||||
Rôle Ansible qui déploie un **local fact** comptant les sessions distantes par protocole (SSH, Citrix, Horizon) et évaluant la fiabilité en comparant avec `who`.
|
||||
Rôle Ansible qui gère un **local fact** comptant les sessions distantes par protocole (SSH, Citrix, Horizon) et évaluant la fiabilité en comparant avec `who`.
|
||||
|
||||
## Gestion du state
|
||||
|
||||
Le rôle est piloté par la variable `remote_users_fact_state` :
|
||||
|
||||
| State | Comportement |
|
||||
|---|---|
|
||||
| `noop` (défaut) | Aucune action — le rôle ne touche à rien |
|
||||
| `present` | Déploie le fact, valide le JSON, affiche le résumé |
|
||||
| `absent` | Supprime le fact, purge ansible_local, nettoie le répertoire si vide |
|
||||
|
||||
Le state peut être défini à tout niveau (all, groupe, hôte, extra-vars). `noop` par défaut garantit qu'un hôte ajouté à l'inventaire sans configuration explicite ne sera pas impacté.
|
||||
|
||||
## Arborescence
|
||||
|
||||
@@ -10,37 +22,47 @@ Rôle Ansible qui déploie un **local fact** comptant les sessions distantes par
|
||||
│ └── hosts.yml # Inventaire exemple
|
||||
└── roles/
|
||||
└── remote_users_fact/
|
||||
├── defaults/main.yml # Variables par défaut
|
||||
├── files/remote_users.fact # Script fact déployé
|
||||
├── handlers/main.yml # Handler rechargement facts
|
||||
├── defaults/main.yml # Variables (dont state)
|
||||
├── files/remote_users.fact # Script fact
|
||||
├── handlers/main.yml # Rechargement facts
|
||||
├── meta/main.yml # Métadonnées Galaxy
|
||||
└── tasks/
|
||||
├── main.yml # Orchestration
|
||||
├── deploy.yml # Création répertoire + copie
|
||||
├── validate.yml # Exécution + parsing JSON
|
||||
└── summary.yml # Affichage résumé + alertes
|
||||
├── main.yml # Assertions → routage par state
|
||||
├── assert.yml # Validation stricte du paramétrage
|
||||
├── present.yml # Déploiement (state=present)
|
||||
├── absent.yml # Suppression (state=absent)
|
||||
├── validate.yml # Exécution + assert structure JSON
|
||||
└── summary.yml # Affichage matrice + alertes
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Déploiement complet
|
||||
# Appliquer le state défini dans l'inventaire
|
||||
ansible-playbook -i inventories/hosts.yml site.yml
|
||||
|
||||
# Déploiement seul
|
||||
ansible-playbook -i inventories/hosts.yml site.yml --tags deploy
|
||||
# Forcer le déploiement partout (override)
|
||||
ansible-playbook -i inventories/hosts.yml site.yml -e remote_users_fact_state=present
|
||||
|
||||
# Vérification seule (fact déjà déployé)
|
||||
ansible-playbook -i inventories/hosts.yml site.yml --tags validate,summary
|
||||
# Supprimer partout
|
||||
ansible-playbook -i inventories/hosts.yml site.yml -e remote_users_fact_state=absent
|
||||
|
||||
# Sur un groupe spécifique
|
||||
ansible-playbook -i inventories/hosts.yml site.yml -l citrix_servers
|
||||
|
||||
# Tags disponibles
|
||||
ansible-playbook ... --tags assert # Assertions seules
|
||||
ansible-playbook ... --tags present,deploy # Déploiement seul
|
||||
ansible-playbook ... --tags validate # Validation seule
|
||||
ansible-playbook ... --tags summary # Résumé seul
|
||||
ansible-playbook ... --tags absent,remove # Suppression seule
|
||||
```
|
||||
|
||||
## Variables
|
||||
|
||||
| Variable | Défaut | Description |
|
||||
|---|---|---|
|
||||
| `remote_users_fact_state` | `noop` | `present` / `absent` / `noop` |
|
||||
| `remote_users_fact_dir` | `/etc/ansible/facts.d` | Répertoire de destination |
|
||||
| `remote_users_fact_name` | `remote_users.fact` | Nom du script |
|
||||
| `remote_users_fact_owner` | `root` | Propriétaire |
|
||||
@@ -49,6 +71,26 @@ ansible-playbook -i inventories/hosts.yml site.yml -l citrix_servers
|
||||
| `remote_users_fact_display_summary` | `true` | Afficher le résumé |
|
||||
| `remote_users_fact_warn_verdicts` | voir defaults | Verdicts déclenchant un warning |
|
||||
|
||||
## Assertions
|
||||
|
||||
Le rôle valide le paramétrage **avant** toute action :
|
||||
|
||||
- `remote_users_fact_state` est défini et vaut `present`, `absent` ou `noop`
|
||||
- `remote_users_fact_dir` est un chemin absolu (si state != noop)
|
||||
- `remote_users_fact_name` respecte le pattern `*.fact` (si state != noop)
|
||||
- `remote_users_fact_owner` et `group` sont définis (si state == present)
|
||||
- `remote_users_fact_validate` et `display_summary` sont des booléens
|
||||
- `remote_users_fact_warn_verdicts` est une liste de verdicts valides
|
||||
|
||||
En cas de state `present`, la validation post-déploiement vérifie aussi :
|
||||
- Le script s'exécute sans erreur (rc == 0)
|
||||
- La sortie est du JSON parsable
|
||||
- Toutes les clés obligatoires sont présentes
|
||||
- Les compteurs sont >= 0
|
||||
- `total_by_protocol == ssh + citrix + horizon`
|
||||
- Le verdict est dans la liste des verdicts connus
|
||||
- Le fact est chargé dans `ansible_local`
|
||||
|
||||
## Fact déployé
|
||||
|
||||
Accessible via `ansible_local.remote_users` :
|
||||
@@ -84,21 +126,48 @@ Accessible via `ansible_local.remote_users` :
|
||||
| Verdict | Signification |
|
||||
|---|---|
|
||||
| `FIABLE` | who == total → compteurs alignés |
|
||||
| `OK` | Écart ≤ 1 → tolérable |
|
||||
| `OK` | Écart <= 1 → tolérable |
|
||||
| `WHO_SUP_TOTAL` | who > total → protocole non surveillé |
|
||||
| `WHO_INF_TOTAL` | who < total → sessions headless sans TTY |
|
||||
| `WHO_SEUL` | total == 0 → protocoles non détectés |
|
||||
| `PROTO_SEUL` | who == 0 → sessions sans allocation TTY |
|
||||
| `NEUTRE` | 0 == 0 → aucune session |
|
||||
|
||||
## Exemple d'inventaire avec states
|
||||
|
||||
```yaml
|
||||
all:
|
||||
vars:
|
||||
remote_users_fact_state: present # Défaut global
|
||||
|
||||
children:
|
||||
prod_servers:
|
||||
hosts:
|
||||
srv-01: {}
|
||||
srv-02: {}
|
||||
|
||||
# Hôte exclu
|
||||
dev_servers:
|
||||
hosts:
|
||||
dev-01:
|
||||
remote_users_fact_state: noop
|
||||
|
||||
# Groupe en décommission
|
||||
legacy:
|
||||
vars:
|
||||
remote_users_fact_state: absent
|
||||
```
|
||||
|
||||
## Utilisation dans d'autres playbooks
|
||||
|
||||
```yaml
|
||||
- hosts: all
|
||||
gather_facts: true
|
||||
tasks:
|
||||
- name: Refuser un déploiement si trop de sessions actives
|
||||
- name: Bloquer un déploiement si trop de sessions
|
||||
ansible.builtin.fail:
|
||||
msg: "{{ ansible_local.remote_users.sessions.total_by_protocol }} sessions actives, déploiement annulé"
|
||||
when: ansible_local.remote_users.sessions.total_by_protocol | int > 10
|
||||
msg: "{{ ansible_local.remote_users.sessions.total_by_protocol }} sessions actives"
|
||||
when:
|
||||
- ansible_local.remote_users is defined
|
||||
- ansible_local.remote_users.sessions.total_by_protocol | int > 10
|
||||
```
|
||||
|
||||
+33
-7
@@ -1,9 +1,29 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# inventories/hosts.yml — Exemple d'inventaire
|
||||
# inventories/hosts.yml — Exemple d'inventaire avec gestion du state
|
||||
# =============================================================================
|
||||
#
|
||||
# remote_users_fact_state:
|
||||
# present → déploie le fact
|
||||
# absent → supprime le fact
|
||||
# noop → ne fait rien (défaut si non spécifié)
|
||||
#
|
||||
# Le state peut être défini à n'importe quel niveau :
|
||||
# - all:vars → défaut global
|
||||
# - group:vars → surcharge par groupe
|
||||
# - host:vars → surcharge par hôte
|
||||
# - extra-vars (-e) → surcharge absolue
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
all:
|
||||
vars:
|
||||
ansible_user: ansible
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
# Défaut global : déployer partout
|
||||
remote_users_fact_state: present
|
||||
|
||||
children:
|
||||
|
||||
ssh_servers:
|
||||
@@ -12,6 +32,10 @@ all:
|
||||
ansible_host: 192.168.1.10
|
||||
srv-linux-02:
|
||||
ansible_host: 192.168.1.11
|
||||
# Exemple : désactiver sur un hôte spécifique
|
||||
srv-linux-03:
|
||||
ansible_host: 192.168.1.12
|
||||
remote_users_fact_state: noop
|
||||
|
||||
citrix_servers:
|
||||
hosts:
|
||||
@@ -20,8 +44,7 @@ all:
|
||||
ctx-vda-02:
|
||||
ansible_host: 192.168.2.11
|
||||
vars:
|
||||
# Optionnel : surcharger les verdicts d'alerte pour Citrix
|
||||
# car WHO_INF_TOTAL est fréquent (apps publiées sans TTY)
|
||||
# Surcharge par groupe : WHO_INF_TOTAL est normal sur Citrix
|
||||
remote_users_fact_warn_verdicts:
|
||||
- WHO_SUP_TOTAL
|
||||
- WHO_SEUL
|
||||
@@ -33,7 +56,10 @@ all:
|
||||
hrz-agent-02:
|
||||
ansible_host: 192.168.3.11
|
||||
|
||||
vars:
|
||||
ansible_user: ansible
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
# Exemple : groupe en cours de décommission
|
||||
legacy_servers:
|
||||
hosts:
|
||||
old-srv-01:
|
||||
ansible_host: 192.168.9.10
|
||||
vars:
|
||||
remote_users_fact_state: absent
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
# defaults/main.yml — Variables par défaut du rôle remote_users_fact
|
||||
# =============================================================================
|
||||
|
||||
# État souhaité du fact :
|
||||
# present → déploie le fact + validation + résumé
|
||||
# absent → supprime le fact + recharge les facts
|
||||
# noop → ne fait rien (utile pour désactiver par host/groupe)
|
||||
remote_users_fact_state: noop
|
||||
|
||||
# Répertoire de destination des local facts
|
||||
remote_users_fact_dir: /etc/ansible/facts.d
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# tasks/absent.yml — Suppression du fact (state=absent)
|
||||
# =============================================================================
|
||||
|
||||
- name: "Absent | Vérifier si le fact existe"
|
||||
ansible.builtin.stat:
|
||||
path: "{{ remote_users_fact_dir }}/{{ remote_users_fact_name }}"
|
||||
register: _remote_users_fact_file
|
||||
|
||||
- name: "Absent | Supprimer le script remote_users.fact"
|
||||
ansible.builtin.file:
|
||||
path: "{{ remote_users_fact_dir }}/{{ remote_users_fact_name }}"
|
||||
state: absent
|
||||
register: _remote_users_fact_removed
|
||||
when: _remote_users_fact_file.stat.exists
|
||||
notify: Recharger les local facts
|
||||
|
||||
- name: "Absent | Recharger les facts pour purger ansible_local"
|
||||
ansible.builtin.setup:
|
||||
filter: ansible_local
|
||||
when: _remote_users_fact_removed.changed | default(false)
|
||||
|
||||
- name: "Absent | Vérifier que le fact n'est plus chargé"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_local.remote_users is not defined
|
||||
fail_msg: >-
|
||||
Le fact remote_users est toujours présent dans ansible_local
|
||||
après suppression. Vérifier le rechargement des facts.
|
||||
success_msg: "Fact remote_users correctement supprimé et purgé d'ansible_local"
|
||||
when: _remote_users_fact_removed.changed | default(false)
|
||||
|
||||
- name: "Absent | Info suppression"
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{ 'Fact supprimé de ' ~ remote_users_fact_dir
|
||||
if _remote_users_fact_removed.changed | default(false)
|
||||
else 'Fact déjà absent, rien à faire' }}
|
||||
|
||||
- name: "Absent | Nettoyer le répertoire facts.d si vide"
|
||||
ansible.builtin.command:
|
||||
cmd: "find {{ remote_users_fact_dir }} -maxdepth 0 -empty -type d"
|
||||
register: _remote_users_factdir_empty
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: "Absent | Supprimer le répertoire facts.d si vide"
|
||||
ansible.builtin.file:
|
||||
path: "{{ remote_users_fact_dir }}"
|
||||
state: absent
|
||||
when: _remote_users_factdir_empty.stdout | length > 0
|
||||
@@ -0,0 +1,135 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# tasks/assert.yml — Validation stricte du paramétrage avant exécution
|
||||
# =============================================================================
|
||||
|
||||
- name: "Assert | remote_users_fact_state est défini"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- remote_users_fact_state is defined
|
||||
- remote_users_fact_state | length > 0
|
||||
fail_msg: >-
|
||||
remote_users_fact_state n'est pas défini.
|
||||
Valeurs acceptées : present, absent, noop
|
||||
quiet: true
|
||||
|
||||
- name: "Assert | remote_users_fact_state contient une valeur valide"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- remote_users_fact_state in _remote_users_fact_valid_states
|
||||
fail_msg: >-
|
||||
remote_users_fact_state='{{ remote_users_fact_state }}' invalide.
|
||||
Valeurs acceptées : {{ _remote_users_fact_valid_states | join(', ') }}
|
||||
quiet: true
|
||||
vars:
|
||||
_remote_users_fact_valid_states:
|
||||
- present
|
||||
- absent
|
||||
- noop
|
||||
|
||||
- name: "Assert | remote_users_fact_dir est un chemin absolu"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- remote_users_fact_dir is defined
|
||||
- remote_users_fact_dir | length > 0
|
||||
- remote_users_fact_dir is match('^/')
|
||||
fail_msg: >-
|
||||
remote_users_fact_dir='{{ remote_users_fact_dir | default('') }}'
|
||||
doit être un chemin absolu (ex: /etc/ansible/facts.d)
|
||||
quiet: true
|
||||
when: remote_users_fact_state != "noop"
|
||||
|
||||
- name: "Assert | remote_users_fact_name est défini et valide"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- remote_users_fact_name is defined
|
||||
- remote_users_fact_name | length > 0
|
||||
- remote_users_fact_name is match('^[a-zA-Z0-9_.-]+\.fact$')
|
||||
fail_msg: >-
|
||||
remote_users_fact_name='{{ remote_users_fact_name | default('') }}'
|
||||
doit correspondre au pattern [a-zA-Z0-9_.-]+.fact
|
||||
quiet: true
|
||||
when: remote_users_fact_state != "noop"
|
||||
|
||||
- name: "Assert | remote_users_fact_owner est défini"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- remote_users_fact_owner is defined
|
||||
- remote_users_fact_owner | length > 0
|
||||
fail_msg: >-
|
||||
remote_users_fact_owner ne peut pas être vide
|
||||
quiet: true
|
||||
when: remote_users_fact_state == "present"
|
||||
|
||||
- name: "Assert | remote_users_fact_group est défini"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- remote_users_fact_group is defined
|
||||
- remote_users_fact_group | length > 0
|
||||
fail_msg: >-
|
||||
remote_users_fact_group ne peut pas être vide
|
||||
quiet: true
|
||||
when: remote_users_fact_state == "present"
|
||||
|
||||
- name: "Assert | remote_users_fact_validate est un booléen"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- remote_users_fact_validate | string | lower in ['true', 'false', 'yes', 'no']
|
||||
fail_msg: >-
|
||||
remote_users_fact_validate='{{ remote_users_fact_validate }}'
|
||||
doit être un booléen (true/false)
|
||||
quiet: true
|
||||
when: remote_users_fact_state == "present"
|
||||
|
||||
- name: "Assert | remote_users_fact_display_summary est un booléen"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- remote_users_fact_display_summary | string | lower in ['true', 'false', 'yes', 'no']
|
||||
fail_msg: >-
|
||||
remote_users_fact_display_summary='{{ remote_users_fact_display_summary }}'
|
||||
doit être un booléen (true/false)
|
||||
quiet: true
|
||||
when: remote_users_fact_state == "present"
|
||||
|
||||
- name: "Assert | remote_users_fact_warn_verdicts est une liste"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- remote_users_fact_warn_verdicts is defined
|
||||
- remote_users_fact_warn_verdicts is iterable
|
||||
- remote_users_fact_warn_verdicts is not string
|
||||
fail_msg: >-
|
||||
remote_users_fact_warn_verdicts doit être une liste
|
||||
(ex: [WHO_SUP_TOTAL, WHO_INF_TOTAL])
|
||||
quiet: true
|
||||
when: remote_users_fact_state == "present"
|
||||
|
||||
- name: "Assert | remote_users_fact_warn_verdicts contient des verdicts valides"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- item in _remote_users_fact_valid_verdicts
|
||||
fail_msg: >-
|
||||
Verdict '{{ item }}' invalide dans remote_users_fact_warn_verdicts.
|
||||
Valeurs acceptées : {{ _remote_users_fact_valid_verdicts | join(', ') }}
|
||||
quiet: true
|
||||
loop: "{{ remote_users_fact_warn_verdicts }}"
|
||||
vars:
|
||||
_remote_users_fact_valid_verdicts:
|
||||
- FIABLE
|
||||
- OK
|
||||
- NEUTRE
|
||||
- WHO_SUP_TOTAL
|
||||
- WHO_INF_TOTAL
|
||||
- WHO_SEUL
|
||||
- PROTO_SEUL
|
||||
when: remote_users_fact_state == "present"
|
||||
|
||||
- name: "Assert | Résumé du paramétrage validé"
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Assertions OK — state={{ remote_users_fact_state }}
|
||||
{% if remote_users_fact_state == 'present' %}
|
||||
dir={{ remote_users_fact_dir }}
|
||||
name={{ remote_users_fact_name }}
|
||||
validate={{ remote_users_fact_validate }}
|
||||
summary={{ remote_users_fact_display_summary }}
|
||||
{% endif %}
|
||||
@@ -1,24 +1,55 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# tasks/main.yml — Déploiement et validation du local fact remote_users
|
||||
# tasks/main.yml — Point d'entrée : assertions puis routage par état
|
||||
# =============================================================================
|
||||
|
||||
- name: Inclure les tâches de déploiement
|
||||
ansible.builtin.include_tasks: deploy.yml
|
||||
- name: Inclure les assertions de paramétrage
|
||||
ansible.builtin.include_tasks: assert.yml
|
||||
tags:
|
||||
- remote_users_fact
|
||||
- assert
|
||||
|
||||
- name: "État noop — aucune action"
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
remote_users_fact_state=noop sur {{ inventory_hostname }},
|
||||
aucune action effectuée.
|
||||
when: remote_users_fact_state == "noop"
|
||||
tags:
|
||||
- remote_users_fact
|
||||
|
||||
- name: "État present — déploiement du fact"
|
||||
ansible.builtin.include_tasks: present.yml
|
||||
when: remote_users_fact_state == "present"
|
||||
tags:
|
||||
- remote_users_fact
|
||||
- present
|
||||
- deploy
|
||||
|
||||
- name: Inclure les tâches de validation
|
||||
- name: "État present — validation"
|
||||
ansible.builtin.include_tasks: validate.yml
|
||||
when: remote_users_fact_validate | bool
|
||||
when:
|
||||
- remote_users_fact_state == "present"
|
||||
- remote_users_fact_validate | bool
|
||||
tags:
|
||||
- remote_users_fact
|
||||
- present
|
||||
- validate
|
||||
|
||||
- name: Inclure les tâches de résumé
|
||||
- name: "État present — résumé"
|
||||
ansible.builtin.include_tasks: summary.yml
|
||||
when: remote_users_fact_display_summary | bool
|
||||
when:
|
||||
- remote_users_fact_state == "present"
|
||||
- remote_users_fact_display_summary | bool
|
||||
tags:
|
||||
- remote_users_fact
|
||||
- present
|
||||
- summary
|
||||
|
||||
- name: "État absent — suppression du fact"
|
||||
ansible.builtin.include_tasks: absent.yml
|
||||
when: remote_users_fact_state == "absent"
|
||||
tags:
|
||||
- remote_users_fact
|
||||
- absent
|
||||
- remove
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# tasks/present.yml — Déploiement du fact (state=present)
|
||||
# =============================================================================
|
||||
|
||||
- name: "Present | Créer le répertoire facts.d"
|
||||
ansible.builtin.file:
|
||||
path: "{{ remote_users_fact_dir }}"
|
||||
state: directory
|
||||
owner: "{{ remote_users_fact_owner }}"
|
||||
group: "{{ remote_users_fact_group }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: "Present | Déployer le script remote_users.fact"
|
||||
ansible.builtin.copy:
|
||||
src: "{{ remote_users_fact_name }}"
|
||||
dest: "{{ remote_users_fact_dir }}/{{ remote_users_fact_name }}"
|
||||
owner: "{{ remote_users_fact_owner }}"
|
||||
group: "{{ remote_users_fact_group }}"
|
||||
mode: "0755"
|
||||
backup: true
|
||||
register: _remote_users_fact_deployed
|
||||
notify: Recharger les local facts
|
||||
|
||||
- name: "Present | Info déploiement"
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Fact {{ 'mis à jour' if _remote_users_fact_deployed.changed else 'déjà en place' }}
|
||||
→ {{ remote_users_fact_dir }}/{{ remote_users_fact_name }}
|
||||
@@ -3,11 +3,12 @@
|
||||
# tasks/summary.yml — Affichage du résumé et alertes éventuelles
|
||||
# =============================================================================
|
||||
|
||||
- name: Afficher le résumé des sessions distantes
|
||||
- name: "Summary | Résumé des sessions distantes"
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "══════════════════════════════════════════"
|
||||
- "Host : {{ inventory_hostname }}"
|
||||
- "State : {{ remote_users_fact_state }}"
|
||||
- "Timestamp : {{ ansible_local.remote_users.timestamp }}"
|
||||
- "──────────────────────────────────────────"
|
||||
- "SSH : {{ ansible_local.remote_users.sessions.ssh }}"
|
||||
@@ -25,7 +26,7 @@
|
||||
- "Horizon Agt : {{ ansible_local.remote_users.detection.horizon_agent_installed }}"
|
||||
- "══════════════════════════════════════════"
|
||||
|
||||
- name: Alerter si le verdict est anormal
|
||||
- name: "Summary | Alerte si verdict anormal"
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
⚠ ATTENTION sur {{ inventory_hostname }} —
|
||||
|
||||
@@ -3,35 +3,111 @@
|
||||
# tasks/validate.yml — Validation du fact (exécution + parsing JSON)
|
||||
# =============================================================================
|
||||
|
||||
- name: Forcer le rechargement des facts si déploiement effectué
|
||||
- name: "Validate | Forcer le rechargement des facts"
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: Exécuter le script fact manuellement pour validation
|
||||
- name: "Validate | Exécuter le script fact pour validation"
|
||||
ansible.builtin.command:
|
||||
cmd: "{{ remote_users_fact_dir }}/{{ remote_users_fact_name }}"
|
||||
register: _remote_users_fact_output
|
||||
changed_when: false
|
||||
failed_when: _remote_users_fact_output.rc != 0
|
||||
|
||||
- name: Valider que la sortie est du JSON parsable
|
||||
- name: "Validate | Parser la sortie JSON"
|
||||
ansible.builtin.set_fact:
|
||||
_remote_users_fact_parsed: "{{ _remote_users_fact_output.stdout | from_json }}"
|
||||
|
||||
- name: Vérifier la présence des clés obligatoires
|
||||
- name: "Validate | Vérifier la structure JSON — clés racine"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- _remote_users_fact_parsed.timestamp is defined
|
||||
- _remote_users_fact_parsed.sessions is defined
|
||||
- _remote_users_fact_parsed.users_remote is defined
|
||||
- _remote_users_fact_parsed.reliability is defined
|
||||
- _remote_users_fact_parsed.detection is defined
|
||||
fail_msg: "Clés racine manquantes dans la sortie JSON du fact"
|
||||
success_msg: "Clés racine OK"
|
||||
quiet: true
|
||||
|
||||
- name: "Validate | Vérifier la structure JSON — sessions"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- _remote_users_fact_parsed.sessions.ssh is defined
|
||||
- _remote_users_fact_parsed.sessions.citrix is defined
|
||||
- _remote_users_fact_parsed.sessions.horizon is defined
|
||||
- _remote_users_fact_parsed.sessions.total_by_protocol is defined
|
||||
- _remote_users_fact_parsed.sessions.who_remote is defined
|
||||
- _remote_users_fact_parsed.reliability is defined
|
||||
- _remote_users_fact_parsed.reliability.verdict is defined
|
||||
- _remote_users_fact_parsed.detection is defined
|
||||
fail_msg: "Le fact remote_users ne retourne pas la structure JSON attendue"
|
||||
success_msg: "Structure JSON validée avec succès"
|
||||
- _remote_users_fact_parsed.sessions.ssh | int >= 0
|
||||
- _remote_users_fact_parsed.sessions.citrix | int >= 0
|
||||
- _remote_users_fact_parsed.sessions.horizon | int >= 0
|
||||
- _remote_users_fact_parsed.sessions.total_by_protocol | int >= 0
|
||||
- _remote_users_fact_parsed.sessions.who_remote | int >= 0
|
||||
fail_msg: "Structure 'sessions' invalide ou valeurs négatives"
|
||||
success_msg: "Structure sessions OK"
|
||||
quiet: true
|
||||
|
||||
- name: Recharger les ansible_local facts
|
||||
- name: "Validate | Vérifier la cohérence total = ssh + citrix + horizon"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- >-
|
||||
_remote_users_fact_parsed.sessions.total_by_protocol | int ==
|
||||
(_remote_users_fact_parsed.sessions.ssh | int +
|
||||
_remote_users_fact_parsed.sessions.citrix | int +
|
||||
_remote_users_fact_parsed.sessions.horizon | int)
|
||||
fail_msg: >-
|
||||
total_by_protocol ({{ _remote_users_fact_parsed.sessions.total_by_protocol }})
|
||||
!= ssh+citrix+horizon
|
||||
({{ _remote_users_fact_parsed.sessions.ssh }}
|
||||
+{{ _remote_users_fact_parsed.sessions.citrix }}
|
||||
+{{ _remote_users_fact_parsed.sessions.horizon }})
|
||||
success_msg: "Cohérence total OK"
|
||||
quiet: true
|
||||
|
||||
- name: "Validate | Vérifier la structure JSON — reliability"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- _remote_users_fact_parsed.reliability.ratio_who_over_total is defined
|
||||
- _remote_users_fact_parsed.reliability.verdict is defined
|
||||
- _remote_users_fact_parsed.reliability.detail is defined
|
||||
- _remote_users_fact_parsed.reliability.verdict in _remote_users_fact_valid_verdicts
|
||||
fail_msg: >-
|
||||
Structure 'reliability' invalide ou verdict inconnu :
|
||||
'{{ _remote_users_fact_parsed.reliability.verdict | default('UNDEFINED') }}'
|
||||
success_msg: "Structure reliability OK"
|
||||
quiet: true
|
||||
vars:
|
||||
_remote_users_fact_valid_verdicts:
|
||||
- FIABLE
|
||||
- OK
|
||||
- NEUTRE
|
||||
- WHO_SUP_TOTAL
|
||||
- WHO_INF_TOTAL
|
||||
- WHO_SEUL
|
||||
- PROTO_SEUL
|
||||
|
||||
- name: "Validate | Vérifier la structure JSON — detection"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- _remote_users_fact_parsed.detection.citrix_vda_installed is defined
|
||||
- _remote_users_fact_parsed.detection.horizon_agent_installed is defined
|
||||
- _remote_users_fact_parsed.detection.ssh_method is defined
|
||||
- _remote_users_fact_parsed.detection.citrix_method is defined
|
||||
- _remote_users_fact_parsed.detection.horizon_method is defined
|
||||
fail_msg: "Structure 'detection' invalide"
|
||||
success_msg: "Structure detection OK"
|
||||
quiet: true
|
||||
|
||||
- name: "Validate | Recharger ansible_local"
|
||||
ansible.builtin.setup:
|
||||
filter: ansible_local
|
||||
|
||||
- name: "Validate | Confirmer la présence dans ansible_local"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_local.remote_users is defined
|
||||
- ansible_local.remote_users.sessions is defined
|
||||
- ansible_local.remote_users.reliability is defined
|
||||
fail_msg: >-
|
||||
Le fact remote_users n'est pas visible dans ansible_local
|
||||
après rechargement. Vérifier les permissions et le format.
|
||||
success_msg: "Fact remote_users chargé dans ansible_local avec succès"
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# site.yml — Playbook de déploiement du local fact remote_users
|
||||
# site.yml — Playbook de gestion du local fact remote_users
|
||||
# =============================================================================
|
||||
#
|
||||
# Usage :
|
||||
# # Déployer sur tous les hôtes (state défini dans l'inventaire) :
|
||||
# ansible-playbook -i inventories/hosts.yml site.yml
|
||||
#
|
||||
# # Déploiement seul (sans validation ni résumé) :
|
||||
# ansible-playbook -i inventories/hosts.yml site.yml --tags deploy
|
||||
# # Forcer le déploiement sur tous (override du state) :
|
||||
# ansible-playbook -i inventories/hosts.yml site.yml \
|
||||
# -e remote_users_fact_state=present
|
||||
#
|
||||
# # Validation + résumé seul (fact déjà déployé) :
|
||||
# ansible-playbook -i inventories/hosts.yml site.yml --tags validate,summary
|
||||
# # Supprimer partout :
|
||||
# ansible-playbook -i inventories/hosts.yml site.yml \
|
||||
# -e remote_users_fact_state=absent
|
||||
#
|
||||
# # Limiter à un groupe :
|
||||
# ansible-playbook -i inventories/hosts.yml site.yml -l citrix_servers
|
||||
#
|
||||
# # Tags disponibles :
|
||||
# --tags assert → assertions seules
|
||||
# --tags present,deploy → déploiement seul
|
||||
# --tags validate → validation seule
|
||||
# --tags summary → résumé seul
|
||||
# --tags absent,remove → suppression seule
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
- name: Déployer et valider le local fact remote_users
|
||||
- name: Gérer le local fact remote_users
|
||||
hosts: all
|
||||
become: true
|
||||
gather_facts: true
|
||||
|
||||
Reference in New Issue
Block a user