1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7let
8 cfg = config.services.oxidized;
9in
10{
11 options.services.oxidized = {
12 enable = lib.mkEnableOption "the oxidized configuration backup service";
13
14 package = lib.mkPackageOption pkgs "oxidized" { };
15
16 user = lib.mkOption {
17 type = lib.types.str;
18 default = "oxidized";
19 description = ''
20 User under which the oxidized service runs.
21 '';
22 };
23
24 group = lib.mkOption {
25 type = lib.types.str;
26 default = "oxidized";
27 description = ''
28 Group under which the oxidized service runs.
29 '';
30 };
31
32 dataDir = lib.mkOption {
33 type = lib.types.path;
34 default = "/var/lib/oxidized";
35 description = "State directory for the oxidized service.";
36 };
37
38 configFile = lib.mkOption {
39 type = lib.types.path;
40 example = lib.literalExpression ''
41 pkgs.writeText "oxidized-config.yml" '''
42 ---
43 debug: true
44 use_syslog: true
45 input:
46 default: ssh
47 ssh:
48 secure: true
49 interval: 3600
50 model_map:
51 dell: powerconnect
52 hp: procurve
53 source:
54 default: csv
55 csv:
56 delimiter: !ruby/regexp /:/
57 file: "/var/lib/oxidized/.config/oxidized/router.db"
58 map:
59 name: 0
60 model: 1
61 username: 2
62 password: 3
63 pid: "/var/lib/oxidized/.config/oxidized/pid"
64 rest: 127.0.0.1:8888
65 retries: 3
66 # ... additional config
67 ''';
68 '';
69 description = ''
70 Path to the oxidized configuration file.
71 '';
72 };
73
74 routerDB = lib.mkOption {
75 type = lib.types.nullOr lib.types.path;
76 default = null;
77 example = lib.literalExpression ''
78 pkgs.writeText "oxidized-router.db" '''
79 hostname-sw1:powerconnect:username1:password2
80 hostname-sw2:procurve:username2:password2
81 # ... additional hosts
82 '''
83 '';
84 description = ''
85 Path to the file/database which contains the targets for oxidized.
86 '';
87 };
88 };
89
90 config = lib.mkIf cfg.enable {
91 users.groups.${cfg.group} = { };
92 users.users.${cfg.user} = {
93 description = "Oxidized service user";
94 group = cfg.group;
95 home = cfg.dataDir;
96 createHome = true;
97 isSystemUser = true;
98 };
99
100 systemd.tmpfiles.settings."10-oxidized" =
101 {
102 "${cfg.dataDir}" = {
103 d = {
104 mode = "0750";
105 user = cfg.user;
106 group = cfg.group;
107 };
108 };
109
110 "${cfg.dataDir}/.config" = {
111 d = {
112 mode = "0750";
113 user = cfg.user;
114 group = cfg.group;
115 };
116 };
117
118 "${cfg.dataDir}/.config/oxidized" = {
119 d = {
120 mode = "0750";
121 user = cfg.user;
122 group = cfg.group;
123 };
124 };
125
126 "${cfg.dataDir}/.config/oxidized/config" = {
127 L = {
128 argument = "${cfg.configFile}";
129 user = cfg.user;
130 group = cfg.group;
131 };
132 };
133
134 }
135 // lib.optionalAttrs (cfg.routerDB != null) {
136 "${cfg.dataDir}/.config/oxidized/router.db" = {
137 L = {
138 argument = "${cfg.routerDB}";
139 user = cfg.user;
140 group = cfg.group;
141 };
142 };
143 };
144
145 systemd.services.oxidized = {
146 wantedBy = [ "multi-user.target" ];
147 after = [ "network.target" ];
148
149 serviceConfig = {
150 ExecStart = lib.getExe cfg.package;
151 User = cfg.user;
152 Group = cfg.group;
153 UMask = "0077";
154 NoNewPrivileges = true;
155 Restart = "always";
156 WorkingDirectory = cfg.dataDir;
157 KillSignal = "SIGKILL";
158 PIDFile = "${cfg.dataDir}/.config/oxidized/pid";
159 };
160 };
161 };
162}