1{
2 lib,
3 pkgs,
4 config,
5 ...
6}:
7let
8 ldapDomain = "example.org";
9 ldapSuffix = "dc=example,dc=org";
10
11 ldapRootUser = "root";
12 ldapRootPassword = "foobar23";
13
14 testUser = "myuser";
15 testPassword = "foobar23";
16 teamName = "myteam";
17in
18{
19 name = "oncall";
20 meta.maintainers = with lib.maintainers; [ onny ];
21
22 nodes = {
23 machine = {
24 virtualisation.memorySize = 2048;
25
26 environment.etc."oncall-secrets.yml".text = ''
27 auth:
28 ldap_bind_password: "${ldapRootPassword}"
29 '';
30
31 environment.systemPackages = [ pkgs.jq ];
32
33 services.oncall = {
34 enable = true;
35 settings = {
36 auth = {
37 module = "oncall.auth.modules.ldap_import";
38 ldap_url = "ldap://localhost";
39 ldap_user_suffix = "";
40 ldap_bind_user = "cn=${ldapRootUser},${ldapSuffix}";
41 ldap_base_dn = "ou=accounts,${ldapSuffix}";
42 ldap_search_filter = "(uid=%s)";
43 import_user = true;
44 attrs = {
45 username = "uid";
46 full_name = "cn";
47 email = "mail";
48 call = "telephoneNumber";
49 sms = "mobile";
50 };
51 };
52 };
53 secretFile = "/etc/oncall-secrets.yml";
54 };
55
56 services.openldap = {
57 enable = true;
58 settings = {
59 children = {
60 "cn=schema".includes = [
61 "${pkgs.openldap}/etc/schema/core.ldif"
62 "${pkgs.openldap}/etc/schema/cosine.ldif"
63 "${pkgs.openldap}/etc/schema/inetorgperson.ldif"
64 "${pkgs.openldap}/etc/schema/nis.ldif"
65 ];
66 "olcDatabase={1}mdb" = {
67 attrs = {
68 objectClass = [
69 "olcDatabaseConfig"
70 "olcMdbConfig"
71 ];
72 olcDatabase = "{1}mdb";
73 olcDbDirectory = "/var/lib/openldap/db";
74 olcSuffix = ldapSuffix;
75 olcRootDN = "cn=${ldapRootUser},${ldapSuffix}";
76 olcRootPW = ldapRootPassword;
77 };
78 };
79 };
80 };
81 declarativeContents = {
82 ${ldapSuffix} = ''
83 dn: ${ldapSuffix}
84 objectClass: top
85 objectClass: dcObject
86 objectClass: organization
87 o: ${ldapDomain}
88
89 dn: ou=accounts,${ldapSuffix}
90 objectClass: top
91 objectClass: organizationalUnit
92
93 dn: uid=${testUser},ou=accounts,${ldapSuffix}
94 objectClass: top
95 objectClass: inetOrgPerson
96 uid: ${testUser}
97 userPassword: ${testPassword}
98 cn: Test User
99 sn: User
100 mail: test@example.org
101 telephoneNumber: 012345678910
102 mobile: 012345678910
103 '';
104 };
105 };
106 };
107 };
108
109 testScript = ''
110 start_all()
111 machine.wait_for_unit("uwsgi.service")
112 machine.wait_for_unit("nginx.service")
113 machine.wait_for_file("/run/uwsgi/oncall.sock")
114 machine.wait_for_unit("oncall-setup-database.service")
115
116 with subtest("Home screen loads"):
117 machine.succeed(
118 "curl -sSfL http://[::1]:80 | grep '<title>Oncall</title>'"
119 )
120
121 with subtest("Staticfiles can be fetched"):
122 machine.wait_until_succeeds(
123 "curl -sSfL http://[::1]:80/static/bundles/libs.js"
124 )
125
126 with subtest("Staticfiles are generated"):
127 machine.succeed(
128 "test -e /var/lib/oncall/static/bundles/libs.js"
129 )
130
131 with subtest("Create and verify team via REST API"):
132 import json
133
134 # Log in and store the session cookie
135 login_response = machine.succeed("""
136 curl -sSfL -c cookies -X POST \
137 --data-raw 'username=${testUser}&password=${testPassword}' \
138 http://[::1]:80/login
139 """)
140
141 # Parse csrf token
142 login_response_data = json.loads(login_response)
143 csrf_token = login_response_data["csrf_token"]
144
145 # Create the team
146 machine.succeed(
147 f"""curl -sSfL -b cookies -X POST -H 'Content-Type: application/json' -H 'X-CSRF-Token: {csrf_token}' -d '{{"name": "${teamName}", "email": "test@example.com", "scheduling_timezone": "Europe/Berlin", "iris_enabled": false}}' http://[::1]:80/api/v0/teams/"""
148 )
149
150 # Query the created team
151 machine.succeed("""
152 curl -sSfL -b cookies http://[::1]:80/api/v0/teams/${teamName} | jq -e '.name == "${teamName}"'
153 """)
154
155 '';
156}