forked from fediversity/fediversity
add DNS zone by octodns
Signed-off-by: Kiara Grouwstra <kiara@procolix.eu>
This commit is contained in:
parent
1690fcb265
commit
c426cf2c55
8 changed files with 357 additions and 1 deletions
22
.forgejo/workflows/octodns.yaml
Normal file
22
.forgejo/workflows/octodns.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
name: octodns
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- synchronize
|
||||||
|
- reopened
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
cancel-in-progress: true
|
||||||
|
group: ${{ forgejo.workflow }}-${{ forgejo.event.pull_request.number || forgejo.ref }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
octodns:
|
||||||
|
runs-on: native
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: nix build .#checks.x86_64-linux.octodns -vL
|
||||||
10
deployment/check/octodns/constants.nix
Normal file
10
deployment/check/octodns/constants.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
targetMachines = [
|
||||||
|
"node"
|
||||||
|
];
|
||||||
|
pathToRoot = builtins.path {
|
||||||
|
path = ../../..;
|
||||||
|
name = "root";
|
||||||
|
};
|
||||||
|
pathFromRoot = "/deployment/check/octodns";
|
||||||
|
}
|
||||||
21
deployment/check/octodns/default.nix
Normal file
21
deployment/check/octodns/default.nix
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
inputs,
|
||||||
|
sources,
|
||||||
|
}:
|
||||||
|
|
||||||
|
pkgs.testers.runNixOSTest {
|
||||||
|
imports = [
|
||||||
|
../common/nixosTest.nix
|
||||||
|
./nixosTest.nix
|
||||||
|
];
|
||||||
|
_module.args = {
|
||||||
|
inherit inputs sources;
|
||||||
|
modulesPath = "${builtins.toString pkgs.path}/nixos/modules";
|
||||||
|
};
|
||||||
|
inherit (import ./constants.nix)
|
||||||
|
targetMachines
|
||||||
|
pathToRoot
|
||||||
|
pathFromRoot
|
||||||
|
;
|
||||||
|
}
|
||||||
90
deployment/check/octodns/nixosTest.nix
Normal file
90
deployment/check/octodns/nixosTest.nix
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
sources,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (pkgs.callPackage ../../utils.nix { }) evalOption;
|
||||||
|
domain = "domain.tld";
|
||||||
|
apiKey = "abcdefghijklm";
|
||||||
|
inherit
|
||||||
|
(evalOption
|
||||||
|
(pkgs.callPackage ../../run {
|
||||||
|
inherit sources;
|
||||||
|
}).octodns-zone
|
||||||
|
{
|
||||||
|
inherit domain;
|
||||||
|
provider = "powerdns";
|
||||||
|
# outside tests, use an actual secrets mechanism instead
|
||||||
|
secretFiles.api_key = builtins.toString (pkgs.writeText "api_key" apiKey);
|
||||||
|
configuration.host = "localhost";
|
||||||
|
zone = {
|
||||||
|
NS = [ "ns.test.com." ];
|
||||||
|
A = [ "203.0.113.2" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
validate
|
||||||
|
sync
|
||||||
|
;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
_class = "nixosTest";
|
||||||
|
name = "octodns";
|
||||||
|
|
||||||
|
nodes.deployer = {
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
services.powerdns = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig = ''
|
||||||
|
api=yes
|
||||||
|
api-key=${apiKey}
|
||||||
|
launch=gmysql
|
||||||
|
gmysql-user=pdns
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
services.mysql = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.mariadb;
|
||||||
|
ensureDatabases = [ "powerdns" ];
|
||||||
|
ensureUsers = lib.singleton {
|
||||||
|
name = "pdns";
|
||||||
|
ensurePermissions = {
|
||||||
|
"powerdns.*" = "ALL PRIVILEGES";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
dnsutils
|
||||||
|
powerdns
|
||||||
|
mariadb
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
extraTestScript = ''
|
||||||
|
|
||||||
|
with subtest("Loading the MySQL schema"):
|
||||||
|
deployer.wait_for_unit("mysql")
|
||||||
|
deployer.succeed(
|
||||||
|
"sudo -u pdns mysql -u pdns -D powerdns <"
|
||||||
|
"${pkgs.powerdns}/share/doc/pdns/schema.mysql.sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
with subtest("PowerDNS server starts"):
|
||||||
|
deployer.wait_for_unit("pdns")
|
||||||
|
|
||||||
|
with subtest("validate"):
|
||||||
|
deployer.succeed("""
|
||||||
|
${lib.getExe validate}
|
||||||
|
""")
|
||||||
|
with subtest("sync"):
|
||||||
|
deployer.succeed("""
|
||||||
|
${lib.getExe sync}
|
||||||
|
""")
|
||||||
|
with subtest("no-op sync"):
|
||||||
|
deployer.succeed("""
|
||||||
|
${lib.getExe sync}
|
||||||
|
""")
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
@ -48,6 +48,10 @@
|
||||||
netbox-ips = import ./check/netbox-ips {
|
netbox-ips = import ./check/netbox-ips {
|
||||||
inherit inputs sources system;
|
inherit inputs sources system;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
octodns = import ./check/octodns {
|
||||||
|
inherit pkgs inputs sources;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,19 @@
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
inherit (lib.types)
|
inherit (lib.types)
|
||||||
|
int
|
||||||
nullOr
|
nullOr
|
||||||
raw
|
raw
|
||||||
str
|
str
|
||||||
submodule
|
submodule
|
||||||
;
|
;
|
||||||
inherit (pkgs.callPackage ../utils.nix { }) withPackages withEnv tfApply;
|
inherit (pkgs.callPackage ../utils.nix { })
|
||||||
|
mapKeys
|
||||||
|
withPackages
|
||||||
|
withEnv
|
||||||
|
withSecrets
|
||||||
|
tfApply
|
||||||
|
;
|
||||||
writeConfig =
|
writeConfig =
|
||||||
{
|
{
|
||||||
system,
|
system,
|
||||||
|
|
@ -628,4 +635,190 @@ in
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
octodns-zone = mkOption {
|
||||||
|
description = "Manage DNS records.";
|
||||||
|
type = submodule (
|
||||||
|
octodns-zone:
|
||||||
|
let
|
||||||
|
dns = pkgs.callPackage sources."dns.nix" { };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
domain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "example.tld";
|
||||||
|
};
|
||||||
|
secretFiles = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
description = "The files from which to read the secrets to use with the provider.";
|
||||||
|
example = {
|
||||||
|
token = "/path/to/token";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
zone = mkOption {
|
||||||
|
# FIXME: error: The option `zones."domain.tld".__toString' is read-only, but it's set multiple times.
|
||||||
|
# type = dns.lib.types.zone;
|
||||||
|
description = "The zone data to use.";
|
||||||
|
example = {
|
||||||
|
NS = [ "ns.example.tld." ];
|
||||||
|
A = [ "12.34.56.78" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
provider = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The OctoDNS provider to use, see <https://octodns.readthedocs.io/en/latest/#providers>.";
|
||||||
|
example = "powerdns";
|
||||||
|
};
|
||||||
|
providers = mkOption {
|
||||||
|
type = types.attrsOf (
|
||||||
|
types.submodule {
|
||||||
|
options = {
|
||||||
|
class = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
secrets = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
};
|
||||||
|
configuration = mkOption {
|
||||||
|
# FIXME how do i express `attrsOf option` if there is no `types.option`?
|
||||||
|
type = types.attrsOf types.raw;
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
default = {
|
||||||
|
desec = {
|
||||||
|
class = "octodns_desec.DesecProvider";
|
||||||
|
secrets = [ "token" ];
|
||||||
|
};
|
||||||
|
hetzner = {
|
||||||
|
class = "octodns_hetzner.HetznerProvider";
|
||||||
|
secrets = [ "token" ];
|
||||||
|
};
|
||||||
|
powerdns = {
|
||||||
|
class = "octodns_powerdns.PowerDnsProvider";
|
||||||
|
secrets = [ "api_key" ];
|
||||||
|
configuration = {
|
||||||
|
host = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = "The host on which PowerDNS api is listening.";
|
||||||
|
};
|
||||||
|
port = mkOption {
|
||||||
|
type = int;
|
||||||
|
description = "The port on which PowerDNS api is listening.";
|
||||||
|
default = 8081;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
configuration = mkOption {
|
||||||
|
type = submodule {
|
||||||
|
options = octodns-zone.config.providers.${octodns-zone.config.provider}.configuration;
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
example = "The package of the OctoDNS provider to deploy to, see <https://search.nixos.org/packages?channel=unstable&query=octodns-providers>.";
|
||||||
|
default = pkgs.octodns-providers.${octodns-zone.config.provider};
|
||||||
|
};
|
||||||
|
packages = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/429294
|
||||||
|
(
|
||||||
|
(pkgs.callPackage "${sources.nixpkgs-unstable}/pkgs/by-name/oc/octodns/package.nix" { })
|
||||||
|
.withProviders
|
||||||
|
(_: [
|
||||||
|
pkgs.octodns-providers.bind
|
||||||
|
octodns-zone.config.package
|
||||||
|
])
|
||||||
|
)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
conf = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default =
|
||||||
|
let
|
||||||
|
inherit (octodns-zone.config)
|
||||||
|
domain
|
||||||
|
zone
|
||||||
|
providers
|
||||||
|
provider
|
||||||
|
;
|
||||||
|
in
|
||||||
|
pkgs.writers.writeYAML "octodns-config.yaml" {
|
||||||
|
zones."${domain}." = {
|
||||||
|
sources = [ "config" ];
|
||||||
|
targets = [ provider ];
|
||||||
|
};
|
||||||
|
providers = {
|
||||||
|
"${provider}" =
|
||||||
|
let
|
||||||
|
inherit (providers."${provider}") class secrets;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit class;
|
||||||
|
}
|
||||||
|
// octodns-zone.config.configuration
|
||||||
|
// (lib.genAttrs secrets (k: "env/${lib.toUpper "${provider}_${k}"}"));
|
||||||
|
config = {
|
||||||
|
file_extension = "";
|
||||||
|
class = "octodns_bind.ZoneFileSource";
|
||||||
|
directory = pkgs.linkFarm "zones" {
|
||||||
|
"${domain}" = dns.util.writeZone domain (
|
||||||
|
# lib.recursiveUpdate
|
||||||
|
{
|
||||||
|
# fake SOA record to satisfy octodns
|
||||||
|
SOA = {
|
||||||
|
serial = 1970010100;
|
||||||
|
nameServer = "ns1.example.com";
|
||||||
|
adminEmail = "admin@example.com";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// zone
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
validate = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default =
|
||||||
|
let
|
||||||
|
inherit (octodns-zone.config)
|
||||||
|
packages
|
||||||
|
conf
|
||||||
|
provider
|
||||||
|
secretFiles
|
||||||
|
;
|
||||||
|
in
|
||||||
|
pkgs.writers.writeBashBin "octodns-validate.sh" (withPackages packages) ''
|
||||||
|
env ${withSecrets (mapKeys (k: lib.toUpper "${provider}_${k}") secretFiles)} \
|
||||||
|
octodns-validate --config ${conf} --all
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sync = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default =
|
||||||
|
let
|
||||||
|
inherit (octodns-zone.config)
|
||||||
|
packages
|
||||||
|
conf
|
||||||
|
provider
|
||||||
|
secretFiles
|
||||||
|
;
|
||||||
|
in
|
||||||
|
pkgs.writers.writeBashBin "octodns-sync.sh" (withPackages packages) ''
|
||||||
|
env ${withSecrets (mapKeys (k: lib.toUpper "${provider}_${k}") secretFiles)} \
|
||||||
|
octodns-sync --config ${conf} --doit
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,9 @@ rec {
|
||||||
|
|
||||||
withEnv = environment: toString (lib.mapAttrsToList (k: v: "${k}=\"${toBash v}\"") environment);
|
withEnv = environment: toString (lib.mapAttrsToList (k: v: "${k}=\"${toBash v}\"") environment);
|
||||||
|
|
||||||
|
withSecrets =
|
||||||
|
environment: toString (lib.mapAttrsToList (k: v: "${k}=\"$(cat ${v})\"") (filterNull environment));
|
||||||
|
|
||||||
tfApply =
|
tfApply =
|
||||||
{
|
{
|
||||||
directory,
|
directory,
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,19 @@
|
||||||
"url": "https://api.github.com/repos/nix-community/disko/tarball/v1.12.0",
|
"url": "https://api.github.com/repos/nix-community/disko/tarball/v1.12.0",
|
||||||
"hash": "0wbx518d2x54yn4xh98cgm65wvj0gpy6nia6ra7ns4j63hx14fkq"
|
"hash": "0wbx518d2x54yn4xh98cgm65wvj0gpy6nia6ra7ns4j63hx14fkq"
|
||||||
},
|
},
|
||||||
|
"dns.nix": {
|
||||||
|
"type": "Git",
|
||||||
|
"repository": {
|
||||||
|
"type": "GitHub",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "dns.nix"
|
||||||
|
},
|
||||||
|
"branch": "master",
|
||||||
|
"submodules": false,
|
||||||
|
"revision": "f3cb11f642d4fa6224e2b1ddfd2c3ba42e9ffea2",
|
||||||
|
"url": "https://github.com/nix-community/dns.nix/archive/f3cb11f642d4fa6224e2b1ddfd2c3ba42e9ffea2.tar.gz",
|
||||||
|
"hash": "1qjdgrn4sxa9n9wws4jg75dy1vnw761dglja8gdhvj8j2yxc27dd"
|
||||||
|
},
|
||||||
"flake-inputs": {
|
"flake-inputs": {
|
||||||
"type": "GitRelease",
|
"type": "GitRelease",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue