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