vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / monitoring / prometheus / exporters / restic.nix
blobef44803ba053d2b11f52462c3167c17cc2b2878f
1 { config, lib, pkgs, options, ... }:
3 let
4   cfg = config.services.prometheus.exporters.restic;
5   inherit (lib)
6     mkOption
7     types
8     concatStringsSep
9     mkIf
10     mapAttrs'
11     splitString
12     toUpper
13     optionalAttrs
14     nameValuePair
15     ;
18   port = 9753;
19   extraOpts = {
20     repository = mkOption {
21       type = types.str;
22       description = ''
23         URI pointing to the repository to monitor.
24       '';
25       example = "sftp:backup@192.168.1.100:/backups/example";
26     };
28     passwordFile = mkOption {
29       type = types.path;
30       description = ''
31         File containing the password to the repository.
32       '';
33       example = "/etc/nixos/restic-password";
34     };
36     environmentFile = mkOption {
37       type = with types; nullOr path;
38       default = null;
39       description = ''
40         File containing the credentials to access the repository, in the
41         format of an EnvironmentFile as described by systemd.exec(5)
42       '';
43     };
45     refreshInterval = mkOption {
46       type = types.ints.unsigned;
47       default = 60;
48       description = ''
49         Refresh interval for the metrics in seconds.
50         Computing the metrics is an expensive task, keep this value as high as possible.
51       '';
52     };
54     rcloneOptions = mkOption {
55       type = with types; attrsOf (oneOf [ str bool ]);
56       default = { };
57       description = ''
58         Options to pass to rclone to control its behavior.
59         See <https://rclone.org/docs/#options> for
60         available options. When specifying option names, strip the
61         leading `--`. To set a flag such as
62         `--drive-use-trash`, which does not take a value,
63         set the value to the Boolean `true`.
64       '';
65     };
67     rcloneConfig = mkOption {
68       type = with types; attrsOf (oneOf [ str bool ]);
69       default = { };
70       description = ''
71         Configuration for the rclone remote being used for backup.
72         See the remote's specific options under rclone's docs at
73         <https://rclone.org/docs/>. When specifying
74         option names, use the "config" name specified in the docs.
75         For example, to set `--b2-hard-delete` for a B2
76         remote, use `hard_delete = true` in the
77         attribute set.
79         ::: {.warning}
80         Secrets set in here will be world-readable in the Nix
81         store! Consider using the {option}`rcloneConfigFile`
82         option instead to specify secret values separately. Note that
83         options set here will override those set in the config file.
84         :::
85       '';
86     };
88     rcloneConfigFile = mkOption {
89       type = with types; nullOr path;
90       default = null;
91       description = ''
92         Path to the file containing rclone configuration. This file
93         must contain configuration for the remote specified in this backup
94         set and also must be readable by root.
96         ::: {.caution}
97         Options set in `rcloneConfig` will override those set in this
98         file.
99         :::
100       '';
101     };
102   };
104   serviceOpts = {
105     script = ''
106       export RESTIC_PASSWORD_FILE=$CREDENTIALS_DIRECTORY/RESTIC_PASSWORD_FILE
107       ${pkgs.prometheus-restic-exporter}/bin/restic-exporter.py \
108         ${concatStringsSep " \\\n  " cfg.extraFlags}
109     '';
110     serviceConfig = {
111       EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
112       LoadCredential = [ "RESTIC_PASSWORD_FILE:${cfg.passwordFile}" ];
113     };
114     environment =
115       let
116         rcloneRemoteName = builtins.elemAt (splitString ":" cfg.repository) 1;
117         rcloneAttrToOpt = v: "RCLONE_" + toUpper (builtins.replaceStrings [ "-" ] [ "_" ] v);
118         rcloneAttrToConf = v: "RCLONE_CONFIG_" + toUpper (rcloneRemoteName + "_" + v);
119         toRcloneVal = v: if lib.isBool v then lib.boolToString v else v;
120       in
121       {
122         RESTIC_REPOSITORY = cfg.repository;
123         LISTEN_ADDRESS = cfg.listenAddress;
124         LISTEN_PORT = toString cfg.port;
125         REFRESH_INTERVAL = toString cfg.refreshInterval;
126       }
127       // (mapAttrs'
128         (name: value:
129           nameValuePair (rcloneAttrToOpt name) (toRcloneVal value)
130         )
131         cfg.rcloneOptions)
132       // optionalAttrs (cfg.rcloneConfigFile != null) {
133         RCLONE_CONFIG = cfg.rcloneConfigFile;
134       }
135       // (mapAttrs'
136         (name: value:
137           nameValuePair (rcloneAttrToConf name) (toRcloneVal value)
138         )
139         cfg.rcloneConfig);
140   };