Paillasse/ansible/roles/supervision/templates/alertmanager-ntfy.py.j2

73 lines
2.4 KiB
Text
Raw Normal View History

#!/usr/bin/env python3
"""Relais local : reçoit le webhook JSON d'Alertmanager, le transforme en
notification ntfy. Géré par Ansible (rôle supervision) — ne pas modifier à la
main. N'écoute que sur 127.0.0.1 : jamais exposé en dehors du serveur.
L'URL ntfy (avec le topic) est un secret : lue depuis {{ supervision_fichier_webhook }}
à chaque notification, jamais mise en cache, jamais journalisée.
"""
import http.server
import json
import urllib.request
FICHIER_WEBHOOK = "{{ supervision_fichier_webhook }}"
ADRESSE = ("127.0.0.1", {{ supervision_port_relais }})
def lire_url_ntfy():
with open(FICHIER_WEBHOOK, encoding="utf-8") as f:
return f.read().strip()
class Gestionnaire(http.server.BaseHTTPRequestHandler):
def do_POST(self):
longueur = int(self.headers.get("Content-Length", 0))
corps = self.rfile.read(longueur)
try:
charge = json.loads(corps)
except ValueError:
self.send_response(400)
self.end_headers()
return
try:
url_ntfy = lire_url_ntfy()
except OSError:
self.send_response(500)
self.end_headers()
return
for alerte in charge.get("alerts", []):
statut = alerte.get("status", "inconnu")
nom = alerte.get("labels", {}).get("alertname", "?")
resume = (
alerte.get("annotations", {}).get("description")
or alerte.get("annotations", {}).get("summary")
or nom
)
titre = f"[{statut.upper()}] {nom}"
requete = urllib.request.Request(
url_ntfy,
data=resume.encode("utf-8"),
method="POST",
headers={
"Title": titre,
"Priority": "high" if statut == "firing" else "default",
},
)
try:
urllib.request.urlopen(requete, timeout=5)
except Exception:
pass # ne bloque jamais Alertmanager ; vérifier manuellement en cas de doute
self.send_response(200)
self.end_headers()
def log_message(self, format, *args): # silencieux : rien de secret à tracer non plus
pass
if __name__ == "__main__":
serveur = http.server.HTTPServer(ADRESSE, Gestionnaire)
serveur.serve_forever()