feat(ansible-role-remote_users_fact): set remote_users_fact_state default var

This commit is contained in:
2026-04-13 23:40:52 +02:00
parent 51f19b678f
commit 1987c5791c
10 changed files with 484 additions and 49 deletions
+52
View File
@@ -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
+135
View File
@@ -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 %}
+38 -7
View File
@@ -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
+29
View File
@@ -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 -2
View File
@@ -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 }} —
+86 -10
View File
@@ -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"