From 1945038c9004ffe551fd2c5669ff27417209496b Mon Sep 17 00:00:00 2001 From: Kaare Hoff Skovgaard Date: Tue, 8 Jul 2025 16:08:37 +0200 Subject: [PATCH] First PoC on provisioning instance end to end on openstack --- flake.lock | 178 +++++++++++++++++- flake.nix | 10 + .../khs@test.kaareskovgaard.net/default.nix | 4 + nix/lib/disko-root-lvm-bios/default.nix | 53 ++++++ .../default.nix | 2 +- nix/modules/nixos/hetzner/default.nix | 2 +- .../nixos/khs-openstack-instance/default.nix | 30 ++- nix/modules/nixos/openstack/default.nix | 5 +- nix/modules/nixos/provisioning/default.nix | 5 + .../nixos/services/openssh/default.nix | 20 ++ nix/modules/nixos/sshd/default.nix | 11 -- nix/modules/terranix/openstack/output.nix | 5 + nix/modules/terranix/unifi/default.nix | 58 +++++- nix/packages/bw-opentofu/secrets-map.nix | 6 +- nix/packages/create-instance/default.nix | 9 + nix/packages/destroy-instance/default.nix | 9 + nix/packages/nixos-install/default.nix | 27 +++ .../terraform-provider-unifi/default.nix | 2 +- nix/packages/update-instance/default.nix | 10 + .../default.nix | 54 ++++++ nix/profiles/hetzner-server.nix | 2 +- nix/profiles/khs-openstack-server.nix | 2 +- .../test.kaareskovgaard.net/default.nix | 7 + rust/program/openbao-helper/src/main.rs | 12 +- 24 files changed, 479 insertions(+), 44 deletions(-) create mode 100644 nix/homes/x86_64-linux/khs@test.kaareskovgaard.net/default.nix create mode 100644 nix/lib/disko-root-lvm-bios/default.nix rename nix/lib/{disko-root-lvm => disko-root-lvm-uefi}/default.nix (98%) create mode 100644 nix/modules/nixos/services/openssh/default.nix delete mode 100644 nix/modules/nixos/sshd/default.nix create mode 100644 nix/packages/create-instance/default.nix create mode 100644 nix/packages/destroy-instance/default.nix create mode 100644 nix/packages/nixos-install/default.nix create mode 100644 nix/packages/update-instance/default.nix create mode 100644 nix/packages/upload-openstack-base-debian-image/default.nix diff --git a/flake.lock b/flake.lock index 813e058..7eecfc5 100644 --- a/flake.lock +++ b/flake.lock @@ -83,6 +83,28 @@ "type": "github" } }, + "disko_2": { + "inputs": { + "nixpkgs": [ + "nixos-anywhere", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1748225455, + "narHash": "sha256-AzlJCKaM4wbEyEpV3I/PUq5mHnib2ryEy32c+qfj6xk=", + "owner": "nix-community", + "repo": "disko", + "rev": "a894f2811e1ee8d10c50560551e50d6ab3c392ba", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "disko", + "type": "github" + } + }, "flake-base": { "inputs": { "nixpkgs": [ @@ -122,6 +144,27 @@ } }, "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixos-anywhere", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { "inputs": { "nixpkgs-lib": [ "terranix", @@ -209,6 +252,116 @@ "type": "github" } }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1751810233, + "narHash": "sha256-kllkNbIqQi3VplgTMeGzuh1t8Gk8TauvkTRt93Km+tQ=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "9b0873b46c9f9e4b7aa01eb634952c206af53068", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-25.05", + "repo": "home-manager", + "type": "github" + } + }, + "nix-vm-test": { + "inputs": { + "nixpkgs": [ + "nixos-anywhere", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1748765518, + "narHash": "sha256-vftOR+7zwnMWl5UpG32GL1VBeNGTDZZT0hv+2uNuBGw=", + "owner": "Mic92", + "repo": "nix-vm-test", + "rev": "d6642fbaf42fc98883d84bab66cd0ec720d9dd0c", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "nix-vm-test", + "type": "github" + } + }, + "nixos-anywhere": { + "inputs": { + "disko": "disko_2", + "flake-parts": "flake-parts", + "nix-vm-test": "nix-vm-test", + "nixos-images": "nixos-images", + "nixos-stable": "nixos-stable", + "nixpkgs": [ + "nixpkgs" + ], + "treefmt-nix": "treefmt-nix_2" + }, + "locked": { + "lastModified": 1749105224, + "narHash": "sha256-hVTCvMnwywxQ6rGgO7ytBiSpVuLOHNgm3w3vE8UNaQY=", + "owner": "nix-community", + "repo": "nixos-anywhere", + "rev": "55fc48f9677822393cd9585b6742e1194accf365", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "1.11.0", + "repo": "nixos-anywhere", + "type": "github" + } + }, + "nixos-images": { + "inputs": { + "nixos-stable": [ + "nixos-anywhere", + "nixos-stable" + ], + "nixos-unstable": [ + "nixos-anywhere", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1748481078, + "narHash": "sha256-jwKRF2EDzlv0VBF8pImPFT7DAJma7stDun25utHtwBw=", + "owner": "nix-community", + "repo": "nixos-images", + "rev": "191a461dc38313ff41bd3df4b82e49f74a56560d", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-images", + "type": "github" + } + }, + "nixos-stable": { + "locked": { + "lastModified": 1748437600, + "narHash": "sha256-hYKMs3ilp09anGO7xzfGs3JqEgUqFMnZ8GMAqI6/k04=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7282cb574e0607e65224d33be8241eae7cfe0979", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1751582995, @@ -246,6 +399,8 @@ "crane": "crane", "disko": "disko", "flake-base": "flake-base", + "home-manager": "home-manager", + "nixos-anywhere": "nixos-anywhere", "nixpkgs": "nixpkgs", "rust-overlay": "rust-overlay", "terranix": "terranix", @@ -327,7 +482,7 @@ }, "terranix": { "inputs": { - "flake-parts": "flake-parts", + "flake-parts": "flake-parts_2", "nixpkgs": [ "nixpkgs" ], @@ -427,6 +582,27 @@ "repo": "treefmt-nix", "type": "github" } + }, + "treefmt-nix_2": { + "inputs": { + "nixpkgs": [ + "nixos-anywhere", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1748243702, + "narHash": "sha256-9YzfeN8CB6SzNPyPm2XjRRqSixDopTapaRsnTpXUEY8=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "1f3f7b784643d488ba4bf315638b2b0a4c5fb007", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index adc20a1..b0f6305 100644 --- a/flake.nix +++ b/flake.nix @@ -15,6 +15,10 @@ url = "github:terranix/terranix"; inputs.nixpkgs.follows = "nixpkgs"; }; + home-manager = { + url = "github:nix-community/home-manager/release-25.05"; + inputs.nixpkgs.follows = "nixpkgs"; + }; terranix-hcloud = { url = "github:terranix/terranix-hcloud"; inputs.nixpkgs.follows = "nixpkgs"; @@ -30,6 +34,12 @@ nixpkgs.follows = "nixpkgs"; }; }; + nixos-anywhere = { + url = "github:nix-community/nixos-anywhere/1.11.0"; + inputs = { + nixpkgs.follows = "nixpkgs"; + }; + }; }; outputs = diff --git a/nix/homes/x86_64-linux/khs@test.kaareskovgaard.net/default.nix b/nix/homes/x86_64-linux/khs@test.kaareskovgaard.net/default.nix new file mode 100644 index 0000000..740142d --- /dev/null +++ b/nix/homes/x86_64-linux/khs@test.kaareskovgaard.net/default.nix @@ -0,0 +1,4 @@ +{ + snowfallorg.user.name = "khs"; + home.stateVersion = "25.05"; +} diff --git a/nix/lib/disko-root-lvm-bios/default.nix b/nix/lib/disko-root-lvm-bios/default.nix new file mode 100644 index 0000000..591e4b2 --- /dev/null +++ b/nix/lib/disko-root-lvm-bios/default.nix @@ -0,0 +1,53 @@ +{ ... }: +{ + disko-root-lvm-bios = + { + diskName, + device, + mbrSize ? "1M", + bootPartName ? "mbr", + rootPartName ? "primary", + volumeGroupName ? "mainpool", + rootLvName ? "root", + }: + { + devices.disk = { + "${diskName}" = { + inherit device; + type = "disk"; + content = { + type = "gpt"; + partitions = { + "${bootPartName}" = { + size = mbrSize; + type = "EF02"; + }; + "${rootPartName}" = { + size = "100%"; + content = { + type = "lvm_pv"; + vg = volumeGroupName; + }; + }; + }; + }; + }; + }; + devices.lvm_vg = { + "${volumeGroupName}" = { + type = "lvm_vg"; + lvs = { + "${rootLvName}" = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + mountOptions = [ "defaults" ]; + }; + }; + }; + }; + }; + }; +} diff --git a/nix/lib/disko-root-lvm/default.nix b/nix/lib/disko-root-lvm-uefi/default.nix similarity index 98% rename from nix/lib/disko-root-lvm/default.nix rename to nix/lib/disko-root-lvm-uefi/default.nix index 8891d9f..7ed7966 100644 --- a/nix/lib/disko-root-lvm/default.nix +++ b/nix/lib/disko-root-lvm-uefi/default.nix @@ -1,6 +1,6 @@ { ... }: { - disko-root-lvm = + disko-root-lvm-uefi = { diskName, device, diff --git a/nix/modules/nixos/hetzner/default.nix b/nix/modules/nixos/hetzner/default.nix index e2f033c..8b4386d 100644 --- a/nix/modules/nixos/hetzner/default.nix +++ b/nix/modules/nixos/hetzner/default.nix @@ -24,7 +24,7 @@ in }; config = lib.mkIf cfg.enable { - disko = lib.khscodes.disko-root-lvm { + disko = lib.khscodes.disko-root-lvm-uefi { device = "/dev/sda"; diskName = cfg.diskName; }; diff --git a/nix/modules/nixos/khs-openstack-instance/default.nix b/nix/modules/nixos/khs-openstack-instance/default.nix index ee58e5e..97ba09b 100644 --- a/nix/modules/nixos/khs-openstack-instance/default.nix +++ b/nix/modules/nixos/khs-openstack-instance/default.nix @@ -184,11 +184,18 @@ in khscodes.openstack.compute_instance.compute = { inherit tags; name = fqdn; - initial_image = "Ubuntu-22.04"; + initial_image = "debian-12"; flavor = cfg.flavor; ssh_public_key = cfg.ssh_key; firewall_rules = firewallRules; }; + khscodes.unifi.enable = true; + khscodes.unifi.static_route.compute = { + name = fqdn; + network = config.khscodes.openstack.output.compute_instance.compute.ipv6_cidr; + distance = 1; + next_hop = config.khscodes.openstack.output.compute_instance.compute.ipv6_external_gateway; + }; khscodes.cloudflare = { enable = true; dns = { @@ -230,15 +237,18 @@ in } ]; - khscodes.provisioning.pre = { - modules = modules; - secretsSource = cfg.secretsSource; - endpoints = [ - "aws" - "cloudflare" - "openstack" - "unifi" - ]; + khscodes.provisioning = { + pre = { + modules = modules; + secretsSource = cfg.secretsSource; + endpoints = [ + "aws" + "cloudflare" + "openstack" + "unifi" + ]; + }; + preImageUsername = "debian"; }; } ); diff --git a/nix/modules/nixos/openstack/default.nix b/nix/modules/nixos/openstack/default.nix index 46bc74a..d34d9f5 100644 --- a/nix/modules/nixos/openstack/default.nix +++ b/nix/modules/nixos/openstack/default.nix @@ -16,11 +16,12 @@ in }; }; config = lib.mkIf cfg.enable { - disko = lib.khscodes.disko-root-lvm { + disko = lib.khscodes.disko-root-lvm-bios { device = "/dev/sda"; diskName = cfg.diskName; }; - khscodes.systemd-boot.enable = lib.mkDefault true; + boot.loader.grub.efiSupport = false; + boot.loader.timeout = 1; khscodes.qemu-guest.enable = true; }; } diff --git a/nix/modules/nixos/provisioning/default.nix b/nix/modules/nixos/provisioning/default.nix index c76cb11..ef3a437 100644 --- a/nix/modules/nixos/provisioning/default.nix +++ b/nix/modules/nixos/provisioning/default.nix @@ -44,6 +44,11 @@ in type = lib.types.nullOr lib.types.path; description = "The generated config for the pre provisioning, if any was specified"; }; + preImageUsername = lib.mkOption { + type = lib.types.str; + description = "The username for the image being deployed before being swapped for NixOS"; + default = "root"; + }; postConfig = lib.mkOption { type = lib.types.nullOr lib.types.path; description = "The generated config for the post provisioning, if any was specified"; diff --git a/nix/modules/nixos/services/openssh/default.nix b/nix/modules/nixos/services/openssh/default.nix new file mode 100644 index 0000000..a5090ba --- /dev/null +++ b/nix/modules/nixos/services/openssh/default.nix @@ -0,0 +1,20 @@ +{ config, lib, ... }: +let + cfg = config.khscodes.services.openssh; +in +{ + options.khscodes.services.openssh = { + enable = lib.mkEnableOption "Enables openssh service for the instance"; + }; + + config = lib.mkIf cfg.enable { + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "no"; + KbdInteractiveAuthentication = false; + }; + }; + }; +} diff --git a/nix/modules/nixos/sshd/default.nix b/nix/modules/nixos/sshd/default.nix deleted file mode 100644 index 9dab23e..0000000 --- a/nix/modules/nixos/sshd/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.khscodes.sshd; -in -{ - options.khscodes.sshd.enable = lib.mkEnableOption "Enables sshd for the instance"; - - config = lib.mkIf cfg.enable { - services.sshd.enable = true; - }; -} diff --git a/nix/modules/terranix/openstack/output.nix b/nix/modules/terranix/openstack/output.nix index da8c6a1..4f501b0 100644 --- a/nix/modules/terranix/openstack/output.nix +++ b/nix/modules/terranix/openstack/output.nix @@ -21,6 +21,10 @@ let type = lib.types.str; description = "The IPv6 external gateway for the network. This is useful to eg. create static routes in Unifi"; }; + ipv6_cidr = lib.mkOption { + type = lib.types.str; + description = "IPv6 cidr"; + }; }; }; in @@ -44,6 +48,7 @@ in ipv4_address = "\${ openstack_networking_floatingip_v2.${sanitizedName}.address }"; ipv6_address = "\${ data.openstack_networking_port_v2.${sanitizedName}.all_fixed_ips[1] }"; ipv6_external_gateway = "\${ [for ip in openstack_networking_router_v2.${sanitizedName}.external_fixed_ip : ip.ip_address if replace(ip.ip_address, \":\", \"\") != ip.ip_address][0] }"; + ipv6_cidr = "\${ openstack_networking_subnet_v2.${sanitizedName}_ip6.cidr }"; } ) ) cfg.compute_instance; diff --git a/nix/modules/terranix/unifi/default.nix b/nix/modules/terranix/unifi/default.nix index d996b61..e7a9f5d 100644 --- a/nix/modules/terranix/unifi/default.nix +++ b/nix/modules/terranix/unifi/default.nix @@ -5,19 +5,65 @@ let modules = [ ./output.nix ]; + unifiStaticRouteModule = khscodesLib.mkSubmodule { + description = "Unifi static route"; + options = { + network = lib.mkOption { + type = lib.types.str; + description = "The network to make a static route for"; + }; + name = lib.mkOption { + type = lib.types.str; + description = "Human friendly name of the static route"; + }; + distance = lib.mkOption { + type = lib.types.int; + description = "The distance of the hop"; + }; + next_hop = lib.mkOption { + type = lib.types.str; + description = "The router that can route the network"; + }; + }; + }; in { options.khscodes.unifi = { enable = lib.mkEnableOption "Enables the unifi provider"; - bucket = { - key = lib.mkOption { - type = lib.types.str; - description = "key for the bucket to use"; - }; + static_route = lib.mkOption { + type = lib.types.attrsOf unifiStaticRouteModule; + description = "Static routes"; }; }; imports = lib.lists.map (m: import m { inherit khscodesLib inputs; }) modules; - config = lib.mkIf cfg.enable { }; + config = lib.mkIf cfg.enable { + terraform.required_providers.unifi = { + source = "paultyng/unifi"; + version = "= 0.42.0-prerelease"; + }; + provider.unifi = { + allow_insecure = true; + }; + + resource.unifi_static_route = lib.mapAttrs' ( + name: value: + let + sanitizedName = khscodesLib.sanitize-terraform-name name; + in + { + name = sanitizedName; + value = { + inherit (value) + network + name + distance + next_hop + ; + type = "nexthop-route"; + }; + } + ) cfg.static_route; + }; } diff --git a/nix/packages/bw-opentofu/secrets-map.nix b/nix/packages/bw-opentofu/secrets-map.nix index 6b613f8..05d18df 100644 --- a/nix/packages/bw-opentofu/secrets-map.nix +++ b/nix/packages/bw-opentofu/secrets-map.nix @@ -17,8 +17,8 @@ TF_VAR_hcloud_api_token = "Terraform API Token"; }; "Ubiquiti" = { - TF_VAR_unifi_username = "Terraform username"; - TF_VAR_unifi_password = "Terraform password"; - TF_VAR_unifi_url = "Terraform URL"; + UNIFI_USERNAME = "Terraform username"; + UNIFI_PASSWORD = "Terraform password"; + UNIFI_API = "Terraform URL"; }; } diff --git a/nix/packages/create-instance/default.nix b/nix/packages/create-instance/default.nix new file mode 100644 index 0000000..b3e1b38 --- /dev/null +++ b/nix/packages/create-instance/default.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: +pkgs.writeShellApplication { + name = "create-instance"; + runtimeInputs = [ pkgs.khscodes.pre-provisioning ]; + text = '' + instance="''${1:-}" + pre-provisioning "$instance" apply + ''; +} diff --git a/nix/packages/destroy-instance/default.nix b/nix/packages/destroy-instance/default.nix new file mode 100644 index 0000000..cdba6bd --- /dev/null +++ b/nix/packages/destroy-instance/default.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: +pkgs.writeShellApplication { + name = "destroy-instance"; + runtimeInputs = [ pkgs.khscodes.pre-provisioning ]; + text = '' + instance="''${1:-}" + pre-provisioning "$instance" destroy + ''; +} diff --git a/nix/packages/nixos-install/default.nix b/nix/packages/nixos-install/default.nix new file mode 100644 index 0000000..692f209 --- /dev/null +++ b/nix/packages/nixos-install/default.nix @@ -0,0 +1,27 @@ +{ + inputs, + pkgs, +}: +pkgs.writeShellApplication { + name = "nixos-install"; + runtimeInputs = [ + pkgs.nix + pkgs.nixos-anywhere + ]; + # TODO: Use secret source and required secrets to set up the correct env variables + text = '' + hostname="$1" + # Build the configuration to ensure it doesn't fail when trying to install it on the host + nix build --no-link '${inputs.self}#nixosConfigurations."'"$hostname"'".config.system.build.toplevel' + # Allow overriding the host to connec tto, this is useful when testing and the DNS entries are stale with older IPs. + host="''${2:-$1}" + baseAttr='${inputs.self}#nixosConfigurations."'"$hostname"'".config.khscodes.provisioning' + config="$(nix build --no-link --print-out-paths "''${baseAttr}.preConfig")" + username="$(nix eval --raw "''${baseAttr}.preImageUsername")" + if [[ "$config" == "null" ]]; then + echo "No preprovisioning needed" + exit 0 + fi + nixos-anywhere --flake "${inputs.self}#$hostname" --target-host "$username@$host" + ''; +} diff --git a/nix/packages/terraform-provider-unifi/default.nix b/nix/packages/terraform-provider-unifi/default.nix index 28fbb45..b2b1e01 100644 --- a/nix/packages/terraform-provider-unifi/default.nix +++ b/nix/packages/terraform-provider-unifi/default.nix @@ -5,7 +5,7 @@ pkgs.terraform-providers.mkProvider { owner = "paultyng"; repo = "terraform-provider-unifi"; rev = "ff9c041b3dc4dc6cf6db4c824a43ed6d3ae408d1"; - version = "v0.42.0-prerelease"; + version = "0.42.0-prerelease"; spdx = "MPL-2.0"; vendorHash = null; } diff --git a/nix/packages/update-instance/default.nix b/nix/packages/update-instance/default.nix new file mode 100644 index 0000000..a18794d --- /dev/null +++ b/nix/packages/update-instance/default.nix @@ -0,0 +1,10 @@ +{ inputs, pkgs, ... }: +pkgs.writeShellApplication { + name = "update-instance"; + runtimeInputs = [ pkgs.nixos-rebuild ]; + text = '' + instance="''${1:-}" + connect_host="''${2:-$1}" + nixos-rebuild switch --flake "${inputs.self}#$instance" --target-host "$connect_host" --build-host "localhost" + ''; +} diff --git a/nix/packages/upload-openstack-base-debian-image/default.nix b/nix/packages/upload-openstack-base-debian-image/default.nix new file mode 100644 index 0000000..42de37b --- /dev/null +++ b/nix/packages/upload-openstack-base-debian-image/default.nix @@ -0,0 +1,54 @@ +{ pkgs, ... }: +let + image = pkgs.fetchurl { + url = "https://cdimage.debian.org/images/cloud/bookworm/20250703-2162/debian-12-genericcloud-amd64-20250703-2162.qcow2"; + hash = "sha256-hfcP4INSfyP90f9DWDqMLXsZa7teXMhePwK6Vyk+dG4="; + }; + script = pkgs.writeShellApplication { + name = "upload-openstack-base-debian-image-wrapped"; + runtimeInputs = [ + pkgs.openstackclient + ]; + text = '' + export OS_AUTH_URL="''${TF_VAR_openstack_auth_url:-}" + # With the addition of Keystone we have standardized on the term **project** + # as the entity that owns the resources. + # export OS_PROJECT_ID=4840ee3bdd0e4285bc46586b8e14aafb + export OS_PROJECT_NAME="khs" + export OS_USER_DOMAIN_NAME="Default" + export OS_PROJECT_DOMAIN_ID="default" + # In addition to the owning entity (tenant), OpenStack stores the entity + # performing the action as the **user**. + export OS_USERNAME="''${TF_VAR_openstack_username:-}" + export OS_PASSWORD="''${TF_VAR_openstack_password:-}" + # If your configuration has multiple regions, we set that information here. + # OS_REGION_NAME is optional and only valid in certain environments. + export OS_REGION_NAME="''${TF_VAR_openstack_region:-}" + export OS_INTERFACE="''${TF_VAR_endpoint_type:-}" + export OS_IDENTITY_API_VERSION=3 + + + openstack image create \ + --container-format bare \ + --disk-format qcow2 \ + --property hw_disk_bus=scsi \ + --property hw_scsi_model=virtio-scsi \ + --property os_type=linux \ + --property os_distro=debian \ + --property os_admin_user=debian \ + --property os_version='12.0.0' \ + --file ${image} \ + debian-12 + ''; + }; +in +pkgs.writeShellApplication { + name = "upload-openstack-base-debian-image"; + runtimeInputs = [ + pkgs.khscodes.openbao-helper + script + ]; + text = '' + openbao-helper wrap-program -e openstack -- upload-openstack-base-debian-image-wrapped + ''; +} diff --git a/nix/profiles/hetzner-server.nix b/nix/profiles/hetzner-server.nix index a0612e8..da9068b 100644 --- a/nix/profiles/hetzner-server.nix +++ b/nix/profiles/hetzner-server.nix @@ -2,6 +2,6 @@ { config.khscodes = { hetzner.enable = true; - sshd.enable = true; + services.openssh.enable = true; }; } diff --git a/nix/profiles/khs-openstack-server.nix b/nix/profiles/khs-openstack-server.nix index acd7575..dafafd2 100644 --- a/nix/profiles/khs-openstack-server.nix +++ b/nix/profiles/khs-openstack-server.nix @@ -2,6 +2,6 @@ { config.khscodes = { openstack.enable = true; - sshd.enable = true; + services.openssh.enable = true; }; } diff --git a/nix/systems/x86_64-linux/test.kaareskovgaard.net/default.nix b/nix/systems/x86_64-linux/test.kaareskovgaard.net/default.nix index 93216be..d27477f 100644 --- a/nix/systems/x86_64-linux/test.kaareskovgaard.net/default.nix +++ b/nix/systems/x86_64-linux/test.kaareskovgaard.net/default.nix @@ -9,6 +9,13 @@ flavor = "m.medium"; secretsSource = "vault"; }; + snowfallorg.users.khs.admin = true; + users.users.khs = { + initialPassword = "test"; + openssh.authorizedKeys.keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqY0FHnWFKfLG2yfgr4qka5sR9CK+EMAhzlHUkaQyWHTKD+G0/vC/fNPyL1VV3Dxc/ajxGuPzVE+mBMoyxazL3EtuCDOVvHJ5CR+MUSEckg/DDwcGHqy6rC8BvVVpTAVL04ByQdwFnpE1qNSBaQLkxaFVdtriGKkgMkc7+UNeYX/bv7yn+APqfP1a3xr6wdkSSdO8x4N2jsSygOIMx10hLyCV4Ueu7Kp8Ww4rGY8j5o7lKJhbgfItBfSOuQHdppHVF/GKYRhdnK6Y2fZVYbhq4KipUtclbZ6O/VYd8/sOO98+LMm7cOX+K35PQjUpYgcoNy5+Sw3CNS/NHn4JvOtTaUEYP7fK6c9LhMULOO3T7Cm6TMdiFjUKHkyG+s2Mu/LXJJoilw571zwuh6chkeitW8+Ht7k0aPV96kNEvTdoXwLhBifVEaChlAsLAzSUjUq+YYCiXVk0VIXCZQWKj8LoVNTmaqDksWwbcT64fw/FpVC0N18WHbKcFUEIW/O4spJMa30CQwf9FeqpoWoaF1oRClCSDPvX0AauCu0JcmRinz1/JmlXljnXWbSfm20/V+WyvktlI0wTD0cdpNuSasT9vS77YfJ8nutcWWZKSkCj4R4uHeCNpDTX5YXzapy7FxpM9ANCXLIvoGX7Yafba2Po+er7SSsUIY1AsnBBr8ZoDVw==" + ]; + }; khscodes.fqdn = "test.kaareskovgaard.net"; system.stateVersion = "25.05"; } diff --git a/rust/program/openbao-helper/src/main.rs b/rust/program/openbao-helper/src/main.rs index 96370c8..9f32de2 100644 --- a/rust/program/openbao-helper/src/main.rs +++ b/rust/program/openbao-helper/src/main.rs @@ -281,9 +281,9 @@ struct UnifiData { impl UnifiData { pub fn read_from_env() -> anyhow::Result { - let username = common::env::read_env("TF_VAR_unifi_username")?; - let password = common::env::read_env("TF_VAR_unifi_password")?; - let url = common::env::read_env("TF_VAR_unifi_url")?; + let username = common::env::read_env("UNIFI_USERNAME")?; + let password = common::env::read_env("UNIFI_PASSWORD")?; + let url = common::env::read_env("UNIFI_API")?; Ok(Self { username, password, @@ -298,9 +298,9 @@ impl UnifiData { pub fn into_env_data(self) -> Vec<(&'static str, String)> { vec![ - ("TF_VAR_unifi_username", self.username), - ("TF_VAR_unifi_password", self.password), - ("TF_VAR_unifi_url", self.url), + ("UNIFI_USERNAME", self.username), + ("UNIFI_PASSWORD", self.password), + ("UNIFI_API", self.url), ] } }