Les 33 roles serveur_* declarent maintenant une sonde. Les huit qui manquaient
sont ceux dont la verite ne ressemble pas a « ce service repond-il ».
Quatre marqueurs du site : ce que tasks/main.yml verifie UNE FOIS au deploiement
cesse d etre vrai sans que rien ne tombe. La racine du cache se retrouve chainee,
la forge du genome repond en n ayant plus rien dedans, un locataire n est plus
admis a resoudre, l isolation d un depot glisse.
serveur_ops_site ne sert rien : il detient un pouvoir. La sonde verifie que la
carte est la, que la voute du site est chiffree et que sa cle est en 0600 — sans
lire le contenu d aucun des trois.
serveur_icingaweb2 surveille la vitrine de la supervision elle-meme : si la
console meurt, tout reste vert et l exploitant est aveugle.
DEFAUT 1 — quatre gabarits qu Ansible aurait refuse de rendre. Jinja lit le
{# de ${#tableau[@]} comme un debut de commentaire. Le depot connaissait le
remede et l appliquait la ou quelqu un s etait fait prendre, nulle part ailleurs.
P76 rend desormais chaque gabarit de role, avec les delimiteurs qu Ansible en
tirerait — pas une recherche de motif.
DEFAUT 2 — la doctrine promettait 54 greffons et citait check_pgsql. La flotte a
monitoring-plugins-basic : 53, sans check_pgsql ni check_dns ni check_ldap. Le
paquet qui les porte traine samba et snmp sur chaque machine. Un greffon absent
sort en 127, qui n est pas un code Nagios.
21 controles negatifs sur les machines reelles du site. ansible-lint production
0/91, harnais 75 OK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
68 lines
3 KiB
Django/Jinja
68 lines
3 KiB
Django/Jinja
#jinja2: comment_start_string:'{=#', comment_end_string:'#=}'
|
|
#!/bin/bash
|
|
# (Le gabarit redefinit le delimiteur de commentaire Jinja : `${#tableau[@]}` contient
|
|
# la sequence `{#`, que Jinja lirait comme un debut de commentaire. Le shell en a
|
|
# besoin ; c'est donc Jinja qui cede. Meme geste que `client_sante/setops-sante.sh.j2`
|
|
# et `serveur_nginx/sonde-edge.sh.j2`.)
|
|
# GENERE par Set-OPS (role serveur_web_dorsal). Ne pas editer a la main.
|
|
#
|
|
# SONDE « apps-servies » — chacune des webapps declarees repond-elle encore ?
|
|
#
|
|
# UNE BOUCLE AUTOUR D'UN GREFFON. Chaque app est mesuree par `check_http` ; ce que la
|
|
# boucle ajoute est la LISTE des apps que cet hebergeur doit servir, qui vient du plan.
|
|
#
|
|
# DEUX LECTURES PAR APP, ET ELLES NE DISENT PAS LA MEME CHOSE :
|
|
# - l'unite systemd est-elle active ? -> l'app a-t-elle ete lancee
|
|
# - son port repond-il ? -> l'app fait-elle encore son travail
|
|
# La seconde est celle qui compte, et c'est justement celle qu'aucun rapport d'unites en
|
|
# echec ne fera jamais. La premiere reste utile pour NOMMER la cause : « pas demarree »
|
|
# et « demarree mais coincee » n'appellent pas le meme geste.
|
|
set -uo pipefail
|
|
|
|
noms=({% for a in serveur_web_dorsal_apps | default([]) %}'{{ a.nom }}' {% endfor %})
|
|
ports=({% for a in serveur_web_dorsal_apps | default([]) %}'{{ a.port }}' {% endfor %})
|
|
|
|
if (( ${#noms[@]} == 0 )); then
|
|
# PAS UN VERT MUET : un hebergeur sans app declaree est un etat legitime, et le dire
|
|
# vaut mieux qu'un succes qui laisserait croire qu'on a verifie quelque chose.
|
|
echo "Aucune webapp declaree sur cet hebergeur : rien a servir, rien a verifier."
|
|
exit 0
|
|
fi
|
|
|
|
fautives=()
|
|
for i in "${!noms[@]}"; do
|
|
nom=${noms[$i]}
|
|
port=${ports[$i]}
|
|
|
|
etat=$(systemctl is-active "${nom}.service" 2>/dev/null || true)
|
|
if [[ "${etat}" != "active" ]]; then
|
|
fautives+=("${nom} : unite ${etat:-introuvable}")
|
|
continue
|
|
fi
|
|
|
|
# LE CODE ATTENDU N'EST PAS 200. Une webapp peut parfaitement rendre 302 (redirection
|
|
# vers une page de connexion), 401 ou 403 a la racine sans etre en panne. Ce qu'on
|
|
# exclut, ce sont les 5xx et l'absence de reponse — c'est-a-dire l'app coincee ou morte.
|
|
sortie=$(/usr/lib/nagios/plugins/check_http -H 127.0.0.1 -p "${port}" -u / \
|
|
-e '{{ serveur_web_dorsal_sonde_codes }}' -t 10 2>&1)
|
|
code=$?
|
|
# LE GREFFON REND PARFOIS DEUX LIGNES — la cause, puis son verdict. Icinga ne
|
|
# garde que la premiere pour resume : sans repliage, la moitie du message
|
|
# disparait de la vue qu'on regarde en premier.
|
|
resume=${sortie%%|*}
|
|
resume=${resume//$'\n'/ }
|
|
if (( code != 0 )); then
|
|
# LE MESSAGE DU GREFFON EST CONSERVE : c'est lui qui distingue « socket ferme » de
|
|
# « delai depasse » — l'app morte de l'app coincee, et le geste n'est pas le meme.
|
|
fautives+=("${nom} : active mais ${resume}")
|
|
fi
|
|
done
|
|
|
|
if (( ${#fautives[@]} > 0 )); then
|
|
liste=$(printf '%s; ' "${fautives[@]}"); liste=${liste%; }
|
|
echo "Webapp(s) qui ne repondent plus — ${liste}"
|
|
exit 2
|
|
fi
|
|
|
|
echo "Webapps : ${#noms[@]} servie(s) — ${noms[*]}."
|
|
exit 0
|