2020-02-07 10:04:22 +01:00
|
|
|
# Webhooks for external integrations.
|
|
|
|
|
2024-07-12 02:30:25 +02:00
|
|
|
from typing import Annotated
|
|
|
|
|
2020-02-07 10:04:22 +01:00
|
|
|
from django.http import HttpRequest, HttpResponse
|
|
|
|
|
2020-08-20 00:32:15 +02:00
|
|
|
from zerver.decorator import webhook_view
|
2020-02-07 10:04:22 +01:00
|
|
|
from zerver.lib.response import json_success
|
2023-09-27 19:01:31 +02:00
|
|
|
from zerver.lib.typed_endpoint import ApiParamConfig, JsonBodyPayload, typed_endpoint
|
2023-08-12 09:34:31 +02:00
|
|
|
from zerver.lib.validator import WildValue, check_string
|
2020-02-07 10:04:22 +01:00
|
|
|
from zerver.lib.webhooks.common import check_send_webhook_message
|
|
|
|
from zerver.models import UserProfile
|
|
|
|
|
2020-06-11 00:54:34 +02:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
@webhook_view("Alertmanager")
|
2023-08-12 09:34:31 +02:00
|
|
|
@typed_endpoint
|
2021-02-12 08:19:30 +01:00
|
|
|
def api_alertmanager_webhook(
|
|
|
|
request: HttpRequest,
|
|
|
|
user_profile: UserProfile,
|
2023-08-12 09:34:31 +02:00
|
|
|
*,
|
2023-09-27 19:01:31 +02:00
|
|
|
payload: JsonBodyPayload[WildValue],
|
2023-08-12 09:34:31 +02:00
|
|
|
name_field: Annotated[str, ApiParamConfig("name")] = "instance",
|
|
|
|
desc_field: Annotated[str, ApiParamConfig("desc")] = "alertname",
|
2021-02-12 08:19:30 +01:00
|
|
|
) -> HttpResponse:
|
2024-07-12 02:30:17 +02:00
|
|
|
topics: dict[str, dict[str, list[str]]] = {}
|
2020-02-07 10:04:22 +01:00
|
|
|
|
|
|
|
for alert in payload["alerts"]:
|
|
|
|
labels = alert.get("labels", {})
|
|
|
|
annotations = alert.get("annotations", {})
|
|
|
|
|
2021-12-17 07:03:22 +01:00
|
|
|
name = labels.get(name_field, annotations.get(name_field, "(unknown)")).tame(check_string)
|
|
|
|
desc = labels.get(
|
|
|
|
desc_field, annotations.get(desc_field, f"<missing field: {desc_field}>")
|
|
|
|
).tame(check_string)
|
2020-02-07 10:04:22 +01:00
|
|
|
|
2021-12-17 07:03:22 +01:00
|
|
|
url = alert["generatorURL"].tame(check_string).replace("tab=1", "tab=0")
|
2020-02-07 10:04:22 +01:00
|
|
|
|
2024-01-30 23:32:41 +01:00
|
|
|
body = f"{desc} ([source]({url}))"
|
2020-02-07 10:04:22 +01:00
|
|
|
if name not in topics:
|
|
|
|
topics[name] = {"firing": [], "resolved": []}
|
2021-12-17 07:03:22 +01:00
|
|
|
topics[name][alert["status"].tame(check_string)].append(body)
|
2020-02-07 10:04:22 +01:00
|
|
|
|
2024-01-17 15:53:30 +01:00
|
|
|
for topic_name, statuses in topics.items():
|
2020-02-07 10:04:22 +01:00
|
|
|
for status, messages in statuses.items():
|
|
|
|
if len(messages) == 0:
|
|
|
|
continue
|
|
|
|
|
|
|
|
if status == "firing":
|
|
|
|
icon = ":alert:"
|
|
|
|
title = "FIRING"
|
|
|
|
else:
|
|
|
|
title = "Resolved"
|
|
|
|
icon = ":squared_ok:"
|
|
|
|
|
|
|
|
if len(messages) == 1:
|
2020-06-10 06:40:53 +02:00
|
|
|
body = f"{icon} **{title}** {messages[0]}"
|
2020-02-07 10:04:22 +01:00
|
|
|
else:
|
2020-09-02 06:20:26 +02:00
|
|
|
message_list = "\n".join(f"* {m}" for m in messages)
|
2020-06-10 06:40:53 +02:00
|
|
|
body = f"{icon} **{title}**\n{message_list}"
|
2020-02-07 10:04:22 +01:00
|
|
|
|
2024-01-17 15:53:30 +01:00
|
|
|
check_send_webhook_message(request, user_profile, topic_name, body)
|
2020-02-07 10:04:22 +01:00
|
|
|
|
2022-01-31 13:44:02 +01:00
|
|
|
return json_success(request)
|