nixpkgs/nixos/modules/services/monitoring/unpoller.nix
2024-09-02 22:30:26 +02:00

320 lines
9.0 KiB
Nix

{ config, lib, pkgs, ... }:
let
cfg = config.services.unpoller;
configFile = pkgs.writeText "unpoller.json" (lib.generators.toJSON {} {
inherit (cfg) poller influxdb loki prometheus unifi;
});
in {
imports = [
(lib.mkRenamedOptionModule [ "services" "unifi-poller" ] [ "services" "unpoller" ])
];
options.services.unpoller = {
enable = lib.mkEnableOption "unpoller";
poller = {
debug = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Turns on line numbers, microsecond logging, and a per-device log.
This may be noisy if you have a lot of devices. It adds one line per device.
'';
};
quiet = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Turns off per-interval logs. Only startup and error logs will be emitted.
'';
};
plugins = lib.mkOption {
type = with lib.types; listOf str;
default = [];
description = ''
Load additional plugins.
'';
};
};
prometheus = {
disable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to disable the prometheus output plugin.
'';
};
http_listen = lib.mkOption {
type = lib.types.str;
default = "[::]:9130";
description = ''
Bind the prometheus exporter to this IP or hostname.
'';
};
report_errors = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to report errors.
'';
};
};
influxdb = {
disable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to disable the influxdb output plugin.
'';
};
url = lib.mkOption {
type = lib.types.str;
default = "http://127.0.0.1:8086";
description = ''
URL of the influxdb host.
'';
};
user = lib.mkOption {
type = lib.types.str;
default = "unifipoller";
description = ''
Username for the influxdb.
'';
};
pass = lib.mkOption {
type = lib.types.path;
default = pkgs.writeText "unpoller-influxdb-default.password" "unifipoller";
defaultText = lib.literalExpression "unpoller-influxdb-default.password";
description = ''
Path of a file containing the password for influxdb.
This file needs to be readable by the unifi-poller user.
'';
apply = v: "file://${v}";
};
db = lib.mkOption {
type = lib.types.str;
default = "unifi";
description = ''
Database name. Database should exist.
'';
};
verify_ssl = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Verify the influxdb's certificate.
'';
};
interval = lib.mkOption {
type = lib.types.str;
default = "30s";
description = ''
Setting this lower than the Unifi controller's refresh
interval may lead to zeroes in your database.
'';
};
};
loki = {
url = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
URL of the Loki host.
'';
};
user = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
Username for Loki.
'';
};
pass = lib.mkOption {
type = lib.types.path;
default = pkgs.writeText "unpoller-loki-default.password" "";
defaultText = "unpoller-influxdb-default.password";
description = ''
Path of a file containing the password for Loki.
This file needs to be readable by the unifi-poller user.
'';
apply = v: "file://${v}";
};
verify_ssl = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Verify Loki's certificate.
'';
};
tenant_id = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
Tenant ID to use in Loki.
'';
};
interval = lib.mkOption {
type = lib.types.str;
default = "2m";
description = ''
How often the events are polled and pushed to Loki.
'';
};
timeout = lib.mkOption {
type = lib.types.str;
default = "10s";
description = ''
Should be increased in case of timeout errors.
'';
};
};
unifi = let
controllerOptions = {
user = lib.mkOption {
type = lib.types.str;
default = "unifi";
description = ''
Unifi service user name.
'';
};
pass = lib.mkOption {
type = lib.types.path;
default = pkgs.writeText "unpoller-unifi-default.password" "unifi";
defaultText = lib.literalExpression "unpoller-unifi-default.password";
description = ''
Path of a file containing the password for the unifi service user.
This file needs to be readable by the unifi-poller user.
'';
apply = v: "file://${v}";
};
url = lib.mkOption {
type = lib.types.str;
default = "https://unifi:8443";
description = ''
URL of the Unifi controller.
'';
};
sites = lib.mkOption {
type = with lib.types; either (enum [ "default" "all" ]) (listOf str);
default = "all";
description = ''
List of site names for which statistics should be exported.
Or the string "default" for the default site or the string "all" for all sites.
'';
apply = lib.toList;
};
save_ids = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Collect and save data from the intrusion detection system to influxdb and Loki.
'';
};
save_events = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Collect and save data from UniFi events to influxdb and Loki.
'';
};
save_alarms = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Collect and save data from UniFi alarms to influxdb and Loki.
'';
};
save_anomalies = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Collect and save data from UniFi anomalies to influxdb and Loki.
'';
};
save_dpi = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Collect and save data from deep packet inspection.
Adds around 150 data points and impacts performance.
'';
};
save_sites = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Collect and save site data.
'';
};
hash_pii = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Hash, with md5, client names and MAC addresses. This attempts
to protect personally identifiable information.
'';
};
verify_ssl = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Verify the Unifi controller's certificate.
'';
};
};
in {
dynamic = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Let prometheus select which controller to poll when scraping.
Use with default credentials. See unifi-poller wiki for more.
'';
};
defaults = controllerOptions;
controllers = lib.mkOption {
type = with lib.types; listOf (submodule { options = controllerOptions; });
default = [];
description = ''
List of Unifi controllers to poll. Use defaults if empty.
'';
apply = map (lib.flip removeAttrs [ "_module" ]);
};
};
};
config = lib.mkIf cfg.enable {
users.groups.unifi-poller = { };
users.users.unifi-poller = {
description = "unifi-poller Service User";
group = "unifi-poller";
isSystemUser = true;
};
systemd.services.unifi-poller = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${pkgs.unpoller}/bin/unpoller --config ${configFile}";
Restart = "always";
PrivateTmp = true;
ProtectHome = true;
ProtectSystem = "full";
DevicePolicy = "closed";
NoNewPrivileges = true;
User = "unifi-poller";
WorkingDirectory = "/tmp";
};
};
};
}