#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