anyrun: 0-unstable-2024-11-08 -> 0-unstable-2024-12-27 (#369731)
[NixPkgs.git] / nixos / modules / services / monitoring / prometheus / exporters / mail.nix
blob7dc40293d464241be229f821a29abd62ac39f1ba
2   config,
3   lib,
4   pkgs,
5   options,
6   ...
7 }:
9 let
10   cfg = config.services.prometheus.exporters.mail;
11   inherit (lib)
12     mkOption
13     types
14     mapAttrs'
15     nameValuePair
16     toLower
17     filterAttrs
18     escapeShellArg
19     literalExpression
20     mkIf
21     concatStringsSep
22     ;
24   configFile =
25     if cfg.configuration != null then configurationFile else (escapeShellArg cfg.configFile);
27   configurationFile = pkgs.writeText "prometheus-mail-exporter.conf" (
28     builtins.toJSON (
29       # removes the _module attribute, null values and converts attrNames to lowercase
30       mapAttrs' (
31         name: value:
32         if name == "servers" then
33           nameValuePair (toLower name) (
34             (map (
35               srv:
36               (mapAttrs' (n: v: nameValuePair (toLower n) v) (
37                 filterAttrs (n: v: !(n == "_module" || v == null)) srv
38               ))
39             ))
40               value
41           )
42         else
43           nameValuePair (toLower name) value
44       ) (filterAttrs (n: _: !(n == "_module")) cfg.configuration)
45     )
46   );
48   serverOptions.options = {
49     name = mkOption {
50       type = types.str;
51       description = ''
52         Value for label 'configname' which will be added to all metrics.
53       '';
54     };
55     server = mkOption {
56       type = types.str;
57       description = ''
58         Hostname of the server that should be probed.
59       '';
60     };
61     port = mkOption {
62       type = types.port;
63       example = 587;
64       description = ''
65         Port to use for SMTP.
66       '';
67     };
68     from = mkOption {
69       type = types.str;
70       example = "exporteruser@domain.tld";
71       description = ''
72         Content of 'From' Header for probing mails.
73       '';
74     };
75     to = mkOption {
76       type = types.str;
77       example = "exporteruser@domain.tld";
78       description = ''
79         Content of 'To' Header for probing mails.
80       '';
81     };
82     detectionDir = mkOption {
83       type = types.path;
84       example = "/var/spool/mail/exporteruser/new";
85       description = ''
86         Directory in which new mails for the exporter user are placed.
87         Note that this needs to exist when the exporter starts.
88       '';
89     };
90     login = mkOption {
91       type = types.nullOr types.str;
92       default = null;
93       example = "exporteruser@domain.tld";
94       description = ''
95         Username to use for SMTP authentication.
96       '';
97     };
98     passphrase = mkOption {
99       type = types.nullOr types.str;
100       default = null;
101       description = ''
102         Password to use for SMTP authentication.
103       '';
104     };
105   };
107   exporterOptions.options = {
108     monitoringInterval = mkOption {
109       type = types.str;
110       example = "10s";
111       description = ''
112         Time interval between two probe attempts.
113       '';
114     };
115     mailCheckTimeout = mkOption {
116       type = types.str;
117       description = ''
118         Timeout until mails are considered "didn't make it".
119       '';
120     };
121     disableFileDeletion = mkOption {
122       type = types.bool;
123       default = false;
124       description = ''
125         Disables the exporter's function to delete probing mails.
126       '';
127     };
128     servers = mkOption {
129       type = types.listOf (types.submodule serverOptions);
130       default = [ ];
131       example = literalExpression ''
132         [ {
133           name = "testserver";
134           server = "smtp.domain.tld";
135           port = 587;
136           from = "exporteruser@domain.tld";
137           to = "exporteruser@domain.tld";
138           detectionDir = "/path/to/Maildir/new";
139         } ]
140       '';
141       description = ''
142         List of servers that should be probed.
144         *Note:* if your mailserver has {manpage}`rspamd(8)` configured,
145         it can happen that emails from this exporter are marked as spam.
147         It's possible to work around the issue with a config like this:
148         ```
149         {
150           services.rspamd.locals."multimap.conf".text = '''
151             ALLOWLIST_PROMETHEUS {
152               filter = "email:domain:tld";
153               type = "from";
154               map = "''${pkgs.writeText "allowmap" "domain.tld"}";
155               score = -100.0;
156             }
157           ''';
158         }
159         ```
160       '';
161     };
162   };
165   port = 9225;
166   extraOpts = {
167     environmentFile = mkOption {
168       type = types.nullOr types.str;
169       default = null;
170       description = ''
171         File containing env-vars to be substituted into the exporter's config.
172       '';
173     };
174     configFile = mkOption {
175       type = types.nullOr types.path;
176       default = null;
177       description = ''
178         Specify the mailexporter configuration file to use.
179       '';
180     };
181     configuration = mkOption {
182       type = types.nullOr (types.submodule exporterOptions);
183       default = null;
184       description = ''
185         Specify the mailexporter configuration file to use.
186       '';
187     };
188     telemetryPath = mkOption {
189       type = types.str;
190       default = "/metrics";
191       description = ''
192         Path under which to expose metrics.
193       '';
194     };
195   };
196   serviceOpts = {
197     serviceConfig = {
198       DynamicUser = false;
199       EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ];
200       RuntimeDirectory = "prometheus-mail-exporter";
201       ExecStartPre = [
202         "${pkgs.writeShellScript "subst-secrets-mail-exporter" ''
203           umask 0077
204           ${pkgs.envsubst}/bin/envsubst -i ${configFile} -o ''${RUNTIME_DIRECTORY}/mail-exporter.json
205         ''}"
206       ];
207       ExecStart = ''
208         ${pkgs.prometheus-mail-exporter}/bin/mailexporter \
209           --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
210           --web.telemetry-path ${cfg.telemetryPath} \
211           --config.file ''${RUNTIME_DIRECTORY}/mail-exporter.json \
212           ${concatStringsSep " \\\n  " cfg.extraFlags}
213       '';
214     };
215   };