allow to set groups/admins/users when setting secrets
All checks were successful
build / test (pull_request) Successful in 20s

This commit is contained in:
Jörg Thalheim 2023-08-08 19:40:35 +02:00
parent 5ee620b77b
commit 2988532909
2 changed files with 50 additions and 9 deletions

View File

@ -3,7 +3,6 @@ import getpass
import os import os
import shutil import shutil
import sys import sys
from io import StringIO
from pathlib import Path from pathlib import Path
from typing import IO, Union from typing import IO, Union
@ -171,14 +170,19 @@ def get_command(args: argparse.Namespace) -> None:
def set_command(args: argparse.Namespace) -> None: def set_command(args: argparse.Namespace) -> None:
secret_value = os.environ.get("SOPS_NIX_SECRET") env_value = os.environ.get("SOPS_NIX_SECRET")
if secret_value: secret_value: Union[str, IO[str]] = sys.stdin
encrypt_secret(sops_secrets_folder() / args.secret, StringIO(secret_value)) if env_value:
secret_value = env_value
elif tty.is_interactive(): elif tty.is_interactive():
secret = getpass.getpass(prompt="Paste your secret: ") secret_value = getpass.getpass(prompt="Paste your secret: ")
encrypt_secret(sops_secrets_folder() / args.secret, StringIO(secret)) encrypt_secret(
else: sops_secrets_folder() / args.secret,
encrypt_secret(sops_secrets_folder() / args.secret, sys.stdin) secret_value,
args.user,
args.machine,
args.group,
)
def register_secrets_parser(subparser: argparse._SubParsersAction) -> None: def register_secrets_parser(subparser: argparse._SubParsersAction) -> None:
@ -191,6 +195,27 @@ def register_secrets_parser(subparser: argparse._SubParsersAction) -> None:
parser_set = subparser.add_parser("set", help="set a secret") parser_set = subparser.add_parser("set", help="set a secret")
add_secret_argument(parser_set) add_secret_argument(parser_set)
parser_set.add_argument(
"--group",
type=str,
action="append",
default=[],
help="the group to import the secrets to",
)
parser_set.add_argument(
"--machine",
type=str,
action="append",
default=[],
help="the machine to import the secrets to",
)
parser_set.add_argument(
"--user",
type=str,
action="append",
default=[],
help="the user to import the secrets to",
)
parser_set.set_defaults(func=set_command) parser_set.set_defaults(func=set_command)
parser_delete = subparser.add_parser("remove", help="remove a secret") parser_delete = subparser.add_parser("remove", help="remove a secret")

View File

@ -122,6 +122,11 @@ def test_secrets(clan_flake: Path, capsys: pytest.CaptureFixture) -> None:
capsys.readouterr() capsys.readouterr()
cli.run(["get", "key"]) cli.run(["get", "key"])
assert capsys.readouterr().out == "foo" assert capsys.readouterr().out == "foo"
capsys.readouterr()
cli.run(["users", "list"])
users = capsys.readouterr().out.rstrip().split("\n")
assert len(users) == 1, f"users: {users}"
owner = users[0]
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["list"]) cli.run(["list"])
@ -147,8 +152,12 @@ def test_secrets(clan_flake: Path, capsys: pytest.CaptureFixture) -> None:
with pytest.raises(ClanError): # does not exist yet with pytest.raises(ClanError): # does not exist yet
cli.run(["groups", "add-secret", "admin-group", "key"]) cli.run(["groups", "add-secret", "admin-group", "key"])
cli.run(["groups", "add-user", "admin-group", "user1"]) cli.run(["groups", "add-user", "admin-group", "user1"])
cli.run(["groups", "add-user", "admin-group", owner])
cli.run(["groups", "add-secret", "admin-group", "key"]) cli.run(["groups", "add-secret", "admin-group", "key"])
capsys.readouterr() # empty the buffer
cli.run(["set", "--group", "admin-group", "key2"])
with mock_env(SOPS_AGE_KEY=PRIVKEY_2, SOPS_AGE_KEY_FILE=""): with mock_env(SOPS_AGE_KEY=PRIVKEY_2, SOPS_AGE_KEY_FILE=""):
capsys.readouterr() capsys.readouterr()
cli.run(["get", "key"]) cli.run(["get", "key"])
@ -156,6 +165,7 @@ def test_secrets(clan_flake: Path, capsys: pytest.CaptureFixture) -> None:
cli.run(["groups", "remove-secret", "admin-group", "key"]) cli.run(["groups", "remove-secret", "admin-group", "key"])
cli.run(["remove", "key"]) cli.run(["remove", "key"])
cli.run(["remove", "key2"])
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["list"]) cli.run(["list"])
@ -169,7 +179,8 @@ def test_import_sops(
with mock_env(SOPS_AGE_KEY=PRIVKEY_2): with mock_env(SOPS_AGE_KEY=PRIVKEY_2):
cli.run(["machines", "add", "machine1", PUBKEY]) cli.run(["machines", "add", "machine1", PUBKEY])
cli.run(["users", "add", "user1", PUBKEY_3]) cli.run(["users", "add", "user1", PUBKEY_2])
cli.run(["users", "add", "user2", PUBKEY_3])
# To edit: # To edit:
# SOPS_AGE_KEY=AGE-SECRET-KEY-1U5ENXZQAY62NC78Y2WC0SEGRRMAEEKH79EYY5TH4GPFWJKEAY0USZ6X7YQ sops --age age14tva0txcrl0zes05x7gkx56qd6wd9q3nwecjac74xxzz4l47r44sv3fz62 ./data/secrets.yaml # SOPS_AGE_KEY=AGE-SECRET-KEY-1U5ENXZQAY62NC78Y2WC0SEGRRMAEEKH79EYY5TH4GPFWJKEAY0USZ6X7YQ sops --age age14tva0txcrl0zes05x7gkx56qd6wd9q3nwecjac74xxzz4l47r44sv3fz62 ./data/secrets.yaml
@ -183,6 +194,11 @@ def test_import_sops(
str(test_root.joinpath("data", "secrets.yaml")), str(test_root.joinpath("data", "secrets.yaml")),
] ]
) )
capsys.readouterr()
cli.run(["users", "list"])
users = sorted(capsys.readouterr().out.rstrip().split())
assert users == ["user1", "user2"]
capsys.readouterr() capsys.readouterr()
cli.run(["get", "secret-key"]) cli.run(["get", "secret-key"])
assert capsys.readouterr().out == "secret-value" assert capsys.readouterr().out == "secret-value"