lab-infra/meta/options.nix
sinavir 2ac0a35c5e
Some checks failed
Check meta / check_meta (push) Successful in 22s
Check meta / check_meta (pull_request) Successful in 21s
lint / check (push) Successful in 23s
lint / check (pull_request) Successful in 24s
build configuration / build_krz01 (pull_request) Failing after 3m26s
chore(meta): Revamp and remove DNS for now
We don't have a dns server for the lab infra for now. Later we will
probably reintroduce the tooling for our dns server. This will be good
for people to get into understanding the main infra repository.
2024-10-17 13:36:27 +02:00

337 lines
9.4 KiB
Nix

{ config, lib, ... }@args:
let
inherit (lib)
mkEnableOption
mkDefault
mkIf
mkOption
;
inherit (lib.types)
attrs
attrsOf
ints
listOf
nullOr
str
submodule
unspecified
;
addressType =
max:
submodule {
options = {
address = mkOption {
type = str;
description = "IP address.";
};
prefixLength = mkOption {
type = ints.between 8 max;
description = "Length of the prefix used in the local network.";
};
};
};
org = config.organization;
in
{
options = {
organization = {
members = mkOption {
type = attrsOf (submodule {
options = {
name = mkOption {
type = str;
description = ''
Name of the member.
'';
};
email = mkOption {
type = str;
description = ''
Main e-mail address of the member.
'';
};
};
});
description = ''
Members of the DGNum organization.
'';
};
groups = mkOption {
type = attrsOf (listOf str);
description = ''
Groups of the DGNum organization.
'';
};
};
nodes = mkOption {
type = attrsOf (
submodule (
{ config, name, ... }:
{
options = {
deployment = mkOption {
type = attrs;
default = { };
};
stateVersion = mkOption {
type = str;
description = ''
State version of the node.
'';
};
nixpkgs = mkOption {
type = str;
inherit (import ./nixpkgs.nix) default;
description = ''
Version of nixpkgs to use.
'';
};
nix-modules = mkOption {
type = listOf str;
default = [ ];
description = ''
List of modules to import from [nix-modules](https://git.hubrecht.ovh/hubrecht/nix-modules).
'';
};
hashedPassword = mkOption {
type = str;
description = ''
The hashed password for the root account.
'';
};
admins = mkOption {
type = listOf str;
default = [ ];
description = ''
List of members to be given root access to this node.
'';
};
adminGroups = mkOption {
type = listOf str;
default = [ ];
description = ''
List of groups to be given root access to this node.
'';
};
site = mkOption {
type = str;
description = ''
Geographical site where the node is located.
'';
};
vm-cluster = mkOption {
type = nullOr str;
default = null;
description = "VM cluster where the VM is located";
};
};
config = {
deployment = {
tags = [ "infra-${config.site}" ];
targetHost =
let
ip = with args.config.network.${name}.addresses; ipv4 ++ ipv6;
in
mkIf (ip != [ ]) (mkDefault (builtins.head ip));
};
};
}
)
);
description = ''
Nodes of the infrastructure.
'';
};
network = mkOption {
type = attrsOf (
submodule (
{ config, ... }:
{
options = {
interfaces = mkOption {
type = attrsOf (
submodule (
{ config, ... }:
{
options = {
ipv4 = mkOption {
type = listOf (addressType 32);
default = [ ];
description = ''
List of ipv4 addresses assigned to the interface.
'';
};
ipv6 = mkOption {
type = listOf (addressType 64);
default = [ ];
description = ''
List of ipv6 addresses assigned to the interface.
'';
};
gateways = mkOption {
type = listOf str;
description = ''
List of gateways used by the interface.
'';
};
DHCP = mkOption {
type = nullOr str;
default = null;
description = "Whether to enable DHCP on the interface.";
};
dns = mkOption {
type = listOf str;
default = [ ];
};
enableDefaultDNS = mkEnableOption "default DNS servers.";
};
config.dns = mkIf config.enableDefaultDNS [
"1.1.1.1#cloudflare-dns.com"
"8.8.8.8#dns.google"
"1.0.0.1#cloudflare-dns.com"
"8.8.4.4#dns.google"
"2606:4700:4700::1111#cloudflare-dns.com"
"2001:4860:4860::8888#dns.google"
"2606:4700:4700::1001#cloudflare-dns.com"
"2001:4860:4860::8844#dns.google"
];
}
)
);
};
addresses = {
ipv4 = mkOption {
type = listOf str;
default = [ ];
description = ''
List of public ipv4 addresses of the node.
'';
};
ipv6 = mkOption {
type = listOf str;
default = [ ];
description = ''
List of public ipv6 addresses of the node.
'';
};
};
hostId = mkOption {
type = str;
description = ''
Network Id of the node.
'';
};
netbirdIp = mkOption {
type = nullOr str;
description = ''
IP address of the node in the netbird network.
'';
};
};
config =
let
getAddresses =
version: builtins.concatMap (int: builtins.map (builtins.getAttr "address") int.${version});
in
{
addresses = {
ipv4 = builtins.filter (ip: builtins.substring 0 7 ip != "192.168") (
getAddresses "ipv4" (builtins.attrValues config.interfaces)
);
ipv6 = builtins.filter (_: true) ((getAddresses "ipv6") (builtins.attrValues config.interfaces));
};
};
}
)
);
description = ''
Network configuration for the different machines.
'';
};
assertions = mkOption {
type = listOf unspecified;
internal = true;
default = [ ];
description = ''
This option allows modules to express conditions that must
hold for the evaluation of the system configuration to
succeed, along with associated error messages for the user.
'';
};
};
config =
let
members = builtins.attrNames org.members;
groups = builtins.attrNames org.groups;
nameExists =
list: f: groups:
builtins.attrValues (
builtins.mapAttrs (name: members: {
assertion = builtins.all (x: builtins.elem x list) members;
message = f name;
}) groups
);
membersExists = nameExists members;
groupsExists = nameExists groups;
extract = name: builtins.mapAttrs (_: builtins.getAttr name);
in
{
assertions = builtins.concatLists [
# Check that all group members exist
(membersExists (
name: "A member of the ${name} group was not found in the members list."
) org.groups)
# Check that all node admins exist
(membersExists (name: "A member of the node ${name} admins was not found in the members list.") (
extract "admins" config.nodes
))
# Check that all node adminGroups exist
(groupsExists (name: "A member of the node ${name} adminGroups was not found in the groups list.") (
extract "adminGroups" config.nodes
))
# Check that all members have ssh keys
(builtins.map (name: {
assertion = ((import ../keys)._keys.${name} or [ ]) != [ ];
message = "No ssh keys found for ${name}.";
}) members)
];
};
}