1import ../../make-test-python.nix (
2 { lib, pkgs, ... }:
3
4 let
5 inherit (lib) mkMerge maintainers;
6
7 baseGrafanaConf = {
8 services.grafana = {
9 enable = true;
10 provision.enable = true;
11 settings = {
12 analytics.reporting_enabled = false;
13
14 server = {
15 http_addr = "::1";
16 domain = "localhost";
17 };
18
19 security = {
20 admin_user = "testadmin";
21 admin_password = "$__file{${pkgs.writeText "pwd" "snakeoilpwd"}}";
22 };
23 };
24 };
25
26 systemd.tmpfiles.rules =
27 let
28 dashboard = pkgs.writeText "test.json" (builtins.readFile ./test_dashboard.json);
29 in
30 [
31 "d /var/lib/grafana/dashboards 0700 grafana grafana -"
32 "C+ /var/lib/grafana/dashboards/test.json - - - - ${dashboard}"
33 ];
34 };
35
36 extraNodeConfs = {
37 provisionNix = {
38 services.grafana.provision = {
39 datasources.settings = {
40 apiVersion = 1;
41 datasources = [
42 {
43 name = "Test Datasource";
44 type = "testdata";
45 access = "proxy";
46 uid = "test_datasource";
47 }
48 ];
49 };
50
51 dashboards.settings = {
52 apiVersion = 1;
53 providers = [
54 {
55 name = "default";
56 options.path = "/var/lib/grafana/dashboards";
57 }
58 ];
59 };
60
61 alerting = {
62 rules.settings = {
63 groups = [
64 {
65 name = "test_rule_group";
66 folder = "test_folder";
67 interval = "60s";
68 rules = [
69 {
70 uid = "test_rule";
71 title = "Test Rule";
72 condition = "A";
73 data = [
74 {
75 refId = "A";
76 datasourceUid = "-100";
77 model = {
78 conditions = [
79 {
80 evaluator = {
81 params = [ 3 ];
82 type = "git";
83 };
84 operator.type = "and";
85 query.params = [ "A" ];
86 reducer.type = "last";
87 type = "query";
88 }
89 ];
90 datasource = {
91 type = "__expr__";
92 uid = "-100";
93 };
94 expression = "1==0";
95 intervalMs = 1000;
96 maxDataPoints = 43200;
97 refId = "A";
98 type = "math";
99 };
100 }
101 ];
102 for = "60s";
103 }
104 ];
105 }
106 ];
107 };
108
109 contactPoints.settings = {
110 contactPoints = [
111 {
112 name = "Test Contact Point";
113 receivers = [
114 {
115 uid = "test_contact_point";
116 type = "prometheus-alertmanager";
117 settings.url = "http://localhost:9000";
118 }
119 ];
120 }
121 ];
122 };
123
124 policies.settings = {
125 policies = [
126 {
127 receiver = "Test Contact Point";
128 }
129 ];
130 };
131
132 templates.settings = {
133 templates = [
134 {
135 name = "Test Template";
136 template = "Test message";
137 }
138 ];
139 };
140
141 muteTimings.settings = {
142 muteTimes = [
143 {
144 name = "Test Mute Timing";
145 }
146 ];
147 };
148 };
149 };
150 };
151
152 provisionYaml = {
153 services.grafana.provision = {
154 datasources.path = ./datasources.yaml;
155 dashboards.path = ./dashboards.yaml;
156 alerting = {
157 rules.path = ./rules.yaml;
158 contactPoints.path = ./contact-points.yaml;
159 policies.path = ./policies.yaml;
160 templates.path = ./templates.yaml;
161 muteTimings.path = ./mute-timings.yaml;
162 };
163 };
164 };
165
166 provisionYamlDirs =
167 let
168 mkdir = p: pkgs.writeTextDir (baseNameOf p) (builtins.readFile p);
169 in
170 {
171 services.grafana.provision = {
172 datasources.path = mkdir ./datasources.yaml;
173 dashboards.path = mkdir ./dashboards.yaml;
174 alerting = {
175 rules.path = mkdir ./rules.yaml;
176 contactPoints.path = mkdir ./contact-points.yaml;
177 policies.path = mkdir ./policies.yaml;
178 templates.path = mkdir ./templates.yaml;
179 muteTimings.path = mkdir ./mute-timings.yaml;
180 };
181 };
182 };
183 };
184
185 nodes = builtins.mapAttrs (
186 _: val:
187 mkMerge [
188 val
189 baseGrafanaConf
190 ]
191 ) extraNodeConfs;
192 in
193 {
194 name = "grafana-provision";
195
196 meta = with maintainers; {
197 maintainers = [ willibutz ];
198 };
199
200 inherit nodes;
201
202 testScript = ''
203 start_all()
204
205 nodeNix = ("Nix (new format)", provisionNix)
206 nodeYaml = ("Nix (YAML)", provisionYaml)
207 nodeYamlDir = ("Nix (YAML in dirs)", provisionYamlDirs)
208
209 for description, machine in [nodeNix, nodeYaml, nodeYamlDir]:
210 with subtest(f"Should start provision node: {description}"):
211 machine.wait_for_unit("grafana.service")
212 machine.wait_for_open_port(3000, addr="::1")
213
214 with subtest(f"Successful datasource provision with {description}"):
215 machine.wait_until_succeeds(
216 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/datasources/uid/test_datasource | grep Test\ Datasource"
217 )
218
219 with subtest(f"Successful dashboard provision with {description}"):
220 machine.wait_until_succeeds(
221 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/dashboards/uid/test_dashboard | grep Test\ Dashboard"
222 )
223
224 with subtest(f"Successful rule provision with {description}"):
225 machine.wait_until_succeeds(
226 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/alert-rules/test_rule | grep Test\ Rule"
227 )
228
229 with subtest(f"Successful contact point provision with {description}"):
230 machine.wait_until_succeeds(
231 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/contact-points | grep Test\ Contact\ Point"
232 )
233
234 with subtest(f"Successful policy provision with {description}"):
235 machine.wait_until_succeeds(
236 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/policies | grep Test\ Contact\ Point"
237 )
238
239 with subtest(f"Successful template provision with {description}"):
240 machine.wait_until_succeeds(
241 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/templates | grep Test\ Template"
242 )
243
244 with subtest("Successful mute timings provision with {description}"):
245 machine.wait_until_succeeds(
246 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/mute-timings | grep Test\ Mute\ Timing"
247 )
248 '';
249 }
250)