From 2274668f9bcef827ecf698844c0ef32889e808f3 Mon Sep 17 00:00:00 2001 From: Tom Hubrecht Date: Thu, 20 Jul 2023 12:32:31 +0200 Subject: [PATCH] modules: Setup dgn-network with configuration from metadata --- hive.nix | 5 +- machines/compute01/_configuration.nix | 5 -- .../compute01/_hardware-configuration.nix | 18 ----- machines/storage01/_configuration.nix | 4 -- .../storage01/_hardware-configuration.nix | 26 +++---- meta/default.nix | 47 +++++++++++-- meta/infrastructure.nix | 14 ++++ meta/network.nix | 69 +++++++++++++++++++ meta/nodes.nix | 57 ++++++++------- modules/default.nix | 1 + modules/dgn-network.nix | 43 ++++++++++++ 11 files changed, 211 insertions(+), 78 deletions(-) create mode 100644 meta/infrastructure.nix create mode 100644 meta/network.nix create mode 100644 modules/dgn-network.nix diff --git a/hive.nix b/hive.nix index 421915e..40d3005 100644 --- a/hive.nix +++ b/hive.nix @@ -16,6 +16,9 @@ let # Deployment config is specified in meta.nodes.${node}.deployment inherit (metadata.nodes.${node}) deployment; + + # Set NIX_PATH to the patched version of nixpkgs + nix.nixPath = [ "nixpkgs=${mkNixpkgs node}" ]; }; mkNixpkgs = node: @@ -42,8 +45,6 @@ in specialArgs = { inherit sources; meta = metadata; }; nodeSpecialArgs = lib.mapSingleFuse mkArgs nodes; - - # TODO: Add remote builders (`machinesFile` option) }; defaults = { ... }: { diff --git a/machines/compute01/_configuration.nix b/machines/compute01/_configuration.nix index 1c92de7..ffc7f5f 100644 --- a/machines/compute01/_configuration.nix +++ b/machines/compute01/_configuration.nix @@ -1,10 +1,5 @@ { ... }: { - # Use the systemd-boot EFI boot loader. - networking.hostName = "compute01"; - networking.domain = "par01.infra.dgnum.eu"; - networking.hostId = "8df60941"; - system.stateVersion = "23.05"; # Did you read the comment? } diff --git a/machines/compute01/_hardware-configuration.nix b/machines/compute01/_hardware-configuration.nix index cf225d8..5c7c0a4 100644 --- a/machines/compute01/_hardware-configuration.nix +++ b/machines/compute01/_hardware-configuration.nix @@ -32,24 +32,6 @@ swapDevices = [{ device = "/dev/disk/by-uuid/30547280-00e9-4ee1-8a07-d116590d9fbf"; }]; - # Enables DHCP on each ethernet and wireless interface. In case of scripted networking - # (the default) this is the recommended approach. When using systemd-networkd it's - # still possible to use this option, but it's recommended to use it in conjunction - # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - # networking.useDHCP = lib.mkDefault true; - networking.interfaces.eno1 = { - useDHCP = true; - ipv4 = { - addresses = [ - { address = "129.199.146.147"; prefixLength = 24; } - { address = "192.168.1.147"; prefixLength = 24; } - ]; - - routes = [ - { address = "192.168.1.0"; prefixLength = 24; } - ]; - }; - }; # networking.interfaces.eno2.useDHCP = lib.mkDefault true; # networking.interfaces.eno3.useDHCP = lib.mkDefault true; # networking.interfaces.eno4.useDHCP = lib.mkDefault true; diff --git a/machines/storage01/_configuration.nix b/machines/storage01/_configuration.nix index 5e758f0..9123abe 100644 --- a/machines/storage01/_configuration.nix +++ b/machines/storage01/_configuration.nix @@ -5,9 +5,5 @@ { config, pkgs, ... }: { - networking.hostName = "storage01"; - networking.domain = "par01.infra.dgnum.eu"; - networking.hostId = "d4e7c369"; - system.stateVersion = "23.05"; # Did you read the comment? } diff --git a/machines/storage01/_hardware-configuration.nix b/machines/storage01/_hardware-configuration.nix index 8b933d5..03e663e 100644 --- a/machines/storage01/_hardware-configuration.nix +++ b/machines/storage01/_hardware-configuration.nix @@ -36,19 +36,19 @@ # (the default) this is the recommended approach. When using systemd-networkd it's # still possible to use this option, but it's recommended to use it in conjunction # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - networking.interfaces.eno1 = { - useDHCP = true; - ipv4 = { - addresses = [ - { address = "129.199.146.148"; prefixLength = 24; } - { address = "192.168.1.148"; prefixLength = 24; } - ]; - - routes = [ - { address = "192.168.1.0"; prefixLength = 24; } - ]; - }; - }; + # networking.interfaces.eno1 = { + # useDHCP = true; + # ipv4 = { + # addresses = [ + # { address = "129.199.146.148"; prefixLength = 24; } + # { address = "192.168.1.148"; prefixLength = 24; } + # ]; + # + # routes = [ + # { address = "192.168.1.0"; prefixLength = 24; } + # ]; + # }; + # }; # networking.interfaces.eno2.useDHCP = lib.mkDefault true; # networking.interfaces.eno3.useDHCP = lib.mkDefault true; # networking.interfaces.eno4.useDHCP = lib.mkDefault true; diff --git a/meta/default.nix b/meta/default.nix index d6e1690..cb11765 100644 --- a/meta/default.nix +++ b/meta/default.nix @@ -1,10 +1,45 @@ -/* -Metadata for the nodes. You can add custom attributes, they are -accessible through the specialArg meta in the config. -*/ +### +# Metadata for the nodes. You can add custom attributes, they are +# accessible through the specialArg meta in the config. + let + ### + # Transforms data from : + # { + # zone01 = [ node01 node02 ]; + # zone02 = [ node03 ]; + # } + # to : + # { + # node01 = zone01; + # node02 = zone01; + # node03 = zone02; + # } + locations = builtins.foldl' + (a: loc: a // loc) + { } + (builtins.concatLists (builtins.attrValues (builtins.mapAttrs + (zone: builtins.map (n: { ${n} = zone; })) + infra))); + + ### + # Add computed data about the nodes : + # - zone + # - deployment tags + # - network information + mkNode = node: attrs: attrs // { + zone = locations.${node}; + deployment = let old = attrs.deployment; in old // { + tags = (old.tags or [ ]) ++ [ "infra-${locations.${node}}" ]; + targetHost = builtins.head network.${node}.addresses.public; + }; + }; + + infra = import ./infrastructure.nix; members = import ./members.nix; - nodes = import ./nodes.nix; + network = import ./network.nix; + + nodes = builtins.mapAttrs mkNode (import ./nodes.nix); in -{ inherit members nodes; } +{ inherit infra members network nodes; } diff --git a/meta/infrastructure.nix b/meta/infrastructure.nix new file mode 100644 index 0000000..d983ec7 --- /dev/null +++ b/meta/infrastructure.nix @@ -0,0 +1,14 @@ +# Description of the infrastructure + +{ + # Salle serveur sous le pavillon Pasteur + par01 = [ + "compute01" + "storage01" + ]; + + # VMs du SPI/NPS/Whatever + dmi01 = [ + "web01" + ]; +} diff --git a/meta/network.nix b/meta/network.nix new file mode 100644 index 0000000..c83105c --- /dev/null +++ b/meta/network.nix @@ -0,0 +1,69 @@ +let + mkDefaultInterface = _: attrs: { ipv4 = [ ]; ipv6 = [ ]; gateways = [ ]; } // attrs; + + mkBase = config: config // { interfaces = builtins.mapAttrs mkDefaultInterface (config.interfaces or { }); }; + + getAddresses = version: interface: builtins.map (builtins.getAttr "address") interface.${version}; + + mkNet = _: value: + let base = mkBase value; in + base // { + addresses = + let + _addresses = builtins.foldl' + ({ ipv4, ipv6 }: net: { + ipv4 = ipv4 ++ getAddresses "ipv4" net; + ipv6 = ipv6 ++ getAddresses "ipv6" net; + }) + { ipv4 = [ ]; ipv6 = [ ]; } + (builtins.attrValues base.interfaces); + in + _addresses // { + public = (builtins.filter + (ip: builtins.substring 0 7 ip != "192.168") + _addresses.ipv4) ++ _addresses.ipv6; + }; + }; +in + +builtins.mapAttrs mkNet { + compute01 = { + interfaces = { + eno1 = { + ipv4 = [ + { address = "129.199.146.147"; prefixLength = 24; } + { address = "192.168.1.147"; prefixLength = 24; } + ]; + + gateways = [ "129.199.146.254" ]; + }; + }; + + hostId = "8df60941"; + }; + + storage01 = { + interfaces = { + eno1 = { + ipv4 = [ + { address = "129.199.146.148"; prefixLength = 24; } + { address = "192.168.1.148"; prefixLength = 24; } + ]; + + gateways = [ "129.199.146.254" ]; + }; + }; + + hostId = "d4e7c369"; + }; + + web01 = { + interfaces = { + ens3 = { + ipv4 = [{ address = "129.199.129.53"; prefixLength = 24; }]; + + gateways = [ "129.199.129.1" ]; + }; + }; + }; +} diff --git a/meta/nodes.nix b/meta/nodes.nix index 5fc84a6..e48571d 100644 --- a/meta/nodes.nix +++ b/meta/nodes.nix @@ -1,49 +1,46 @@ -/* File specifying all the deployement options for the nodes administrated by the dgnum. +### +# File specifying all the deployement options for the nodes administrated by the dgnum. +# +# Node metadata template is: +# +# NODE_NAME = { +# adminGroups = []; # List of groups that have root access +# admins = []; # List of individuals that have root access +# deployment = {}; # Colmena deployment options +# nixpkgs = "unstable" or "22.11"; # nixpkgs version +# } -Node metadata template is: - -NODE_NAME = { - adminGroups = []; # List of groups that have root access - admins = []; # List of individuals that have root access - deployment = {}; # Colmena deployment options - nixpkgs = "unstable" or "22.11"; # nixpkgs version -} -*/ - -{ - web-01 = { - adminGroups = [ "web" ]; +let + mkNode = _: attrs: { + adminGroups = [ ]; admins = [ ]; + deployment = { }; + + nixpkgs = "23.05"; + } // attrs; +in + +builtins.mapAttrs mkNode { + web01 = { + adminGroups = [ "web" ]; + deployment = { tags = [ "web" ]; - targetHost = "129.199.129.200"; }; - nixpkgs = "23.05"; + stateVersion = "23.05"; }; compute01 = { adminGroups = [ "bureau" ]; - admins = [ ]; - deployment = { - tags = [ "infra-pasteur" ]; - targetHost = "129.199.146.147"; - }; - - nixpkgs = "23.05"; + stateVersion = "23.05"; }; storage01 = { adminGroups = [ "bureau" ]; - admins = [ ]; - deployment = { - tags = [ "infra-pasteur" ]; - targetHost = "129.199.146.148"; - }; - - nixpkgs = "23.05"; + stateVersion = "23.05"; }; } diff --git a/modules/default.nix b/modules/default.nix index cb1a24b..fca9132 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -39,6 +39,7 @@ "dgn-acme" "dgn-console" "dgn-hardware" + "dgn-network" "dgn-secrets" "dgn-ssh" ]) ++ [ diff --git a/modules/dgn-network.nix b/modules/dgn-network.nix new file mode 100644 index 0000000..0d8dff8 --- /dev/null +++ b/modules/dgn-network.nix @@ -0,0 +1,43 @@ +{ config, lib, meta, name, ... }: + +let + inherit (lib) + mapAttrs' + mkEnableOption + mkIf + optionalAttrs; + + net = meta.network.${name}; + + mkAddress = { address, prefixLength, ... }: "${address}/${builtins.toString prefixLength}"; + mkRoute = gateway: { routeConfig = { Gateway = gateway; GatewayOnLink = true; }; }; + + mkInterface = interface: net: { + name = "10-${interface}"; + value = { + name = interface; + address = builtins.map mkAddress (net.ipv4 ++ net.ipv6); + routes = builtins.map mkRoute net.gateways; + + networkConfig = optionalAttrs (net ? DHCP) { inherit (net) DHCP; }; + }; + }; + + cfg = config.dgn-network; +in + +{ + options.dgn-network.enable = mkEnableOption "automatic network configuration based on metadata" // { default = true; }; + + config = mkIf cfg.enable { + networking = { + inherit (net) hostId; + + hostName = name; + domain = "${meta.nodes.${name}.zone}.infra.dgnum.eu"; + useNetworkd = true; + }; + + systemd.network.networks = mapAttrs' mkInterface net.interfaces; + }; +}