Elle etait verte pendant que les tableaux etaient vides. Eprouvee avec une source recreant le defaut du jour, puis retiree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
3.1 KiB
Django/Jinja
63 lines
3.1 KiB
Django/Jinja
#!/bin/bash
|
|
# GENERE par Set-OPS (role serveur_grafana). Ne pas editer a la main.
|
|
#
|
|
# SONDE « tableaux » — Grafana repond, sa base tient, et ses SOURCES DE DONNEES aussi.
|
|
#
|
|
# Contrat : docs/supervision-conception.md (API des greffons Nagios) — une ligne, 0/1/2.
|
|
# Mise en defaut PAR PARAMETRE : `serveur_grafana_sonde_url` (port ferme).
|
|
#
|
|
# LES SOURCES, DEPUIS LE 2026-09-28. Cette sonde etait verte pendant que les tableaux des
|
|
# locataires n'affichaient RIEN : Grafana repondait, sa base tenait — mais sa source Loki
|
|
# parlait en clair a un Loki qui servait en HTTPS. Les tableaux tirent leur liste d'hotes de
|
|
# Loki : vide, aucun panneau ne se remplissait. « Grafana repond » n'etait pas la question ;
|
|
# « Grafana peut-il montrer quelque chose » l'est.
|
|
#
|
|
# LE MOT DE PASSE EST LU LA OU IL EST, pas recopie : dans le drop-in systemd de Grafana,
|
|
# en 0600 root. La sonde tourne en root ; rien d'autre ne le voit, et il n'est pas affiche.
|
|
set -uo pipefail
|
|
|
|
URL={{ serveur_grafana_sonde_url }}
|
|
DROPIN=/etc/systemd/system/grafana-server.service.d/setops.conf
|
|
|
|
s=$(curl -s --max-time 10 "${URL}/api/health" 2>/dev/null)
|
|
[[ -n "${s}" ]] || { echo "Grafana ne repond pas sur ${URL}."; exit 2; }
|
|
base=$(printf '%s' "${s}" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("database","?"))' 2>/dev/null)
|
|
ver=$(printf '%s' "${s}" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("version","?"))' 2>/dev/null)
|
|
[[ "${base}" == "ok" ]] || { echo "Grafana repond mais sa base est en defaut (${base:-illisible})."; exit 2; }
|
|
|
|
MDP=$(grep -hoP 'GF_SECURITY_ADMIN_PASSWORD=\K\S+' "${DROPIN}" 2>/dev/null | head -1)
|
|
if [[ -z "${MDP}" ]]; then
|
|
echo "Grafana ${ver} : base ok, mais sources NON verifiees (mot de passe illisible dans ${DROPIN})."
|
|
exit 1
|
|
fi
|
|
|
|
GRAFANA_MDP="${MDP}" python3 - "${URL}" "${ver}" <<'EOF'
|
|
import base64, json, os, sys, urllib.request
|
|
url, ver = sys.argv[1], sys.argv[2]
|
|
auth = "Basic " + base64.b64encode(f"admin:{os.environ['GRAFANA_MDP']}".encode()).decode()
|
|
def lire(chemin):
|
|
req = urllib.request.Request(url + chemin, headers={"Authorization": auth})
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=8) as r:
|
|
return json.loads(r.read())
|
|
except urllib.error.HTTPError as e:
|
|
try:
|
|
return json.loads(e.read())
|
|
except ValueError:
|
|
return {"status": "ERROR", "message": f"HTTP {e.code}"}
|
|
except OSError as e:
|
|
return {"status": "ERROR", "message": str(e)[:80]}
|
|
sources = lire("/api/datasources")
|
|
if not isinstance(sources, list):
|
|
print(f"Grafana {ver} : base ok, mais la liste des sources est illisible ({str(sources)[:80]}).")
|
|
sys.exit(1)
|
|
ko, ok = [], []
|
|
for d in sources:
|
|
h = lire(f"/api/datasources/uid/{d['uid']}/health")
|
|
(ok if h.get("status") == "OK" else ko).append(f"{d['name']} ({str(h.get('message'))[:70]})" if h.get("status") != "OK" else d["name"])
|
|
perf = f"| sources_ok={len(ok)} sources_ko={len(ko)}"
|
|
if ko:
|
|
print(f"Grafana {ver} repond, mais source(s) EN DEFAUT : {'; '.join(ko)} — les tableaux restent vides. {perf}")
|
|
sys.exit(2)
|
|
print(f"Grafana {ver} : base ok, sources saines ({', '.join(ok) or 'aucune'}). {perf}")
|
|
EOF
|