diff --git a/.forgejo/workflows/nix-flake-check.yaml b/.forgejo/workflows/nix-flake-check.yaml index 8e6817e4..4fa9b827 100644 --- a/.forgejo/workflows/nix-flake-check.yaml +++ b/.forgejo/workflows/nix-flake-check.yaml @@ -12,7 +12,7 @@ on: jobs: _checks: - needs: ["deployment-basic","deployment-cli","deployment-model-nixops4","deployment-model-ssh","deployment-model-tf","deployment-model-tf-proxmox","deployment-panel","nixops-deployment-providers-default","nixops-deployment-providers-fedi201","nixops-deployment-providers-forgejo-ci","nixops-deployment-providers-test","nixops-deployment-providers-vm02116","nixops-deployment-providers-vm02187","nixosConfigurations-fedi201","nixosConfigurations-forgejo-ci","nixosConfigurations-test01","nixosConfigurations-test02","nixosConfigurations-test03","nixosConfigurations-test04","nixosConfigurations-test05","nixosConfigurations-test06","nixosConfigurations-test11","nixosConfigurations-test12","nixosConfigurations-test13","nixosConfigurations-test14","nixosConfigurations-vm02116","nixosConfigurations-vm02187","panel","pre-commit","proxmox-basic","test-mastodon-service","test-peertube-service","vmOptions-fedi201","vmOptions-test01","vmOptions-test02","vmOptions-test03","vmOptions-test04","vmOptions-test05","vmOptions-test06","vmOptions-test11","vmOptions-test12","vmOptions-test13","vmOptions-test14"] + needs: ["deployment-basic","deployment-cli","deployment-model-nixops4","deployment-model-ssh","deployment-model-tf","deployment-model-tf-proxmox","deployment-panel","netbox-ips","nixops-deployment-providers-default","nixops-deployment-providers-fedi201","nixops-deployment-providers-forgejo-ci","nixops-deployment-providers-test","nixops-deployment-providers-vm02116","nixops-deployment-providers-vm02187","nixosConfigurations-fedi201","nixosConfigurations-forgejo-ci","nixosConfigurations-test01","nixosConfigurations-test02","nixosConfigurations-test03","nixosConfigurations-test04","nixosConfigurations-test05","nixosConfigurations-test06","nixosConfigurations-test11","nixosConfigurations-test12","nixosConfigurations-test13","nixosConfigurations-test14","nixosConfigurations-vm02116","nixosConfigurations-vm02187","panel","pre-commit","proxmox-basic","test-mastodon-service","test-peertube-service","vmOptions-fedi201","vmOptions-test01","vmOptions-test02","vmOptions-test03","vmOptions-test04","vmOptions-test05","vmOptions-test06","vmOptions-test11","vmOptions-test12","vmOptions-test13","vmOptions-test14"] runs-on: native steps: - run: true @@ -65,6 +65,12 @@ jobs: - uses: actions/checkout@v4 - run: nix build .#checks.x86_64-linux.deployment-panel -vL + netbox-ips: + runs-on: native + steps: + - uses: actions/checkout@v4 + - run: nix build .#checks.x86_64-linux.netbox-ips -vL + nixops-deployment-providers-default: runs-on: native steps: diff --git a/deployment/check/data-model-tf-proxmox/nixosTest.nix b/deployment/check/data-model-tf-proxmox/nixosTest.nix index 9074c996..dd5c25a2 100644 --- a/deployment/check/data-model-tf-proxmox/nixosTest.nix +++ b/deployment/check/data-model-tf-proxmox/nixosTest.nix @@ -43,52 +43,13 @@ let vmDatastoreId = "local"; cdDatastoreId = "local"; ipv4Gateway = "192.168.10.1"; - ipv4Address = null; + ipv4Address = "192.168.10.236/24"; ipv6Gateway = ""; ipv6Address = ""; # dynamically get the id from the template upload step templateId = null; }; }).default.tf-proxmox-vm; - inherit - (pkgs.callPackage ../../run { - inherit sources system; - }) - tf-netbox-store-ips - tf-netbox-get-ip - ; - netbox-store-ips = - (lib.evalModules { - modules = [ - { - options = { inherit tf-netbox-store-ips; }; - config.tf-netbox-store-ips = { - httpBackend = tfBackend "proxmox-test/store-ips"; - startAddress = "192.168.10.236/24"; - endAddress = "192.168.10.240/24"; - }; - } - ]; - }).config.tf-netbox-store-ips; - netbox-get-ip = - (lib.evalModules { - modules = [ - { - options = { inherit tf-netbox-get-ip; }; - config.tf-netbox-get-ip = { - httpBackend = tfBackend "proxmox-test/get-ip"; - }; - } - ]; - }).config.tf-netbox-get-ip; - netboxUser = "netbox"; - netboxPassword = "netbox"; - changePassword = pkgs.writeText "change-password.py" '' - from users.models import User - u = User.objects.get(username='${netboxUser}') - u.set_password('${netboxPassword}') - u.save() - ''; in { _class = "nixosTest"; @@ -164,11 +125,8 @@ in pkgs.pve-manager pkgs.openssl pkgs.jq - pkgs.netbox (pkgs.callPackage ../../run/tf-proxmox-template/tf.nix { }) (pkgs.callPackage ../../run/tf-proxmox-vm/tf.nix { }) - (pkgs.callPackage ../../run/tf-netbox-store-ips/tf.nix { }) - (pkgs.callPackage ../../run/tf-netbox-get-ip/tf.nix { }) ]; # needed only when building from deployer @@ -200,35 +158,9 @@ in KMS_KEY = "tsjxw9NjKUBUlzbTnD7orqIAdEmpGYRARvxD51jtY+o="; }; }; - services.netbox = { - enable = true; - # FIXME randomly generate this - secretKeyFile = pkgs.writeText "netbox-secret" "634da8232803a8155a58584d3186127000207e079d600fc10a890e5cd59c2f4b8f0e0654005944d2ce87f5be9c22ceebec66"; - # listenAddress = "[::1]"; - port = 8001; - }; }; extraTestScript = '' - deployer.succeed(""" - netbox-manage createsuperuser --noinput --user "${netboxUser}" --email "test@domain.tld" >&2 - cat '${changePassword}' | netbox-manage shell - """) - # FIXME use ldap - netbox_token = deployer.succeed(""" - curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" http://localhost:8001/api/users/tokens/provision/ --data '{"username":"${netboxUser}","password":"${netboxPassword}"}' | jq -r .key - """).strip() - ip_range_id = deployer.succeed(f""" - export NETBOX_SERVER_URL="localhost:8001" - export NETBOX_API_TOKEN="{netbox_token}" - ${lib.getExe netbox-store-ips.run} | jq -r '.id.value' - """).strip() - ipv4 = deployer.succeed(f""" - export NETBOX_SERVER_URL="localhost:8001" - export NETBOX_API_TOKEN="{netbox_token}" - export TF_VAR_ip_range_id={ip_range_id} - ${lib.getExe netbox-get-ip.run} | jq -r '.ipv4.value' - """).strip() pve.wait_for_unit("pveproxy.service") assert "running" in pve.succeed("pveproxy status") pve.succeed("mkdir -p /run/pve") @@ -291,7 +223,6 @@ in export PROXMOX_VE_INSECURE="true" export SSL_CERT_FILE=/tmp/pve-ca-bundle.crt export PROXMOX_VE_API_TOKEN="root@pam!template={template_token}" - export TF_VAR_ipv4_address="{ipv4}" ${lib.getExe template-deployment.run} | jq -r '.id.value' """).strip() @@ -302,7 +233,6 @@ in export SSL_CERT_FILE=/tmp/pve-ca-bundle.crt export PROXMOX_VE_API_TOKEN="root@pam!vm={vm_token}" export TF_VAR_template_id="{template_id}" - export TF_VAR_ipv4_address="{ipv4}" ${lib.getExe vm-deployment.run} | jq -r '.ipv4.value[0]' """ diff --git a/deployment/check/netbox-ips/constants.nix b/deployment/check/netbox-ips/constants.nix new file mode 100644 index 00000000..8242c6fb --- /dev/null +++ b/deployment/check/netbox-ips/constants.nix @@ -0,0 +1,10 @@ +{ + targetMachines = [ + "node" + ]; + pathToRoot = builtins.path { + path = ../../..; + name = "root"; + }; + pathFromRoot = "/deployment/check/netbox-ips"; +} diff --git a/deployment/check/netbox-ips/default.nix b/deployment/check/netbox-ips/default.nix new file mode 100644 index 00000000..9fb576a6 --- /dev/null +++ b/deployment/check/netbox-ips/default.nix @@ -0,0 +1,55 @@ +{ + inputs, + sources, + system, +}: + +let + overlay = _: prev: { + terraform-backend = + prev.callPackage "${sources.nixpkgs-unstable}/pkgs/by-name/te/terraform-backend/package.nix" + { }; + # FIXME centralize overlays + # XXX using recent revision for https://github.com/NixOS/nixpkgs/pull/447849 + opentofu = + (pkgs.callPackage "${sources.nixpkgs-unstable}/pkgs/by-name/op/opentofu/package.nix" { }) + .overrideAttrs + (old: rec { + patches = (old.patches or [ ]) ++ [ + # TF with back-end poses a problem for nix: initialization involves both + # mutation (nix: only inside build) and a network call (nix: not inside build) + ../../check/data-model-tf/02-opentofu-sandboxed-init.patch + ]; + # versions > 1.9.0 need go 1.24+ + version = "1.9.0"; + src = pkgs.fetchFromGitHub { + owner = "opentofu"; + repo = "opentofu"; + tag = "v${version}"; + hash = "sha256-e0ZzbQdex0DD7Bj9WpcVI5roh0cMbJuNr5nsSVaOSu4="; + }; + vendorHash = "sha256-fMTbLSeW+pw6GK8/JLZzG2ER90ss2g1FSDX5+f292do="; + }); + }; + pkgs = import sources.nixpkgs { + inherit system; + overlays = [ overlay ]; + }; +in +pkgs.testers.runNixOSTest { + imports = [ + ../../data-model.nix + ../../function.nix + ../common/nixosTest.nix + ./nixosTest.nix + ]; + _module.args = { + inherit inputs sources; + modulesPath = "${builtins.toString pkgs.path}/nixos/modules"; + }; + inherit (import ./constants.nix) + targetMachines + pathToRoot + pathFromRoot + ; +} diff --git a/deployment/check/netbox-ips/nixosTest.nix b/deployment/check/netbox-ips/nixosTest.nix new file mode 100644 index 00000000..069f225e --- /dev/null +++ b/deployment/check/netbox-ips/nixosTest.nix @@ -0,0 +1,111 @@ +{ + lib, + pkgs, + sources, + ... +}: +let + inherit (pkgs) system; + backendPort = builtins.toString 8080; + tfBackend = fragment: { + address = "http://localhost:${backendPort}/state/${fragment}"; + }; + inherit + (pkgs.callPackage ../../run { + inherit sources system; + }) + tf-netbox-store-ips + tf-netbox-get-ip + ; + netbox-store-ips = + (lib.evalModules { + modules = [ + { + options = { inherit tf-netbox-store-ips; }; + config.tf-netbox-store-ips = { + httpBackend = tfBackend "proxmox-test/store-ips"; + startAddress = "192.168.10.236/24"; + endAddress = "192.168.10.240/24"; + }; + } + ]; + }).config.tf-netbox-store-ips; + netbox-get-ip = + (lib.evalModules { + modules = [ + { + options = { inherit tf-netbox-get-ip; }; + config.tf-netbox-get-ip = { + httpBackend = tfBackend "proxmox-test/get-ip"; + }; + } + ]; + }).config.tf-netbox-get-ip; + netboxUser = "netbox"; + netboxPassword = "netbox"; + changePassword = pkgs.writeText "change-password.py" '' + from users.models import User + u = User.objects.get(username='${netboxUser}') + u.set_password('${netboxPassword}') + u.save() + ''; +in +{ + _class = "nixosTest"; + name = "netbox-ips"; + + nodes.deployer = + { ... }: + { + imports = [ + ../../modules/terraform-backend + ]; + + nix.nixPath = [ + (lib.concatStringsSep ":" (lib.mapAttrsToList (k: v: k + "=" + v) sources)) + ]; + + environment.systemPackages = [ + pkgs.jq + (pkgs.callPackage ../../run/tf-netbox-store-ips/tf.nix { }) + (pkgs.callPackage ../../run/tf-netbox-get-ip/tf.nix { }) + ]; + + services.terraform-backend = { + enable = true; + settings = { + LISTEN_ADDR = ":${backendPort}"; + # FIXME randomly generate this + KMS_KEY = "tsjxw9NjKUBUlzbTnD7orqIAdEmpGYRARvxD51jtY+o="; + }; + }; + services.netbox = { + enable = true; + # FIXME randomly generate this + secretKeyFile = pkgs.writeText "netbox-secret" "634da8232803a8155a58584d3186127000207e079d600fc10a890e5cd59c2f4b8f0e0654005944d2ce87f5be9c22ceebec66"; + port = 8001; + }; + }; + + extraTestScript = '' + deployer.succeed(""" + netbox-manage createsuperuser --noinput --user "${netboxUser}" --email "test@domain.tld" >&2 + cat '${changePassword}' | netbox-manage shell + """) + netbox_token = deployer.succeed(""" + curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" http://localhost:8001/api/users/tokens/provision/ --data '{"username":"${netboxUser}","password":"${netboxPassword}"}' | jq -r .key + """).strip() + ip_range_id = deployer.succeed(f""" + export NETBOX_SERVER_URL="localhost:8001" + export NETBOX_API_TOKEN="{netbox_token}" + ${lib.getExe netbox-store-ips.run} | jq -r '.id.value' + """).strip() + ipv4 = deployer.succeed(f""" + export NETBOX_SERVER_URL="localhost:8001" + export NETBOX_API_TOKEN="{netbox_token}" + export TF_VAR_ip_range_id={ip_range_id} + ${lib.getExe netbox-get-ip.run} | jq -r '.ipv4.value' + """).strip() + assert ipv4 == "192.168.10.236/24" + ''; +} diff --git a/deployment/flake-part.nix b/deployment/flake-part.nix index 002e71c8..f9272a19 100644 --- a/deployment/flake-part.nix +++ b/deployment/flake-part.nix @@ -44,6 +44,10 @@ deployment-model-tf-proxmox = import ./check/data-model-tf-proxmox { inherit inputs sources system; }; + + netbox-ips = import ./check/netbox-ips { + inherit inputs sources system; + }; }; }; }