feat: configure age plugins for SOPS in buildClan
This commit is contained in:
committed by
Michael Hoang
parent
d3e1c0b4e4
commit
a438fe77a7
@@ -1,5 +1,11 @@
|
||||
[
|
||||
"age",
|
||||
"age-plugin-fido2-hmac",
|
||||
"age-plugin-ledger",
|
||||
"age-plugin-se",
|
||||
"age-plugin-sss",
|
||||
"age-plugin-tpm",
|
||||
"age-plugin-yubikey",
|
||||
"avahi",
|
||||
"bash",
|
||||
"bubblewrap",
|
||||
|
||||
@@ -240,6 +240,7 @@ def add_group_argument(parser: argparse.ArgumentParser) -> None:
|
||||
|
||||
def add_secret(flake_dir: Path, group: str, name: str) -> None:
|
||||
secrets.allow_member(
|
||||
flake_dir,
|
||||
secrets.groups_folder(sops_secrets_folder(flake_dir) / name),
|
||||
sops_groups_folder(flake_dir),
|
||||
group,
|
||||
@@ -267,7 +268,7 @@ def add_secret_command(args: argparse.Namespace) -> None:
|
||||
|
||||
def remove_secret(flake_dir: Path, group: str, name: str) -> None:
|
||||
updated_paths = secrets.disallow_member(
|
||||
secrets.groups_folder(sops_secrets_folder(flake_dir) / name), group
|
||||
flake_dir, secrets.groups_folder(sops_secrets_folder(flake_dir) / name), group
|
||||
)
|
||||
commit_files(
|
||||
updated_paths,
|
||||
|
||||
@@ -74,6 +74,7 @@ def list_sops_machines(flake_dir: Path) -> list[str]:
|
||||
|
||||
def add_secret(flake_dir: Path, machine: str, secret_path: Path) -> None:
|
||||
paths = secrets.allow_member(
|
||||
flake_dir,
|
||||
secrets.machines_folder(secret_path),
|
||||
sops_machines_folder(flake_dir),
|
||||
machine,
|
||||
@@ -87,7 +88,9 @@ def add_secret(flake_dir: Path, machine: str, secret_path: Path) -> None:
|
||||
|
||||
def remove_secret(flake_dir: Path, machine: str, secret: str) -> None:
|
||||
updated_paths = secrets.disallow_member(
|
||||
secrets.machines_folder(sops_secrets_folder(flake_dir) / secret), machine
|
||||
flake_dir,
|
||||
secrets.machines_folder(sops_secrets_folder(flake_dir) / secret),
|
||||
machine,
|
||||
)
|
||||
commit_files(
|
||||
updated_paths,
|
||||
|
||||
@@ -86,6 +86,7 @@ def update_secrets(
|
||||
changed_files.extend(cleanup_dangling_symlinks(path / "machines"))
|
||||
changed_files.extend(
|
||||
update_keys(
|
||||
flake_dir,
|
||||
path,
|
||||
collect_keys_for_path(path),
|
||||
)
|
||||
@@ -172,6 +173,7 @@ def encrypt_secret(
|
||||
for user in add_users:
|
||||
files_to_commit.extend(
|
||||
allow_member(
|
||||
flake_dir,
|
||||
users_folder(secret_path),
|
||||
sops_users_folder(flake_dir),
|
||||
user,
|
||||
@@ -182,6 +184,7 @@ def encrypt_secret(
|
||||
for machine in add_machines:
|
||||
files_to_commit.extend(
|
||||
allow_member(
|
||||
flake_dir,
|
||||
machines_folder(secret_path),
|
||||
sops_machines_folder(flake_dir),
|
||||
machine,
|
||||
@@ -192,6 +195,7 @@ def encrypt_secret(
|
||||
for group in add_groups:
|
||||
files_to_commit.extend(
|
||||
allow_member(
|
||||
flake_dir,
|
||||
groups_folder(secret_path),
|
||||
sops_groups_folder(flake_dir),
|
||||
group,
|
||||
@@ -206,6 +210,7 @@ def encrypt_secret(
|
||||
|
||||
files_to_commit.extend(
|
||||
allow_member(
|
||||
flake_dir,
|
||||
users_folder(secret_path),
|
||||
sops_users_folder(flake_dir),
|
||||
username,
|
||||
@@ -214,7 +219,7 @@ def encrypt_secret(
|
||||
)
|
||||
|
||||
secret_path = secret_path / "secret"
|
||||
encrypt_file(secret_path, value, sorted(recipient_keys))
|
||||
encrypt_file(flake_dir, secret_path, value, sorted(recipient_keys))
|
||||
files_to_commit.append(secret_path)
|
||||
if git_commit:
|
||||
commit_files(
|
||||
@@ -274,7 +279,11 @@ def list_directory(directory: Path) -> str:
|
||||
|
||||
|
||||
def allow_member(
|
||||
group_folder: Path, source_folder: Path, name: str, do_update_keys: bool = True
|
||||
flake_dir: str | Path,
|
||||
group_folder: Path,
|
||||
source_folder: Path,
|
||||
name: str,
|
||||
do_update_keys: bool = True,
|
||||
) -> list[Path]:
|
||||
source = source_folder / name
|
||||
if not source.exists():
|
||||
@@ -297,6 +306,7 @@ def allow_member(
|
||||
if do_update_keys:
|
||||
changed.extend(
|
||||
update_keys(
|
||||
flake_dir,
|
||||
group_folder.parent,
|
||||
collect_keys_for_path(group_folder.parent),
|
||||
)
|
||||
@@ -304,7 +314,7 @@ def allow_member(
|
||||
return changed
|
||||
|
||||
|
||||
def disallow_member(group_folder: Path, name: str) -> list[Path]:
|
||||
def disallow_member(flake_dir: str | Path, group_folder: Path, name: str) -> list[Path]:
|
||||
target = group_folder / name
|
||||
if not target.exists():
|
||||
msg = f"{name} does not exist in group in {group_folder}: "
|
||||
@@ -324,7 +334,9 @@ def disallow_member(group_folder: Path, name: str) -> list[Path]:
|
||||
if next(group_folder.parent.iterdir(), None) is None:
|
||||
group_folder.parent.rmdir()
|
||||
|
||||
return update_keys(target.parent.parent, collect_keys_for_path(group_folder.parent))
|
||||
return update_keys(
|
||||
flake_dir, target.parent.parent, collect_keys_for_path(group_folder.parent)
|
||||
)
|
||||
|
||||
|
||||
def has_secret(secret_path: Path) -> bool:
|
||||
@@ -364,7 +376,7 @@ def decrypt_secret(flake_dir: Path, secret_path: Path) -> str:
|
||||
if not path.exists():
|
||||
msg = f"Secret '{secret_path!s}' does not exist"
|
||||
raise ClanError(msg)
|
||||
return decrypt_file(path)
|
||||
return decrypt_file(flake_dir, path)
|
||||
|
||||
|
||||
def get_command(args: argparse.Namespace) -> None:
|
||||
|
||||
@@ -18,7 +18,7 @@ from clan_lib.api import API
|
||||
from clan_cli.cmd import Log, RunOpts, run
|
||||
from clan_cli.dirs import user_config_dir
|
||||
from clan_cli.errors import ClanError
|
||||
from clan_cli.nix import nix_shell
|
||||
from clan_cli.nix import nix_eval, nix_shell
|
||||
|
||||
from .folders import sops_users_folder
|
||||
|
||||
@@ -191,7 +191,41 @@ class Operation(enum.StrEnum):
|
||||
UPDATE_KEYS = "updatekeys"
|
||||
|
||||
|
||||
def load_age_plugins(flake_dir: str | Path) -> list[str]:
|
||||
if not flake_dir:
|
||||
msg = "Missing flake directory"
|
||||
raise ClanError(msg)
|
||||
|
||||
cmd = nix_eval(
|
||||
[
|
||||
f"{flake_dir}#clanInternals.secrets.age.plugins",
|
||||
"--json",
|
||||
]
|
||||
)
|
||||
|
||||
try:
|
||||
result = run(cmd)
|
||||
except Exception as e:
|
||||
msg = f"Failed to load age plugins {flake_dir}"
|
||||
raise ClanError(msg) from e
|
||||
|
||||
json_str = result.stdout.strip()
|
||||
|
||||
try:
|
||||
plugins = json.loads(json_str)
|
||||
except json.JSONDecodeError as e:
|
||||
msg = f"Failed to decode '{json_str}': {e}"
|
||||
raise ClanError(msg) from e
|
||||
|
||||
if isinstance(plugins, list):
|
||||
return plugins
|
||||
|
||||
msg = f"Expected a list of age plugins but {type(plugins)!r} was provided"
|
||||
raise ClanError(msg)
|
||||
|
||||
|
||||
def sops_run(
|
||||
flake_dir: str | Path,
|
||||
call: Operation,
|
||||
secret_path: Path,
|
||||
public_keys: Iterable[SopsKey],
|
||||
@@ -249,7 +283,9 @@ def sops_run(
|
||||
raise ClanError(msg)
|
||||
sops_cmd.append(str(secret_path))
|
||||
|
||||
cmd = nix_shell(["sops", "gnupg"], sops_cmd)
|
||||
age_plugins = load_age_plugins(flake_dir)
|
||||
|
||||
cmd = nix_shell(["sops", "gnupg", *age_plugins], sops_cmd)
|
||||
opts = (
|
||||
dataclasses.replace(run_opts, env=environ)
|
||||
if run_opts
|
||||
@@ -411,11 +447,14 @@ def ensure_admin_public_keys(flake_dir: Path) -> set[SopsKey]:
|
||||
return user_keys
|
||||
|
||||
|
||||
def update_keys(secret_path: Path, keys: Iterable[SopsKey]) -> list[Path]:
|
||||
def update_keys(
|
||||
flake_dir: str | Path, secret_path: Path, keys: Iterable[SopsKey]
|
||||
) -> list[Path]:
|
||||
secret_path = secret_path / "secret"
|
||||
error_msg = f"Could not update keys for {secret_path}"
|
||||
|
||||
rc, _ = sops_run(
|
||||
flake_dir,
|
||||
Operation.UPDATE_KEYS,
|
||||
secret_path,
|
||||
keys,
|
||||
@@ -426,6 +465,7 @@ def update_keys(secret_path: Path, keys: Iterable[SopsKey]) -> list[Path]:
|
||||
|
||||
|
||||
def encrypt_file(
|
||||
flake_dir: str | Path,
|
||||
secret_path: Path,
|
||||
content: str | IO[bytes] | bytes | None,
|
||||
pubkeys: list[SopsKey],
|
||||
@@ -436,6 +476,7 @@ def encrypt_file(
|
||||
if not content:
|
||||
# This will spawn an editor to edit the file.
|
||||
rc, _ = sops_run(
|
||||
flake_dir,
|
||||
Operation.EDIT,
|
||||
secret_path,
|
||||
pubkeys,
|
||||
@@ -474,6 +515,7 @@ def encrypt_file(
|
||||
msg = f"Invalid content type: {type(content)}"
|
||||
raise ClanError(msg)
|
||||
sops_run(
|
||||
flake_dir,
|
||||
Operation.ENCRYPT,
|
||||
Path(source.name),
|
||||
pubkeys,
|
||||
@@ -488,11 +530,12 @@ def encrypt_file(
|
||||
Path(source.name).unlink()
|
||||
|
||||
|
||||
def decrypt_file(secret_path: Path) -> str:
|
||||
def decrypt_file(flake_dir: str | Path, secret_path: Path) -> str:
|
||||
# decryption uses private keys from the environment or default paths:
|
||||
no_public_keys_needed: list[SopsKey] = []
|
||||
|
||||
_, stdout = sops_run(
|
||||
flake_dir,
|
||||
Operation.DECRYPT,
|
||||
secret_path,
|
||||
no_public_keys_needed,
|
||||
|
||||
@@ -93,6 +93,7 @@ def list_users(flake_dir: Path) -> list[str]:
|
||||
|
||||
def add_secret(flake_dir: Path, user: str, secret: str) -> None:
|
||||
updated_paths = secrets.allow_member(
|
||||
flake_dir,
|
||||
secrets.users_folder(sops_secrets_folder(flake_dir) / secret),
|
||||
sops_users_folder(flake_dir),
|
||||
user,
|
||||
@@ -106,7 +107,7 @@ def add_secret(flake_dir: Path, user: str, secret: str) -> None:
|
||||
|
||||
def remove_secret(flake_dir: Path, user: str, secret: str) -> None:
|
||||
updated_paths = secrets.disallow_member(
|
||||
secrets.users_folder(sops_secrets_folder(flake_dir) / secret), user
|
||||
flake_dir, secrets.users_folder(sops_secrets_folder(flake_dir) / secret), user
|
||||
)
|
||||
commit_files(
|
||||
updated_paths,
|
||||
|
||||
@@ -10,9 +10,10 @@ if TYPE_CHECKING:
|
||||
from .age_keys import KeyPair
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_import_sops(
|
||||
test_root: Path,
|
||||
test_flake: FlakeForTest,
|
||||
test_flake_with_core: FlakeForTest,
|
||||
capture_output: CaptureOutput,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
age_keys: list["KeyPair"],
|
||||
@@ -24,7 +25,7 @@ def test_import_sops(
|
||||
"machines",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"machine1",
|
||||
age_keys[0].pubkey,
|
||||
]
|
||||
@@ -35,7 +36,7 @@ def test_import_sops(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"user1",
|
||||
age_keys[1].pubkey,
|
||||
]
|
||||
@@ -46,7 +47,7 @@ def test_import_sops(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"user2",
|
||||
age_keys[2].pubkey,
|
||||
]
|
||||
@@ -57,7 +58,7 @@ def test_import_sops(
|
||||
"groups",
|
||||
"add-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"group1",
|
||||
"user1",
|
||||
]
|
||||
@@ -68,7 +69,7 @@ def test_import_sops(
|
||||
"groups",
|
||||
"add-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"group1",
|
||||
"user2",
|
||||
]
|
||||
@@ -80,7 +81,7 @@ def test_import_sops(
|
||||
"secrets",
|
||||
"import-sops",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"--group",
|
||||
"group1",
|
||||
"--machine",
|
||||
@@ -90,11 +91,13 @@ def test_import_sops(
|
||||
|
||||
cli.run(cmd)
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "users", "list", "--flake", str(test_flake.path)])
|
||||
cli.run(["secrets", "users", "list", "--flake", str(test_flake_with_core.path)])
|
||||
|
||||
users = sorted(output.out.rstrip().split())
|
||||
assert users == ["user1", "user2"]
|
||||
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake.path), "secret-key"])
|
||||
cli.run(
|
||||
["secrets", "get", "--flake", str(test_flake_with_core.path), "secret-key"]
|
||||
)
|
||||
assert output.out == "secret-value"
|
||||
|
||||
@@ -22,14 +22,15 @@ if TYPE_CHECKING:
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def _test_identities(
|
||||
what: str,
|
||||
test_flake: FlakeForTest,
|
||||
test_flake_with_core: FlakeForTest,
|
||||
capture_output: CaptureOutput,
|
||||
age_keys: list["KeyPair"],
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
sops_folder = test_flake.path / "sops"
|
||||
sops_folder = test_flake_with_core.path / "sops"
|
||||
|
||||
what_singular = what[:-1]
|
||||
test_secret_name = f"{what_singular}_secret"
|
||||
@@ -45,7 +46,7 @@ def _test_identities(
|
||||
what,
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"foo",
|
||||
age_keys[0].pubkey,
|
||||
]
|
||||
@@ -58,7 +59,7 @@ def _test_identities(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"admin",
|
||||
admin_age_key.pubkey,
|
||||
]
|
||||
@@ -71,7 +72,7 @@ def _test_identities(
|
||||
what,
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"foo",
|
||||
age_keys[0].pubkey,
|
||||
]
|
||||
@@ -86,7 +87,7 @@ def _test_identities(
|
||||
"secrets",
|
||||
"set",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
f"--{what_singular}",
|
||||
"foo",
|
||||
test_secret_name,
|
||||
@@ -94,7 +95,7 @@ def _test_identities(
|
||||
)
|
||||
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
test_secret_name,
|
||||
expected_age_recipients_keypairs=[age_keys[0], admin_age_key],
|
||||
)
|
||||
@@ -107,14 +108,14 @@ def _test_identities(
|
||||
what,
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"-f",
|
||||
"foo",
|
||||
age_keys[1].privkey,
|
||||
]
|
||||
)
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
test_secret_name,
|
||||
expected_age_recipients_keypairs=[age_keys[1], admin_age_key],
|
||||
)
|
||||
@@ -126,24 +127,35 @@ def _test_identities(
|
||||
what,
|
||||
"get",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"foo",
|
||||
]
|
||||
)
|
||||
assert age_keys[1].pubkey in output.out
|
||||
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", what, "list", "--flake", str(test_flake.path)])
|
||||
cli.run(["secrets", what, "list", "--flake", str(test_flake_with_core.path)])
|
||||
assert "foo" in output.out
|
||||
|
||||
cli.run(["secrets", what, "remove", "--flake", str(test_flake.path), "foo"])
|
||||
cli.run(
|
||||
["secrets", what, "remove", "--flake", str(test_flake_with_core.path), "foo"]
|
||||
)
|
||||
assert not (sops_folder / what / "foo" / "key.json").exists()
|
||||
|
||||
with pytest.raises(ClanError): # already removed
|
||||
cli.run(["secrets", what, "remove", "--flake", str(test_flake.path), "foo"])
|
||||
cli.run(
|
||||
[
|
||||
"secrets",
|
||||
what,
|
||||
"remove",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
"foo",
|
||||
]
|
||||
)
|
||||
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", what, "list", "--flake", str(test_flake.path)])
|
||||
cli.run(["secrets", what, "list", "--flake", str(test_flake_with_core.path)])
|
||||
assert "foo" not in output.out
|
||||
|
||||
user_or_machine_symlink = sops_folder / "secrets" / test_secret_name / what / "foo"
|
||||
@@ -155,23 +167,27 @@ def _test_identities(
|
||||
assert not user_or_machine_symlink.exists(follow_symlinks=False), err_msg
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_users(
|
||||
test_flake: FlakeForTest,
|
||||
test_flake_with_core: FlakeForTest,
|
||||
capture_output: CaptureOutput,
|
||||
age_keys: list["KeyPair"],
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
with monkeypatch.context():
|
||||
_test_identities("users", test_flake, capture_output, age_keys, monkeypatch)
|
||||
_test_identities(
|
||||
"users", test_flake_with_core, capture_output, age_keys, monkeypatch
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_multiple_user_keys(
|
||||
test_flake: FlakeForTest,
|
||||
test_flake_with_core: FlakeForTest,
|
||||
capture_output: CaptureOutput,
|
||||
age_keys: list["KeyPair"],
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
sops_folder = test_flake.path / "sops"
|
||||
sops_folder = test_flake_with_core.path / "sops"
|
||||
|
||||
users_keys = {
|
||||
"bob": {age_keys[0], age_keys[1]},
|
||||
@@ -187,7 +203,7 @@ def test_multiple_user_keys(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
user,
|
||||
*[f"--age-key={key.pubkey}" for key in user_keys],
|
||||
]
|
||||
@@ -196,7 +212,16 @@ def test_multiple_user_keys(
|
||||
|
||||
# check they are returned in get
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "users", "get", "--flake", str(test_flake.path), user])
|
||||
cli.run(
|
||||
[
|
||||
"secrets",
|
||||
"users",
|
||||
"get",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
user,
|
||||
]
|
||||
)
|
||||
|
||||
for user_key in user_keys:
|
||||
assert user_key.pubkey in output.out
|
||||
@@ -220,14 +245,14 @@ def test_multiple_user_keys(
|
||||
"secrets",
|
||||
"set",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
secret_name,
|
||||
]
|
||||
)
|
||||
|
||||
# check the secret has each of our user's keys as a recipient
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
secret_name,
|
||||
expected_age_recipients_keypairs=[*user_keys],
|
||||
)
|
||||
@@ -235,7 +260,13 @@ def test_multiple_user_keys(
|
||||
# check we can get the secret
|
||||
with capture_output as output:
|
||||
cli.run(
|
||||
["secrets", "get", "--flake", str(test_flake.path), secret_name]
|
||||
[
|
||||
"secrets",
|
||||
"get",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
secret_name,
|
||||
]
|
||||
)
|
||||
|
||||
assert secret_value in output.out
|
||||
@@ -259,7 +290,7 @@ def test_multiple_user_keys(
|
||||
"users",
|
||||
"remove-key",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
user,
|
||||
key_to_remove.pubkey,
|
||||
]
|
||||
@@ -267,7 +298,7 @@ def test_multiple_user_keys(
|
||||
|
||||
# check the secret has been updated
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
secret_name,
|
||||
expected_age_recipients_keypairs=list({*user_keys} - {key_to_remove}),
|
||||
)
|
||||
@@ -279,7 +310,7 @@ def test_multiple_user_keys(
|
||||
"users",
|
||||
"add-key",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
user,
|
||||
key_to_remove.pubkey,
|
||||
]
|
||||
@@ -287,29 +318,35 @@ def test_multiple_user_keys(
|
||||
|
||||
# check the secret has been updated
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
secret_name,
|
||||
expected_age_recipients_keypairs=user_keys,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_machines(
|
||||
test_flake: FlakeForTest,
|
||||
test_flake_with_core: FlakeForTest,
|
||||
capture_output: CaptureOutput,
|
||||
age_keys: list["KeyPair"],
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
_test_identities("machines", test_flake, capture_output, age_keys, monkeypatch)
|
||||
_test_identities(
|
||||
"machines", test_flake_with_core, capture_output, age_keys, monkeypatch
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_groups(
|
||||
test_flake: FlakeForTest,
|
||||
test_flake_with_core: FlakeForTest,
|
||||
capture_output: CaptureOutput,
|
||||
age_keys: list["KeyPair"],
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "groups", "list", "--flake", str(test_flake.path)])
|
||||
cli.run(
|
||||
["secrets", "groups", "list", "--flake", str(test_flake_with_core.path)]
|
||||
)
|
||||
assert output.out == ""
|
||||
|
||||
machine1_age_key = age_keys[0]
|
||||
@@ -323,7 +360,7 @@ def test_groups(
|
||||
"groups",
|
||||
"add-machine",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"group1",
|
||||
"machine1",
|
||||
]
|
||||
@@ -335,7 +372,7 @@ def test_groups(
|
||||
"groups",
|
||||
"add-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"groupb1",
|
||||
"user1",
|
||||
]
|
||||
@@ -346,7 +383,7 @@ def test_groups(
|
||||
"machines",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"machine1",
|
||||
machine1_age_key.pubkey,
|
||||
]
|
||||
@@ -357,7 +394,7 @@ def test_groups(
|
||||
"groups",
|
||||
"add-machine",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"group1",
|
||||
"machine1",
|
||||
]
|
||||
@@ -370,7 +407,7 @@ def test_groups(
|
||||
"groups",
|
||||
"add-machine",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"group1",
|
||||
"machine1",
|
||||
]
|
||||
@@ -382,7 +419,7 @@ def test_groups(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"user1",
|
||||
user1_age_key.pubkey,
|
||||
]
|
||||
@@ -393,7 +430,7 @@ def test_groups(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"admin",
|
||||
admin_age_key.pubkey,
|
||||
]
|
||||
@@ -404,14 +441,16 @@ def test_groups(
|
||||
"groups",
|
||||
"add-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"group1",
|
||||
"user1",
|
||||
]
|
||||
)
|
||||
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "groups", "list", "--flake", str(test_flake.path)])
|
||||
cli.run(
|
||||
["secrets", "groups", "list", "--flake", str(test_flake_with_core.path)]
|
||||
)
|
||||
out = output.out
|
||||
assert "user1" in out
|
||||
assert "machine1" in out
|
||||
@@ -427,7 +466,7 @@ def test_groups(
|
||||
"secrets",
|
||||
"set",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"--group",
|
||||
"group1",
|
||||
secret_name,
|
||||
@@ -435,7 +474,7 @@ def test_groups(
|
||||
)
|
||||
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
secret_name,
|
||||
expected_age_recipients_keypairs=[
|
||||
machine1_age_key,
|
||||
@@ -454,13 +493,13 @@ def test_groups(
|
||||
"groups",
|
||||
"remove-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"group1",
|
||||
"user1",
|
||||
]
|
||||
)
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
secret_name,
|
||||
expected_age_recipients_keypairs=[machine1_age_key, admin_age_key],
|
||||
err_msg=(
|
||||
@@ -476,13 +515,13 @@ def test_groups(
|
||||
"groups",
|
||||
"add-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"group1",
|
||||
"user1",
|
||||
]
|
||||
)
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
secret_name,
|
||||
expected_age_recipients_keypairs=[
|
||||
machine1_age_key,
|
||||
@@ -498,12 +537,12 @@ def test_groups(
|
||||
"users",
|
||||
"remove",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"user1",
|
||||
]
|
||||
)
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
secret_name,
|
||||
expected_age_recipients_keypairs=[machine1_age_key, admin_age_key],
|
||||
err_msg=(
|
||||
@@ -518,13 +557,13 @@ def test_groups(
|
||||
"groups",
|
||||
"remove-machine",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"group1",
|
||||
"machine1",
|
||||
]
|
||||
)
|
||||
assert_secrets_file_recipients(
|
||||
test_flake.path,
|
||||
test_flake_with_core.path,
|
||||
secret_name,
|
||||
expected_age_recipients_keypairs=[admin_age_key],
|
||||
err_msg=(
|
||||
@@ -533,11 +572,11 @@ def test_groups(
|
||||
),
|
||||
)
|
||||
|
||||
first_group = next((test_flake.path / "sops" / "groups").iterdir(), None)
|
||||
first_group = next((test_flake_with_core.path / "sops" / "groups").iterdir(), None)
|
||||
assert first_group is None
|
||||
|
||||
# Check if the symlink to the group was removed from our foo test secret:
|
||||
group_symlink = test_flake.path / "sops/secrets/foo/groups/group1"
|
||||
group_symlink = test_flake_with_core.path / "sops/secrets/foo/groups/group1"
|
||||
err_msg = (
|
||||
"Symlink to group1's key in foo secret "
|
||||
"was not cleaned up after group1 was removed"
|
||||
@@ -574,25 +613,30 @@ def use_gpg_key(key: GpgKey, monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
|
||||
monkeypatch.setenv("SOPS_AGE_KEY", old_key)
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_secrets(
|
||||
test_flake: FlakeForTest,
|
||||
test_flake_with_core: FlakeForTest,
|
||||
capture_output: CaptureOutput,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
gpg_key: GpgKey,
|
||||
age_keys: list["KeyPair"],
|
||||
) -> None:
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "list", "--flake", str(test_flake.path)])
|
||||
cli.run(["secrets", "list", "--flake", str(test_flake_with_core.path)])
|
||||
assert output.out == ""
|
||||
|
||||
# Generate a new key for the clan
|
||||
monkeypatch.setenv("SOPS_AGE_KEY_FILE", str(test_flake.path / ".." / "age.key"))
|
||||
monkeypatch.setenv(
|
||||
"SOPS_AGE_KEY_FILE", str(test_flake_with_core.path / ".." / "age.key")
|
||||
)
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "key", "generate", "--flake", str(test_flake.path)])
|
||||
cli.run(
|
||||
["secrets", "key", "generate", "--flake", str(test_flake_with_core.path)]
|
||||
)
|
||||
assert "age private key" in output.out
|
||||
# Read the key that was generated
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "key", "show", "--flake", str(test_flake.path)])
|
||||
cli.run(["secrets", "key", "show", "--flake", str(test_flake_with_core.path)])
|
||||
|
||||
key = json.loads(output.out)
|
||||
assert key["publickey"].startswith("age1")
|
||||
@@ -603,41 +647,71 @@ def test_secrets(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"testuser",
|
||||
key["publickey"],
|
||||
]
|
||||
)
|
||||
|
||||
with pytest.raises(ClanError): # does not exist yet
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake.path), "nonexisting"])
|
||||
cli.run(
|
||||
["secrets", "get", "--flake", str(test_flake_with_core.path), "nonexisting"]
|
||||
)
|
||||
monkeypatch.setenv("SOPS_NIX_SECRET", "foo")
|
||||
cli.run(["secrets", "set", "--flake", str(test_flake.path), "initialkey"])
|
||||
cli.run(["secrets", "set", "--flake", str(test_flake_with_core.path), "initialkey"])
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake.path), "initialkey"])
|
||||
cli.run(
|
||||
["secrets", "get", "--flake", str(test_flake_with_core.path), "initialkey"]
|
||||
)
|
||||
assert output.out == "foo"
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "users", "list", "--flake", str(test_flake.path)])
|
||||
cli.run(["secrets", "users", "list", "--flake", str(test_flake_with_core.path)])
|
||||
users = output.out.rstrip().split("\n")
|
||||
assert len(users) == 1, f"users: {users}"
|
||||
owner = users[0]
|
||||
|
||||
monkeypatch.setenv("EDITOR", "cat")
|
||||
cli.run(["secrets", "set", "--edit", "--flake", str(test_flake.path), "initialkey"])
|
||||
cli.run(
|
||||
[
|
||||
"secrets",
|
||||
"set",
|
||||
"--edit",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
"initialkey",
|
||||
]
|
||||
)
|
||||
monkeypatch.delenv("EDITOR")
|
||||
|
||||
cli.run(["secrets", "rename", "--flake", str(test_flake.path), "initialkey", "key"])
|
||||
cli.run(
|
||||
[
|
||||
"secrets",
|
||||
"rename",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
"initialkey",
|
||||
"key",
|
||||
]
|
||||
)
|
||||
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "list", "--flake", str(test_flake.path)])
|
||||
cli.run(["secrets", "list", "--flake", str(test_flake_with_core.path)])
|
||||
assert output.out == "key\n"
|
||||
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "list", "--flake", str(test_flake.path), "nonexisting"])
|
||||
cli.run(
|
||||
[
|
||||
"secrets",
|
||||
"list",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
"nonexisting",
|
||||
]
|
||||
)
|
||||
assert output.out == ""
|
||||
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "list", "--flake", str(test_flake.path), "key"])
|
||||
cli.run(["secrets", "list", "--flake", str(test_flake_with_core.path), "key"])
|
||||
assert output.out == "key\n"
|
||||
|
||||
# using the `age_keys` KeyPair, add a machine and rotate its key
|
||||
@@ -648,7 +722,7 @@ def test_secrets(
|
||||
"machines",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"machine1",
|
||||
age_keys[1].pubkey,
|
||||
]
|
||||
@@ -659,18 +733,22 @@ def test_secrets(
|
||||
"machines",
|
||||
"add-secret",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"machine1",
|
||||
"key",
|
||||
]
|
||||
)
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "machines", "list", "--flake", str(test_flake.path)])
|
||||
cli.run(
|
||||
["secrets", "machines", "list", "--flake", str(test_flake_with_core.path)]
|
||||
)
|
||||
assert output.out == "machine1\n"
|
||||
|
||||
with use_age_key(age_keys[1].privkey, monkeypatch):
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
|
||||
cli.run(
|
||||
["secrets", "get", "--flake", str(test_flake_with_core.path), "key"]
|
||||
)
|
||||
assert output.out == "foo"
|
||||
|
||||
# rotate machines key
|
||||
@@ -680,7 +758,7 @@ def test_secrets(
|
||||
"machines",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"-f",
|
||||
"machine1",
|
||||
age_keys[0].privkey,
|
||||
@@ -690,7 +768,9 @@ def test_secrets(
|
||||
# should also rotate the encrypted secret
|
||||
with use_age_key(age_keys[0].privkey, monkeypatch):
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
|
||||
cli.run(
|
||||
["secrets", "get", "--flake", str(test_flake_with_core.path), "key"]
|
||||
)
|
||||
assert output.out == "foo"
|
||||
|
||||
cli.run(
|
||||
@@ -699,7 +779,7 @@ def test_secrets(
|
||||
"machines",
|
||||
"remove-secret",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"machine1",
|
||||
"key",
|
||||
]
|
||||
@@ -711,7 +791,7 @@ def test_secrets(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"user1",
|
||||
age_keys[1].pubkey,
|
||||
]
|
||||
@@ -722,13 +802,13 @@ def test_secrets(
|
||||
"users",
|
||||
"add-secret",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"user1",
|
||||
"key",
|
||||
]
|
||||
)
|
||||
with capture_output as output, use_age_key(age_keys[1].privkey, monkeypatch):
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake_with_core.path), "key"])
|
||||
assert output.out == "foo"
|
||||
cli.run(
|
||||
[
|
||||
@@ -736,7 +816,7 @@ def test_secrets(
|
||||
"users",
|
||||
"remove-secret",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"user1",
|
||||
"key",
|
||||
]
|
||||
@@ -749,7 +829,7 @@ def test_secrets(
|
||||
"groups",
|
||||
"add-secret",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"admin-group",
|
||||
"key",
|
||||
]
|
||||
@@ -760,7 +840,7 @@ def test_secrets(
|
||||
"groups",
|
||||
"add-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"admin-group",
|
||||
"user1",
|
||||
]
|
||||
@@ -771,7 +851,7 @@ def test_secrets(
|
||||
"groups",
|
||||
"add-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"admin-group",
|
||||
owner,
|
||||
]
|
||||
@@ -782,7 +862,7 @@ def test_secrets(
|
||||
"groups",
|
||||
"add-secret",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"admin-group",
|
||||
"key",
|
||||
]
|
||||
@@ -793,7 +873,7 @@ def test_secrets(
|
||||
"secrets",
|
||||
"set",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"--group",
|
||||
"admin-group",
|
||||
"key2",
|
||||
@@ -802,7 +882,9 @@ def test_secrets(
|
||||
|
||||
with use_age_key(age_keys[1].privkey, monkeypatch):
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
|
||||
cli.run(
|
||||
["secrets", "get", "--flake", str(test_flake_with_core.path), "key"]
|
||||
)
|
||||
assert output.out == "foo"
|
||||
|
||||
# Add an user with a GPG key
|
||||
@@ -812,7 +894,7 @@ def test_secrets(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"--pgp-key",
|
||||
gpg_key.fingerprint,
|
||||
"user2",
|
||||
@@ -826,7 +908,7 @@ def test_secrets(
|
||||
"groups",
|
||||
"add-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"admin-group",
|
||||
"user2",
|
||||
]
|
||||
@@ -834,7 +916,9 @@ def test_secrets(
|
||||
|
||||
with use_gpg_key(gpg_key, monkeypatch): # user2
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
|
||||
cli.run(
|
||||
["secrets", "get", "--flake", str(test_flake_with_core.path), "key"]
|
||||
)
|
||||
assert output.out == "foo"
|
||||
|
||||
cli.run(
|
||||
@@ -843,7 +927,7 @@ def test_secrets(
|
||||
"groups",
|
||||
"remove-user",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"admin-group",
|
||||
"user2",
|
||||
]
|
||||
@@ -854,7 +938,7 @@ def test_secrets(
|
||||
capture_output as output,
|
||||
):
|
||||
# user2 is not in the group anymore
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
|
||||
cli.run(["secrets", "get", "--flake", str(test_flake_with_core.path), "key"])
|
||||
print(output.out)
|
||||
|
||||
cli.run(
|
||||
@@ -863,22 +947,23 @@ def test_secrets(
|
||||
"groups",
|
||||
"remove-secret",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"admin-group",
|
||||
"key",
|
||||
]
|
||||
)
|
||||
|
||||
cli.run(["secrets", "remove", "--flake", str(test_flake.path), "key"])
|
||||
cli.run(["secrets", "remove", "--flake", str(test_flake.path), "key2"])
|
||||
cli.run(["secrets", "remove", "--flake", str(test_flake_with_core.path), "key"])
|
||||
cli.run(["secrets", "remove", "--flake", str(test_flake_with_core.path), "key2"])
|
||||
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "list", "--flake", str(test_flake.path)])
|
||||
cli.run(["secrets", "list", "--flake", str(test_flake_with_core.path)])
|
||||
assert output.out == ""
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_secrets_key_generate_gpg(
|
||||
test_flake: FlakeForTest,
|
||||
test_flake_with_core: FlakeForTest,
|
||||
capture_output: CaptureOutput,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
gpg_key: GpgKey,
|
||||
@@ -893,14 +978,16 @@ def test_secrets_key_generate_gpg(
|
||||
"key",
|
||||
"generate",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
]
|
||||
)
|
||||
assert "age private key" not in output.out
|
||||
assert re.match(r"PGP key.+is already set", output.err) is not None
|
||||
|
||||
with capture_output as output:
|
||||
cli.run(["secrets", "key", "show", "--flake", str(test_flake.path)])
|
||||
cli.run(
|
||||
["secrets", "key", "show", "--flake", str(test_flake_with_core.path)]
|
||||
)
|
||||
key = json.loads(output.out)
|
||||
assert key["type"] == "pgp"
|
||||
assert key["publickey"] == gpg_key.fingerprint
|
||||
@@ -912,7 +999,7 @@ def test_secrets_key_generate_gpg(
|
||||
"users",
|
||||
"add",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"--pgp-key",
|
||||
gpg_key.fingerprint,
|
||||
"testuser",
|
||||
@@ -926,7 +1013,7 @@ def test_secrets_key_generate_gpg(
|
||||
"users",
|
||||
"get",
|
||||
"--flake",
|
||||
str(test_flake.path),
|
||||
str(test_flake_with_core.path),
|
||||
"testuser",
|
||||
]
|
||||
)
|
||||
@@ -940,9 +1027,23 @@ def test_secrets_key_generate_gpg(
|
||||
with monkeypatch.context() as m:
|
||||
m.setenv("SOPS_NIX_SECRET", "secret-value")
|
||||
|
||||
cli.run(["secrets", "set", "--flake", str(test_flake.path), "secret-name"])
|
||||
cli.run(
|
||||
[
|
||||
"secrets",
|
||||
"set",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
"secret-name",
|
||||
]
|
||||
)
|
||||
with capture_output as output:
|
||||
cli.run(
|
||||
["secrets", "get", "--flake", str(test_flake.path), "secret-name"]
|
||||
[
|
||||
"secrets",
|
||||
"get",
|
||||
"--flake",
|
||||
str(test_flake_with_core.path),
|
||||
"secret-name",
|
||||
]
|
||||
)
|
||||
assert output.out == "secret-value"
|
||||
|
||||
@@ -302,6 +302,7 @@ class SecretStore(StoreBase):
|
||||
|
||||
for group in self.machine.deployment["sops"]["defaultGroups"]:
|
||||
allow_member(
|
||||
self.machine.flake_dir,
|
||||
groups_folder(secret_path),
|
||||
sops_groups_folder(self.machine.flake_dir),
|
||||
group,
|
||||
@@ -310,6 +311,7 @@ class SecretStore(StoreBase):
|
||||
)
|
||||
|
||||
update_keys(
|
||||
self.machine.flake_dir,
|
||||
secret_path,
|
||||
collect_keys_for_path(secret_path),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user