218 lines
7.1 KiB
Markdown
218 lines
7.1 KiB
Markdown
# remote_users_fact
|
|
|
|
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
|
|
|
|
```
|
|
├── site.yml # Playbook principal
|
|
├── inventories/
|
|
│ └── hosts.yml # Inventaire exemple
|
|
└── roles/
|
|
└── remote_users_fact/
|
|
├── 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 # 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
|
|
# Appliquer le state défini dans l'inventaire
|
|
ansible-playbook -i inventories/hosts.yml site.yml
|
|
|
|
# Forcer le déploiement partout (override)
|
|
ansible-playbook -i inventories/hosts.yml site.yml -e remote_users_fact_state=present
|
|
|
|
# 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 |
|
|
| `remote_users_fact_group` | `root` | Groupe |
|
|
| `remote_users_fact_validate` | `true` | Activer la validation post-deploy |
|
|
| `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` :
|
|
|
|
```json
|
|
{
|
|
"timestamp": "2026-04-13T10:30:00Z",
|
|
"sessions": {
|
|
"ssh": 3,
|
|
"citrix": 12,
|
|
"horizon": 0,
|
|
"total_by_protocol": 15,
|
|
"who_remote": 14
|
|
},
|
|
"users_remote": "alice,bob,charlie",
|
|
"reliability": {
|
|
"ratio_who_over_total": 0.93,
|
|
"verdict": "WHO_INF_TOTAL",
|
|
"detail": "who manque 1 session(s) sans TTY"
|
|
},
|
|
"detection": {
|
|
"citrix_vda_installed": true,
|
|
"horizon_agent_installed": false,
|
|
"ssh_method": "sshd_process_and_ss",
|
|
"citrix_method": "ctxquery",
|
|
"horizon_method": "fallback_ports"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Verdicts
|
|
|
|
| Verdict | Signification |
|
|
| --- | --- |
|
|
| `FIABLE` | who == total → compteurs alignés |
|
|
| `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
|
|
```
|
|
|
|
## CI / Tests
|
|
|
|
Le rôle est testé automatiquement sur toutes les distributions déclarées dans `meta/main.yml` via Docker.
|
|
|
|
### Commandes Make
|
|
|
|
```bash
|
|
make help # Affiche les cibles disponibles
|
|
make matrix # Affiche la matrice JSON des distros
|
|
make lint # yamllint + ansible-lint
|
|
make test # Teste toutes les distros
|
|
make test-el9 # Teste une seule distro
|
|
make clean # Supprime les images Docker de test
|
|
```
|
|
|
|
### Registry privée
|
|
|
|
Par défaut les images sont tirées depuis Docker Hub. Pour utiliser une registry privée (Artifactory, Harbor, etc.), définir les variables d'environnement :
|
|
|
|
| Variable | Défaut | Exemple |
|
|
| --- | --- | --- |
|
|
| `DOCKER_REGISTRY` | *(vide = Docker Hub)* | `registry.nuevolia.dev` |
|
|
| `DOCKER_REGISTRY_PREFIX` | *(vide)* | `library/` |
|
|
|
|
```bash
|
|
# Artifactory
|
|
DOCKER_REGISTRY=registry.nuevolia.dev DOCKER_REGISTRY_PREFIX=library/ make test
|
|
|
|
# Harbor
|
|
DOCKER_REGISTRY=harbor.local DOCKER_REGISTRY_PREFIX=proxy/ make test
|
|
```
|
|
|
|
### Pipelines CI
|
|
|
|
Trois configurations sont fournies :
|
|
|
|
| Fichier | Système | Stratégie |
|
|
| --- | --- | --- |
|
|
| `.gitea/workflows/ci.yml` | Gitea Actions | Matrix dynamique parallèle |
|
|
| `.gitlab-ci.yml` | GitLab CI | Séquentiel |
|
|
| `Jenkinsfile` | Jenkins | Stages parallèles |
|
|
|
|
Les variables `DOCKER_REGISTRY` et `DOCKER_REGISTRY_PREFIX` peuvent être définies dans les secrets/variables de chaque CI.
|
|
|
|
## Utilisation dans d'autres playbooks
|
|
|
|
```yaml
|
|
- hosts: all
|
|
gather_facts: true
|
|
tasks:
|
|
- name: Bloquer un déploiement si trop de sessions
|
|
ansible.builtin.fail:
|
|
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
|
|
```
|