1{ pkgs, ... }:
2{
3 name = "influxdb2";
4 meta = with pkgs.lib.maintainers; {
5 maintainers = [ offline ];
6 };
7
8 nodes.machine =
9 { lib, ... }:
10 {
11 environment.systemPackages = [ pkgs.influxdb2-cli ];
12 # Make sure that the service is restarted immediately if tokens need to be rewritten
13 # without relying on any Restart=on-failure behavior
14 systemd.services.influxdb2.serviceConfig.RestartSec = 6000;
15 services.influxdb2.enable = true;
16 services.influxdb2.provision = {
17 enable = true;
18 initialSetup = {
19 organization = "default";
20 bucket = "default";
21 passwordFile = pkgs.writeText "admin-pw" "ExAmPl3PA55W0rD";
22 tokenFile = pkgs.writeText "admin-token" "verysecureadmintoken";
23 };
24 organizations.someorg = {
25 buckets.somebucket = { };
26 auths.sometoken = {
27 description = "some auth token";
28 readBuckets = [ "somebucket" ];
29 writeBuckets = [ "somebucket" ];
30 };
31 };
32 users.someuser.passwordFile = pkgs.writeText "tmp-pw" "abcgoiuhaoga";
33 };
34
35 specialisation.withModifications.configuration =
36 { ... }:
37 {
38 services.influxdb2.provision = {
39 organizations.someorg.buckets.somebucket.present = false;
40 organizations.someorg.auths.sometoken.present = false;
41 users.someuser.present = false;
42
43 organizations.myorg = {
44 description = "Myorg description";
45 buckets.mybucket = {
46 description = "Mybucket description";
47 };
48 auths.mytoken = {
49 operator = true;
50 description = "operator token";
51 tokenFile = pkgs.writeText "tmp-tok" "someusertoken";
52 };
53 };
54 users.myuser.passwordFile = pkgs.writeText "tmp-pw" "abcgoiuhaoga";
55 };
56 };
57
58 specialisation.withParentDelete.configuration =
59 { ... }:
60 {
61 services.influxdb2.provision = {
62 organizations.someorg.present = false;
63 # Deleting the parent implies:
64 #organizations.someorg.buckets.somebucket.present = false;
65 #organizations.someorg.auths.sometoken.present = false;
66 };
67 };
68
69 specialisation.withNewTokens.configuration =
70 { ... }:
71 {
72 services.influxdb2.provision = {
73 organizations.default = {
74 auths.operator = {
75 operator = true;
76 description = "new optoken";
77 tokenFile = pkgs.writeText "tmp-tok" "newoptoken";
78 };
79 auths.allaccess = {
80 operator = true;
81 description = "new allaccess";
82 tokenFile = pkgs.writeText "tmp-tok" "newallaccess";
83 };
84 auths.specifics = {
85 description = "new specifics";
86 readPermissions = [
87 "users"
88 "tasks"
89 ];
90 writePermissions = [ "tasks" ];
91 tokenFile = pkgs.writeText "tmp-tok" "newspecificstoken";
92 };
93 };
94 };
95 };
96 };
97
98 testScript =
99 { nodes, ... }:
100 let
101 specialisations = "${nodes.machine.system.build.toplevel}/specialisation";
102 tokenArg = "--token verysecureadmintoken";
103 in
104 ''
105 def assert_contains(haystack, needle):
106 if needle not in haystack:
107 print("The haystack that will cause the following exception is:")
108 print("---")
109 print(haystack)
110 print("---")
111 raise Exception(f"Expected string '{needle}' was not found")
112
113 def assert_lacks(haystack, needle):
114 if needle in haystack:
115 print("The haystack that will cause the following exception is:")
116 print("---")
117 print(haystack, end="")
118 print("---")
119 raise Exception(f"Unexpected string '{needle}' was found")
120
121 machine.wait_for_unit("influxdb2.service")
122
123 machine.fail("curl --fail -X POST 'http://localhost:8086/api/v2/signin' -u admin:wrongpassword")
124 machine.succeed("curl --fail -X POST 'http://localhost:8086/api/v2/signin' -u admin:ExAmPl3PA55W0rD")
125
126 out = machine.succeed("influx org list ${tokenArg}")
127 assert_contains(out, "default")
128 assert_lacks(out, "myorg")
129 assert_contains(out, "someorg")
130
131 out = machine.succeed("influx bucket list ${tokenArg} --org default")
132 assert_contains(out, "default")
133
134 machine.fail("influx bucket list ${tokenArg} --org myorg")
135
136 out = machine.succeed("influx bucket list ${tokenArg} --org someorg")
137 assert_contains(out, "somebucket")
138
139 out = machine.succeed("influx user list ${tokenArg}")
140 assert_contains(out, "admin")
141 assert_lacks(out, "myuser")
142 assert_contains(out, "someuser")
143
144 out = machine.succeed("influx auth list ${tokenArg}")
145 assert_lacks(out, "operator token")
146 assert_contains(out, "some auth token")
147
148 with subtest("withModifications"):
149 machine.succeed('${specialisations}/withModifications/bin/switch-to-configuration test')
150 machine.wait_for_unit("influxdb2.service")
151
152 out = machine.succeed("influx org list ${tokenArg}")
153 assert_contains(out, "default")
154 assert_contains(out, "myorg")
155 assert_contains(out, "someorg")
156
157 out = machine.succeed("influx bucket list ${tokenArg} --org myorg")
158 assert_contains(out, "mybucket")
159
160 out = machine.succeed("influx bucket list ${tokenArg} --org someorg")
161 assert_lacks(out, "somebucket")
162
163 out = machine.succeed("influx user list ${tokenArg}")
164 assert_contains(out, "admin")
165 assert_contains(out, "myuser")
166 assert_lacks(out, "someuser")
167
168 out = machine.succeed("influx auth list ${tokenArg}")
169 assert_contains(out, "operator token")
170 assert_lacks(out, "some auth token")
171
172 # Make sure the user token is also usable
173 machine.succeed("influx auth list --token someusertoken")
174
175 with subtest("keepsUnrelated"):
176 machine.succeed('${nodes.machine.system.build.toplevel}/bin/switch-to-configuration test')
177 machine.wait_for_unit("influxdb2.service")
178
179 out = machine.succeed("influx org list ${tokenArg}")
180 assert_contains(out, "default")
181 assert_contains(out, "myorg")
182 assert_contains(out, "someorg")
183
184 out = machine.succeed("influx bucket list ${tokenArg} --org default")
185 assert_contains(out, "default")
186
187 out = machine.succeed("influx bucket list ${tokenArg} --org myorg")
188 assert_contains(out, "mybucket")
189
190 out = machine.succeed("influx bucket list ${tokenArg} --org someorg")
191 assert_contains(out, "somebucket")
192
193 out = machine.succeed("influx user list ${tokenArg}")
194 assert_contains(out, "admin")
195 assert_contains(out, "myuser")
196 assert_contains(out, "someuser")
197
198 out = machine.succeed("influx auth list ${tokenArg}")
199 assert_contains(out, "operator token")
200 assert_contains(out, "some auth token")
201
202 with subtest("withParentDelete"):
203 machine.succeed('${specialisations}/withParentDelete/bin/switch-to-configuration test')
204 machine.wait_for_unit("influxdb2.service")
205
206 out = machine.succeed("influx org list ${tokenArg}")
207 assert_contains(out, "default")
208 assert_contains(out, "myorg")
209 assert_lacks(out, "someorg")
210
211 out = machine.succeed("influx bucket list ${tokenArg} --org default")
212 assert_contains(out, "default")
213
214 out = machine.succeed("influx bucket list ${tokenArg} --org myorg")
215 assert_contains(out, "mybucket")
216
217 machine.fail("influx bucket list ${tokenArg} --org someorg")
218
219 out = machine.succeed("influx user list ${tokenArg}")
220 assert_contains(out, "admin")
221 assert_contains(out, "myuser")
222 assert_contains(out, "someuser")
223
224 out = machine.succeed("influx auth list ${tokenArg}")
225 assert_contains(out, "operator token")
226 assert_lacks(out, "some auth token")
227
228 with subtest("withNewTokens"):
229 machine.succeed('${specialisations}/withNewTokens/bin/switch-to-configuration test')
230 machine.wait_for_unit("influxdb2.service")
231
232 out = machine.succeed("influx auth list ${tokenArg}")
233 assert_contains(out, "operator token")
234 assert_contains(out, "some auth token")
235 assert_contains(out, "new optoken")
236 assert_contains(out, "new allaccess")
237 assert_contains(out, "new specifics")
238 '';
239}