feat(tf): generate records

This commit is contained in:
arcnmx 2024-03-24 13:38:36 -07:00
parent 9cc471e2dc
commit 43ccdaac9a
8 changed files with 266 additions and 25 deletions

View file

@ -3,6 +3,7 @@ set -eu
for node in reisen; do
nix eval --json "${NF_CONFIG_ROOT}#lib.generate.$node.users" | jq -M . > "$NF_CONFIG_ROOT/systems/$node/users.json"
nix eval --json "${NF_CONFIG_ROOT}#lib.generate.$node.systems" | jq -M . > "$NF_CONFIG_ROOT/systems/$node/systems.json"
done
for ciconfig in "${NF_CONFIG_FILES[@]}"; do

View file

@ -3,8 +3,10 @@
tree,
}: let
nixlib = inputs.nixpkgs.lib;
inherit (nixlib.attrsets) filterAttrs mapAttrsToList;
inherit (nixlib.lists) sortOn;
inherit (nixlib.attrsets) mapAttrs filterAttrs mapAttrsToList;
inherit (nixlib.lists) elem sortOn;
inherit (nixlib.strings) removeSuffix;
inherit (nixlib.trivial) mapNullable warn;
inherit (inputs.self.lib.lib) userIs;
templateSystem = inputs.self.nixosConfigurations.reimu;
templateUsers = filterAttrs (_: userIs "peeps") templateSystem.config.users.users;
@ -16,8 +18,39 @@
inherit (user) name uid;
authorizedKeys = user.openssh.authorizedKeys.keys;
};
nodeSystems = let
matchesNode = nodeName: system: system.config.proxmox.enabled && system.config.proxmox.node.name == nodeName;
in nodeName: filterAttrs (_: matchesNode nodeName) inputs.self.lib.systems;
mkNodeSystem = system: {
network = let
inherit (system.config.proxmox) network;
inherit (network) internal;
inherit (network.interfaces) net0;
mapAddress6 = prefix: interface:
if interface.address6 == "dhcp" then null
else if interface.address6 == "auto" then "${prefix}${interface.slaac.postfix}"
else mapNullable (removeSuffix "/64") interface.address6;
mapAddress4 = interface:
if elem interface.address4 [ "dhcp" "auto" ] then null
else mapNullable (removeSuffix "/24") interface.address4;
in {
int = if internal.interface != null then {
inherit (internal.interface) macAddress;
address6 = mapAddress6 "fd0c::" internal.interface;
address4 = mapAddress4 internal.interface;
} else null;
local = if network.interfaces.net0.bridge or null == "vmbr0" then {
inherit (net0) macAddress;
address6 = mapAddress6 "fd0a::" net0;
address4 = mapAddress4 net0;
} else null;
tail = warn "TODO: generate network.tail" null;
};
};
mkNodeSystems = systems: mapAttrs (_: mkNodeSystem) systems;
mkNode = {name}: {
users = mkNodeUsers templateUsers;
systems = mkNodeSystems (nodeSystems name);
};
in {
reisen = mkNode {name = "reisen";};

View file

@ -9,6 +9,8 @@ _: {
net0 = {
name = "ens18";
macAddress = "BC:24:11:3D:39:91";
address4 = "10.1.1.46/24";
address6 = "auto";
};
net1.internal.enable = true;
};

View file

@ -7,7 +7,10 @@ _: {
};
network.interfaces = {
net0 = {
name = "ens18";
macAddress = "BC:24:11:33:19:04";
address4 = "dhcp";
address6 = "auto";
};
};
};

159
systems/reisen/systems.json Normal file
View file

