From 4e95030e55086f2e410a75ad087fd933113c63ae Mon Sep 17 00:00:00 2001 From: a-kenji Date: Tue, 4 Jun 2024 11:44:18 +0200 Subject: [PATCH 1/5] clan: `clan secrets groups` add machine completions --- pkgs/clan-cli/clan_cli/secrets/groups.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/secrets/groups.py b/pkgs/clan-cli/clan_cli/secrets/groups.py index 6056a9f19..3a38c944e 100644 --- a/pkgs/clan-cli/clan_cli/secrets/groups.py +++ b/pkgs/clan-cli/clan_cli/secrets/groups.py @@ -4,6 +4,7 @@ from pathlib import Path from clan_cli.git import commit_files +from ..completions import add_dynamic_completer, complete_machines from ..errors import ClanError from ..machines.types import machine_name_type, validate_hostname from . import secrets @@ -234,9 +235,10 @@ def register_groups_parser(parser: argparse.ArgumentParser) -> None: "add-machine", help="add a machine to group" ) add_group_argument(add_machine_parser) - add_machine_parser.add_argument( + add_machine_action = add_machine_parser.add_argument( "machine", help="the name of the machines to add", type=machine_name_type ) + add_dynamic_completer(add_machine_action, complete_machines) add_machine_parser.set_defaults(func=add_machine_command) # Remove machine @@ -244,9 +246,10 @@ def register_groups_parser(parser: argparse.ArgumentParser) -> None: "remove-machine", help="remove a machine from group" ) add_group_argument(remove_machine_parser) - remove_machine_parser.add_argument( + remove_machine_action = remove_machine_parser.add_argument( "machine", help="the name of the machines to remove", type=machine_name_type ) + add_dynamic_completer(remove_machine_action, complete_machines) remove_machine_parser.set_defaults(func=remove_machine_command) # Add user @@ -259,7 +262,7 @@ def register_groups_parser(parser: argparse.ArgumentParser) -> None: # Remove user remove_user_parser = subparser.add_parser( - "remove-user", help="remove a user from group" + "remove-user", help="remove a user from a group" ) add_group_argument(remove_user_parser) remove_user_parser.add_argument( From e7e5a1ded86c846338ca46bb99700d55215b702e Mon Sep 17 00:00:00 2001 From: a-kenji Date: Tue, 4 Jun 2024 11:51:27 +0200 Subject: [PATCH 2/5] clan: add completion function for clan users --- pkgs/clan-cli/clan_cli/completions.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pkgs/clan-cli/clan_cli/completions.py b/pkgs/clan-cli/clan_cli/completions.py index 4a0f02f1c..80ffde76a 100644 --- a/pkgs/clan-cli/clan_cli/completions.py +++ b/pkgs/clan-cli/clan_cli/completions.py @@ -144,6 +144,27 @@ def complete_secrets( return secrets_dict +def complete_users( + prefix: str, parsed_args: argparse.Namespace, **kwargs: Any +) -> Iterable[str]: + """ + Provides completion functionality for clan users + """ + from pathlib import Path + + from .secrets.users import list_users + + if (clan_dir_result := clan_dir(None)) is not None: + flake = clan_dir_result + else: + flake = "." + + users = list_users(Path(flake)) + + users_dict = {name: "user" for name in users} + return users_dict + + def add_dynamic_completer( action: argparse.Action, completer: Callable[..., Iterable[str]], From 533ed97fc16159b4a93107a8955d93938b5de867 Mon Sep 17 00:00:00 2001 From: a-kenji Date: Tue, 4 Jun 2024 13:25:33 +0200 Subject: [PATCH 3/5] clan: add dynamic completion for `clan secret groups` --- pkgs/clan-cli/clan_cli/secrets/groups.py | 35 +++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/secrets/groups.py b/pkgs/clan-cli/clan_cli/secrets/groups.py index 3a38c944e..78cdd0fbe 100644 --- a/pkgs/clan-cli/clan_cli/secrets/groups.py +++ b/pkgs/clan-cli/clan_cli/secrets/groups.py @@ -4,7 +4,13 @@ from pathlib import Path from clan_cli.git import commit_files -from ..completions import add_dynamic_completer, complete_machines +from ..completions import ( + add_dynamic_completer, + complete_groups, + complete_machines, + complete_secrets, + complete_users, +) from ..errors import ClanError from ..machines.types import machine_name_type, validate_hostname from . import secrets @@ -190,7 +196,10 @@ def remove_machine_command(args: argparse.Namespace) -> None: def add_group_argument(parser: argparse.ArgumentParser) -> None: - parser.add_argument("group", help="the name of the group", type=group_name_type) + group_action = parser.add_argument( + "group", help="the name of the secret", type=group_name_type + ) + add_dynamic_completer(group_action, complete_groups) def add_secret(flake_dir: Path, group: str, name: str) -> None: @@ -255,9 +264,10 @@ def register_groups_parser(parser: argparse.ArgumentParser) -> None: # Add user add_user_parser = subparser.add_parser("add-user", help="add a user to group") add_group_argument(add_user_parser) - add_user_parser.add_argument( + add_user_action = add_user_parser.add_argument( "user", help="the name of the user to add", type=user_name_type ) + add_dynamic_completer(add_user_action, complete_users) add_user_parser.set_defaults(func=add_user_command) # Remove user @@ -265,31 +275,30 @@ def register_groups_parser(parser: argparse.ArgumentParser) -> None: "remove-user", help="remove a user from a group" ) add_group_argument(remove_user_parser) - remove_user_parser.add_argument( + remove_user_action = remove_user_parser.add_argument( "user", help="the name of the user to remove", type=user_name_type ) + add_dynamic_completer(remove_user_action, complete_users) remove_user_parser.set_defaults(func=remove_user_command) # Add secret add_secret_parser = subparser.add_parser( - "add-secret", help="allow a user to access a secret" + "add-secret", help="allow a groups to access a secret" ) - add_secret_parser.add_argument( - "group", help="the name of the user", type=group_name_type - ) - add_secret_parser.add_argument( + add_group_argument(add_secret_parser) + add_secret_action = add_secret_parser.add_argument( "secret", help="the name of the secret", type=secret_name_type ) + add_dynamic_completer(add_secret_action, complete_secrets) add_secret_parser.set_defaults(func=add_secret_command) # Remove secret remove_secret_parser = subparser.add_parser( "remove-secret", help="remove a group's access to a secret" ) - remove_secret_parser.add_argument( - "group", help="the name of the group", type=group_name_type - ) - remove_secret_parser.add_argument( + add_group_argument(remove_secret_parser) + remove_secret_action = remove_secret_parser.add_argument( "secret", help="the name of the secret", type=secret_name_type ) + add_dynamic_completer(remove_secret_action, complete_secrets) remove_secret_parser.set_defaults(func=remove_secret_command) From b21bef0b98ab189791dd21af14059d61c1da62a1 Mon Sep 17 00:00:00 2001 From: a-kenji Date: Tue, 4 Jun 2024 13:27:51 +0200 Subject: [PATCH 4/5] clan: add dynamic completions for `clan secrets users` --- pkgs/clan-cli/clan_cli/secrets/users.py | 29 +++++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/secrets/users.py b/pkgs/clan-cli/clan_cli/secrets/users.py index 8f08eeb06..b6cdd5690 100644 --- a/pkgs/clan-cli/clan_cli/secrets/users.py +++ b/pkgs/clan-cli/clan_cli/secrets/users.py @@ -1,6 +1,11 @@ import argparse from pathlib import Path +from ..completions import ( + add_dynamic_completer, + complete_secrets, + complete_users, +) from ..errors import ClanError from ..git import commit_files from . import secrets @@ -141,31 +146,41 @@ def register_users_parser(parser: argparse.ArgumentParser) -> None: add_parser.set_defaults(func=add_command) get_parser = subparser.add_parser("get", help="get a user public key") - get_parser.add_argument("user", help="the name of the user", type=user_name_type) + get_user_action = get_parser.add_argument( + "user", help="the name of the user", type=user_name_type + ) + add_dynamic_completer(get_user_action, complete_users) get_parser.set_defaults(func=get_command) remove_parser = subparser.add_parser("remove", help="remove a user") - remove_parser.add_argument("user", help="the name of the user", type=user_name_type) + remove_user_action = remove_parser.add_argument( + "user", help="the name of the user", type=user_name_type + ) + add_dynamic_completer(remove_user_action, complete_users) remove_parser.set_defaults(func=remove_command) add_secret_parser = subparser.add_parser( "add-secret", help="allow a user to access a secret" ) - add_secret_parser.add_argument( - "user", help="the name of the group", type=user_name_type + add_secret_user_action = add_secret_parser.add_argument( + "user", help="the name of the user", type=user_name_type ) - add_secret_parser.add_argument( + add_dynamic_completer(add_secret_user_action, complete_users) + add_secrets_action = add_secret_parser.add_argument( "secret", help="the name of the secret", type=secret_name_type ) + add_dynamic_completer(add_secrets_action, complete_secrets) add_secret_parser.set_defaults(func=add_secret_command) remove_secret_parser = subparser.add_parser( "remove-secret", help="remove a user's access to a secret" ) - remove_secret_parser.add_argument( + remove_secret_user_action = remove_secret_parser.add_argument( "user", help="the name of the group", type=user_name_type ) - remove_secret_parser.add_argument( + add_dynamic_completer(remove_secret_user_action, complete_users) + remove_secrets_action = remove_secret_parser.add_argument( "secret", help="the name of the secret", type=secret_name_type ) + add_dynamic_completer(remove_secrets_action, complete_secrets) remove_secret_parser.set_defaults(func=remove_secret_command) From d4fabff7f42d4a659fc2111aa9f00f5cc45a73c3 Mon Sep 17 00:00:00 2001 From: a-kenji Date: Tue, 4 Jun 2024 13:28:08 +0200 Subject: [PATCH 5/5] clan: add dynamic completions for secret groups --- pkgs/clan-cli/clan_cli/completions.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pkgs/clan-cli/clan_cli/completions.py b/pkgs/clan-cli/clan_cli/completions.py index 80ffde76a..0fd4663b0 100644 --- a/pkgs/clan-cli/clan_cli/completions.py +++ b/pkgs/clan-cli/clan_cli/completions.py @@ -165,6 +165,28 @@ def complete_users( return users_dict +def complete_groups( + prefix: str, parsed_args: argparse.Namespace, **kwargs: Any +) -> Iterable[str]: + """ + Provides completion functionality for clan groups + """ + from pathlib import Path + + from .secrets.groups import list_groups + + if (clan_dir_result := clan_dir(None)) is not None: + flake = clan_dir_result + else: + flake = "." + + groups_list = list_groups(Path(flake)) + groups = [group.name for group in groups_list] + + groups_dict = {name: "group" for name in groups} + return groups_dict + + def add_dynamic_completer( action: argparse.Action, completer: Callable[..., Iterable[str]],