1{ pkgs, ... }:
2let
3 secret-files = pkgs.runCommandLocal "secret-files" { } ''
4 mkdir -p $out
5 echo -n faketoken > $out/token.txt
6 echo -n wontbeused > $out/secret.txt
7 '';
8in
9{
10 name = "matrix-alertmanager";
11 meta.maintainers = with pkgs.lib.maintainers; [ erethon ];
12
13 nodes = {
14 homeserver =
15 { pkgs, ... }:
16 {
17 services.matrix-synapse = {
18 enable = true;
19 settings = {
20 database.name = "sqlite3";
21 tls_certificate_path = "../common/acme/server/acme.test.cert.pem";
22 tls_private_key_path = "../common/acme/server/acme.test.key.pem";
23 enable_registration = true;
24 enable_registration_without_verification = true;
25 registration_shared_secret = "supersecret-registration";
26 listeners = [
27 {
28 # The default but tls=false
29 bind_addresses = [
30 "0.0.0.0"
31 ];
32 port = 8448;
33 resources = [
34 {
35 compress = true;
36 names = [ "client" ];
37 }
38 {
39 compress = false;
40 names = [ "federation" ];
41 }
42 ];
43 tls = false;
44 type = "http";
45 x_forwarded = false;
46 }
47 ];
48 };
49 };
50
51 networking.firewall.allowedTCPPorts = [ 8448 ];
52
53 environment.systemPackages = [
54 (pkgs.writeShellScriptBin "register_alertmanager_user" ''
55 exec ${pkgs.matrix-synapse}/bin/register_new_matrix_user \
56 -u alertmanager \
57 -p alertmanager-password \
58 --admin \
59 --shared-secret supersecret-registration \
60 http://localhost:8448
61 '')
62 # This is needed to solve a chicken and egg
63 # problem. Matrix-alertmanager expects a token for authentication,
64 # but a token is created after the user has been registered. This
65 # changes the token in the database to match the one specified in
66 # the service settings.
67 (pkgs.writers.writePython3Bin "hardcode_matrix_values"
68 {
69 libraries = with pkgs.python3Packages; [
70 sqlite-utils
71 ];
72 }
73 ''
74 import sqlite3
75 con = sqlite3.connect("/var/lib/matrix-synapse/homeserver.db")
76 cur = con.cursor()
77 cur.execute(
78 "update access_tokens set token='%s' where user_id = '%s'"
79 % ("faketoken", "@alertmanager:homeserver")
80 )
81 con.commit()
82 con.close()
83 ''
84 )
85 ];
86 };
87
88 matrix_alertmanager =
89 { config, pkgs, ... }:
90 {
91 environment.etc.token-file.source = "${secret-files}/token.txt";
92 environment.etc.secret-file.source = "${secret-files}/secret.txt";
93 services.matrix-alertmanager = {
94 enable = true;
95 tokenFile = "/etc/${config.environment.etc.token-file.target}";
96 secretFile = "/etc/${config.environment.etc.secret-file.target}";
97 homeserverUrl = "http://homeserver:8448";
98 # Matrix-alertmanager expects at least a room in its configuration
99 # in order to start. However, the room doesn't have to exist for
100 # matrix-alertmanager to start, so this is a configuration only
101 # placeholder.
102 matrixRooms = [
103 {
104 receivers = [ "matrix" ];
105 roomId = "!room_id:homeserver";
106 }
107 ];
108 matrixUser = "alertmanager";
109 };
110 };
111 };
112
113 testScript = ''
114 with subtest("start homeserver"):
115 homeserver.start()
116 homeserver.wait_for_unit("matrix-synapse.service")
117 homeserver.wait_until_succeeds("curl --fail -L http://localhost:8448/")
118
119 with subtest("register user"):
120 # register alertmanager user
121 homeserver.succeed("register_alertmanager_user")
122
123 with subtest("hardcode matrix values for matrix-alertmanager to use"):
124 homeserver.succeed("hardcode_matrix_values")
125
126 with subtest("start matrix_alertmanager"):
127 matrix_alertmanager.start()
128 matrix_alertmanager.wait_for_unit("matrix-alertmanager.service")
129 matrix_alertmanager.wait_until_succeeds("curl --fail -L http://localhost:3000/")
130 matrix_alertmanager.wait_for_console_text("matrix-alertmanager initialized and ready")
131 '';
132}