at 22.05-pre 8.9 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 "unifi-poller"; 15 16 poller = { 17 debug = mkOption { 18 type = types.bool; 19 default = false; 20 description = '' 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 = '' 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 = '' 36 Load additional plugins. 37 ''; 38 }; 39 }; 40 41 prometheus = { 42 disable = mkOption { 43 type = types.bool; 44 default = false; 45 description = '' 46 Whether to disable the prometheus ouput plugin. 47 ''; 48 }; 49 http_listen = mkOption { 50 type = types.str; 51 default = "[::]:9130"; 52 description = '' 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 = '' 60 Whether to report errors. 61 ''; 62 }; 63 }; 64 65 influxdb = { 66 disable = mkOption { 67 type = types.bool; 68 default = false; 69 description = '' 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 = '' 77 URL of the influxdb host. 78 ''; 79 }; 80 user = mkOption { 81 type = types.str; 82 default = "unifipoller"; 83 description = '' 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 = '' 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 = '' 101 Database name. Database should exist. 102 ''; 103 }; 104 verify_ssl = mkOption { 105 type = types.bool; 106 default = true; 107 description = '' 108 Verify the influxdb's certificate. 109 ''; 110 }; 111 interval = mkOption { 112 type = types.str; 113 default = "30s"; 114 description = '' 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 = '' 126 URL of the Loki host. 127 ''; 128 }; 129 user = mkOption { 130 type = types.str; 131 default = ""; 132 description = '' 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 = '' 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 = '' 150 Verify Loki's certificate. 151 ''; 152 }; 153 tenant_id = mkOption { 154 type = types.str; 155 default = ""; 156 description = '' 157 Tenant ID to use in Loki. 158 ''; 159 }; 160 interval = mkOption { 161 type = types.str; 162 default = "2m"; 163 description = '' 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 = '' 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 = '' 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 = '' 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 = '' 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 = '' 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 = '' 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 = '' 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 = '' 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 = '' 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 = '' 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 = '' 251 Collect and save site data. 252 ''; 253 }; 254 hash_pii = mkOption { 255 type = types.bool; 256 default = false; 257 description = '' 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 = '' 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 = '' 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 = '' 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}