{ nixosConfigurations, lib, config, ... }: let inherit (lib) mkEnableOption mkIf tf genList filterAttrs; cfg = config.bagel.dnsimple; filterBaremetalNodes = submodule: nodes: filterAttrs (name: node: node.config.bagel.baremetal.enable && node.config.bagel.baremetal.${submodule}.enable) nodes; builderNodes = builtins.attrValues (filterBaremetalNodes "builders" nixosConfigurations); storageNodes = builtins.attrValues (filterBaremetalNodes "storage" nixosConfigurations); in { options.bagel.dnsimple = { enable = mkEnableOption "the DNSimple configuration"; }; config = mkIf cfg.enable { terraform.required_providers.dnsimple = { version = "~> 1.7.0"; source = "dnsimple/dnsimple"; }; resource.secret_resource.dnsimple_token.lifecycle.prevent_destroy = true; resource.secret_resource.dnsimple_account.lifecycle.prevent_destroy = true; provider.dnsimple = { token = tf.ref "resource.secret_resource.dnsimple_token.value"; account = tf.ref "resource.secret_resource.dnsimple_account.value"; }; resource.dnsimple_zone.forkos_org = { name = "forkos.org"; }; resource.dnsimple_zone.fleurixos_org = { name = "fleurixos.org"; }; resource.dnsimple_zone.floral_systems = { name = "floral.systems"; }; resource.dnsimple_zone.flowery_systems = { name = "flowery.systems"; }; resource.dnsimple_zone.petalpkgs_org = { name = "petalpkgs.org"; }; resource.dnsimple_zone.vzfdfp_de = { name = "vzfdfp.de"; }; resource.dnsimple_zone_record = let # https://registry.terraform.io/providers/dnsimple/dnsimple/latest/docs/resources/zone_record canonicalName = zoneName: record: let # TODO: make less fragile and have actual unique and stable names normalize = builtins.replaceStrings ["." "@"] ["_" "_root_"]; zone = normalize zoneName; name = normalize record.name; in "${zone}_${record.type}_${name}"; record = name: ttl: type: value: { inherit name ttl type value; }; proxyRecords = name: ttl: type: value: [ # kurisu.lahfa.xyz running a sniproxy: (record name ttl "A" "163.172.69.160") (record name ttl type value) ]; # Creates a extra *.p record pointing to the sniproxy dualProxyRecords = name: ttl: type: value: lib.flatten [ (record name ttl type value) (proxyRecords "${name}.p" ttl type value) ]; domain = zoneName: records: builtins.listToAttrs (map (record: { name = canonicalName zoneName record; value = record // { zone_name = zoneName; }; } ) (lib.flatten records)); zones = domains: lib.zipAttrs (lib.mapAttrsToList (zoneName: records: domain zoneName records) domains); in zones { "forkos.org" = ([ # (record "@" 300 "A" "163.172.69.160") (record "@" 300 "AAAA" "2001:bc8:38ee:100:1000::20") (dualProxyRecords "bagel-box.infra" 300 "AAAA" "2001:bc8:38ee:100:100::1") (dualProxyRecords "gerrit01.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::10") (dualProxyRecords "meta01.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::20") (dualProxyRecords "fodwatch.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::30") # git.infra.forkos.org exposes opensshd (dualProxyRecords "git.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::41") # git.p.forkos.org exposes forgejo ssh server. (proxyRecords "git.p" 300 "AAAA" "2001:bc8:38ee:100:1000::40") (dualProxyRecords "buildbot.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::50") (dualProxyRecords "public01.infra" 300 "AAAA" "2001:bc8:38ee:100:1000::60") (record "cl" 300 "CNAME" "gerrit01.infra.p.forkos.org") (record "fodwatch" 300 "CNAME" "fodwatch.infra.p.forkos.org") # git.p.forkos.org is the proxy variant of the Forgejo server. (record "git" 300 "CNAME" "git.p.forkos.org") (record "netbox" 300 "CNAME" "meta01.infra.p.forkos.org") (record "amqp" 300 "CNAME" "bagel-box.infra.p.forkos.org") (record "grafana" 300 "CNAME" "meta01.infra.p.forkos.org") (record "hydra" 300 "CNAME" "build-coord.wob01.infra.p.forkos.org") (record "loki" 300 "CNAME" "meta01.infra.p.forkos.org") (record "mimir" 300 "CNAME" "meta01.infra.p.forkos.org") (record "pyroscope" 300 "CNAME" "meta01.infra.p.forkos.org") (record "tempo" 300 "CNAME" "meta01.infra.p.forkos.org") (record "matrix" 300 "CNAME" "meta01.infra.p.forkos.org") (record "alerts" 300 "CNAME" "meta01.infra.p.forkos.org") (record "buildbot" 300 "CNAME" "buildbot.infra.p.forkos.org") (record "b" 300 "CNAME" "public01.infra.p.forkos.org") (record "postgres" 300 "CNAME" "bagel-box.infra.p.forkos.org") (record "news" 3600 "CNAME" "public01.infra.p.forkos.org") (record "status" 3600 "CNAME" "public01.infra.p.forkos.org") # S3 in delroth's basement (record "cache" 300 "AAAA" "2a02:168:6426::12") # smol.delroth.net (record "cache" 300 "A" "195.39.247.161") # sni proxy (record "vpn-gw.wob01.infra" 300 "AAAA" "2a01:584:11::2") (dualProxyRecords "build-coord.wob01.infra" 300 "AAAA" "2a01:584:11::1:11") # TODO: do not hardcode, just reuse the Colmena hive module outputs to generate all the required details. ] ++ (map (index: record "bm-${toString index}.wob01.infra" 300 "AAAA" "2a01:584:11::1:${toString index}") (genList lib.id 11)) ++ (map (node: record "builder-${toString node.config.bagel.baremetal.builders.num}.wob01.infra" 300 "CNAME" "bm-${toString node.config.bagel.baremetal.num}") builderNodes) ++ (map (node: record "storage-${toString node.config.bagel.baremetal.storage.num}.wob01.infra" 300 "CNAME" "bm-${toString node.config.bagel.baremetal.num}") storageNodes) ++ ( let # FIXME: figure out a way to poke `config.services.s3-revproxy` and # automate the DNS part away? buckets = [ "channels" "releases" "channel-scripts-test" ]; in map (bucket: record "${bucket}" 300 "CNAME" "public01.infra.p.forkos.org") buckets )); "flowery.systems" = [ (record "" 300 "ALIAS" "news.forkos.org") ]; "vzfdfp.de" = [ ]; }; }; }