Merge #361424: refactor lib.packagesFromDirectoryRecursive (v2)
[NixPkgs.git] / nixos / modules / services / monitoring / unpoller.nix
blob514afb2fe8b27e59b9cfa3866dbfd00728a1e429
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
7 let
8   cfg = config.services.unpoller;
10   configFile = pkgs.writeText "unpoller.json" (
11     lib.generators.toJSON { } {
12       inherit (cfg)
13         poller
14         influxdb
15         loki
16         prometheus
17         unifi
18         ;
19     }
20   );
24   imports = [
25     (lib.mkRenamedOptionModule [ "services" "unifi-poller" ] [ "services" "unpoller" ])
26   ];
28   options.services.unpoller = {
29     enable = lib.mkEnableOption "unpoller";
31     poller = {
32       debug = lib.mkOption {
33         type = lib.types.bool;
34         default = false;
35         description = ''
36           Turns on line numbers, microsecond logging, and a per-device log.
37           This may be noisy if you have a lot of devices. It adds one line per device.
38         '';
39       };
40       quiet = lib.mkOption {
41         type = lib.types.bool;
42         default = false;
43         description = ''
44           Turns off per-interval logs. Only startup and error logs will be emitted.
45         '';
46       };
47       plugins = lib.mkOption {
48         type = with lib.types; listOf str;
49         default = [ ];
50         description = ''
51           Load additional plugins.
52         '';
53       };
54     };
56     prometheus = {
57       disable = lib.mkOption {
58         type = lib.types.bool;
59         default = false;
60         description = ''
61           Whether to disable the prometheus output plugin.
62         '';
63       };
64       http_listen = lib.mkOption {
65         type = lib.types.str;
66         default = "[::]:9130";
67         description = ''
68           Bind the prometheus exporter to this IP or hostname.
69         '';
70       };
71       report_errors = lib.mkOption {
72         type = lib.types.bool;
73         default = false;
74         description = ''
75           Whether to report errors.
76         '';
77       };
78     };
80     influxdb = {
81       disable = lib.mkOption {
82         type = lib.types.bool;
83         default = false;
84         description = ''
85           Whether to disable the influxdb output plugin.
86         '';
87       };
88       url = lib.mkOption {
89         type = lib.types.str;
90         default = "http://127.0.0.1:8086";
91         description = ''
92           URL of the influxdb host.
93         '';
94       };
95       user = lib.mkOption {
96         type = lib.types.str;
97         default = "unifipoller";
98         description = ''
99           Username for the influxdb.
100         '';
101       };
102       pass = lib.mkOption {
103         type = lib.types.path;
104         default = pkgs.writeText "unpoller-influxdb-default.password" "unifipoller";
105         defaultText = lib.literalExpression "unpoller-influxdb-default.password";
106         description = ''
107           Path of a file containing the password for influxdb.
108           This file needs to be readable by the unifi-poller user.
109         '';
110         apply = v: "file://${v}";
111       };
112       db = lib.mkOption {
113         type = lib.types.str;
114         default = "unifi";
115         description = ''
116           Database name. Database should exist.
117         '';
118       };
119       verify_ssl = lib.mkOption {
120         type = lib.types.bool;
121         default = true;
122         description = ''
123           Verify the influxdb's certificate.
124         '';
125       };
126       interval = lib.mkOption {
127         type = lib.types.str;
128         default = "30s";
129         description = ''
130           Setting this lower than the Unifi controller's refresh
131           interval may lead to zeroes in your database.
132         '';
133       };
134     };
136     loki = {
137       url = lib.mkOption {
138         type = lib.types.str;
139         default = "";
140         description = ''
141           URL of the Loki host.
142         '';
143       };
144       user = lib.mkOption {
145         type = lib.types.str;
146         default = "";
147         description = ''
148           Username for Loki.
149         '';
150       };
151       pass = lib.mkOption {
152         type = lib.types.path;
153         default = pkgs.writeText "unpoller-loki-default.password" "";
154         defaultText = "unpoller-influxdb-default.password";
155         description = ''
156           Path of a file containing the password for Loki.
157           This file needs to be readable by the unifi-poller user.
158         '';
159         apply = v: "file://${v}";
160       };
161       verify_ssl = lib.mkOption {
162         type = lib.types.bool;
163         default = false;
164         description = ''
165           Verify Loki's certificate.
166         '';
167       };
168       tenant_id = lib.mkOption {
169         type = lib.types.str;
170         default = "";
171         description = ''
172           Tenant ID to use in Loki.
173         '';
174       };
175       interval = lib.mkOption {
176         type = lib.types.str;
177         default = "2m";
178         description = ''
179           How often the events are polled and pushed to Loki.
180         '';
181       };
182       timeout = lib.mkOption {
183         type = lib.types.str;
184         default = "10s";
185         description = ''
186           Should be increased in case of timeout errors.
187         '';
188       };
189     };
191     unifi =
192       let
193         controllerOptions = {
194           user = lib.mkOption {
195             type = lib.types.str;
196             default = "unifi";
197             description = ''
198               Unifi service user name.
199             '';
200           };
201           pass = lib.mkOption {
202             type = lib.types.path;
203             default = pkgs.writeText "unpoller-unifi-default.password" "unifi";
204             defaultText = lib.literalExpression "unpoller-unifi-default.password";
205             description = ''
206               Path of a file containing the password for the unifi service user.
207               This file needs to be readable by the unifi-poller user.
208             '';
209             apply = v: "file://${v}";
210           };
211           url = lib.mkOption {
212             type = lib.types.str;
213             default = "https://unifi:8443";
214             description = ''
215               URL of the Unifi controller.
216             '';
217           };
218           sites = lib.mkOption {
219             type =
220               with lib.types;
221               either (enum [
222                 "default"
223                 "all"
224               ]) (listOf str);
225             default = "all";
226             description = ''
227               List of site names for which statistics should be exported.
228               Or the string "default" for the default site or the string "all" for all sites.
229             '';
230             apply = lib.toList;
231           };
232           save_ids = lib.mkOption {
233             type = lib.types.bool;
234             default = false;
235             description = ''
236               Collect and save data from the intrusion detection system to influxdb and Loki.
237             '';
238           };
239           save_events = lib.mkOption {
240             type = lib.types.bool;
241             default = false;
242             description = ''
243               Collect and save data from UniFi events to influxdb and Loki.
244             '';
245           };
246           save_alarms = lib.mkOption {
247             type = lib.types.bool;
248             default = false;
249             description = ''
250               Collect and save data from UniFi alarms to influxdb and Loki.
251             '';
252           };
253           save_anomalies = lib.mkOption {
254             type = lib.types.bool;
255             default = false;
256             description = ''
257               Collect and save data from UniFi anomalies to influxdb and Loki.
258             '';
259           };
260           save_dpi = lib.mkOption {
261             type = lib.types.bool;
262             default = false;
263             description = ''
264               Collect and save data from deep packet inspection.
265               Adds around 150 data points and impacts performance.
266             '';
267           };
268           save_sites = lib.mkOption {
269             type = lib.types.bool;
270             default = true;
271             description = ''
272               Collect and save site data.
273             '';
274           };
275           hash_pii = lib.mkOption {
276             type = lib.types.bool;
277             default = false;
278             description = ''
279               Hash, with md5, client names and MAC addresses. This attempts
280               to protect personally identifiable information.
281             '';
282           };
283           verify_ssl = lib.mkOption {
284             type = lib.types.bool;
285             default = true;
286             description = ''
287               Verify the Unifi controller's certificate.
288             '';
289           };
290         };
292       in
293       {
294         dynamic = lib.mkOption {
295           type = lib.types.bool;
296           default = false;
297           description = ''
298             Let prometheus select which controller to poll when scraping.
299             Use with default credentials. See unifi-poller wiki for more.
300           '';
301         };
303         defaults = controllerOptions;
305         controllers = lib.mkOption {
306           type =
307             with lib.types;
308             listOf (submodule {
309               options = controllerOptions;
310             });
311           default = [ ];
312           description = ''
313             List of Unifi controllers to poll. Use defaults if empty.
314           '';
315           apply = map (lib.flip removeAttrs [ "_module" ]);
316         };
317       };
318   };
320   config = lib.mkIf cfg.enable {
321     users.groups.unifi-poller = { };
322     users.users.unifi-poller = {
323       description = "unifi-poller Service User";
324       group = "unifi-poller";
325       isSystemUser = true;
326     };
328     systemd.services.unifi-poller = {
329       wantedBy = [ "multi-user.target" ];
330       after = [ "network.target" ];
331       serviceConfig = {
332         ExecStart = "${pkgs.unpoller}/bin/unpoller --config ${configFile}";
333         Restart = "always";
334         PrivateTmp = true;
335         ProtectHome = true;
336         ProtectSystem = "full";
337         DevicePolicy = "closed";
338         NoNewPrivileges = true;
339         User = "unifi-poller";
340         WorkingDirectory = "/tmp";
341       };
342     };
343   };