python312Packages.mandown: 1.10.0 -> 1.10.1 (#370595)
[NixPkgs.git] / nixos / modules / services / networking / kea.nix
blob39b2380cadd341988abd272c1c6c34297c4716d5
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
7 let
8   cfg = config.services.kea;
10   format = pkgs.formats.json { };
12   chooseNotNull = x: y: if x != null then x else y;
14   ctrlAgentConfig = chooseNotNull cfg.ctrl-agent.configFile (
15     format.generate "kea-ctrl-agent.conf" {
16       Control-agent = cfg.ctrl-agent.settings;
17     }
18   );
20   dhcp4Config = chooseNotNull cfg.dhcp4.configFile (
21     format.generate "kea-dhcp4.conf" {
22       Dhcp4 = cfg.dhcp4.settings;
23     }
24   );
26   dhcp6Config = chooseNotNull cfg.dhcp6.configFile (
27     format.generate "kea-dhcp6.conf" {
28       Dhcp6 = cfg.dhcp6.settings;
29     }
30   );
32   dhcpDdnsConfig = chooseNotNull cfg.dhcp-ddns.configFile (
33     format.generate "kea-dhcp-ddns.conf" {
34       DhcpDdns = cfg.dhcp-ddns.settings;
35     }
36   );
38   package = pkgs.kea;
41   options.services.kea = with lib.types; {
42     ctrl-agent = lib.mkOption {
43       description = ''
44         Kea Control Agent configuration
45       '';
46       default = { };
47       type = submodule {
48         options = {
49           enable = lib.mkEnableOption "Kea Control Agent";
51           extraArgs = lib.mkOption {
52             type = listOf str;
53             default = [ ];
54             description = ''
55               List of additional arguments to pass to the daemon.
56             '';
57           };
59           configFile = lib.mkOption {
60             type = nullOr path;
61             default = null;
62             description = ''
63               Kea Control Agent configuration as a path, see <https://kea.readthedocs.io/en/kea-${package.version}/arm/agent.html>.
65               Takes preference over [settings](#opt-services.kea.ctrl-agent.settings).
66               Most users should prefer using [settings](#opt-services.kea.ctrl-agent.settings) instead.
67             '';
68           };
70           settings = lib.mkOption {
71             type = format.type;
72             default = null;
73             description = ''
74               Kea Control Agent configuration as an attribute set, see <https://kea.readthedocs.io/en/kea-${package.version}/arm/agent.html>.
75             '';
76           };
77         };
78       };
79     };
81     dhcp4 = lib.mkOption {
82       description = ''
83         DHCP4 Server configuration
84       '';
85       default = { };
86       type = submodule {
87         options = {
88           enable = lib.mkEnableOption "Kea DHCP4 server";
90           extraArgs = lib.mkOption {
91             type = listOf str;
92             default = [ ];
93             description = ''
94               List of additional arguments to pass to the daemon.
95             '';
96           };
98           configFile = lib.mkOption {
99             type = nullOr path;
100             default = null;
101             description = ''
102               Kea DHCP4 configuration as a path, see <https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp4-srv.html>.
104               Takes preference over [settings](#opt-services.kea.dhcp4.settings).
105               Most users should prefer using [settings](#opt-services.kea.dhcp4.settings) instead.
106             '';
107           };
109           settings = lib.mkOption {
110             type = format.type;
111             default = null;
112             example = {
113               valid-lifetime = 4000;
114               renew-timer = 1000;
115               rebind-timer = 2000;
116               interfaces-config = {
117                 interfaces = [
118                   "eth0"
119                 ];
120               };
121               lease-database = {
122                 type = "memfile";
123                 persist = true;
124                 name = "/var/lib/kea/dhcp4.leases";
125               };
126               subnet4 = [
127                 {
128                   id = 1;
129                   subnet = "192.0.2.0/24";
130                   pools = [
131                     {
132                       pool = "192.0.2.100 - 192.0.2.240";
133                     }
134                   ];
135                 }
136               ];
137             };
138             description = ''
139               Kea DHCP4 configuration as an attribute set, see <https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp4-srv.html>.
140             '';
141           };
142         };
143       };
144     };
146     dhcp6 = lib.mkOption {
147       description = ''
148         DHCP6 Server configuration
149       '';
150       default = { };
151       type = submodule {
152         options = {
153           enable = lib.mkEnableOption "Kea DHCP6 server";
155           extraArgs = lib.mkOption {
156             type = listOf str;
157             default = [ ];
158             description = ''
159               List of additional arguments to pass to the daemon.
160             '';
161           };
163           configFile = lib.mkOption {
164             type = nullOr path;
165             default = null;
166             description = ''
167               Kea DHCP6 configuration as a path, see <https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp6-srv.html>.
169               Takes preference over [settings](#opt-services.kea.dhcp6.settings).
170               Most users should prefer using [settings](#opt-services.kea.dhcp6.settings) instead.
171             '';
172           };
174           settings = lib.mkOption {
175             type = format.type;
176             default = null;
177             example = {
178               valid-lifetime = 4000;
179               renew-timer = 1000;
180               rebind-timer = 2000;
181               preferred-lifetime = 3000;
182               interfaces-config = {
183                 interfaces = [
184                   "eth0"
185                 ];
186               };
187               lease-database = {
188                 type = "memfile";
189                 persist = true;
190                 name = "/var/lib/kea/dhcp6.leases";
191               };
192               subnet6 = [
193                 {
194                   id = 1;
195                   subnet = "2001:db8:1::/64";
196                   pools = [
197                     {
198                       pool = "2001:db8:1::1-2001:db8:1::ffff";
199                     }
200                   ];
201                 }
202               ];
203             };
204             description = ''
205               Kea DHCP6 configuration as an attribute set, see <https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp6-srv.html>.
206             '';
207           };
208         };
209       };
210     };
212     dhcp-ddns = lib.mkOption {
213       description = ''
214         Kea DHCP-DDNS configuration
215       '';
216       default = { };
217       type = submodule {
218         options = {
219           enable = lib.mkEnableOption "Kea DDNS server";
221           extraArgs = lib.mkOption {
222             type = listOf str;
223             default = [ ];
224             description = ''
225               List of additional arguments to pass to the daemon.
226             '';
227           };
229           configFile = lib.mkOption {
230             type = nullOr path;
231             default = null;
232             description = ''
233               Kea DHCP-DDNS configuration as a path, see <https://kea.readthedocs.io/en/kea-${package.version}/arm/ddns.html>.
235               Takes preference over [settings](#opt-services.kea.dhcp-ddns.settings).
236               Most users should prefer using [settings](#opt-services.kea.dhcp-ddns.settings) instead.
237             '';
238           };
240           settings = lib.mkOption {
241             type = format.type;
242             default = null;
243             example = {
244               ip-address = "127.0.0.1";
245               port = 53001;
246               dns-server-timeout = 100;
247               ncr-protocol = "UDP";
248               ncr-format = "JSON";
249               tsig-keys = [ ];
250               forward-ddns = {
251                 ddns-domains = [ ];
252               };
253               reverse-ddns = {
254                 ddns-domains = [ ];
255               };
256             };
257             description = ''
258               Kea DHCP-DDNS configuration as an attribute set, see <https://kea.readthedocs.io/en/kea-${package.version}/arm/ddns.html>.
259             '';
260           };
261         };
262       };
263     };
264   };
266   config =
267     let
268       commonServiceConfig = {
269         ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
270         DynamicUser = true;
271         User = "kea";
272         ConfigurationDirectory = "kea";
273         RuntimeDirectory = "kea";
274         RuntimeDirectoryPreserve = true;
275         StateDirectory = "kea";
276         UMask = "0077";
277       };
278     in
279     lib.mkIf (cfg.ctrl-agent.enable || cfg.dhcp4.enable || cfg.dhcp6.enable || cfg.dhcp-ddns.enable) (
280       lib.mkMerge [
281         {
282           environment.systemPackages = [ package ];
283         }
285         (lib.mkIf cfg.ctrl-agent.enable {
286           assertions = [
287             {
288               assertion = lib.xor (cfg.ctrl-agent.settings == null) (cfg.ctrl-agent.configFile == null);
289               message = "Either services.kea.ctrl-agent.settings or services.kea.ctrl-agent.configFile must be set to a non-null value.";
290             }
291           ];
293           environment.etc."kea/ctrl-agent.conf".source = ctrlAgentConfig;
295           systemd.services.kea-ctrl-agent = {
296             description = "Kea Control Agent";
297             documentation = [
298               "man:kea-ctrl-agent(8)"
299               "https://kea.readthedocs.io/en/kea-${package.version}/arm/agent.html"
300             ];
302             wants = [
303               "network-online.target"
304             ];
305             after = [
306               "network-online.target"
307               "time-sync.target"
308             ];
309             wantedBy = [
310               "kea-dhcp4-server.service"
311               "kea-dhcp6-server.service"
312               "kea-dhcp-ddns-server.service"
313             ];
315             environment = {
316               KEA_PIDFILE_DIR = "/run/kea";
317               KEA_LOCKFILE_DIR = "/run/kea";
318             };
320             restartTriggers = [
321               ctrlAgentConfig
322             ];
324             serviceConfig = {
325               ExecStart = "${package}/bin/kea-ctrl-agent -c /etc/kea/ctrl-agent.conf ${lib.escapeShellArgs cfg.ctrl-agent.extraArgs}";
326               KillMode = "process";
327               Restart = "on-failure";
328             } // commonServiceConfig;
329           };
330         })
332         (lib.mkIf cfg.dhcp4.enable {
333           assertions = [
334             {
335               assertion = lib.xor (cfg.dhcp4.settings == null) (cfg.dhcp4.configFile == null);
336               message = "Either services.kea.dhcp4.settings or services.kea.dhcp4.configFile must be set to a non-null value.";
337             }
338           ];
340           environment.etc."kea/dhcp4-server.conf".source = dhcp4Config;
342           systemd.services.kea-dhcp4-server = {
343             description = "Kea DHCP4 Server";
344             documentation = [
345               "man:kea-dhcp4(8)"
346               "https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp4-srv.html"
347             ];
349             after = [
350               "network-online.target"
351               "time-sync.target"
352             ];
353             wants = [
354               "network-online.target"
355             ];
356             wantedBy = [
357               "multi-user.target"
358             ];
360             environment = {
361               KEA_PIDFILE_DIR = "/run/kea";
362               KEA_LOCKFILE_DIR = "/run/kea";
363             };
365             restartTriggers = [
366               dhcp4Config
367             ];
369             serviceConfig = {
370               ExecStart = "${package}/bin/kea-dhcp4 -c /etc/kea/dhcp4-server.conf ${lib.escapeShellArgs cfg.dhcp4.extraArgs}";
371               # Kea does not request capabilities by itself
372               AmbientCapabilities = [
373                 "CAP_NET_BIND_SERVICE"
374                 "CAP_NET_RAW"
375               ];
376               CapabilityBoundingSet = [
377                 "CAP_NET_BIND_SERVICE"
378                 "CAP_NET_RAW"
379               ];
380             } // commonServiceConfig;
381           };
382         })
384         (lib.mkIf cfg.dhcp6.enable {
385           assertions = [
386             {
387               assertion = lib.xor (cfg.dhcp6.settings == null) (cfg.dhcp6.configFile == null);
388               message = "Either services.kea.dhcp6.settings or services.kea.dhcp6.configFile must be set to a non-null value.";
389             }
390           ];
392           environment.etc."kea/dhcp6-server.conf".source = dhcp6Config;
394           systemd.services.kea-dhcp6-server = {
395             description = "Kea DHCP6 Server";
396             documentation = [
397               "man:kea-dhcp6(8)"
398               "https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp6-srv.html"
399             ];
401             after = [
402               "network-online.target"
403               "time-sync.target"
404             ];
405             wants = [
406               "network-online.target"
407             ];
408             wantedBy = [
409               "multi-user.target"
410             ];
412             environment = {
413               KEA_PIDFILE_DIR = "/run/kea";
414               KEA_LOCKFILE_DIR = "/run/kea";
415             };
417             restartTriggers = [
418               dhcp6Config
419             ];
421             serviceConfig = {
422               ExecStart = "${package}/bin/kea-dhcp6 -c /etc/kea/dhcp6-server.conf ${lib.escapeShellArgs cfg.dhcp6.extraArgs}";
423               # Kea does not request capabilities by itself
424               AmbientCapabilities = [
425                 "CAP_NET_BIND_SERVICE"
426               ];
427               CapabilityBoundingSet = [
428                 "CAP_NET_BIND_SERVICE"
429               ];
430             } // commonServiceConfig;
431           };
432         })
434         (lib.mkIf cfg.dhcp-ddns.enable {
435           assertions = [
436             {
437               assertion = lib.xor (cfg.dhcp-ddns.settings == null) (cfg.dhcp-ddns.configFile == null);
438               message = "Either services.kea.dhcp-ddns.settings or services.kea.dhcp-ddns.configFile must be set to a non-null value.";
439             }
440           ];
442           environment.etc."kea/dhcp-ddns.conf".source = dhcpDdnsConfig;
444           systemd.services.kea-dhcp-ddns-server = {
445             description = "Kea DHCP-DDNS Server";
446             documentation = [
447               "man:kea-dhcp-ddns(8)"
448               "https://kea.readthedocs.io/en/kea-${package.version}/arm/ddns.html"
449             ];
451             wants = [ "network-online.target" ];
452             after = [
453               "network-online.target"
454               "time-sync.target"
455             ];
456             wantedBy = [
457               "multi-user.target"
458             ];
460             environment = {
461               KEA_PIDFILE_DIR = "/run/kea";
462               KEA_LOCKFILE_DIR = "/run/kea";
463             };
465             restartTriggers = [
466               dhcpDdnsConfig
467             ];
469             serviceConfig = {
470               ExecStart = "${package}/bin/kea-dhcp-ddns -c /etc/kea/dhcp-ddns.conf ${lib.escapeShellArgs cfg.dhcp-ddns.extraArgs}";
471               AmbientCapabilities = [
472                 "CAP_NET_BIND_SERVICE"
473               ];
474               CapabilityBoundingSet = [
475                 "CAP_NET_BIND_SERVICE"
476               ];
477             } // commonServiceConfig;
478           };
479         })
481       ]
482     );
484   meta.maintainers = with lib.maintainers; [ hexa ];
485   # uses attributes of the linked package
486   meta.buildDocsInSandbox = false;