alertmanager-gotify-bridge: initial commit with bridge and CI
Some checks failed
ci/woodpecker/tag/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/tag/woodpecker Pipeline failed
This commit is contained in:
86
bridge.py
Normal file
86
bridge.py
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Alertmanager webhook receiver that forwards alerts to Gotify."""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.error import URLError
|
||||
|
||||
GOTIFY_URL = os.environ["GOTIFY_URL"]
|
||||
DISASTER_TOKEN = os.environ["DISASTER_TOKEN"]
|
||||
WARNING_TOKEN = os.environ["WARNING_TOKEN"]
|
||||
DISASTER_PRIORITY = int(os.environ.get("DISASTER_PRIORITY", "8"))
|
||||
WARNING_PRIORITY = int(os.environ.get("WARNING_PRIORITY", "4"))
|
||||
|
||||
SEVERITY_MAP = {
|
||||
"critical": (DISASTER_TOKEN, DISASTER_PRIORITY),
|
||||
"warning": (WARNING_TOKEN, WARNING_PRIORITY),
|
||||
}
|
||||
|
||||
|
||||
def send_gotify(token, title, message, priority):
|
||||
data = json.dumps({
|
||||
"title": title,
|
||||
"message": message,
|
||||
"priority": priority,
|
||||
}).encode()
|
||||
req = Request(
|
||||
f"{GOTIFY_URL}/message?token={token}",
|
||||
data=data,
|
||||
headers={"Content-Type": "application/json"},
|
||||
)
|
||||
try:
|
||||
urlopen(req)
|
||||
except URLError as e:
|
||||
print(f"ERROR sending to Gotify: {e}", file=sys.stderr)
|
||||
|
||||
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
try:
|
||||
length = int(self.headers.get("Content-Length", 0))
|
||||
body = json.loads(self.rfile.read(length))
|
||||
except (json.JSONDecodeError, ValueError) as e:
|
||||
self.send_response(400)
|
||||
self.end_headers()
|
||||
self.wfile.write(f"Bad request: {e}".encode())
|
||||
return
|
||||
|
||||
for alert in body.get("alerts", []):
|
||||
severity = alert.get("labels", {}).get("severity", "warning")
|
||||
token, priority = SEVERITY_MAP.get(severity, SEVERITY_MAP["warning"])
|
||||
status = alert.get("status", "firing")
|
||||
alertname = alert.get("labels", {}).get("alertname", "Unknown")
|
||||
summary = alert.get("annotations", {}).get("summary", "")
|
||||
|
||||
prefix = "RESOLVED" if status == "resolved" else "FIRING"
|
||||
title = f"[{prefix}] {alertname}"
|
||||
message = summary or f"{alertname} is {status}"
|
||||
|
||||
send_gotify(token, title, message, priority)
|
||||
print(f"Forwarded: {title} -> severity={severity} priority={priority}")
|
||||
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
self.wfile.write(b"ok")
|
||||
|
||||
def do_GET(self):
|
||||
if self.path == "/health":
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
self.wfile.write(b"ok")
|
||||
return
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
|
||||
def log_message(self, format, *args):
|
||||
print(format % args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
port = int(os.environ.get("PORT", "8080"))
|
||||
server = HTTPServer(("0.0.0.0", port), Handler)
|
||||
print(f"Bridge listening on :{port}")
|
||||
server.serve_forever()
|
||||
Reference in New Issue
Block a user