diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix index 2dc12a221bf0..9cad5636b579 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters.nix @@ -29,6 +29,7 @@ let "blackbox" "buildkite-agent" "collectd" + "deluge" "dmarc" "dnsmasq" "dnssec" @@ -413,6 +414,14 @@ in Please ensure you have either `services.prometheus.exporters.idrac.configuration' or `services.prometheus.exporters.idrac.configurationPath' set! ''; + } { + assertion = cfg.deluge.enable -> ( + (cfg.deluge.delugePassword == null) != (cfg.deluge.delugePasswordFile == null) + ); + message = '' + Please ensure you have either `services.prometheus.exporters.deluge.delugePassword' + or `services.prometheus.exporters.deluge.delugePasswordFile' set! + ''; } ] ++ (flip map (attrNames exporterOpts) (exporter: { assertion = cfg.${exporter}.firewallFilter != null -> cfg.${exporter}.openFirewall; message = '' @@ -446,6 +455,13 @@ in hardware.rtl-sdr.enable = mkDefault true; })] ++ [(mkIf config.services.postfix.enable { services.prometheus.exporters.postfix.group = mkDefault config.services.postfix.setgidGroup; + })] ++ [(mkIf config.services.prometheus.exporters.deluge.enable { + system.activationScripts = { + deluge-exported.text = '' + mkdir -p /etc/deluge-exporter + echo "DELUGE_PASSWORD=$(cat ${config.services.prometheus.exporters.deluge.delugePasswordFile})" > /etc/deluge-exporter/password + ''; + }; })] ++ (mapAttrsToList (name: conf: mkExporterConf { inherit name; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/deluge.nix b/nixos/modules/services/monitoring/prometheus/exporters/deluge.nix new file mode 100644 index 000000000000..5943b46eeb5f --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/deluge.nix @@ -0,0 +1,85 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.prometheus.exporters.deluge; + inherit (lib) mkOption types concatStringsSep; +in +{ + port = 9354; + + extraOpts = { + delugeHost = mkOption { + type = types.str; + default = "localhost"; + description = '' + Hostname where deluge server is running. + ''; + }; + + delugePort = mkOption { + type = types.port; + default = 58846; + description = '' + Port where deluge server is listening. + ''; + }; + + delugeUser = mkOption { + type = types.str; + default = "localclient"; + description = '' + User to connect to deluge server. + ''; + }; + + delugePassword = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Password to connect to deluge server. + + This stores the password unencrypted in the nix store and is thus considered unsafe. Prefer + using the delugePasswordFile option. + ''; + }; + + delugePasswordFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing the password to connect to deluge server. + ''; + }; + + exportPerTorrentMetrics = mkOption { + type = types.bool; + default = false; + description = '' + Enable per-torrent metrics. + + This may significantly increase the number of time series depending on the number of + torrents in your Deluge instance. + ''; + }; + }; + serviceOpts = { + serviceConfig = { + ExecStart = '' + ${pkgs.prometheus-deluge-exporter}/bin/deluge-exporter + ''; + Environment = [ + "LISTEN_PORT=${toString cfg.port}" + "LISTEN_ADDRESS=${toString cfg.listenAddress}" + + "DELUGE_HOST=${cfg.delugeHost}" + "DELUGE_USER=${cfg.delugeUser}" + "DELUGE_PORT=${toString cfg.delugePort}" + ] ++ lib.optionals (cfg.delugePassword != null) [ + "DELUGE_PASSWORD=${cfg.delugePassword}" + ] ++ lib.optionals cfg.exportPerTorrentMetrics [ + "PER_TORRENT_METRICS=1" + ]; + EnvironmentFile = lib.optionalString (cfg.delugePasswordFile != null) "/etc/deluge-exporter/password"; + }; + }; +} diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix index 56569c4de2c8..41a76b2e2f75 100644 --- a/nixos/tests/prometheus-exporters.nix +++ b/nixos/tests/prometheus-exporters.nix @@ -209,6 +209,34 @@ let ''; }; + deluge = { + exporterConfig = { + enable = true; + port = 1234; + listenAddress = "127.0.0.1"; + + delugeUser = "user"; + delugePort = 2345; + delugePasswordFile = pkgs.writeText "password" "weak_password"; + }; + metricProvider = { + services.deluge.enable = true; + services.deluge.declarative = true; + services.deluge.config.daemon_port = 2345; + services.deluge.authFile = pkgs.writeText "authFile" '' + localclient:abcdef:10 + user:weak_password:10 + ''; + }; + exporterTest = '' + wait_for_unit("deluged.service") + wait_for_open_port(2345) + wait_for_unit("prometheus-deluge-exporter.service") + wait_for_open_port(1234) + succeed("curl -sSf http://localhost:1234 | grep 'deluge_torrents'") + ''; + }; + dnsmasq = { exporterConfig = { enable = true; diff --git a/pkgs/by-name/pr/prometheus-deluge-exporter/package.nix b/pkgs/by-name/pr/prometheus-deluge-exporter/package.nix new file mode 100644 index 000000000000..3b98cf5e3d76 --- /dev/null +++ b/pkgs/by-name/pr/prometheus-deluge-exporter/package.nix @@ -0,0 +1,35 @@ +{ lib +, python3 +, fetchFromGitHub +, nixosTests +}: + +python3.pkgs.buildPythonApplication rec { + pname = "deluge-exporter"; + version = "2.4.0-unstable-2024-06-02"; + + src = fetchFromGitHub { + owner = "ibizaman"; + repo = "deluge_exporter"; + rev = "8d446c8cba4a324aa052e66c115121b23adc970f"; + hash = "sha256-1brLWx6IEGffcvHPCkz10k9GCNQIXXJ9PYZuEzlKHTA="; + }; + + propagatedBuildInputs = with python3.pkgs; [ + deluge-client + loguru + prometheus-client + ]; + + pythonImportsCheck = [ + "deluge_exporter" + ]; + + meta = with lib; { + description = "Prometheus exporter for Deluge"; + homepage = "https://github.com/ibizaman/deluge_exporter"; + license = licenses.isc; + maintainers = with maintainers; [ ibizaman ]; + mainProgram = "deluge-exporter"; + }; +}