modules: Setup dgn-network with configuration from metadata

This commit is contained in:
Tom Hubrecht 2023-07-20 12:32:31 +02:00
parent 8d2c4ec379
commit 2274668f9b
11 changed files with 211 additions and 78 deletions

View file

@ -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 = { ... }: {

View file

@ -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?
}

View file

@ -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.<interface>.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;

View file

@ -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?
}

View file

@ -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.<interface>.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;

View file

@ -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; }

14
meta/infrastructure.nix Normal file
View file

@ -0,0 +1,14 @@
# Description of the infrastructure
{
# Salle serveur sous le pavillon Pasteur
par01 = [
"compute01"
"storage01"
];
# VMs du SPI/NPS/Whatever
dmi01 = [
"web01"
];
}

69
meta/network.nix Normal file
View file

@ -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" ];
};
};
};
}

View file

@ -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";
};
}

View file

@ -39,6 +39,7 @@
"dgn-acme"
"dgn-console"
"dgn-hardware"
"dgn-network"
"dgn-secrets"
"dgn-ssh"
]) ++ [

43
modules/dgn-network.nix Normal file
View file

@ -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;
};
}