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.maintainers = [ ];
197
198 inherit nodes;
199
200 testScript = ''
201 start_all()
202
203 nodeNix = ("Nix (new format)", provisionNix)
204 nodeYaml = ("Nix (YAML)", provisionYaml)
205 nodeYamlDir = ("Nix (YAML in dirs)", provisionYamlDirs)
206
207 for description, machine in [nodeNix, nodeYaml, nodeYamlDir]:
208 with subtest(f"Should start provision node: {description}"):
209 machine.wait_for_unit("grafana.service")
210 machine.wait_for_open_port(3000, addr="::1")
211
212 with subtest(f"Successful datasource provision with {description}"):
213 machine.wait_until_succeeds(
214 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/datasources/uid/test_datasource | grep Test\ Datasource"
215 )
216
217 with subtest(f"Successful dashboard provision with {description}"):
218 machine.wait_until_succeeds(
219 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/dashboards/uid/test_dashboard | grep Test\ Dashboard"
220 )
221
222 with subtest(f"Successful rule provision with {description}"):
223 machine.wait_until_succeeds(
224 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/alert-rules/test_rule | grep Test\ Rule"
225 )
226
227 with subtest(f"Successful contact point provision with {description}"):
228 machine.wait_until_succeeds(
229 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/contact-points | grep Test\ Contact\ Point"
230 )
231
232 with subtest(f"Successful policy provision with {description}"):
233 machine.wait_until_succeeds(
234 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/policies | grep Test\ Contact\ Point"
235 )
236
237 with subtest(f"Successful template provision with {description}"):
238 machine.wait_until_succeeds(
239 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/templates | grep Test\ Template"
240 )
241
242 with subtest("Successful mute timings provision with {description}"):
243 machine.wait_until_succeeds(
244 "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/mute-timings | grep Test\ Mute\ Timing"
245 )
246 '';
247 }
248)