@ -0,0 +1,159 @@
{
"aya": {
"network": {
"int": {
"address4": "10.9.1.73",
"address6": "fd0c::49",
"macAddress": "BC:24:19:C4:66:A9"
},
"local": {
"address4": "10.1.1.47",
"address6": "fd0a::be24:11ff:fec4:66a9",
"macAddress": "BC:24:11:C4:66:A9"
},
"tail": null
}
},
"freeipa": {
"network": {
"int": {
"address4": "10.9.1.170",
"address6": "fd0c::aa",
"macAddress": "BC:24:19:3D:39:91"
},
"local": {
"address4": "10.1.1.46",
"address6": "fd0a::be24:11ff:fe3d:3991",
"macAddress": "BC:24:11:3D:39:91"
},
"tail": null
}
},
"freepbx": {
"network": {
"int": null,
"local": {
"address4": null,
"address6": "fd0a::be24:11ff:fe33:1904",
"macAddress": "BC:24:11:33:19:04"
},
"tail": null
}
},
"hakurei": {
"network": {
"int": {
"address4": "10.9.1.71",
"address6": "fd0c::47",
"macAddress": "BC:24:19:C4:66:A7"
},
"local": {
"address4": "10.1.1.41",
"address6": "fd0a::be24:11ff:fec4:66a7",
"macAddress": "BC:24:11:C4:66:A7"
},
"tail": null
}
},
"keycloak": {
"network": {
"int": {
"address4": "10.9.1.75",
"address6": "fd0c::4b",
"macAddress": "BC:24:19:C4:66:AC"
},
"local": {
"address4": "10.1.1.48",
"address6": "fd0a::be24:11ff:fec4:66ac",
"macAddress": "BC:24:11:C4:66:AC"
},
"tail": null
}
},
"kuwubernetes": {
"network": {
"int": null,
"local": {
"address4": "10.1.1.42",
"address6": "fd0a::be24:11ff:fe49:fedc",
"macAddress": "BC:24:11:49:FE:DC"
},
"tail": null
}
},
"litterbox": {
"network": {
"int": {
"address4": "10.9.1.74",
"address6": "fd0c::4a",
"macAddress": "BC:24:19:C4:66:AB"
},
"local": {
"address4": null,
"address6": "fd0a::be24:11ff:fec4:66ab",
"macAddress": "BC:24:11:C4:66:AB"
},
"tail": null
}
},
"mediabox": {
"network": {
"int": {
"address4": "10.9.1.70",
"address6": "fd0c::46",
"macAddress": "BC:24:19:34:F4:A8"
},
"local": {
"address4": "10.1.1.44",
"address6": "fd0a::be24:11ff:fe34:f4a8",
"macAddress": "BC:24:11:34:F4:A8"
},
"tail": null
}
},
"reimu": {
"network": {
"int": {
"address4": "10.9.1.72",
"address6": "fd0c::48",
"macAddress": "BC:24:19:C4:66:A8"
},
"local": {
"address4": "10.1.1.45",
"address6": "fd0a::be24:11ff:fec4:66a8",
"macAddress": "BC:24:11:C4:66:A8"
},
"tail": null
}
},
"tei": {
"network": {
"int": {
"address4": "10.9.1.69",
"address6": "fd0c::45",
"macAddress": "BC:24:19:CC:66:57"
},
"local": {
"address4": "10.1.1.39",
"address6": "fd0a::be24:11ff:fecc:6657",
"macAddress": "BC:24:11:CC:66:57"
},
"tail": null
}
},
"utsuho": {
"network": {
"int": {
"address4": "10.9.1.76",
"address6": "fd0c::4c",
"macAddress": "BC:24:19:C4:66:A6"
},
"local": {
"address4": "10.1.1.38",
"address6": "fd0a::be24:11ff:fec4:66a6",
"macAddress": "BC:24:11:C4:66:A6"
},
"tail": null
}
}
}

View file

