1 { config, lib, pkgs, ... }:
3 cfg = config.services.unpoller;
5 configFile = pkgs.writeText "unpoller.json" (lib.generators.toJSON {} {
6 inherit (cfg) poller influxdb loki prometheus unifi;
11 (lib.mkRenamedOptionModule [ "services" "unifi-poller" ] [ "services" "unpoller" ])
14 options.services.unpoller = {
15 enable = lib.mkEnableOption "unpoller";
18 debug = lib.mkOption {
19 type = lib.types.bool;
22 Turns on line numbers, microsecond logging, and a per-device log.
23 This may be noisy if you have a lot of devices. It adds one line per device.
26 quiet = lib.mkOption {
27 type = lib.types.bool;
30 Turns off per-interval logs. Only startup and error logs will be emitted.
33 plugins = lib.mkOption {
34 type = with lib.types; listOf str;
37 Load additional plugins.
43 disable = lib.mkOption {
44 type = lib.types.bool;
47 Whether to disable the prometheus output plugin.
50 http_listen = lib.mkOption {
52 default = "[::]:9130";
54 Bind the prometheus exporter to this IP or hostname.
57 report_errors = lib.mkOption {
58 type = lib.types.bool;
61 Whether to report errors.
67 disable = lib.mkOption {
68 type = lib.types.bool;
71 Whether to disable the influxdb output plugin.
76 default = "http://127.0.0.1:8086";
78 URL of the influxdb host.
83 default = "unifipoller";
85 Username for the influxdb.
89 type = lib.types.path;
90 default = pkgs.writeText "unpoller-influxdb-default.password" "unifipoller";
91 defaultText = lib.literalExpression "unpoller-influxdb-default.password";
93 Path of a file containing the password for influxdb.
94 This file needs to be readable by the unifi-poller user.
96 apply = v: "file://${v}";
102 Database name. Database should exist.
105 verify_ssl = lib.mkOption {
106 type = lib.types.bool;
109 Verify the influxdb's certificate.
112 interval = lib.mkOption {
113 type = lib.types.str;
116 Setting this lower than the Unifi controller's refresh
117 interval may lead to zeroes in your database.
124 type = lib.types.str;
127 URL of the Loki host.
130 user = lib.mkOption {
131 type = lib.types.str;
137 pass = lib.mkOption {
138 type = lib.types.path;
139 default = pkgs.writeText "unpoller-loki-default.password" "";
140 defaultText = "unpoller-influxdb-default.password";
142 Path of a file containing the password for Loki.
143 This file needs to be readable by the unifi-poller user.
145 apply = v: "file://${v}";
147 verify_ssl = lib.mkOption {
148 type = lib.types.bool;
151 Verify Loki's certificate.
154 tenant_id = lib.mkOption {
155 type = lib.types.str;
158 Tenant ID to use in Loki.
161 interval = lib.mkOption {
162 type = lib.types.str;
165 How often the events are polled and pushed to Loki.
168 timeout = lib.mkOption {
169 type = lib.types.str;
172 Should be increased in case of timeout errors.
178 controllerOptions = {
179 user = lib.mkOption {
180 type = lib.types.str;
183 Unifi service user name.
186 pass = lib.mkOption {
187 type = lib.types.path;
188 default = pkgs.writeText "unpoller-unifi-default.password" "unifi";
189 defaultText = lib.literalExpression "unpoller-unifi-default.password";
191 Path of a file containing the password for the unifi service user.
192 This file needs to be readable by the unifi-poller user.
194 apply = v: "file://${v}";
197 type = lib.types.str;
198 default = "https://unifi:8443";
200 URL of the Unifi controller.
203 sites = lib.mkOption {
204 type = with lib.types; either (enum [ "default" "all" ]) (listOf str);
207 List of site names for which statistics should be exported.
208 Or the string "default" for the default site or the string "all" for all sites.
212 save_ids = lib.mkOption {
213 type = lib.types.bool;
216 Collect and save data from the intrusion detection system to influxdb and Loki.
219 save_events = lib.mkOption {
220 type = lib.types.bool;
223 Collect and save data from UniFi events to influxdb and Loki.
226 save_alarms = lib.mkOption {
227 type = lib.types.bool;
230 Collect and save data from UniFi alarms to influxdb and Loki.
233 save_anomalies = lib.mkOption {
234 type = lib.types.bool;
237 Collect and save data from UniFi anomalies to influxdb and Loki.
240 save_dpi = lib.mkOption {
241 type = lib.types.bool;
244 Collect and save data from deep packet inspection.
245 Adds around 150 data points and impacts performance.
248 save_sites = lib.mkOption {
249 type = lib.types.bool;
252 Collect and save site data.
255 hash_pii = lib.mkOption {
256 type = lib.types.bool;
259 Hash, with md5, client names and MAC addresses. This attempts
260 to protect personally identifiable information.
263 verify_ssl = lib.mkOption {
264 type = lib.types.bool;
267 Verify the Unifi controller's certificate.
273 dynamic = lib.mkOption {
274 type = lib.types.bool;
277 Let prometheus select which controller to poll when scraping.
278 Use with default credentials. See unifi-poller wiki for more.
282 defaults = controllerOptions;
284 controllers = lib.mkOption {
285 type = with lib.types; listOf (submodule { options = controllerOptions; });
288 List of Unifi controllers to poll. Use defaults if empty.
290 apply = map (lib.flip removeAttrs [ "_module" ]);
295 config = lib.mkIf cfg.enable {
296 users.groups.unifi-poller = { };
297 users.users.unifi-poller = {
298 description = "unifi-poller Service User";
299 group = "unifi-poller";
303 systemd.services.unifi-poller = {
304 wantedBy = [ "multi-user.target" ];
305 after = [ "network.target" ];
307 ExecStart = "${pkgs.unpoller}/bin/unpoller --config ${configFile}";
311 ProtectSystem = "full";
312 DevicePolicy = "closed";
313 NoNewPrivileges = true;
314 User = "unifi-poller";
315 WorkingDirectory = "/tmp";