Merge pull request 'clan-cli: secrets check command' (#800) from lassulus-check_secrets into main
This commit is contained in:
@@ -43,7 +43,6 @@ class Machine:
|
|||||||
self._deployment_info = json.loads(
|
self._deployment_info = json.loads(
|
||||||
self.build_nix("config.system.clan.deployment.file").read_text()
|
self.build_nix("config.system.clan.deployment.file").read_text()
|
||||||
)
|
)
|
||||||
print(f"self_deployment_info: {self.deployment_info}")
|
|
||||||
return self._deployment_info
|
return self._deployment_info
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -141,7 +140,6 @@ class Machine:
|
|||||||
else:
|
else:
|
||||||
flake = self.flake
|
flake = self.flake
|
||||||
|
|
||||||
log.info(f"building {flake}#{attr}")
|
|
||||||
outpath = run(nix_build([f"{flake}#{attr}"])).stdout.strip()
|
outpath = run(nix_build([f"{flake}#{attr}"])).stdout.strip()
|
||||||
self.build_cache[attr] = Path(outpath)
|
self.build_cache[attr] = Path(outpath)
|
||||||
return Path(outpath)
|
return Path(outpath)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# !/usr/bin/env python3
|
# !/usr/bin/env python3
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
from .check import register_check_parser
|
||||||
from .generate import register_generate_parser
|
from .generate import register_generate_parser
|
||||||
from .groups import register_groups_parser
|
from .groups import register_groups_parser
|
||||||
from .import_sops import register_import_sops_parser
|
from .import_sops import register_import_sops_parser
|
||||||
@@ -32,6 +33,9 @@ def register_parser(parser: argparse.ArgumentParser) -> None:
|
|||||||
import_sops_parser = subparser.add_parser("import-sops", help="import a sops file")
|
import_sops_parser = subparser.add_parser("import-sops", help="import a sops file")
|
||||||
register_import_sops_parser(import_sops_parser)
|
register_import_sops_parser(import_sops_parser)
|
||||||
|
|
||||||
|
check_parser = subparser.add_parser("check", help="check if secrets are up to date")
|
||||||
|
register_check_parser(check_parser)
|
||||||
|
|
||||||
parser_generate = subparser.add_parser(
|
parser_generate = subparser.add_parser(
|
||||||
"generate", help="generate secrets for machines if they don't exist yet"
|
"generate", help="generate secrets for machines if they don't exist yet"
|
||||||
)
|
)
|
||||||
|
|||||||
42
pkgs/clan-cli/clan_cli/secrets/check.py
Normal file
42
pkgs/clan-cli/clan_cli/secrets/check.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import argparse
|
||||||
|
import importlib
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from ..machines.machines import Machine
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def check_secrets(machine: Machine) -> bool:
|
||||||
|
secrets_module = importlib.import_module(machine.secrets_module)
|
||||||
|
secret_store = secrets_module.SecretStore(machine=machine)
|
||||||
|
|
||||||
|
missing_secrets = []
|
||||||
|
missing_facts = []
|
||||||
|
for service in machine.secrets_data:
|
||||||
|
for secret in machine.secrets_data[service]["secrets"]:
|
||||||
|
if not secret_store.exists(service, secret):
|
||||||
|
log.info(f"Secret {secret} for service {service} is missing")
|
||||||
|
missing_secrets.append((service, secret))
|
||||||
|
|
||||||
|
for fact in machine.secrets_data[service]["facts"].values():
|
||||||
|
if not (machine.flake / fact).exists():
|
||||||
|
log.info(f"Fact {fact} for service {service} is missing")
|
||||||
|
missing_facts.append((service, fact))
|
||||||
|
|
||||||
|
if missing_secrets or missing_facts:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_command(args: argparse.Namespace) -> None:
|
||||||
|
machine = Machine(name=args.machine, flake=args.flake)
|
||||||
|
check_secrets(machine)
|
||||||
|
|
||||||
|
|
||||||
|
def register_check_parser(parser: argparse.ArgumentParser) -> None:
|
||||||
|
parser.add_argument(
|
||||||
|
"machine",
|
||||||
|
help="The machine to check secrets for",
|
||||||
|
)
|
||||||
|
parser.set_defaults(func=check_command)
|
||||||
@@ -11,6 +11,7 @@ from clan_cli.cmd import run
|
|||||||
from ..errors import ClanError
|
from ..errors import ClanError
|
||||||
from ..machines.machines import Machine
|
from ..machines.machines import Machine
|
||||||
from ..nix import nix_shell
|
from ..nix import nix_shell
|
||||||
|
from .check import check_secrets
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -24,13 +25,7 @@ def generate_secrets(machine: Machine) -> None:
|
|||||||
print(service)
|
print(service)
|
||||||
tmpdir = Path(d) / service
|
tmpdir = Path(d) / 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
|
||||||
needs_regeneration = any(
|
needs_regeneration = not check_secrets(machine)
|
||||||
not secret_store.exists(service, secret)
|
|
||||||
for secret in machine.secrets_data[service]["secrets"]
|
|
||||||
) or any(
|
|
||||||
not (machine.flake / fact).exists()
|
|
||||||
for fact in machine.secrets_data[service]["facts"].values()
|
|
||||||
)
|
|
||||||
for fact in machine.secrets_data[service]["facts"].values():
|
for fact in machine.secrets_data[service]["facts"].values():
|
||||||
if not (machine.flake / fact).exists():
|
if not (machine.flake / fact).exists():
|
||||||
print(f"fact {fact} is missing")
|
print(f"fact {fact} is missing")
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ class SecretStore:
|
|||||||
"PASSWORD_STORE_DIR", f"{os.environ['HOME']}/.password-store"
|
"PASSWORD_STORE_DIR", f"{os.environ['HOME']}/.password-store"
|
||||||
)
|
)
|
||||||
secret_path = Path(password_store) / f"machines/{self.machine.name}/{name}.gpg"
|
secret_path = Path(password_store) / f"machines/{self.machine.name}/{name}.gpg"
|
||||||
print(f"checking {secret_path}")
|
|
||||||
return secret_path.exists()
|
return secret_path.exists()
|
||||||
|
|
||||||
def generate_hash(self) -> bytes:
|
def generate_hash(self) -> bytes:
|
||||||
|
|||||||
Reference in New Issue
Block a user