@ -4,6 +4,8 @@ module "reisen_system_records" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
local_v4 = "10.1.1.40"
int_v4 = "10.9.1.2"
int_v6 = "fd0c::2"
}
module "hakurei_system_records" {
@ -11,10 +13,9 @@ module "hakurei_system_records" {
name = "hakurei"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
net_data = local.proxmox_reisen_systems.hakurei.network
tailscale_v4 = "100.71.65.59"
tailscale_v6 = "fd7a:115c:a1e0::9187:413b"
local_v4 = "10.1.1.41"
local_v6 = "fd0a::be24:11ff:fec4:66a7"
local_subdomains = [
"prox",
"id",
@ -49,9 +50,9 @@ module "reimu_system_records" {
name = "reimu"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
net_data = local.proxmox_reisen_systems.reimu.network
tailscale_v4 = "100.113.253.48"
tailscale_v6 = "fd7a:115c:a1e0::f1b1:fd30"
local_v6 = "fd0a::be24:11ff:fec4:66a8"
local_subdomains = [
"nfs",
]
@ -62,8 +63,7 @@ module "keycloak_system_records" {
name = "keycloak"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
local_v4 = "10.1.1.48"
local_v6 = "fd0a::be24:11ff:fec4:66ac"
net_data = local.proxmox_reisen_systems.keycloak.network
}
module "utsuho_system_records" {
@ -71,8 +71,7 @@ module "utsuho_system_records" {
name = "utsuho"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
local_v4 = "10.1.1.38"
local_v6 = "fd0a::be24:11ff:fec4:66a6"
net_data = local.proxmox_reisen_systems.utsuho.network
}
module "aya_system_records" {
@ -80,10 +79,9 @@ module "aya_system_records" {
name = "aya"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
net_data = local.proxmox_reisen_systems.aya.network
tailscale_v4 = "100.109.213.94"
tailscale_v6 = "fd7a:115c:a1e0::eaed:d55e"
local_v4 = "10.1.1.47"
local_v6 = "fd0a::be24:11ff:fec4:66a9"
local_subdomains = [
"nixbld",
]
@ -94,10 +92,9 @@ module "tewi_system_records" {
name = "tei"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
net_data = local.proxmox_reisen_systems.tei.network
tailscale_v4 = "100.74.104.29"
tailscale_v6 = "fd7a:115c:a1e0::fd8a:681d"
local_v4 = "10.1.1.39"
local_v6 = "fd0a::be24:11ff:fecc:6657"
local_subdomains = [
"mqtt",
"postgresql",
@ -109,8 +106,7 @@ module "mediabox_system_records" {
name = "mediabox"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
local_v4 = "10.1.1.44"
local_v6 = "fd0a::be24:11ff:fe34:f4a8"
net_data = local.proxmox_reisen_systems.mediabox.network
local_subdomains = [
"plex",
]
@ -121,7 +117,7 @@ module "litterbox_system_records" {
name = "litterbox"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
local_v6 = "fd0a::be24:11ff:fec4:66ab"
net_data = local.proxmox_reisen_systems.litterbox.network
}
module "idp_system_records" {
@ -129,8 +125,7 @@ module "idp_system_records" {
name = "idp"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
local_v4 = "10.1.1.46"
local_v6 = "fd0a::be24:11ff:fe3d:3991"
net_data = local.proxmox_reisen_systems.freeipa.network
}
module "kubernetes_system_records" {
@ -138,7 +133,7 @@ module "kubernetes_system_records" {
name = "kubernetes"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
local_v6 = "fd0a::be24:11ff:fe49:fedc"
net_data = local.proxmox_reisen_systems.kuwubernetes.network
}
module "freepbx_system_records" {
@ -146,7 +141,7 @@ module "freepbx_system_records" {
name = "freepbx"
zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
local_v6 = "fd0a::be24:11ff:fe33:1904"
net_data = local.proxmox_reisen_systems.freepbx.network
}
module "kitchencam_system_records" {

View file

@ -16,7 +16,8 @@ locals {
proxmox_reisen_udev_dri = file("${path.root}/../systems/reisen/udev.90-dri.rules")
proxmox_reisen_udev_z2m = file("${path.root}/../systems/reisen/udev.90-z2m.rules")
proxmox_reisen_users = jsondecode(file("${path.root}/../systems/reisen/users.json"))
proxmox_reisen_users = jsondecode(file("${path.root}/../systems/reisen/users.json"))
proxmox_reisen_systems = jsondecode(file("${path.root}/../systems/reisen/systems.json"))
}
resource "terraform_data" "proxmox_reisen_etc" {

View file

@ -10,6 +10,15 @@ variable "name" {
type = string
}
variable "net_data" {
type = map(map(any))
default = {
local = null
int = null
tail = null
}
}
variable "tailscale_name" {
type = string
default = null
@ -25,6 +34,21 @@ variable "tailscale_v6" {
default = null
}
variable "int_name" {
type = string
default = null
}
variable "int_v4" {
type = string
default = null
}
variable "int_v6" {
type = string
default = null
}
variable "local_name" {
type = string
default = null
@ -57,20 +81,39 @@ variable "global_v6" {
locals {
local_name = coalesce(var.local_name, "${var.name}.local")
local_net = coalesce(var.net_data.local, local.empty_net)
local_v4 = coalesce(var.local_v4, local.local_net.address4, local.empty_address)
local_v6 = coalesce(var.local_v6, local.local_net.address6, local.empty_address)
int_name = coalesce(var.int_name, "${var.name}.int")
int_net = coalesce(var.net_data.int, local.empty_net)
int_v4 = coalesce(var.int_v4, local.int_net.address4, local.empty_address)
int_v6 = coalesce(var.int_v6, local.int_net.address6, local.empty_address)
tailscale_name = coalesce(var.tailscale_name, "${var.name}.tail")
tailscale_net = coalesce(var.net_data.tail, local.empty_net)
tailscale_v4 = coalesce(var.tailscale_v4, local.tailscale_net.address4, local.empty_address)
tailscale_v6 = coalesce(var.tailscale_v6, local.tailscale_net.address6, local.empty_address)
global_name = coalesce(var.global_name, var.name)
has_tailscale = var.tailscale_v4 != null || var.tailscale_v6 != null
empty_address = "EMPTY"
empty_net = {
address4 = null
address6 = null
}
a_records = [
{
name = local.local_name,
value = var.local_v4,
value = local.local_v4,
},
{
name = local.global_name,
value = var.global_v4,
},
{
name = local.int_name,
value = local.int_v4,
},
{
name = local.tailscale_name,
value = var.tailscale_v4,
@ -80,12 +123,16 @@ locals {
aaaa_records = [
{
name = local.local_name,
value = var.local_v6,
value = local.local_v6,
},
{
name = local.global_name,
value = var.global_v6,
},
{
name = local.int_name,
value = local.int_v6,
},
{
name = local.tailscale_name,
value = var.tailscale_v6,
@ -94,7 +141,7 @@ locals {
}
resource "cloudflare_record" "a_records" {
for_each = { for i, a in local.a_records : a.name => i if a.value != null }
for_each = { for i, a in local.a_records : a.name => i if a.value != null && a.value != local.empty_address }
name = local.a_records[each.value].name
proxied = false
ttl = 3600
@ -104,7 +151,7 @@ resource "cloudflare_record" "a_records" {
}
resource "cloudflare_record" "aaaa_records" {
for_each = { for i, aaaa in local.aaaa_records : aaaa.name => i if aaaa.value != null }
for_each = { for i, aaaa in local.aaaa_records : aaaa.name => i if aaaa.value != null && aaaa.value != local.empty_address }
name = local.aaaa_records[each.value].name
proxied = false
ttl = 3600