From d1ef00ebee8b311951c757b4a7ebb2b16aaf1ef2 Mon Sep 17 00:00:00 2001 From: Andreas Rammhold Date: Sun, 4 Nov 2018 16:57:47 +0100 Subject: [PATCH 1/3] nixos/prometheus: add `package` option to alertmanager --- .../services/monitoring/prometheus/alertmanager.nix | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/monitoring/prometheus/alertmanager.nix b/nixos/modules/services/monitoring/prometheus/alertmanager.nix index 8a44cf7fd8f..ae294478819 100644 --- a/nixos/modules/services/monitoring/prometheus/alertmanager.nix +++ b/nixos/modules/services/monitoring/prometheus/alertmanager.nix @@ -23,6 +23,15 @@ in { services.prometheus.alertmanager = { enable = mkEnableOption "Prometheus Alertmanager"; + package = mkOption { + type = types.package; + default = pkgs.prometheus-alertmanager; + defaultText = "pkgs.alertmanager"; + description = '' + Package that should be used for alertmanager. + ''; + }; + user = mkOption { type = types.str; default = "nobody"; @@ -127,7 +136,7 @@ in { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; script = '' - ${pkgs.prometheus-alertmanager.bin}/bin/alertmanager \ + ${cfg.package}/bin/alertmanager \ ${concatStringsSep " \\\n " cmdlineArgs} ''; From b1032db5a9a2c65737a4fb2a8410224e6b87db56 Mon Sep 17 00:00:00 2001 From: Andreas Rammhold Date: Sun, 4 Nov 2018 16:58:13 +0100 Subject: [PATCH 2/3] nixos/prometheus: check alertmanager configuration --- .../monitoring/prometheus/alertmanager.nix | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/nixos/modules/services/monitoring/prometheus/alertmanager.nix b/nixos/modules/services/monitoring/prometheus/alertmanager.nix index ae294478819..cec5bb8df86 100644 --- a/nixos/modules/services/monitoring/prometheus/alertmanager.nix +++ b/nixos/modules/services/monitoring/prometheus/alertmanager.nix @@ -5,10 +5,18 @@ with lib; let cfg = config.services.prometheus.alertmanager; mkConfigFile = pkgs.writeText "alertmanager.yml" (builtins.toJSON cfg.configuration); - alertmanagerYml = - if cfg.configText != null then - pkgs.writeText "alertmanager.yml" cfg.configText - else mkConfigFile; + + checkedConfig = file: pkgs.runCommand "checked-config" { buildInputs = [ cfg.package ]; } '' + ln -s ${file} $out + amtool check-config $out + ''; + + alertmanagerYml = let + yml = if cfg.configText != null then + pkgs.writeText "alertmanager.yml" cfg.configText + else mkConfigFile; + in checkedConfig yml; + cmdlineArgs = cfg.extraFlags ++ [ "--config.file ${alertmanagerYml}" "--web.listen-address ${cfg.listenAddress}:${toString cfg.port}" From 51c30821199f8b3170fdf5f54921f20a1082ad79 Mon Sep 17 00:00:00 2001 From: Andreas Rammhold Date: Sun, 4 Nov 2018 19:27:43 +0100 Subject: [PATCH 3/3] nixos/prometheus: require one alertmanager configuration parameter This commit adds an assertion that checks that either `configFile` or `configuration` is configured for alertmanager. The alertmanager config can not be an empty attributeset. The check executed with `amtool` fails before the service even has the chance to start. We should probably not allow a broken alertmanager configuration anyway. This also introduces a test for alertmanager configuration that piggy backs on the existing prometheus tests. --- .../monitoring/prometheus/alertmanager.nix | 54 +++++++++++-------- nixos/tests/prometheus.nix | 22 ++++++++ 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/nixos/modules/services/monitoring/prometheus/alertmanager.nix b/nixos/modules/services/monitoring/prometheus/alertmanager.nix index cec5bb8df86..43b4a41eaf3 100644 --- a/nixos/modules/services/monitoring/prometheus/alertmanager.nix +++ b/nixos/modules/services/monitoring/prometheus/alertmanager.nix @@ -57,8 +57,8 @@ in { }; configuration = mkOption { - type = types.attrs; - default = {}; + type = types.nullOr types.attrs; + default = null; description = '' Alertmanager configuration as nix attribute set. ''; @@ -136,26 +136,34 @@ in { }; }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.alertmanager = { - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - script = '' - ${cfg.package}/bin/alertmanager \ - ${concatStringsSep " \\\n " cmdlineArgs} - ''; - - serviceConfig = { - User = cfg.user; - Group = cfg.group; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = "/tmp"; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + config = mkMerge [ + (mkIf cfg.enable { + assertions = singleton { + assertion = cfg.configuration != null || cfg.configText != null; + message = "Can not enable alertmanager without a configuration. " + + "Set either the `configuration` or `configText` attribute."; }; - }; - }; + }) + (mkIf cfg.enable { + networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; + + systemd.services.alertmanager = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + script = '' + ${cfg.package}/bin/alertmanager \ + ${concatStringsSep " \\\n " cmdlineArgs} + ''; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + Restart = "always"; + PrivateTmp = true; + WorkingDirectory = "/tmp"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + }; + }; + }) + ]; } diff --git a/nixos/tests/prometheus.nix b/nixos/tests/prometheus.nix index 87a6510f40f..f1b20a33d71 100644 --- a/nixos/tests/prometheus.nix +++ b/nixos/tests/prometheus.nix @@ -13,6 +13,25 @@ import ./make-test.nix { }]; }]; rules = [ ''testrule = count(up{job="prometheus"})'' ]; + + # a very simple version of the alertmanager configuration just to see if + # configuration checks & service startup are working + alertmanager = { + enable = true; + listenAddress = "[::1]"; + port = 9093; + configuration = { + route.receiver = "webhook"; + receivers = [ + { + name = "webhook"; + webhook_configs = [ + { url = "http://localhost"; } + ]; + } + ]; + }; + }; }; }; }; @@ -22,5 +41,8 @@ import ./make-test.nix { $one->waitForUnit("prometheus.service"); $one->waitForOpenPort(9090); $one->succeed("curl -s http://127.0.0.1:9090/metrics"); + $one->waitForUnit("alertmanager.service"); + $one->waitForOpenPort("9093"); + $one->succeed("curl -f -s http://localhost:9093/"); ''; }