diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index eb21ab718578..69eeada28f4a 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1030,6 +1030,7 @@ ./services/monitoring/grafana-to-ntfy.nix ./services/monitoring/grafana.nix ./services/monitoring/graphite.nix + ./services/monitoring/gs1200-exporter.nix ./services/monitoring/hdaps.nix ./services/monitoring/heapster.nix ./services/monitoring/incron.nix diff --git a/nixos/modules/services/monitoring/gs1200-exporter.nix b/nixos/modules/services/monitoring/gs1200-exporter.nix new file mode 100644 index 000000000000..96be5a9d659f --- /dev/null +++ b/nixos/modules/services/monitoring/gs1200-exporter.nix @@ -0,0 +1,95 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.services.gs1200-exporter; +in +{ + meta.maintainers = with lib.maintainers; [ DerGrumpf ]; + + options.services.gs1200-exporter = { + enable = lib.mkEnableOption "gs1200-exporter"; + + address = lib.mkOption { + type = lib.types.str; + description = "IP address or hostname of the GS1200 switch."; + example = "192.168.1.3"; + }; + + port = lib.mkOption { + type = lib.types.port; + default = 9934; + description = "Port on which to expose Prometheus metrics."; + }; + + passwordFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = '' + Path to a file containing the password to log in to the GS1200 web interface. + This is the recommended option as it avoids storing the password in the Nix store. + Compatible with sops-nix and agenix. + ''; + example = "/run/secrets/gs1200-password"; + }; + + debug = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Enable debug logging. Logs are accessible via journalctl -u gs1200-exporter."; + }; + + verbose = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Enable verbose logging. Logs are accessible via journalctl -u gs1200-exporter."; + }; + + json = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Output logs in JSON format. Logs are accessible via journalctl -u gs1200-exporter."; + }; + }; + + config = lib.mkIf cfg.enable { + + systemd.services.gs1200-exporter = { + description = "Prometheus exporter for Zyxel GS1200 switches"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + DynamicUser = true; + Restart = "always"; + + # Hardening + NoNewPrivileges = true; + PrivateTmp = true; + ProtectSystem = "strict"; + ProtectHome = true; + CapabilityBoundingSet = ""; + }; + + script = + let + args = lib.concatStringsSep " " ( + [ + "--address ${cfg.address}" + "--port ${toString cfg.port}" + ] + ++ lib.optional cfg.debug "--debug" + ++ lib.optional cfg.verbose "--verbose" + ++ lib.optional cfg.json "--json" + ); + in + '' + export GS1200_PASSWORD=$(cat ${cfg.passwordFile}) + exec ${lib.getExe pkgs.gs1200-exporter} ${args} + ''; + }; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 8fc788e0aa89..1718f0ccdaad 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -692,6 +692,7 @@ in grocy = runTest ./grocy.nix; grow-partition = runTest ./grow-partition.nix; grub = runTest ./grub.nix; + gs1200-exporter = runTest ./gs1200-exporter.nix; guacamole-server = runTest ./guacamole-server.nix; guix = handleTest ./guix { }; gvisor = runTest ./gvisor.nix; diff --git a/nixos/tests/gs1200-exporter.nix b/nixos/tests/gs1200-exporter.nix new file mode 100644 index 000000000000..5f4b4c611c36 --- /dev/null +++ b/nixos/tests/gs1200-exporter.nix @@ -0,0 +1,20 @@ +{ lib, ... }: +{ + name = "gs1200-exporter"; + meta.maintainers = with lib.maintainers; [ DerGrumpf ]; + nodes.machine = _: { + services.gs1200-exporter = { + enable = true; + address = "192.168.2.4"; + passwordFile = "/run/secrets/gs1200-password"; + }; + systemd.tmpfiles.rules = [ + "f /run/secrets/gs1200-password 0400 root root - testpassword" + ]; + }; + testScript = '' + machine.wait_for_unit("gs1200-exporter.service") + machine.wait_for_open_port(9934) + machine.succeed("curl -f http://localhost:9934/metrics") + ''; +}