Clean up provisioning code by moving some logic into
All checks were successful
/ terraform-providers (push) Successful in 1m23s
/ systems (push) Successful in 4m8s
/ dev-shell (push) Successful in 47s
/ rust-packages (push) Successful in 52s
/ check (push) Successful in 2m34s

readOnly options
This commit is contained in:
Kaare Hoff Skovgaard 2025-08-04 22:23:47 +02:00
parent eec5e02770
commit 7adc4a20bd
Signed by: khs
GPG key ID: C7D890804F01E9F0
5 changed files with 67 additions and 78 deletions

View file

@ -10,4 +10,15 @@
shorthandOnlyDefinesConfig = true; shorthandOnlyDefinesConfig = true;
modules = lib.toList { inherit options; }; modules = lib.toList { inherit options; };
}; };
mkSubmodule' =
fn:
lib.types.submodule (
{ config, ... }:
let
data = fn { inherit config; };
in
{
inherit (data) options;
}
);
} }

View file

@ -1,19 +1,20 @@
{ {
config,
lib, lib,
inputs, inputs,
pkgs, pkgs,
... ...
}: }:
let let
cfg = config.khscodes.infrastructure.provisioning; terranixConfig =
provisioning = { cfg:
modules = lib.mkOption { if lib.lists.length cfg.modules > 0 then
type = lib.types.listOf lib.types.anything; inputs.terranix.lib.terranixConfiguration {
description = "Modules used to bring up the needed resources"; system = pkgs.hostPlatform.system;
default = [ ]; modules = cfg.modules;
}; extraArgs = { inherit lib inputs; };
}; }
else
null;
usesEndpoint = usesEndpoint =
search: endpoint: config: search: endpoint: config:
if lib.strings.hasInfix search (builtins.readFile config) then [ endpoint ] else [ ]; if lib.strings.hasInfix search (builtins.readFile config) then [ endpoint ] else [ ];
@ -49,31 +50,49 @@ let
[ ] [ ]
else else
lib.lists.flatten (lib.lists.map (c: usesEndpoint c.search c.endpoint config) endpointsMaps); lib.lists.flatten (lib.lists.map (c: usesEndpoint c.search c.endpoint config) endpointsMaps);
preConfig = provisioning = lib.khscodes.mkSubmodule' (
if lib.lists.length cfg.pre.modules > 0 then { config }:
inputs.terranix.lib.terranixConfiguration { {
system = pkgs.hostPlatform.system; description = "Module for handling provisioning";
modules = cfg.pre.modules; options = {
extraArgs = { inherit lib inputs; }; modules = lib.mkOption {
} type = lib.types.listOf lib.types.anything;
else description = "Modules used to bring up the needed resources";
null; default = [ ];
preEndpoints = endpointsUsed preConfig; };
postConfig = config = lib.mkOption {
if lib.lists.length cfg.post.modules > 0 then type = lib.types.nullOr lib.types.path;
inputs.terranix.lib.terranixConfiguration { readOnly = true;
system = pkgs.hostPlatform.system; default = terranixConfig config;
modules = cfg.post.modules; };
extraArgs = { inherit lib inputs; }; endpoints = lib.mkOption {
} type = lib.types.listOf (
else lib.types.enum [
null; "openstack"
postEndpoints = endpointsUsed postConfig; "aws"
"unifi"
"hcloud"
"cloudflare"
"vault"
]
);
readOnly = true;
default = endpointsUsed config.config;
};
};
}
);
in in
{ {
options.khscodes.infrastructure.provisioning = { options.khscodes.infrastructure.provisioning = {
pre = provisioning; pre = lib.mkOption {
post = provisioning; type = provisioning;
default = { };
};
post = lib.mkOption {
type = provisioning;
default = { };
};
secretsSource = lib.mkOption { secretsSource = lib.mkOption {
type = lib.types.enum [ type = lib.types.enum [
"vault" "vault"
@ -87,53 +106,12 @@ in
description = "User data that should be added to the instance during provisioning"; description = "User data that should be added to the instance during provisioning";
default = ""; default = "";
}; };
preConfig = lib.mkOption {
type = lib.types.nullOr lib.types.path;
description = "The generated config for the pre provisioning, if any was specified";
};
preEndpoints = lib.mkOption {
type = lib.types.listOf (
lib.types.enum [
"openstack"
"aws"
"unifi"
"hcloud"
"cloudflare"
"vault"
]
);
description = "Needed endpoints to be used during provisioning";
default = [ ];
};
preImageUsername = lib.mkOption { preImageUsername = lib.mkOption {
type = lib.types.str; type = lib.types.str;
description = "The username for the image being deployed before being swapped for NixOS"; description = "The username for the image being deployed before being swapped for NixOS";
default = "root"; default = "root";
}; };
postConfig = lib.mkOption {
type = lib.types.nullOr lib.types.path;
description = "The generated config for the post provisioning, if any was specified";
};
postEndpoints = lib.mkOption {
type = lib.types.listOf (
lib.types.enum [
"openstack"
"aws"
"unifi"
"hcloud"
"cloudflare"
"vault"
]
);
description = "Needed endpoints to be used during provisioning";
default = [ ];
};
}; };
config = { config = { };
khscodes.infrastructure.provisioning.preConfig = preConfig;
khscodes.infrastructure.provisioning.preEndpoints = preEndpoints;
khscodes.infrastructure.provisioning.postConfig = postConfig;
khscodes.infrastructure.provisioning.postEndpoints = postEndpoints;
};
} }

View file

@ -19,7 +19,7 @@ pkgs.writeShellApplication {
nix build --no-link '${inputs.self}#nixosConfigurations."'"$hostname"'".config.system.build.toplevel' nix build --no-link '${inputs.self}#nixosConfigurations."'"$hostname"'".config.system.build.toplevel'
fi fi
baseAttr='${inputs.self}#nixosConfigurations."'"$hostname"'".config.khscodes.infrastructure' baseAttr='${inputs.self}#nixosConfigurations."'"$hostname"'".config.khscodes.infrastructure'
config="$(nix build --no-link --print-out-paths "''${baseAttr}.provisioning.preConfig")" config="$(nix build --no-link --print-out-paths "''${baseAttr}.provisioning.pre.config")"
preScript="$(nix eval --raw "''${baseAttr}.nixos-install.preScript")" preScript="$(nix eval --raw "''${baseAttr}.nixos-install.preScript")"
username="$(nix eval --raw "''${baseAttr}.provisioning.preImageUsername")" username="$(nix eval --raw "''${baseAttr}.provisioning.preImageUsername")"
if [[ "$config" == "null" ]]; then if [[ "$config" == "null" ]]; then

View file

@ -15,9 +15,9 @@ pkgs.writeShellApplication {
hostname="$1" hostname="$1"
cmd="''${2:-apply}" cmd="''${2:-apply}"
baseAttr='${inputs.self}#nixosConfigurations."'"$hostname"'".config.khscodes.infrastructure.provisioning' baseAttr='${inputs.self}#nixosConfigurations."'"$hostname"'".config.khscodes.infrastructure.provisioning'
config="$(nix build --no-link --print-out-paths "''${baseAttr}.postConfig")" config="$(nix build --no-link --print-out-paths "''${baseAttr}.post.config")"
secretsSource="$(nix eval --raw "''${baseAttr}.secretsSource")" secretsSource="$(nix eval --raw "''${baseAttr}.secretsSource")"
endpoints="$(nix eval --show-trace --json "''${baseAttr}.postEndpoints")" endpoints="$(nix eval --show-trace --json "''${baseAttr}.post.endpoints")"
if [[ "$config" == "null" ]]; then if [[ "$config" == "null" ]]; then
echo "No postprovisioning needed" echo "No postprovisioning needed"
exit 0 exit 0

View file

@ -16,9 +16,9 @@ pkgs.writeShellApplication {
hostname="$1" hostname="$1"
cmd="''${2:-apply}" cmd="''${2:-apply}"
baseAttr='${inputs.self}#nixosConfigurations."'"$hostname"'".config.khscodes.infrastructure.provisioning' baseAttr='${inputs.self}#nixosConfigurations."'"$hostname"'".config.khscodes.infrastructure.provisioning'
config="$(nix build --no-link --print-out-paths "''${baseAttr}.preConfig")" config="$(nix build --no-link --print-out-paths "''${baseAttr}.pre.config")"
secretsSource="$(nix eval --raw "''${baseAttr}.secretsSource")" secretsSource="$(nix eval --raw "''${baseAttr}.secretsSource")"
endpoints="$(nix eval --show-trace --json "''${baseAttr}.preEndpoints")" endpoints="$(nix eval --show-trace --json "''${baseAttr}.pre.endpoints")"
if [[ "$config" == "null" ]]; then if [[ "$config" == "null" ]]; then
echo "No preprovisioning needed" echo "No preprovisioning needed"
exit 0 exit 0