WIP: clan-cli interactive secrets
All checks were successful
checks / check-links (pull_request) Successful in 21s
checks / checks-impure (pull_request) Successful in 1m58s
checks / checks (pull_request) Successful in 2m46s

This commit is contained in:
lassulus 2024-03-01 10:25:39 +01:00
parent f500aee786
commit b0ea30f625
3 changed files with 31 additions and 5 deletions

View File

@ -54,6 +54,14 @@
Extra paths to add to the PATH environment variable when running the generator. Extra paths to add to the PATH environment variable when running the generator.
''; '';
}; };
prompt = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
prompt text to ask for a value.
This value will be passed to the script as the environment variabel $prompt_value.
'';
};
script = lib.mkOption { script = lib.mkOption {
type = lib.types.str; type = lib.types.str;
description = '' description = ''
@ -92,14 +100,14 @@
config' = config; config' = config;
in in
lib.mkOption { lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({ config, ... }: { type = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: {
options = { options = {
name = lib.mkOption { name = lib.mkOption {
type = lib.types.str; type = lib.types.str;
description = '' description = ''
name of the secret name of the secret
''; '';
default = config._module.args.name; default = name;
}; };
path = lib.mkOption { path = lib.mkOption {
type = lib.types.str; type = lib.types.str;

View File

@ -2,6 +2,7 @@ import argparse
import importlib import importlib
import logging import logging
import os import os
from collections.abc import Callable
from pathlib import Path from pathlib import Path
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
@ -24,6 +25,7 @@ def generate_service_secrets(
secret_store: SecretStoreBase, secret_store: SecretStoreBase,
fact_store: FactStoreBase, fact_store: FactStoreBase,
tmpdir: Path, tmpdir: Path,
prompt: Callable[[str], str],
) -> None: ) -> None:
service_dir = tmpdir / service service_dir = tmpdir / service
# check if all secrets exist and generate them if at least one is missing # check if all secrets exist and generate them if at least one is missing
@ -41,6 +43,9 @@ def generate_service_secrets(
secrets_dir = service_dir / "secrets" secrets_dir = service_dir / "secrets"
secrets_dir.mkdir(parents=True) secrets_dir.mkdir(parents=True)
env["secrets"] = str(secrets_dir) env["secrets"] = str(secrets_dir)
if machine.secrets_data[service]["generator"]["prompt"]:
prompt_value = prompt(machine.secrets_data[service]["generator"]["prompt"])
env["prompt_value"] = prompt_value
# fmt: off # fmt: off
cmd = nix_shell( cmd = nix_shell(
[ [
@ -105,17 +110,30 @@ def generate_service_secrets(
) )
def generate_secrets(machine: Machine) -> None: def generate_secrets(
machine: Machine,
prompt: None | Callable[[str], str] = None,
) -> None:
secrets_module = importlib.import_module(machine.secrets_module) secrets_module = importlib.import_module(machine.secrets_module)
secret_store = secrets_module.SecretStore(machine=machine) secret_store = secrets_module.SecretStore(machine=machine)
facts_module = importlib.import_module(machine.facts_module) facts_module = importlib.import_module(machine.facts_module)
fact_store = facts_module.FactStore(machine=machine) fact_store = facts_module.FactStore(machine=machine)
if prompt is None:
prompt = input
with TemporaryDirectory() as tmp: with TemporaryDirectory() as tmp:
tmpdir = Path(tmp) tmpdir = Path(tmp)
for service in machine.secrets_data: for service in machine.secrets_data:
generate_service_secrets(machine, service, secret_store, fact_store, tmpdir) generate_service_secrets(
machine=machine,
service=service,
secret_store=secret_store,
fact_store=fact_store,
tmpdir=tmpdir,
prompt=prompt,
)
print("successfully generated secrets") print("successfully generated secrets")

View File

@ -39,6 +39,7 @@ def facts_to_nixos_config(facts: dict[str, dict[str, bytes]]) -> dict:
def build_vm( def build_vm(
machine: Machine, tmpdir: Path, nix_options: list[str] = [] machine: Machine, tmpdir: Path, nix_options: list[str] = []
) -> dict[str, str]: ) -> dict[str, str]:
# TODO pass prompt here for the GTK gui
secrets_dir = get_secrets(machine, tmpdir) secrets_dir = get_secrets(machine, tmpdir)
facts_module = importlib.import_module(machine.facts_module) facts_module = importlib.import_module(machine.facts_module)
@ -68,7 +69,6 @@ def get_secrets(
secrets_module = importlib.import_module(machine.secrets_module) secrets_module = importlib.import_module(machine.secrets_module)
secret_store = secrets_module.SecretStore(machine=machine) secret_store = secrets_module.SecretStore(machine=machine)
# TODO Only generate secrets for local clans
generate_secrets(machine) generate_secrets(machine)
secret_store.upload(secrets_dir) secret_store.upload(secrets_dir)