Set-OPS-Public/roles/serveur_icinga/templates/setops-sondes.conf.j2
Daniel Allaire d2e2bb8990 connectivite : une sonde a la minute remplace la matrice du pare-feu
make flux ecrit, a cote de chaque .nft et depuis les memes regles, la
liste de ce que chaque VM doit joindre. La sonde (nftables_baseline) la
teste chaque minute avec la cause (rejete, delai, personne n'ecoute) ;
client_sante la porte en mode minute ; Icinga a une fraicheur par sonde.
eprouver_parefeu --sondes : tout activer d'un coup, juger par Icinga.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:46:49 -04:00

72 lines
3.7 KiB
Django/Jinja

/*
* Gere par Set-OPS (role serveur_icinga). Ne pas editer a la main.
*
* LES SONDES QUE LES ROLES DECLARENT — voir docs/supervision-conception.md.
*
* Rien ici n'est ecrit a la main : chaque service vient d'un `meta/supervision.yml`, et
* s'attache aux hotes qui portent le role qui le declare. Ajouter une sonde a un role la
* fait apparaitre ici sans toucher a ce fichier — comme un flux declare devient une
* regle nftables.
*
* CE QUE CA REMPLACE : dix-neuf lignes `surveillance:` en prose dans
* `docs/dependances-groupes.yml`, ecrites, versionnees, relues — et qu'aucun mecanisme
* n'executait. La carte disait ce qui etait surveille, et personne ne surveillait.
*
* Les HOTES sont definis dans `setops-hotes.conf` : ici, rien que des services.
*/
{#
* UN SERVICE PASSIF N'EXISTE QUE POUR UN HOTE QUI PEUT POUSSER (2026-09-10).
*
* Les hyperviseurs ont rejoint `client_metrique` — c'est par ce groupe qu'on leur
* DEPLOIE node_exporter. La derivation en tirait donc `asgard!metriques`, et Icinga
* refusait la configuration ENTIERE :
*
* Attribute 'host_name': Object 'asgard' of type 'Host' does not exist.
*
* Meme en definissant l'hote, le service serait reste UNKNOWN pour toujours : un
* hyperviseur ne porte pas `client_sante`, parce que sa route par defaut est gelee et
* qu'il ne peut rien pousser (D-57). On le TIRE avec Prometheus.
*
* L'appartenance a un groupe sert donc DEUX choses qui ne coincident pas toujours : a
* qui l'on deploie, et de qui l'on attend un rapport. La seconde se lit sur le porteur
* lui-meme — `client_sante` — et nulle part ailleurs.
UNE SONDE POSEE SOUS CONDITION N'EST ATTENDUE QUE LA OU ELLE EST POSEE (2026-09-28).
Trois roles posent leur sonde sous `when:` (`journaux-frontiere`, `audit`,
`console-ops`). Ce fichier les attendait pourtant sur tout hote du groupe : chaque
locataire portait un `journaux-frontiere` rouge a vie, sa frontiere appartenant au site.
La declaration porte donc la MEME condition que le depot : `seulement_si: <variable>`,
lue dans l'inventaire de l'hote, sinon dans les defauts du role qui la definit
(`defini_par`, par defaut le role declarant) — la valeur meme que ce role voit.
`test_sondes_conditionnelles.py` garde l'accord entre le `when:` et la declaration.
#}
{#
UNE FRAICHEUR PAR SONDE, SI ELLE LA DECLARE (2026-09-30). `connectivite` bat a la minute :
attendue au quart d'heure et demi comme les autres, son silence ne se verrait qu'au bout
de 90 min. `fraicheur:` dans `meta/supervision.yml`, sinon la valeur commune.
#}
{% for role, sondes in (serveur_icinga_sondes | default({})) | dictsort %}
{% for hote in ((groups[role] | default([])) | intersect(groups['client_sante'] | default([]))) | sort %}
{% for sonde in sondes %}
{% set condition = sonde.seulement_si | default('') %}
{% if condition %}
{% set defauts = lookup('file', role_path ~ '/../' ~ (sonde.defini_par | default(role)) ~ '/defaults/main.yml') | from_yaml %}
{% set valeur = hostvars[hote][condition] if hostvars[hote][condition] is defined else defauts.get(condition) %}
{% endif %}
{% if not condition or valeur %}
{% set fraicheur = sonde.fraicheur | default(serveur_icinga_fraicheur_sondes) %}
object Service "{{ sonde.nom }}" {
import "setops-rapport-attendu"
host_name = "{{ hote }}"
check_interval = {{ fraicheur }}s
retry_interval = {{ fraicheur }}s
vars.dummy_text = "AUCUN RAPPORT depuis {{ (fraicheur / 60) | int }} min : cette sonde ne rapporte plus, ou n a jamais rapporte."
vars.setops_source = "{{ hote }}"
vars.setops_role = "{{ role }}"
vars.setops_raison = "{{ (sonde.raison | default('')) | replace('"', "'") | replace('\n', ' ') | trim }}"
}
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}