{ lib, config, ... }: let tempSensorOptions = (import ./suboptions/tempSensorOptions.nix) { inherit lib; }; vulnixWhitelistRule = (import ./suboptions/vulnixWhitelistRule.nix) { inherit lib; }; netInterfaceOptions = (import ./suboptions/netInterfaceOptions.nix) { inherit lib; }; in { options.services.lego-monitoring = { enable = lib.mkEnableOption "lego-monitoring service"; logLevel = lib.mkOption { type = lib.types.enum [ "CRITICAL" "ERROR" "WARNING" "INFO" "DEBUG" ]; default = "INFO"; description = "Level of logging. INFO generates a log message with every check."; }; enabledCheckSets = lib.mkOption { type = lib.types.listOf (lib.types.enum [ "self" "remind" "cpu" "ram" "temp" "net" "ups" "lvmraid" "vulnix" ]); default = [ ]; description = '' List of enabled check sets. Each check set is a module which checks something and generates alerts based on check results. Available check sets: * self -- send an alert when lego-monitoring is started and stopped * remind -- periodically (daily by default) remind about ongoing unresolved alerts * cpu -- alerts when CPU usage is above threshold * ram -- alerts when RAM usage is above threshold * temp -- alerts when temperature readings are above thresholds * net -- alerts when network usage is above threshold * ups -- alerts on UPS events * lvmraid -- alerts when RAID LVs are unhealthy * vulnix -- periodically scans system for known CVEs, alerts if any are found (NixOS only)''; }; alertChannels = { telegram = { enable = lib.mkEnableOption "Telegram notification channel"; credsSecretPath = lib.mkOption { type = lib.types.str; default = ""; description = "Path to a file containing Telegram api_id, api_hash, and bot token, separated by the `,` character."; }; roomId = lib.mkOption { type = lib.types.int; default = 0; description = "ID of chat where to send alerts."; }; }; healthchecks = { enable = lib.mkEnableOption "[Healthchecks](https://healthchecks.io) notification channel"; pingingApiEndpoint = lib.mkOption { type = lib.types.str; default = "https://hc-ping.com/"; description = "Endpoint URL for Healthchecks pinging API."; example = "https://your-healthchecks-instance.com/ping/"; }; pingingKeysSecretPath = lib.mkOption { type = lib.types.str; default = ""; description = '' Path to a file containing the pinging keys in a `slug:key` format, one on each line (ex: `lego-cpu:aaaaaaaaaaaaaaaaaaaaaa`). Specify `default` as the slug to use this key for check types that don't have a key explicitly assigned to them. If you are unsure of the exact slug a check will generate, it is recommended to try it out with the default key first, before assigning a specific one. **Note**: checks will be auto-provisioned, but correct intervals and grace periods have to be configured manually from the web console, otherwise silent failures will not be recorded until after 1 day (the default healthchecks interval).''; }; }; }; checks = { temp = { sensors = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule tempSensorOptions); default = { }; description = '' Temp sensor override definitions. Sensors not defined here, or missing options in definitions, will be read with default parameters. To get list of sensors and their default configurations, run `lego-monitoring --print-temp`.''; example = lib.literalExpression '' { amdgpu.readings.edge.label = "Integrated GPU"; k10temp.readings = { Tctl = { label = "AMD CPU"; criticalTemp = 95.0; }; Tccd1.enabled = false; Tccd2.enabled = false; }; nvme.readings = { "Sensor 1".enabled = false; "Sensor 2".enabled = false; }; }''; }; }; vulnix = { whitelist = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule vulnixWhitelistRule); default = { }; description = "Whitelist rules for vulnix. Attr name is package with version, package name, or `*`."; example = lib.literalExpression '' { "ffmpeg-3.4.2" = { cve = [ "CVE-2018-6912" "CVE-2018-7557" ]; until = "2018-05-01"; issueUrl = "https://issues.example.com/29952"; }; }''; }; }; cpu = { warningPercentage = lib.mkOption { type = lib.types.nullOr lib.types.numbers.positive; default = 80.0; description = "CPU load percentage for a warning alert to be sent. Null means never generate a CPU warning alert."; }; criticalPercentage = lib.mkOption { type = lib.types.nullOr lib.types.numbers.positive; default = 90.0; description = "CPU load percentage for a critical alert to be sent. Null means never generate a CPU critical alert."; }; }; ram = { warningPercentage = lib.mkOption { type = lib.types.nullOr lib.types.numbers.positive; default = 80.0; description = "RAM usage percentage for a warning alert to be sent. Null means never generate a RAM warning alert."; }; criticalPercentage = lib.mkOption { type = lib.types.nullOr lib.types.numbers.positive; default = 90.0; description = "RAM usage percentage for a critical alert to be sent. Null means never generate a RAM critical alert."; }; }; net = { interfaces = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule netInterfaceOptions); default = { }; description = "Per-interface configuration of IO byte thresholds."; example = lib.literalExpression '' { br0 = { warningThresholdCombBytes = 700 * 1024 * 128; # 700 Megabits criticalThresholdCombBytes = 1 * 1024 * 1024 * 128; # 1 Gigabit }; }''; }; }; ups = { upsToCheck = lib.mkOption { type = with lib.types; nullOr (listOf str); default = null; description = "List of UPS's to monitor, in `upsc`-compatible format. If null, all UPS's connected to localhost are checked."; }; upsmonGroup = lib.mkOption { type = lib.types.str; default = config.power.ups.upsmon.user; defaultText = lib.literalExpression "config.power.ups.upsmon.user"; description = "Group to allow to send UPS status updates. This should usually include the user upsmon runs as."; }; }; lvmraid = { lvPaths = lib.mkOption { type = with lib.types; listOf str; default = [ ]; description = "List of LV paths to monitor."; example = lib.literalExpression ''[ Data/lvol0 ]''; }; }; }; }; }