diff --git a/oks_cli/user.py b/oks_cli/user.py index ae67ef3..056ee66 100644 --- a/oks_cli/user.py +++ b/oks_cli/user.py @@ -7,6 +7,7 @@ from nacl.public import PrivateKey, SealedBox from nacl.encoding import Base64Encoder +from prettytable import TableStyle from .utils import do_request, print_output, find_project_id_by_name, ctx_update, login_profile, profile_completer, project_completer, JSONClickException @@ -166,4 +167,38 @@ def user_delete(ctx, project_name, user, output, dry_run, force, profile): if force or click.confirm(f"Are you sure you want to delete the user '{user}'?", abort=True): data = do_request("DELETE", f"projects/{project_id}/eim_users/{user}") print_output(data, output) + + +@user.command('types', help="List available user types") +@click.option('--project-name', '-p', required=False, help="Project Name", shell_complete=project_completer) +@click.option('--output', '-o', type=click.Choice(["json", "yaml"]), help="Specify output format") +@click.option('--plain', is_flag=True, help="Plain table format") +@click.option('--profile', help="Configuration profile to use", shell_complete=profile_completer) +@click.pass_context +def user_types(ctx, project_name, output, plain, profile): + """Display available user types.""" + project_name, _, profile = ctx_update(ctx, project_name, None, profile) + login_profile(profile) + + project_id = find_project_id_by_name(project_name) + + data = do_request("GET", f'projects/{project_id}/eim_users/types') + + if output: + print_output(data, output) + return + + table = prettytable.PrettyTable() + table.field_names = ["USER TYPE", "DESCRIPTION"] + + if plain: + table.set_style(TableStyle.PLAIN_COLUMNS) + + for entry in data: + table.add_row([ + entry.get("UserType", ""), + entry.get("Description") or "-" + ]) + + click.echo(table) diff --git a/oks_cli/utils.py b/oks_cli/utils.py index a0e719a..ef41bd6 100644 --- a/oks_cli/utils.py +++ b/oks_cli/utils.py @@ -85,6 +85,8 @@ def find_response_object(data): return response["EimUser"] elif key == "Data": return response + elif key == "EimUserTypes": + return response["EimUserTypes"] raise click.ClickException("The API response format is incorrect.") diff --git a/tests/test_user.py b/tests/test_user.py index e0dcb71..7963708 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -53,4 +53,36 @@ def test_user_delete_command(mock_request, add_default_profile): runner = CliRunner() result = runner.invoke(cli, ["user", "delete", "-p", "test", "-u", "OKSAuditor", "--force"]) assert result.exit_code == 0 - assert 'User has been deleted.' in result.output \ No newline at end of file + assert 'User has been deleted.' in result.output + +@patch("oks_cli.utils.requests.request") +def test_user_types_command(mock_request, add_default_profile): + mock_request.side_effect = [ + MagicMock(status_code=200, headers={}, json=lambda: {"ResponseContext": {}, "Projects": [{"id": "12345"}]}), + MagicMock(status_code=200, headers={}, json=lambda: {"ResponseContext": {}, "EimUserTypes": [ + {"UserType": "OKSSnapshotsManager", "Description": "OKS user with full access to snapshots"}, + {"UserType": "OKSVolumesManager", "Description": "OKS user with management access to volumes BSU"}, + ]}) + ] + + runner = CliRunner() + result = runner.invoke(cli, ["user", "types", "-p", "test"]) + assert result.exit_code == 0 + assert 'OKSSnapshotsManager' in result.output + assert 'OKSVolumesManager' in result.output + +@patch("oks_cli.utils.requests.request") +def test_user_types_command_json(mock_request, add_default_profile): + mock_request.side_effect = [ + MagicMock(status_code=200, headers={}, json=lambda: {"ResponseContext": {}, "Projects": [{"id": "12345"}]}), + MagicMock(status_code=200, headers={}, json=lambda: {"ResponseContext": {}, "EimUserTypes": [ + {"UserType": "OKSSnapshotsManager", "Description": "OKS user with full access to snapshots"}, + {"UserType": "OKSVolumesManager", "Description": "OKS user with management access to volumes BSU"}, + ]}) + ] + + runner = CliRunner() + result = runner.invoke(cli, ["user", "types", "-p", "test", "-o", "json"]) + assert result.exit_code == 0 + assert 'OKSSnapshotsManager' in result.output + assert 'OKS user with full access to snapshots' in result.output \ No newline at end of file