diff --git a/.gitignore b/.gitignore index 2119b44..4dc6905 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ debian/files debian/prometheus-mgit-exporter.debhelper.log debian/prometheus-mgit-exporter.substvars debian/prometheus-mgit-exporter/ -prometheus-mgit-exporter \ No newline at end of file +prometheus-mgit-exporter +result* diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..fe14c62 --- /dev/null +++ b/default.nix @@ -0,0 +1,21 @@ +{ buildGoModule +, lib +}: + +buildGoModule rec { + pname = "prometheus-mgit-exporter"; + # get version from BUILD.bazel + version = with builtins; elemAt (match ".*version = \"([0-9.]*)\".*" (readFile ./BUILD.bazel)) 0; + + src = ./.; + + vendorHash = "sha256-q2e6Q8MbnpOguUNxTumpm3tGbBNes3ada9ma1agcTvs="; + + meta = with lib; { + description = "A collection of useful monitoring for Prometheus by mgIT GmbH."; + homepage = "https://github.com/mgit-at/prometheus-mgit-exporter"; + license = licenses.apsl20; + maintainers = with maintainers; [ mkg20001 ]; + mainProgram = "prometheus-mgit-exporter"; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..c713d75 --- /dev/null +++ b/flake.lock @@ -0,0 +1,44 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1727429674, + "narHash": "sha256-2/wcpn7a8xEx/c1/ih1DHTyVLOUME7xLRfi0mOBT35s=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "e0f477a570df7375172a08ddb9199c90853c63f0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "patches4nixpkgs": { + "locked": { + "lastModified": 1713984892, + "narHash": "sha256-rPu+gkj3qvjor3vvAFurlonyo03bop8s84fvvtNq5mc=", + "owner": "mgit-at", + "repo": "patches4nixpkgs", + "rev": "24952ef04759d20868efe437bb4a88e8dc0265e3", + "type": "github" + }, + "original": { + "owner": "mgit-at", + "ref": "master", + "repo": "patches4nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "patches4nixpkgs": "patches4nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..5ca3881 --- /dev/null +++ b/flake.nix @@ -0,0 +1,56 @@ +{ + description = "A collection of useful monitoring for Prometheus by mgIT GmbH."; + + inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + inputs.patches4nixpkgs.url = "github:mgit-at/patches4nixpkgs/master"; + + outputs = { self, patches4nixpkgs, ... }@inputs: + let + patchPkgs = patches4nixpkgs.patch inputs.nixpkgs [ self ]; + nixpkgs = patches4nixpkgs.eval patchPkgs; + + supportedSystems = [ "x86_64-linux" "aarch64-linux" ]; + forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system: f system); + in + { + overlays.default = final: prev: { + prometheus-mgit-exporter = prev.callPackage ./. {}; + }; + + patches4nixpkgs = nixpkgs: [ + [ + (! builtins.pathExists "${nixpkgs}/nixos/modules/services/monitoring/prometheus/mk-downstream-exporter.nix") + ./nixos-prom-downstream.patch + ] + ]; + + packages = forAllSystems (system: + let + pkgs = (import nixpkgs { + inherit system; + overlays = [ self.overlays.default ]; + }); + in + { + inherit (pkgs) prometheus-mgit-exporter; + default = pkgs.prometheus-mgit-exporter; + } + ); + + nixosModules = { + prometheus-mgit-exporter = import ./module.nix; + }; + + checks = forAllSystems (system: + let + pkgs = (import nixpkgs { + inherit system; + overlays = [ self.overlays.default ]; + }); + in + { + prometheus-mgit-exporter = pkgs.testers.runNixOSTest (import ./test.nix); + } + ); + }; +} diff --git a/mgit-exporter.nix b/mgit-exporter.nix new file mode 100644 index 0000000..655290e --- /dev/null +++ b/mgit-exporter.nix @@ -0,0 +1,159 @@ +# nixpkgs/nixos/modules/services/prometheus/exporters/mgit.nix +{ config, lib, pkgs, options, utils, ... }: + +with lib; + +let + # for convenience we define cfg here + cfg = config.services.prometheus.exporters.mgit; + json = pkgs.formats.json {}; + configurationFile = json.generate "config.json" cfg; +in +{ + port = 9328; # The mgit exporter listens on this port by default + + # `extraOpts` is an attribute set which contains additional options + # (and optional overrides for default options). + # Note that this attribute is optional. + extraOpts = { + listen = mkOption { + default = ":${toString cfg.port}"; + type = types.str; + description = "Listening address"; + }; + + certFile = { + enable = mkEnableOption "certificate file watching"; + globs = mkOption { + default = []; + type = types.listOf types.str; + description = "List of globs"; + }; + exclude_system = mkOption { + type = types.bool; + description = "Exclude system certificates"; + default = false; + }; + }; + + mceLog = { + enable = mkEnableOption "MCE log"; + path = mkOption { + default = ""; + type = types.str; + description = "Path to MCE log"; + }; + }; + + ptHeartbeat = { + enable = mkEnableOption "PT heartbeat"; + database = mkOption { + default = ""; + type = types.str; + description = "Database for PT heartbeat"; + }; + table = mkOption { + default = ""; + type = types.str; + description = "Table for PT heartbeat"; + }; + defaultsFile = mkOption { + default = ""; + type = types.str; + description = "Defaults file for PT heartbeat"; + }; + masterId = mkOption { + default = 0; + type = types.int; + description = "Master ID for PT heartbeat"; + }; + }; + + fsTab = { + enable = mkEnableOption "fsTab"; + }; + + binLog = { + enable = mkEnableOption "binLog"; + path = mkOption { + default = ""; + type = types.str; + description = "Path to binLog"; + }; + }; + + rasDaemon = { + enable = mkEnableOption "rasDaemon"; + path = mkOption { + default = ""; + type = types.str; + description = "Path to rasDaemon"; + }; + }; + + elk = { + enable = mkEnableOption "elk"; + duration = mkOption { + default = ""; + type = types.str; + description = "Duration for elk"; + }; + node = mkOption { + default = "default_node"; + type = types.str; + description = "Node for elk"; + }; + }; + + exec = { + enable = mkEnableOption "exec"; + scripts = mkOption { + default = {}; + type = types.attrsOf (types.submodule ({ ... }: { + options = { + command = mkOption { + type = types.listOf types.str; + description = "Command"; + }; + + dir = mkOption { + type = types.str; + description = "Working directory"; + default = ""; + }; + + timeout = mkOption { + type = types.str; + description = "Timeout"; + default = ""; + }; + }; + })); + description = "Scripts for exec"; + }; + }; + }; + + # `serviceOpts` is an attribute set which contains configuration + # for the exporter's systemd service. One of + # `serviceOpts.script` and `serviceOpts.serviceConfig.ExecStart` + # has to be specified here. This will be merged with the default + # service configuration. + # Note that by default 'DynamicUser' is 'true'. + serviceOpts = { + unitConfig = { + Description = "mgIT exporter for Prometheus"; + Documentation = "https://prometheus.io/docs/introduction/overview/"; + }; + serviceConfig = { + MemoryMax = "1G"; + Restart = "on-failure"; + RestartSec = 1; + DynamicUser = false; + ExecStart = utils.escapeSystemdExecArgs [ + (getExe pkgs.prometheus-mgit-exporter) + "-config" (toString configurationFile) + ]; + }; + }; +} diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..3580142 --- /dev/null +++ b/module.nix @@ -0,0 +1,8 @@ +{ modulesPath, ... }: { + imports = [ + (import "${modulesPath}/services/monitoring/prometheus/mk-downstream-exporter.nix" { + name = "mgit"; + file = ./mgit-exporter.nix; + }) + ]; +} diff --git a/nixos-prom-downstream.patch b/nixos-prom-downstream.patch new file mode 100644 index 0000000..091b711 --- /dev/null +++ b/nixos-prom-downstream.patch @@ -0,0 +1,423 @@ +From 9da240c326ad9e5333cf37f9d43f78441b3ce0d6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20Kr=C3=BCger?= +Date: Fri, 22 Mar 2024 22:55:56 +0100 +Subject: [PATCH] nixos/prometheus: abbility to add downstream exporters + +--- + .../monitoring/prometheus/exporters.md | 17 ++ + .../monitoring/prometheus/exporters.nix | 150 +------------- + .../prometheus/mk-downstream-exporter.nix | 8 + + .../monitoring/prometheus/mk-exporter.nix | 187 ++++++++++++++++++ + 4 files changed, 214 insertions(+), 148 deletions(-) + create mode 100644 nixos/modules/services/monitoring/prometheus/mk-downstream-exporter.nix + create mode 100644 nixos/modules/services/monitoring/prometheus/mk-exporter.nix + +diff --git a/nixos/modules/services/monitoring/prometheus/exporters.md b/nixos/modules/services/monitoring/prometheus/exporters.md +index 23464b9d315e..c7154b0c4597 100644 +--- a/nixos/modules/services/monitoring/prometheus/exporters.md ++++ b/nixos/modules/services/monitoring/prometheus/exporters.md +@@ -178,3 +178,20 @@ in + ]; + } + ``` ++ ++## Adding a downstream exporter {#module-services-prometheus-exporters-downstream-exporter} ++ ++First create the exporter file, `EXPORTER-exporter.nix` as you would with an upstream exporter ++ ++Then create a module that imports the exporter ++ ++```nix ++{ modulesPath, ... }: { ++ imports = [ ++ (import "${modulesPath}/services/monitoring/prometheus/mk-downstream-exporter.nix" { ++ name = "EXPORTER"; ++ file = ./EXPORTER-exporter.nix; ++ }) ++ ]; ++} ++``` +diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix +index 29a30e938e75..385fd821a52e 100644 +--- a/nixos/modules/services/monitoring/prometheus/exporters.nix ++++ b/nixos/modules/services/monitoring/prometheus/exporters.nix +@@ -1,5 +1,7 @@ + { config, pkgs, lib, options, utils, ... }: + ++with (import ./mk-exporter.nix config.networking.nftables.enable lib); ++ + let + inherit (lib) concatStrings foldl foldl' genAttrs literalExpression maintainers + mapAttrs mapAttrsToList mkDefault mkEnableOption mkIf mkMerge mkOption +@@ -129,91 +131,6 @@ let + } + ); + +- mkExporterOpts = ({ name, port }: { +- enable = mkEnableOption "the prometheus ${name} exporter"; +- port = mkOption { +- type = types.port; +- default = port; +- description = '' +- Port to listen on. +- ''; +- }; +- listenAddress = mkOption { +- type = types.str; +- default = "0.0.0.0"; +- description = '' +- Address to listen on. +- ''; +- }; +- extraFlags = mkOption { +- type = types.listOf types.str; +- default = []; +- description = '' +- Extra commandline options to pass to the ${name} exporter. +- ''; +- }; +- openFirewall = mkOption { +- type = types.bool; +- default = false; +- description = '' +- Open port in firewall for incoming connections. +- ''; +- }; +- firewallFilter = mkOption { +- type = types.nullOr types.str; +- default = null; +- example = literalExpression '' +- "-i eth0 -p tcp -m tcp --dport ${toString port}" +- ''; +- description = '' +- Specify a filter for iptables to use when +- {option}`services.prometheus.exporters.${name}.openFirewall` +- is true. It is used as `ip46tables -I nixos-fw firewallFilter -j nixos-fw-accept`. +- ''; +- }; +- firewallRules = mkOption { +- type = types.nullOr types.lines; +- default = null; +- example = literalExpression '' +- iifname "eth0" tcp dport ${toString port} counter accept +- ''; +- description = '' +- Specify rules for nftables to add to the input chain +- when {option}`services.prometheus.exporters.${name}.openFirewall` is true. +- ''; +- }; +- user = mkOption { +- type = types.str; +- default = "${name}-exporter"; +- description = '' +- User name under which the ${name} exporter shall be run. +- ''; +- }; +- group = mkOption { +- type = types.str; +- default = "${name}-exporter"; +- description = '' +- Group under which the ${name} exporter shall be run. +- ''; +- }; +- }); +- +- mkSubModule = { name, port, extraOpts, imports }: { +- ${name} = mkOption { +- type = types.submodule [{ +- inherit imports; +- options = (mkExporterOpts { +- inherit name port; +- } // extraOpts); +- } ({ config, ... }: mkIf config.openFirewall { +- firewallFilter = mkDefault "-p tcp -m tcp --dport ${toString config.port}"; +- firewallRules = mkDefault ''tcp dport ${toString config.port} accept comment "${name}-exporter"''; +- })]; +- internal = true; +- default = {}; +- }; +- }; +- + mkSubModules = (foldl' (a: b: a//b) {} + (mapAttrsToList (name: opts: mkSubModule { + inherit name; +@@ -222,69 +139,6 @@ let + imports = opts.imports or []; + }) exporterOpts) + ); +- +- mkExporterConf = { name, conf, serviceOpts }: +- let +- enableDynamicUser = serviceOpts.serviceConfig.DynamicUser or true; +- nftables = config.networking.nftables.enable; +- in +- mkIf conf.enable { +- warnings = conf.warnings or []; +- assertions = conf.assertions or []; +- users.users."${name}-exporter" = (mkIf (conf.user == "${name}-exporter" && !enableDynamicUser) { +- description = "Prometheus ${name} exporter service user"; +- isSystemUser = true; +- inherit (conf) group; +- }); +- users.groups = mkMerge [ +- (mkIf (conf.group == "${name}-exporter" && !enableDynamicUser) { +- "${name}-exporter" = {}; +- }) +- (mkIf (name == "smartctl") { +- "smartctl-exporter-access" = {}; +- }) +- ]; +- services.udev.extraRules = mkIf (name == "smartctl") '' +- ACTION=="add", SUBSYSTEM=="nvme", KERNEL=="nvme[0-9]*", RUN+="${pkgs.acl}/bin/setfacl -m g:smartctl-exporter-access:rw /dev/$kernel" +- ''; +- networking.firewall.extraCommands = mkIf (conf.openFirewall && !nftables) (concatStrings [ +- "ip46tables -A nixos-fw ${conf.firewallFilter} " +- "-m comment --comment ${name}-exporter -j nixos-fw-accept" +- ]); +- networking.firewall.extraInputRules = mkIf (conf.openFirewall && nftables) conf.firewallRules; +- systemd.services."prometheus-${name}-exporter" = mkMerge ([{ +- wantedBy = [ "multi-user.target" ]; +- after = [ "network.target" ]; +- serviceConfig.Restart = mkDefault "always"; +- serviceConfig.PrivateTmp = mkDefault true; +- serviceConfig.WorkingDirectory = mkDefault /tmp; +- serviceConfig.DynamicUser = mkDefault enableDynamicUser; +- serviceConfig.User = mkDefault conf.user; +- serviceConfig.Group = conf.group; +- # Hardening +- serviceConfig.CapabilityBoundingSet = mkDefault [ "" ]; +- serviceConfig.DeviceAllow = [ "" ]; +- serviceConfig.LockPersonality = true; +- serviceConfig.MemoryDenyWriteExecute = true; +- serviceConfig.NoNewPrivileges = true; +- serviceConfig.PrivateDevices = mkDefault true; +- serviceConfig.ProtectClock = mkDefault true; +- serviceConfig.ProtectControlGroups = true; +- serviceConfig.ProtectHome = true; +- serviceConfig.ProtectHostname = true; +- serviceConfig.ProtectKernelLogs = true; +- serviceConfig.ProtectKernelModules = true; +- serviceConfig.ProtectKernelTunables = true; +- serviceConfig.ProtectSystem = mkDefault "strict"; +- serviceConfig.RemoveIPC = true; +- serviceConfig.RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; +- serviceConfig.RestrictNamespaces = true; +- serviceConfig.RestrictRealtime = true; +- serviceConfig.RestrictSUIDSGID = true; +- serviceConfig.SystemCallArchitectures = "native"; +- serviceConfig.UMask = "0077"; +- } serviceOpts ]); +- }; + in + { + +diff --git a/nixos/modules/services/monitoring/prometheus/mk-downstream-exporter.nix b/nixos/modules/services/monitoring/prometheus/mk-downstream-exporter.nix +new file mode 100644 +index 000000000000..ab2285b13ec5 +--- /dev/null ++++ b/nixos/modules/services/monitoring/prometheus/mk-downstream-exporter.nix +@@ -0,0 +1,8 @@ ++{ name, file }: { config, pkgs, lib, options, utils, ... }@args: ++ ++with (import ./mk-exporter.nix config.networking.nftables.enable lib); ++ ++{ ++ options.services.prometheus.exporters = mkDownstreamOptions name (import file args); ++ config = mkDownstreamConfig name (import file args) config.services.prometheus.exporters.${name}; ++} +diff --git a/nixos/modules/services/monitoring/prometheus/mk-exporter.nix b/nixos/modules/services/monitoring/prometheus/mk-exporter.nix +new file mode 100644 +index 000000000000..17aaad474b65 +--- /dev/null ++++ b/nixos/modules/services/monitoring/prometheus/mk-exporter.nix +@@ -0,0 +1,187 @@ ++nftables: lib: ++ ++let ++ inherit (lib) concatStrings foldl foldl' genAttrs literalExpression maintainers ++ mapAttrs mapAttrsToList mkDefault mkEnableOption mkIf mkMerge mkOption ++ optional types mkOptionDefault flip attrNames; ++ ++ # each attribute in `exporterOpts` is expected to have specified: ++ # - port (types.int): port on which the exporter listens ++ # - serviceOpts (types.attrs): config that is merged with the ++ # default definition of the exporter's ++ # systemd service ++ # - extraOpts (types.attrs): extra configuration options to ++ # configure the exporter with, which ++ # are appended to the default options ++ # ++ # Note that `extraOpts` is optional, but a script for the exporter's ++ # systemd service must be provided by specifying either ++ # `serviceOpts.script` or `serviceOpts.serviceConfig.ExecStart` ++ ++ mkExporterOpts = ({ name, port }: { ++ enable = mkEnableOption "the prometheus ${name} exporter"; ++ port = mkOption { ++ type = types.port; ++ default = port; ++ description = '' ++ Port to listen on. ++ ''; ++ }; ++ listenAddress = mkOption { ++ type = types.str; ++ default = "0.0.0.0"; ++ description = '' ++ Address to listen on. ++ ''; ++ }; ++ extraFlags = mkOption { ++ type = types.listOf types.str; ++ default = []; ++ description = '' ++ Extra commandline options to pass to the ${name} exporter. ++ ''; ++ }; ++ openFirewall = mkOption { ++ type = types.bool; ++ default = false; ++ description = '' ++ Open port in firewall for incoming connections. ++ ''; ++ }; ++ firewallFilter = mkOption { ++ type = types.nullOr types.str; ++ default = null; ++ example = literalExpression '' ++ "-i eth0 -p tcp -m tcp --dport ${toString port}" ++ ''; ++ description = '' ++ Specify a filter for iptables to use when ++ {option}`services.prometheus.exporters.${name}.openFirewall` ++ is true. It is used as `ip46tables -I nixos-fw firewallFilter -j nixos-fw-accept`. ++ ''; ++ }; ++ firewallRules = mkOption { ++ type = types.nullOr types.lines; ++ default = null; ++ example = literalExpression '' ++ iifname "eth0" tcp dport ${toString port} counter accept ++ ''; ++ description = '' ++ Specify rules for nftables to add to the input chain ++ when {option}`services.prometheus.exporters.${name}.openFirewall` is true. ++ ''; ++ }; ++ user = mkOption { ++ type = types.str; ++ default = "${name}-exporter"; ++ description = '' ++ User name under which the ${name} exporter shall be run. ++ ''; ++ }; ++ group = mkOption { ++ type = types.str; ++ default = "${name}-exporter"; ++ description = '' ++ Group under which the ${name} exporter shall be run. ++ ''; ++ }; ++ }); ++ ++ mkSubModule = { name, port, extraOpts, imports }: { ++ ${name} = mkOption { ++ type = types.submodule [{ ++ inherit imports; ++ options = (mkExporterOpts { ++ inherit name port; ++ } // extraOpts); ++ } ({ config, ... }: mkIf config.openFirewall { ++ firewallFilter = mkDefault "-p tcp -m tcp --dport ${toString config.port}"; ++ firewallRules = mkDefault ''tcp dport ${toString config.port} accept comment "${name}-exporter"''; ++ })]; ++ internal = true; ++ default = {}; ++ }; ++ }; ++ ++ mkExporterConf = { name, conf, serviceOpts }: ++ let ++ enableDynamicUser = serviceOpts.serviceConfig.DynamicUser or true; ++ in ++ mkIf conf.enable { ++ warnings = conf.warnings or []; ++ assertions = conf.assertions or []; ++ users.users."${name}-exporter" = (mkIf (conf.user == "${name}-exporter" && !enableDynamicUser) { ++ description = "Prometheus ${name} exporter service user"; ++ isSystemUser = true; ++ inherit (conf) group; ++ }); ++ users.groups = mkMerge [ ++ (mkIf (conf.group == "${name}-exporter" && !enableDynamicUser) { ++ "${name}-exporter" = {}; ++ }) ++ (mkIf (name == "smartctl") { ++ "smartctl-exporter-access" = {}; ++ }) ++ ]; ++ services.udev.extraRules = mkIf (name == "smartctl") '' ++ ACTION=="add", SUBSYSTEM=="nvme", KERNEL=="nvme[0-9]*", RUN+="${pkgs.acl}/bin/setfacl -m g:smartctl-exporter-access:rw /dev/$kernel" ++ ''; ++ networking.firewall.extraCommands = mkIf (conf.openFirewall && !nftables) (concatStrings [ ++ "ip46tables -A nixos-fw ${conf.firewallFilter} " ++ "-m comment --comment ${name}-exporter -j nixos-fw-accept" ++ ]); ++ networking.firewall.extraInputRules = mkIf (conf.openFirewall && nftables) conf.firewallRules; ++ systemd.services."prometheus-${name}-exporter" = mkMerge ([{ ++ wantedBy = [ "multi-user.target" ]; ++ after = [ "network.target" ]; ++ serviceConfig.Restart = mkDefault "always"; ++ serviceConfig.PrivateTmp = mkDefault true; ++ serviceConfig.WorkingDirectory = mkDefault /tmp; ++ serviceConfig.DynamicUser = mkDefault enableDynamicUser; ++ serviceConfig.User = mkDefault conf.user; ++ serviceConfig.Group = conf.group; ++ # Hardening ++ serviceConfig.CapabilityBoundingSet = mkDefault [ "" ]; ++ serviceConfig.DeviceAllow = [ "" ]; ++ serviceConfig.LockPersonality = true; ++ serviceConfig.MemoryDenyWriteExecute = true; ++ serviceConfig.NoNewPrivileges = true; ++ serviceConfig.PrivateDevices = mkDefault true; ++ serviceConfig.ProtectClock = mkDefault true; ++ serviceConfig.ProtectControlGroups = true; ++ serviceConfig.ProtectHome = true; ++ serviceConfig.ProtectHostname = true; ++ serviceConfig.ProtectKernelLogs = true; ++ serviceConfig.ProtectKernelModules = true; ++ serviceConfig.ProtectKernelTunables = true; ++ serviceConfig.ProtectSystem = mkDefault "strict"; ++ serviceConfig.RemoveIPC = true; ++ serviceConfig.RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; ++ serviceConfig.RestrictNamespaces = true; ++ serviceConfig.RestrictRealtime = true; ++ serviceConfig.RestrictSUIDSGID = true; ++ serviceConfig.SystemCallArchitectures = "native"; ++ serviceConfig.UMask = "0077"; ++ } serviceOpts ]); ++ }; ++ ++ mkDownstreamOptions = name: opts: ++ mkSubModule { ++ inherit name; ++ inherit (opts) port; ++ extraOpts = opts.extraOpts or {}; ++ imports = opts.imports or []; ++ }; ++ ++ mkDownstreamConfig = name: opts: cfg: ++ mkExporterConf { ++ inherit name; ++ inherit (opts) serviceOpts; ++ conf = cfg; ++ }; ++in ++{ ++ inherit ++ mkExporterConf mkSubModule ++ mkDownstreamOptions mkDownstreamConfig; ++} +-- +2.46.0 + diff --git a/test.nix b/test.nix new file mode 100644 index 0000000..b3219fd --- /dev/null +++ b/test.nix @@ -0,0 +1,18 @@ +{ pkgs, lib, ... }: +{ + name = "prometheus-mgit-exporter"; + + nodes = { + server = { lib, pkgs, ... }: { + imports = [ ./module.nix ]; + services.prometheus.exporters.mgit.enable = true; + environment.systemPackages = with pkgs; [ wget ]; + }; + }; + + testScript = '' + start_all() + server.wait_for_unit("prometheus-mgit-exporter.service") + server.succeed("wget localhost:9328/metrics") + ''; +}