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