at 23.11-pre 7.0 kB view raw
1{ config, pkgs, lib, ... }: 2 3with lib; 4 5let 6 cfg = config.services.prometheus.alertmanager; 7 mkConfigFile = pkgs.writeText "alertmanager.yml" (builtins.toJSON cfg.configuration); 8 9 checkedConfig = file: 10 if cfg.checkConfig then 11 pkgs.runCommand "checked-config" { buildInputs = [ cfg.package ]; } '' 12 ln -s ${file} $out 13 amtool check-config $out 14 '' else file; 15 16 alertmanagerYml = let 17 yml = if cfg.configText != null then 18 pkgs.writeText "alertmanager.yml" cfg.configText 19 else mkConfigFile; 20 in checkedConfig yml; 21 22 cmdlineArgs = cfg.extraFlags ++ [ 23 "--config.file /tmp/alert-manager-substituted.yaml" 24 "--web.listen-address ${cfg.listenAddress}:${toString cfg.port}" 25 "--log.level ${cfg.logLevel}" 26 "--storage.path /var/lib/alertmanager" 27 (toString (map (peer: "--cluster.peer ${peer}:9094") cfg.clusterPeers)) 28 ] ++ (optional (cfg.webExternalUrl != null) 29 "--web.external-url ${cfg.webExternalUrl}" 30 ) ++ (optional (cfg.logFormat != null) 31 "--log.format ${cfg.logFormat}" 32 ); 33in { 34 imports = [ 35 (mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "user" ] "The alertmanager service is now using systemd's DynamicUser mechanism which obviates a user setting.") 36 (mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "group" ] "The alertmanager service is now using systemd's DynamicUser mechanism which obviates a group setting.") 37 (mkRemovedOptionModule [ "services" "prometheus" "alertmanagerURL" ] '' 38 Due to incompatibility, the alertmanagerURL option has been removed, 39 please use 'services.prometheus.alertmanagers' instead. 40 '') 41 ]; 42 43 options = { 44 services.prometheus.alertmanager = { 45 enable = mkEnableOption (lib.mdDoc "Prometheus Alertmanager"); 46 47 package = mkOption { 48 type = types.package; 49 default = pkgs.prometheus-alertmanager; 50 defaultText = literalExpression "pkgs.alertmanager"; 51 description = lib.mdDoc '' 52 Package that should be used for alertmanager. 53 ''; 54 }; 55 56 configuration = mkOption { 57 type = types.nullOr types.attrs; 58 default = null; 59 description = lib.mdDoc '' 60 Alertmanager configuration as nix attribute set. 61 ''; 62 }; 63 64 configText = mkOption { 65 type = types.nullOr types.lines; 66 default = null; 67 description = lib.mdDoc '' 68 Alertmanager configuration as YAML text. If non-null, this option 69 defines the text that is written to alertmanager.yml. If null, the 70 contents of alertmanager.yml is generated from the structured config 71 options. 72 ''; 73 }; 74 75 checkConfig = mkOption { 76 type = types.bool; 77 default = true; 78 description = lib.mdDoc '' 79 Check configuration with `amtool check-config`. The call to `amtool` is 80 subject to sandboxing by Nix. 81 82 If you use credentials stored in external files 83 (`environmentFile`, etc), 84 they will not be visible to `amtool` 85 and it will report errors, despite a correct configuration. 86 ''; 87 }; 88 89 logFormat = mkOption { 90 type = types.nullOr types.str; 91 default = null; 92 description = lib.mdDoc '' 93 If set use a syslog logger or JSON logging. 94 ''; 95 }; 96 97 logLevel = mkOption { 98 type = types.enum ["debug" "info" "warn" "error" "fatal"]; 99 default = "warn"; 100 description = lib.mdDoc '' 101 Only log messages with the given severity or above. 102 ''; 103 }; 104 105 webExternalUrl = mkOption { 106 type = types.nullOr types.str; 107 default = null; 108 description = lib.mdDoc '' 109 The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy). 110 Used for generating relative and absolute links back to Alertmanager itself. 111 If the URL has a path portion, it will be used to prefix all HTTP endoints served by Alertmanager. 112 If omitted, relevant URL components will be derived automatically. 113 ''; 114 }; 115 116 listenAddress = mkOption { 117 type = types.str; 118 default = ""; 119 description = lib.mdDoc '' 120 Address to listen on for the web interface and API. Empty string will listen on all interfaces. 121 "localhost" will listen on 127.0.0.1 (but not ::1). 122 ''; 123 }; 124 125 port = mkOption { 126 type = types.port; 127 default = 9093; 128 description = lib.mdDoc '' 129 Port to listen on for the web interface and API. 130 ''; 131 }; 132 133 openFirewall = mkOption { 134 type = types.bool; 135 default = false; 136 description = lib.mdDoc '' 137 Open port in firewall for incoming connections. 138 ''; 139 }; 140 141 clusterPeers = mkOption { 142 type = types.listOf types.str; 143 default = []; 144 description = lib.mdDoc '' 145 Initial peers for HA cluster. 146 ''; 147 }; 148 149 extraFlags = mkOption { 150 type = types.listOf types.str; 151 default = []; 152 description = lib.mdDoc '' 153 Extra commandline options when launching the Alertmanager. 154 ''; 155 }; 156 157 environmentFile = mkOption { 158 type = types.nullOr types.path; 159 default = null; 160 example = "/root/alertmanager.env"; 161 description = lib.mdDoc '' 162 File to load as environment file. Environment variables 163 from this file will be interpolated into the config file 164 using envsubst with this syntax: 165 `$ENVIRONMENT ''${VARIABLE}` 166 ''; 167 }; 168 }; 169 }; 170 171 config = mkMerge [ 172 (mkIf cfg.enable { 173 assertions = singleton { 174 assertion = cfg.configuration != null || cfg.configText != null; 175 message = "Can not enable alertmanager without a configuration. " 176 + "Set either the `configuration` or `configText` attribute."; 177 }; 178 }) 179 (mkIf cfg.enable { 180 networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; 181 182 systemd.services.alertmanager = { 183 wantedBy = [ "multi-user.target" ]; 184 after = [ "network-online.target" ]; 185 preStart = '' 186 ${lib.getBin pkgs.envsubst}/bin/envsubst -o "/tmp/alert-manager-substituted.yaml" \ 187 -i "${alertmanagerYml}" 188 ''; 189 serviceConfig = { 190 Restart = "always"; 191 StateDirectory = "alertmanager"; 192 DynamicUser = true; # implies PrivateTmp 193 EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; 194 WorkingDirectory = "/tmp"; 195 ExecStart = "${cfg.package}/bin/alertmanager" + 196 optionalString (length cmdlineArgs != 0) (" \\\n " + 197 concatStringsSep " \\\n " cmdlineArgs); 198 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 199 }; 200 }; 201 }) 202 ]; 203}