diff --git a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
index 0c10451add4c..664fa1b03690 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
@@ -187,6 +187,14 @@
services.mtr-exporter.
+
+
+ prometheus-pve-exporter,
+ a tool that exposes information from the Proxmox VE API for
+ use by Prometheus. Available as
+ services.prometheus.exporters.pve.
+
+
tetrd, share your
diff --git a/nixos/doc/manual/release-notes/rl-2205.section.md b/nixos/doc/manual/release-notes/rl-2205.section.md
index b9402ba5f9dd..c65428ea7e7d 100644
--- a/nixos/doc/manual/release-notes/rl-2205.section.md
+++ b/nixos/doc/manual/release-notes/rl-2205.section.md
@@ -55,6 +55,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [mtr-exporter](https://github.com/mgumz/mtr-exporter), a Prometheus exporter for mtr metrics. Available as [services.mtr-exporter](options.html#opt-services.mtr-exporter.enable).
+- [prometheus-pve-exporter](https://github.com/prometheus-pve/prometheus-pve-exporter), a tool that exposes information from the Proxmox VE API for use by Prometheus. Available as [services.prometheus.exporters.pve](options.html#opt-services.prometheus.exporters.pve).
+
- [tetrd](https://tetrd.app), share your internet connection from your device to your PC and vice versa through a USB cable. Available at [services.tetrd](#opt-services.tetrd.enable).
- [agate](https://github.com/mbrubeck/agate), a very simple server for the Gemini hypertext protocol. Available as [services.agate](options.html#opt-services.agate.enable).
diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix
index d29d50706ef6..46e410f11d42 100644
--- a/nixos/modules/services/monitoring/prometheus/exporters.nix
+++ b/nixos/modules/services/monitoring/prometheus/exporters.nix
@@ -55,6 +55,7 @@ let
"postfix"
"postgres"
"process"
+ "pve"
"py-air-control"
"redis"
"rspamd"
diff --git a/nixos/modules/services/monitoring/prometheus/exporters/pve.nix b/nixos/modules/services/monitoring/prometheus/exporters/pve.nix
new file mode 100644
index 000000000000..ef708414c95e
--- /dev/null
+++ b/nixos/modules/services/monitoring/prometheus/exporters/pve.nix
@@ -0,0 +1,118 @@
+{ config, lib, pkgs, options }:
+
+with lib;
+let
+ cfg = config.services.prometheus.exporters.pve;
+
+ # pve exporter requires a config file so create an empty one if configFile is not provided
+ emptyConfigFile = pkgs.writeTextFile {
+ name = "pve.yml";
+ text = "default:";
+ };
+
+ computedConfigFile = "${if cfg.configFile == null then emptyConfigFile else cfg.configFile}";
+in
+{
+ port = 9221;
+ extraOpts = {
+ package = mkOption {
+ type = types.package;
+ default = pkgs.prometheus-pve-exporter;
+ defaultText = literalExpression "pkgs.prometheus-pve-exporter";
+ example = literalExpression "pkgs.prometheus-pve-exporter";
+ description = ''
+ The package to use for prometheus-pve-exporter
+ '';
+ };
+
+ environmentFile = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ example = "/etc/prometheus-pve-exporter/pve.env";
+ description = ''
+ Path to the service's environment file. This path can either be a computed path in /nix/store or a path in the local filesystem.
+
+ The environment file should NOT be stored in /nix/store as it contains passwords and/or keys in plain text.
+
+ Environment reference: https://github.com/prometheus-pve/prometheus-pve-exporter#authentication
+ '';
+ };
+
+ configFile = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ example = "/etc/prometheus-pve-exporter/pve.yml";
+ description = ''
+ Path to the service's config file. This path can either be a computed path in /nix/store or a path in the local filesystem.
+
+ The config file should NOT be stored in /nix/store as it will contain passwords and/or keys in plain text.
+
+ If both configFile and environmentFile are provided, the configFile option will be ignored.
+
+ Configuration reference: https://github.com/prometheus-pve/prometheus-pve-exporter/#authentication
+ '';
+ };
+
+ collectors = {
+ status = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect Node/VM/CT status
+ '';
+ };
+ version = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE version info
+ '';
+ };
+ node = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE node info
+ '';
+ };
+ cluster = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE cluster info
+ '';
+ };
+ resources = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE resources info
+ '';
+ };
+ config = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE onboot status
+ '';
+ };
+ };
+ };
+ serviceOpts = {
+ serviceConfig = {
+ ExecStart = ''
+ ${cfg.package}/bin/pve_exporter \
+ --${if cfg.collectors.status == true then "" else "no-"}collector.status \
+ --${if cfg.collectors.version == true then "" else "no-"}collector.version \
+ --${if cfg.collectors.node == true then "" else "no-"}collector.node \
+ --${if cfg.collectors.cluster == true then "" else "no-"}collector.cluster \
+ --${if cfg.collectors.resources == true then "" else "no-"}collector.resources \
+ --${if cfg.collectors.config == true then "" else "no-"}collector.config \
+ ${computedConfigFile} \
+ ${toString cfg.port} ${cfg.listenAddress}
+ '';
+ } // optionalAttrs (cfg.environmentFile != null) {
+ EnvironmentFile = cfg.environmentFile;
+ };
+ };
+}
diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix
index 18b64a958dd6..ce3b3fbf3bf3 100644
--- a/nixos/tests/prometheus-exporters.nix
+++ b/nixos/tests/prometheus-exporters.nix
@@ -933,6 +933,27 @@ let
'';
};
+ pve = let
+ pveExporterEnvFile = pkgs.writeTextFile {
+ name = "pve.env";
+ text = ''
+ PVE_USER="test_user@pam"
+ PVE_PASSWORD="hunter3"
+ PVE_VERIFY_SSL="false"
+ '';
+ };
+ in {
+ exporterConfig = {
+ enable = true;
+ environmentFile = pveExporterEnvFile;
+ };
+ exporterTest = ''
+ wait_for_unit("prometheus-pve-exporter.service")
+ wait_for_open_port(9221)
+ wait_until_succeeds("curl localhost:9221")
+ '';
+ };
+
py-air-control = {
nodeName = "py_air_control";
exporterConfig = {
diff --git a/pkgs/servers/monitoring/prometheus/pve-exporter.nix b/pkgs/servers/monitoring/prometheus/pve-exporter.nix
new file mode 100644
index 000000000000..707c121cc50a
--- /dev/null
+++ b/pkgs/servers/monitoring/prometheus/pve-exporter.nix
@@ -0,0 +1,37 @@
+{ lib
+, python3
+, nixosTests
+}:
+
+python3.pkgs.buildPythonApplication rec {
+ pname = "prometheus-pve-exporter";
+ version = "2.2.2";
+
+ src = python3.pkgs.fetchPypi {
+ inherit pname version;
+ sha256 = "0vvsiw8nj8zkx6v42f260xbsdd92l0ac4vwpm7w38j3qwvanar7k";
+ };
+
+ propagatedBuildInputs = with python3.pkgs; [
+ prometheus-client
+ proxmoxer
+ pyyaml
+ requests
+ werkzeug
+ ];
+
+ doCheck = false;
+
+ pythonImportsCheck = [ "pve_exporter" ];
+
+ passthru.tests = {
+ inherit (nixosTests.prometheus-exporters) pve;
+ };
+
+ meta = with lib; {
+ description = "Exposes information gathered from Proxmox VE cluster for use by the Prometheus monitoring system";
+ homepage = "https://github.com/prometheus-pve/prometheus-pve-exporter";
+ license = licenses.asl20;
+ maintainers = with maintainers; [ nukaduka ];
+ };
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 62a3006dd704..f5d5eb740ad2 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -21925,6 +21925,7 @@ with pkgs;
prometheus-postgres-exporter = callPackage ../servers/monitoring/prometheus/postgres-exporter.nix { };
prometheus-process-exporter = callPackage ../servers/monitoring/prometheus/process-exporter.nix { };
prometheus-pushgateway = callPackage ../servers/monitoring/prometheus/pushgateway.nix { };
+ prometheus-pve-exporter = callPackage ../servers/monitoring/prometheus/pve-exporter.nix { };
prometheus-redis-exporter = callPackage ../servers/monitoring/prometheus/redis-exporter.nix { };
prometheus-rabbitmq-exporter = callPackage ../servers/monitoring/prometheus/rabbitmq-exporter.nix { };
prometheus-rtl_433-exporter = callPackage ../servers/monitoring/prometheus/rtl_433-exporter.nix { };