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.nullOr 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 "${cfg.dataDir}" = {
102 d = {
103 mode = "0750";
104 user = cfg.user;
105 group = cfg.group;
106 };
107 };
108
109 "${cfg.dataDir}/.config" = {
110 d = {
111 mode = "0750";
112 user = cfg.user;
113 group = cfg.group;
114 };
115 };
116
117 "${cfg.dataDir}/.config/oxidized" = {
118 d = {
119 mode = "0750";
120 user = cfg.user;
121 group = cfg.group;
122 };
123 };
124
125 }
126 // lib.optionalAttrs (cfg.configFile != null) {
127 "${cfg.dataDir}/.config/oxidized/config" = {
128 "L+" = {
129 argument = "${cfg.configFile}";
130 user = cfg.user;
131 group = cfg.group;
132 };
133 };
134
135 }
136 // lib.optionalAttrs (cfg.routerDB != null) {
137 "${cfg.dataDir}/.config/oxidized/router.db" = {
138 "L+" = {
139 argument = "${cfg.routerDB}";
140 user = cfg.user;
141 group = cfg.group;
142 };
143 };
144 };
145
146 systemd.services.oxidized = {
147 wantedBy = [ "multi-user.target" ];
148 after = [ "network.target" ];
149
150 serviceConfig = {
151 ExecStart = lib.getExe cfg.package;
152 User = cfg.user;
153 Group = cfg.group;
154 UMask = "0077";
155 NoNewPrivileges = true;
156 Restart = "always";
157 WorkingDirectory = cfg.dataDir;
158 KillSignal = "SIGKILL";
159 PIDFile = "${cfg.dataDir}/.config/oxidized/pid";
160 };
161 };
162 };
163}