Fediversity/deployment/check/data-model-tf-proxmox/nixosTest.nix

250 lines
7.2 KiB
Nix

{
lib,
pkgs,
modulesPath,
sources,
...
}:
let
inherit (pkgs) system;
backendPort = builtins.toString 8080;
tfBackend = fragment: {
address = "http://localhost:${backendPort}/state/${fragment}";
};
template-deployment =
(import ./setups/template.nix {
inherit sources system modulesPath;
config = {
httpBackend = tfBackend "proxmox-test/upload";
nodeName = "pve";
targetSystem = system;
node-name = "pve";
imageDatastoreId = "local";
};
}).default.tf-proxmox-template;
vm-deployment =
(import ./setups/vm.nix {
inherit sources system modulesPath;
config = {
httpBackend = tfBackend "proxmox-test/nixos";
inherit (import ./constants.nix) pathToRoot;
nodeName = "pve";
targetSystem = system;
# for the test use the proxmox host as jump host,
# as we have no static IPs the deployer can reach the deployed VM on
sshOpts = [
"ProxyCommand=ssh -W %h:%p pve"
];
key-file = "/root/.ssh/id_ed25519";
node-name = "pve";
bridge = "br0";
vlanId = 0;
imageDatastoreId = "local";
vmDatastoreId = "local";
cdDatastoreId = "local";
ipv4Gateway = "192.168.10.1";
ipv4Address = "192.168.10.236/24";
ipv6Gateway = "";
ipv6Address = "";
# dynamically get the id from the template upload step
templateId = null;
};
}).default.tf-proxmox-vm;
in
{
_class = "nixosTest";
name = "deployment-model";
sourceFileset = lib.fileset.unions [
../../run/tf-proxmox-vm/await-ssh.sh
];
nodes.pve =
{ sources, ... }:
{
imports = [
"${sources.proxmox-nixos}/modules/proxmox-ve"
];
environment.systemPackages = [
pkgs.jq
pkgs.qemu
];
networking.firewall.enable = false;
networking.vlans = {
vlan0 = {
id = 0;
interface = "eth0";
};
};
networking.useDHCP = false;
networking = {
bridges.br0.interfaces = [ ];
interfaces.br0.ipv4.addresses = [
{
address = "192.168.10.1";
prefixLength = 24;
}
];
nat = {
enable = true;
internalInterfaces = [ "br0" ];
};
};
boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
users.users.root = {
password = "mytestpw";
hashedPasswordFile = lib.mkForce null;
};
# https://github.com/SaumonNet/proxmox-nixos/blob/main/modules/proxmox-ve/default.nix
services.proxmox-ve = {
enable = true;
ipAddress = "192.168.1.1";
};
virtualisation = {
diskSize = 5 * 1024;
memorySize = 3 * 1024;
};
};
nodes.deployer =
{ ... }:
{
imports = [
../../modules/terraform-backend
];
networking.firewall.enable = false;
nix.nixPath = [
(lib.concatStringsSep ":" (lib.mapAttrsToList (k: v: k + "=" + v) sources))
];
environment.systemPackages = [
vm-deployment.run
template-deployment.run
pkgs.pve-manager
pkgs.openssl
pkgs.jq
(pkgs.callPackage ../../run/tf-proxmox-template/tf.nix { })
(pkgs.callPackage ../../run/tf-proxmox-vm/tf.nix { })
];
# needed only when building from deployer
system.extraDependenciesFromModule =
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
hello
];
};
system.extraDependencies = [
sources.disko
pkgs.ubootQemuX86
pkgs.ubootQemuX86.inputDerivation
pkgs.pve-qemu
pkgs.pve-qemu.inputDerivation
pkgs.gnu-config
pkgs.byacc
pkgs.stdenv
pkgs.stdenvNoCC
sources.nixpkgs
pkgs.vte
];
services.terraform-backend = {
enable = true;
settings = {
LISTEN_ADDR = ":${backendPort}";
# FIXME randomly generate this
KMS_KEY = "tsjxw9NjKUBUlzbTnD7orqIAdEmpGYRARvxD51jtY+o=";
};
};
};
extraTestScript = ''
pve.wait_for_unit("pveproxy.service")
assert "running" in pve.succeed("pveproxy status")
pve.succeed("mkdir -p /run/pve")
assert "Proxmox" in pve.succeed("curl -s -i -k https://localhost:8006")
cert = pve.succeed("cat /etc/pve/pve-root-ca.pem").strip()
pve.succeed("pvesh create /pools --poolid Fediversity")
# allow upload of `import` (template) files
pve.succeed("""
pvesh set /storage/local --content "vztmpl,rootdir,backup,snippets,import,iso,images" 1>/dev/null
""")
template_token = pve.succeed("""
pvesh create /access/users/root@pam/token/template --output-format json | jq -r .value
pvesh set /access/acl --path "/" --token "root@pam!template" --roles "PVEDatastoreAdmin"
""").strip()
vm_token = pve.succeed("""
pvesh create /access/users/root@pam/token/vm --output-format json | jq -r .value
pvesh set /access/acl --path "/" --token "root@pam!vm" --roles "PVEVMAdmin PVEDatastoreAdmin PVESDNUser"
""").strip()
# skip indent for EOF
deployer.succeed(f"""
cat > /etc/ssl/certs/pve-root-ca.pem <<EOF
{cert}
EOF
mkdir -p /root/.ssh
cat > /root/.ssh/id_ed25519 <<EOF
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBWbJXVjBLGo2MrI2LBKTbzDozuA/C9taU630EtU/h38gAAAJDAOy8uwDsv
LgAAAAtzc2gtZWQyNTUxOQAAACBWbJXVjBLGo2MrI2LBKTbzDozuA/C9taU630EtU/h38g
AAAECcF8xjLavgWePoVx45Euewsh6Kw07L6QDDy3WXFCn4bFZsldWMEsajYysjYsEpNvMO
jO4D8L21pTrfQS1T+HfyAAAAC2tpYXJhQG5peG9zAQI=
-----END OPENSSH PRIVATE KEY-----
EOF
chmod 600 /root/.ssh/id_ed25519
""")
deployer.succeed("""
set -e
cd /etc/ssl/certs
{ cat ca-bundle.crt
cat ca-certificates.crt
cat pve-root-ca.pem
} > new-ca-bundle.crt
rm ca-bundle.crt ca-certificates.crt
mv new-ca-bundle.crt ca-bundle.crt
ln -s ca-bundle.crt ca-certificates.crt
openssl verify -CApath /etc/ssl/certs ./pve-root-ca.pem
""")
with subtest("Deploy the template"):
template_id = deployer.succeed(f"""
ssh -o BatchMode=yes -o StrictHostKeyChecking=no pve "true"
export PROXMOX_VE_INSECURE="true"
export SSL_CERT_FILE=/tmp/pve-ca-bundle.crt
export PROXMOX_VE_API_TOKEN="root@pam!template={template_token}"
${lib.getExe template-deployment.run} | jq -r '.id.value'
""").strip()
deploy = f"""
set -e
ssh -o BatchMode=yes -o StrictHostKeyChecking=no pve "true"
export PROXMOX_VE_INSECURE="true"
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}"
${lib.getExe vm-deployment.run} | jq -r '.ipv4.value[0]'
"""
with subtest("Run the deployment"):
ip = deployer.succeed(deploy).strip()
with subtest("Verify package"):
deployer.succeed(f"""
ssh -i "/root/.ssh/id_ed25519" -o StrictHostKeyChecking=no -o BatchMode=yes -J pve root@{ip} su - operator -c hello >&2
""")
with subtest("No-op update"):
deployer.succeed(deploy, timeout=120)
'';
}