vars/keygen: fix + cleanup tests

- generate keys in ./sops instead of ./sops/vars for now
- don't initialize all flakes with sops keys, only generate when needed
- use the new 'clan vars keygen' in tests
This commit is contained in:
DavHau
2024-10-04 17:25:02 +02:00
parent 73daa2ecc1
commit 11c37ebeba
7 changed files with 31 additions and 57 deletions

View File

@@ -6,6 +6,7 @@ from clan_cli.clan_uri import FlakeId
from clan_cli.errors import ClanError
from clan_cli.secrets.key import generate_key
from clan_cli.secrets.users import add_user
from clan_cli.vars.secret_modules.sops import SecretStore as SopsSecretStore
log = logging.getLogger(__name__)
@@ -16,9 +17,12 @@ def keygen(user: str | None, flake: FlakeId, force: bool) -> None:
if not user:
msg = "No user provided and $USER is not set. Please provide a user via --user."
raise ClanError(msg)
pub_key = generate_key()
pub_key = SopsSecretStore.maybe_get_admin_public_key()
if not pub_key:
pub_key = generate_key()
# TODO set flake_dir=flake.path / "vars"
add_user(
flake_dir=flake.path / "vars",
flake_dir=flake.path,
name=user,
key=pub_key,
force=force,

View File

@@ -99,13 +99,15 @@ class SecretStore(SecretStoreBase):
with os.fdopen(fd, "w") as f:
json.dump({"publickey": publickey, "type": "age"}, f, indent=2)
def default_admin_key_path(self) -> Path:
@staticmethod
def default_admin_key_path() -> Path:
raw_path = os.environ.get("SOPS_AGE_KEY_FILE")
if raw_path:
return Path(raw_path)
return user_config_dir() / "sops" / "age" / "keys.txt"
def get_public_key(self, privkey: str) -> str:
@staticmethod
def get_public_key(privkey: str) -> str:
cmd = nix_shell(["nixpkgs#age"], ["age-keygen", "-y"])
try:
res = subprocess.run(
@@ -116,19 +118,20 @@ class SecretStore(SecretStoreBase):
raise ClanError(msg) from e
return res.stdout.strip()
def maybe_get_admin_public_key(self) -> str | None:
@classmethod
def maybe_get_admin_public_key(cls: type["SecretStore"]) -> str | None:
key = os.environ.get("SOPS_AGE_KEY")
if key:
return self.get_public_key(key)
path = self.default_admin_key_path()
return cls.get_public_key(key)
path = cls.default_admin_key_path()
if path.exists():
return self.get_public_key(path.read_text())
return cls.get_public_key(path.read_text())
return None
# TODO: get rid of `clan secrets generate` dependency
def admin_key(self) -> SopsKey:
pub_key = self.maybe_get_admin_public_key()
pub_key = SecretStore.maybe_get_admin_public_key()
if not pub_key:
raise MissingKeyError
return self.ensure_user_or_machine(pub_key)