1{ lib, ... }:
2
3let
4 ports = {
5 alertmanager-ntfy = 8000;
6 ntfy-sh = 8001;
7 alertmanager = 8002;
8 };
9in
10
11{
12 name = "alertmanager-ntfy";
13 meta.maintainers = with lib.maintainers; [ defelo ];
14
15 nodes.machine = {
16 services.prometheus.alertmanager = {
17 enable = true;
18 listenAddress = "127.0.0.1";
19 port = ports.alertmanager;
20
21 configuration = {
22 route = {
23 receiver = "test";
24 group_by = [ "..." ];
25 group_wait = "0s";
26 group_interval = "1s";
27 repeat_interval = "2h";
28 };
29
30 receivers = [
31 {
32 name = "test";
33 webhook_configs = [ { url = "http://127.0.0.1:${toString ports.alertmanager-ntfy}/hook"; } ];
34 }
35 ];
36 };
37 };
38
39 services.prometheus.alertmanager-ntfy = {
40 enable = true;
41 settings = {
42 http.addr = "127.0.0.1:${toString ports.alertmanager-ntfy}";
43 ntfy = {
44 baseurl = "http://127.0.0.1:${toString ports.ntfy-sh}";
45 notification.topic = "alertmanager";
46 };
47 };
48 };
49
50 services.ntfy-sh = {
51 enable = true;
52 settings = {
53 listen-http = "127.0.0.1:${toString ports.ntfy-sh}";
54 base-url = "http://127.0.0.1:${toString ports.ntfy-sh}";
55 };
56 };
57 };
58
59 interactive.nodes.machine = {
60 services.prometheus.alertmanager.listenAddress = lib.mkForce "0.0.0.0";
61 services.prometheus.alertmanager-ntfy.settings.http.addr =
62 lib.mkForce "0.0.0.0:${toString ports.alertmanager-ntfy}";
63 services.ntfy-sh.settings.listen-http = lib.mkForce "0.0.0.0:${toString ports.ntfy-sh}";
64 networking.firewall.enable = false;
65 virtualisation.forwardPorts = lib.mapAttrsToList (_: port: {
66 from = "host";
67 host = { inherit port; };
68 guest = { inherit port; };
69 }) ports;
70 };
71
72 testScript = ''
73 import json
74 import time
75
76 machine.wait_for_unit("alertmanager.service")
77 machine.wait_for_unit("alertmanager-ntfy.service")
78 machine.wait_for_unit("ntfy-sh.service")
79 machine.wait_for_open_port(${toString ports.alertmanager})
80 machine.wait_for_open_port(${toString ports.alertmanager-ntfy})
81 machine.wait_for_open_port(${toString ports.ntfy-sh})
82
83 machine.succeed("""curl 127.0.0.1:${toString ports.alertmanager}/api/v2/alerts \
84 -X POST -H 'Content-Type: application/json' \
85 -d '[{ \
86 "labels": {"alertname": "test"},
87 "annotations": {"summary": "alert summary", "description": "alert description"} \
88 }]'""")
89
90 while not (resp := machine.succeed("curl '127.0.0.1:${toString ports.ntfy-sh}/alertmanager/json?poll=1'")):
91 time.sleep(1)
92
93 msg = json.loads(resp)
94 assert msg["title"] == "alert summary"
95 assert msg["message"] == "alert description"
96 assert msg["priority"] == 4
97 assert "red_circle" in msg["tags"]
98 '';
99}