From df3ef7486205eeba4f0dd5b18d4c68a24b9f6b85 Mon Sep 17 00:00:00 2001 From: Astro Date: Wed, 31 Mar 2021 02:11:19 +0200 Subject: [PATCH] nixos-module/container/dhcp-server.nix: init --- nix/lib/config/legacy.nix | 11 ++++++- nix/lib/config/options.nix | 15 +++++++++ nix/nixos-module/container/dhcp-server.nix | 38 ++++++++++++++++++++++ nix/nixos-module/default.nix | 1 + 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 nix/nixos-module/container/dhcp-server.nix diff --git a/nix/lib/config/legacy.nix b/nix/lib/config/legacy.nix index 82be186..9822ac5 100644 --- a/nix/lib/config/legacy.nix +++ b/nix/lib/config/legacy.nix @@ -16,6 +16,11 @@ let forceVeth = interface: interface // { type = "veth"; }; + + netHasDHCP = net: + net == "pub" || + net == "serv" || + builtins.match "priv[[:digit:]]+" net != null; in { options.salt-pillar = lib.mkOption {}; @@ -25,9 +30,13 @@ in (builtins.mapAttrs (_: vlan: { vlan = vlan; }) pillar.vlans) (builtins.mapAttrs (_: subnet4: { inherit subnet4; }) pillar.subnets-inet) (builtins.mapAttrs (_: hosts4: { inherit hosts4; }) pillar.hosts-inet) - (builtins.mapAttrs (_: dhcpData: { + (builtins.mapAttrs (net: dhcpData: { dhcp = { inherit (dhcpData) start end time max-time; + server = + if netHasDHCP net + then "${net}-gw" + else null; router = dhcpData.host-opts.routers; domainName = dhcpData.string-opts.domain-name; }; diff --git a/nix/lib/config/options.nix b/nix/lib/config/options.nix index 476698e..f828f6d 100644 --- a/nix/lib/config/options.nix +++ b/nix/lib/config/options.nix @@ -19,6 +19,10 @@ let description = "Max renew time in seconds"; type = types.int; }; + server = mkOption { + description = "Container that runs the DHCP server"; + type = types.str; + }; router = mkOption { description = "Gateway"; type = types.str; @@ -39,6 +43,17 @@ let type = with types; nullOr str; default = null; }; + subnet4Net = mkOption { + type = with types; nullOr types.str; + default = + let + inherit (config.site.net.${name}) subnet4; + s = lib.splitString "/" subnet4; + in + if subnet4 != null && builtins.length s == 2 + then builtins.head s + else null; + }; subnet4Len = mkOption { type = with types; nullOr types.int; default = diff --git a/nix/nixos-module/container/dhcp-server.nix b/nix/nixos-module/container/dhcp-server.nix new file mode 100644 index 000000000..64764ab --- /dev/null +++ b/nix/nixos-module/container/dhcp-server.nix @@ -0,0 +1,38 @@ +{ hostName, config, lib, ... }: + +let + dhcpNets = + lib.filterAttrs (_: { dhcp, ... }: + dhcp != null && + dhcp.server == hostName + ) config.site.net; + + enabled = builtins.length (builtins.attrNames dhcpNets) > 0; +in +{ + services.dhcpd4 = lib.optionalAttrs enabled { + enable = true; + + interfaces = builtins.attrNames dhcpNets; + + extraConfig = '' + option domain-name-servers 172.20.73.8, 9.9.9.9; + ${builtins.concatStringsSep "\n" ( + builtins.attrValues ( + builtins.mapAttrs (net: { dhcp, subnet4Net, subnet4Len, ...}: + '' + subnet ${subnet4Net} netmask ${lib.netmasks.${toString subnet4Len}} { + range ${dhcp.start} ${dhcp.end}; + default-lease-time ${toString dhcp.time}; + max-lease-time ${toString dhcp.max-time}; + option routers ${config.site.net.${net}.hosts4.${builtins.replaceStrings [".${net}"] [""] dhcp.router}}; + option domain-name "${dhcp.domainName}"; + } + '' + ) dhcpNets + ) + )} + ''; + # TODO: fixed-hosts + }; +} diff --git a/nix/nixos-module/default.nix b/nix/nixos-module/default.nix index b739977..f8f3a24 100644 --- a/nix/nixos-module/default.nix +++ b/nix/nixos-module/default.nix @@ -18,6 +18,7 @@ in { ] ++ optionals (hostConfig.role == "container") [ ./container/defaults.nix + ./container/dhcp-server.nix ] ++ optionals ( hostConfig.role == "container" && lib.config.site.hosts.${hostName}.isRouter