From 39495c39c689e874b53302100b56c806a61b9660 Mon Sep 17 00:00:00 2001 From: Kube Date: Tue, 23 Sep 2025 19:00:06 -0400 Subject: [PATCH 01/18] Adding in `collection role create` --- .../commands/collection/role/__init__.py | 1 + .../commands/collection/role/_common.py | 17 +++++ .../commands/collection/role/create.py | 68 +++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/globus_cli/commands/collection/role/_common.py create mode 100644 src/globus_cli/commands/collection/role/create.py diff --git a/src/globus_cli/commands/collection/role/__init__.py b/src/globus_cli/commands/collection/role/__init__.py index b16aa84bb..3bfbd8e5e 100644 --- a/src/globus_cli/commands/collection/role/__init__.py +++ b/src/globus_cli/commands/collection/role/__init__.py @@ -6,6 +6,7 @@ lazy_subcommands={ "list": (".list", "list_command"), "show": (".show", "show_command"), + "create": (".create", "create_command"), "delete": (".delete", "delete_command"), }, ) diff --git a/src/globus_cli/commands/collection/role/_common.py b/src/globus_cli/commands/collection/role/_common.py new file mode 100644 index 000000000..0eb5f26bb --- /dev/null +++ b/src/globus_cli/commands/collection/role/_common.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +import typing as t + +from globus_cli.termio import Field +from globus_cli.termio.formatters.auth import PrincipalURNFormatter + +if t.TYPE_CHECKING: + from globus_cli.services.auth import CustomAuthClient + + +def role_fields(auth_client: CustomAuthClient) -> list[Field]: + return [ + Field("ID", "id"), + Field("Role", "role"), + Field("Principal", "principal", formatter=PrincipalURNFormatter(auth_client)), + ] diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py new file mode 100644 index 000000000..b3e9dad3e --- /dev/null +++ b/src/globus_cli/commands/collection/role/create.py @@ -0,0 +1,68 @@ +import typing as t +import uuid + +import click +import globus_sdk + +from globus_cli.commands.collection.role._common import role_fields +from globus_cli.login_manager import LoginManager +from globus_cli.parsing import collection_id_arg, command +from globus_cli.termio import display +from globus_cli.utils import resolve_principal_urn + +_VALID_ROLES = t.Literal[ + "access_manager", "activity_manager", "activity_monitor", "administrator" +] + + +@command("create") +@collection_id_arg +@click.argument("ROLE", type=click.Choice(t.get_args(_VALID_ROLES)), metavar="ROLE") +@click.argument("PRINCIPAL", type=str) +@click.option( + "--principal-type", + type=click.Choice(["identity", "group"]), + help="Qualifier to specify what type of principal (identity or group) is provided.", +) +@LoginManager.requires_login("transfer") +def create_command( + login_manager: LoginManager, + *, + collection_id: uuid.UUID, + role: str, + principal: str, + principal_type: t.Literal["identity", "group"] | None, +) -> None: + """ + Create a role on a Collection. + + ROLE must be one of: + "administrator", + "access_manager", + "activity_manager", + "activity_monitor" + + PRINCIPAL must be a username, UUID, or URN associated with a globus identity or + group. + + If UUID, use `--principal-type` to specify the type (defaults to "identity"). + """ + + gcs_client = login_manager.get_gcs_client(collection_id=collection_id) + auth_client = login_manager.get_auth_client() + + # Format the principal into a URN + principal_urn = resolve_principal_urn( + auth_client=auth_client, + principal_type=principal_type, + principal=principal, + ) + + data = globus_sdk.GCSRoleDocument( + DATA_TYPE="role#1.0.0", + collection=collection_id, + role=role, + principal=principal_urn, + ) + res = gcs_client.create_role(data=data) + display(res, text_mode=display.RECORD, fields=role_fields(auth_client)) From cb68ac3469df307ea2d352d31024091d2f1aeaa3 Mon Sep 17 00:00:00 2001 From: Kube Date: Tue, 23 Sep 2025 20:07:37 -0400 Subject: [PATCH 02/18] Updated testing as well as formatting in create.py --- .../commands/collection/role/create.py | 25 ++++++------ .../api_fixtures/collection_operations.yaml | 11 ++++++ .../collection/role/test_role_create.py | 39 +++++++++++++++++++ 3 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 tests/functional/collection/role/test_role_create.py diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py index b3e9dad3e..6c248f50c 100644 --- a/src/globus_cli/commands/collection/role/create.py +++ b/src/globus_cli/commands/collection/role/create.py @@ -34,13 +34,14 @@ def create_command( principal_type: t.Literal["identity", "group"] | None, ) -> None: """ - Create a role on a Collection. + Create a role assignment on a Collection. ROLE must be one of: - "administrator", - "access_manager", - "activity_manager", - "activity_monitor" + + "administrator", + "access_manager", + "activity_manager", + "activity_monitor" PRINCIPAL must be a username, UUID, or URN associated with a globus identity or group. @@ -58,11 +59,13 @@ def create_command( principal=principal, ) - data = globus_sdk.GCSRoleDocument( - DATA_TYPE="role#1.0.0", - collection=collection_id, - role=role, - principal=principal_urn, + res = gcs_client.create_role( + globus_sdk.GCSRoleDocument( + DATA_TYPE="role#1.0.0", + collection=collection_id, + role=role, + principal=principal_urn, + ) ) - res = gcs_client.create_role(data=data) + display(res, text_mode=display.RECORD, fields=role_fields(auth_client)) diff --git a/tests/files/api_fixtures/collection_operations.yaml b/tests/files/api_fixtures/collection_operations.yaml index 065c1d9f8..a64670f10 100644 --- a/tests/files/api_fixtures/collection_operations.yaml +++ b/tests/files/api_fixtures/collection_operations.yaml @@ -1,4 +1,5 @@ metadata: + role: "activity_monitor" role_id: "0174edd0-998c-4147-a123-99ea38068145" role_identity_id: "081cfa08-b857-4f26-bf2b-13d08e581545" mapped_collection_id: "1405823f-0597-4a16-b296-46d4f0ae4b15" @@ -431,6 +432,16 @@ gcs: } ] } + - path: /roles/ + method: post + json: + { + "DATA_TYPE": "role#1.0.0", + "collection": "1405823f-0597-4a16-b296-46d4f0ae4b15", + "id": "0174edd0-998c-4147-a123-99ea38068145", + "principal": "urn:globus:auth:identity:081cfa08-b857-4f26-bf2b-13d08e581545", + "role": "activity_monitor" + } - path: /roles/0174edd0-998c-4147-a123-99ea38068145 method: delete json: diff --git a/tests/functional/collection/role/test_role_create.py b/tests/functional/collection/role/test_role_create.py new file mode 100644 index 000000000..7665b1396 --- /dev/null +++ b/tests/functional/collection/role/test_role_create.py @@ -0,0 +1,39 @@ +from globus_sdk._testing import RegisteredResponse, load_response_set + + +def test_successful_gcs_collection_role_creation( + run_line, + add_gcs_login, +): + # setup data for the collection_id -> endpoint_id lookup + # and create dummy credentials for the test to run against that GCS + meta = load_response_set("cli.collection_operations").metadata + endpoint_id = meta["endpoint_id"] + user_id = meta["role_identity_id"] + role = meta["role"] + role_id = meta["role_id"] + collection_id = meta["mapped_collection_id"] + add_gcs_login(endpoint_id) + + role = "activity_monitor" + + # mock the responses for the Delete Role API (GCS) + RegisteredResponse( + service="gcs", + path="/roles/", + json={ + "DATA_TYPE": "role#1.0.0", + "collection": f"{collection_id}", + "id": f"{role_id}", + "principal": f"urn:globus:auth:identity:{user_id}", + "role": "activity_monitor", + }, + ).add() + + # now test the command and confirm that a successful role creation is reported + run_line( + ["globus", "collection", "role", "create", collection_id, role, user_id], + search_stdout=[ + "success", + ], + ) From ee4569e70f17061f3a2f04a84958cb41c6655e07 Mon Sep 17 00:00:00 2001 From: Kube Date: Wed, 24 Sep 2025 17:41:30 -0400 Subject: [PATCH 03/18] Correcting test_role_delete.py and testin test_role_create.py change --- .../functional/collection/role/test_role_create.py | 13 +++++++++---- .../functional/collection/role/test_role_delete.py | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/functional/collection/role/test_role_create.py b/tests/functional/collection/role/test_role_create.py index 7665b1396..5418af521 100644 --- a/tests/functional/collection/role/test_role_create.py +++ b/tests/functional/collection/role/test_role_create.py @@ -8,16 +8,18 @@ def test_successful_gcs_collection_role_creation( # setup data for the collection_id -> endpoint_id lookup # and create dummy credentials for the test to run against that GCS meta = load_response_set("cli.collection_operations").metadata + + collection_id = meta["mapped_collection_id"] endpoint_id = meta["endpoint_id"] - user_id = meta["role_identity_id"] role = meta["role"] role_id = meta["role_id"] - collection_id = meta["mapped_collection_id"] + user_id = meta["role_identity_id"] + # username = meta["username"] add_gcs_login(endpoint_id) role = "activity_monitor" - # mock the responses for the Delete Role API (GCS) + # mock the responses for the Role API creation (GCS) RegisteredResponse( service="gcs", path="/roles/", @@ -30,10 +32,13 @@ def test_successful_gcs_collection_role_creation( }, ).add() + # ("Role", "activity_monitor"), + # ("ID", role_id), + # ("Principal", username), # now test the command and confirm that a successful role creation is reported run_line( ["globus", "collection", "role", "create", collection_id, role, user_id], search_stdout=[ - "success", + "activity_monitor", ], ) diff --git a/tests/functional/collection/role/test_role_delete.py b/tests/functional/collection/role/test_role_delete.py index 729e2060f..7a354b3e9 100644 --- a/tests/functional/collection/role/test_role_delete.py +++ b/tests/functional/collection/role/test_role_delete.py @@ -30,7 +30,7 @@ def test_successful_gcs_collection_role_delete( # now test the command and confirm that a successful role deletion is reported run_line( - ["globus", "gcs", "collection", "role", "delete", collection_id, role_id], + ["globus", "collection", "role", "delete", collection_id, role_id], search_stdout=[ "success", ], From 4c099120a80f867eeeddff1c202835b3b0555972 Mon Sep 17 00:00:00 2001 From: Kube Date: Sat, 27 Sep 2025 19:23:16 -0400 Subject: [PATCH 04/18] Switched to returning the role ID only --- .../commands/collection/role/_common.py | 17 ---------- .../commands/collection/role/create.py | 3 +- .../api_fixtures/collection_operations.yaml | 24 ++++++++++---- .../collection/role/test_role_create.py | 32 +++++++++++-------- .../collection/role/test_role_list.py | 2 +- 5 files changed, 38 insertions(+), 40 deletions(-) delete mode 100644 src/globus_cli/commands/collection/role/_common.py diff --git a/src/globus_cli/commands/collection/role/_common.py b/src/globus_cli/commands/collection/role/_common.py deleted file mode 100644 index 0eb5f26bb..000000000 --- a/src/globus_cli/commands/collection/role/_common.py +++ /dev/null @@ -1,17 +0,0 @@ -from __future__ import annotations - -import typing as t - -from globus_cli.termio import Field -from globus_cli.termio.formatters.auth import PrincipalURNFormatter - -if t.TYPE_CHECKING: - from globus_cli.services.auth import CustomAuthClient - - -def role_fields(auth_client: CustomAuthClient) -> list[Field]: - return [ - Field("ID", "id"), - Field("Role", "role"), - Field("Principal", "principal", formatter=PrincipalURNFormatter(auth_client)), - ] diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py index 6c248f50c..02bcf8d18 100644 --- a/src/globus_cli/commands/collection/role/create.py +++ b/src/globus_cli/commands/collection/role/create.py @@ -4,7 +4,6 @@ import click import globus_sdk -from globus_cli.commands.collection.role._common import role_fields from globus_cli.login_manager import LoginManager from globus_cli.parsing import collection_id_arg, command from globus_cli.termio import display @@ -68,4 +67,4 @@ def create_command( ) ) - display(res, text_mode=display.RECORD, fields=role_fields(auth_client)) + display(res, simple_text="ID: {}".format(res["id"])) diff --git a/tests/files/api_fixtures/collection_operations.yaml b/tests/files/api_fixtures/collection_operations.yaml index a64670f10..e2a73bbd0 100644 --- a/tests/files/api_fixtures/collection_operations.yaml +++ b/tests/files/api_fixtures/collection_operations.yaml @@ -1,13 +1,13 @@ metadata: role: "activity_monitor" role_id: "0174edd0-998c-4147-a123-99ea38068145" - role_identity_id: "081cfa08-b857-4f26-bf2b-13d08e581545" mapped_collection_id: "1405823f-0597-4a16-b296-46d4f0ae4b15" guest_collection_id: "0e4a77f8-b778-4d5c-abaa-e1254e71427f" endpoint_id: "cf37806c-572c-47ff-88e2-511c646ef1a4" gcp_endpoint_id: "06e2c959-d311-4bab-b2ea-25ad77d9fc12" local_username: "recyclops" identity_id: "e926d510-cb98-11e5-a6ac-0b0216052512" + identity_username: "pytest@globus.org" gcs_hostname: "abc.xyz.data.globus.org" guest_display_name: "Happy Fun Guest Collection Name" @@ -432,15 +432,25 @@ gcs: } ] } - - path: /roles/ + - path: /roles method: post json: { - "DATA_TYPE": "role#1.0.0", - "collection": "1405823f-0597-4a16-b296-46d4f0ae4b15", - "id": "0174edd0-998c-4147-a123-99ea38068145", - "principal": "urn:globus:auth:identity:081cfa08-b857-4f26-bf2b-13d08e581545", - "role": "activity_monitor" + "DATA_TYPE": "result#1.1.0", + "code": "success", + "data": [ + { + "DATA_TYPE": "role#1.0.0", + "collection": "1405823f-0597-4a16-b296-46d4f0ae4b15", + "id": "0174edd0-998c-4147-a123-99ea38068145", + "principal": "urn:globus:auth:identity:e926d510-cb98-11e5-a6ac-0b0216052512", + "role": "activity_monitor" + } + ], + "detail": "success", + "has_next_page": False, + "http_response_code" : 200, + "message": "Created new role 0174edd0-998c-4147-a123-99ea38068145" } - path: /roles/0174edd0-998c-4147-a123-99ea38068145 method: delete diff --git a/tests/functional/collection/role/test_role_create.py b/tests/functional/collection/role/test_role_create.py index 5418af521..34dea849e 100644 --- a/tests/functional/collection/role/test_role_create.py +++ b/tests/functional/collection/role/test_role_create.py @@ -13,32 +13,38 @@ def test_successful_gcs_collection_role_creation( endpoint_id = meta["endpoint_id"] role = meta["role"] role_id = meta["role_id"] - user_id = meta["role_identity_id"] - # username = meta["username"] + user_id = meta["identity_id"] add_gcs_login(endpoint_id) role = "activity_monitor" - # mock the responses for the Role API creation (GCS) + # mock the responses for the [post] Role API (GCS) RegisteredResponse( service="gcs", - path="/roles/", + path="/roles", json={ - "DATA_TYPE": "role#1.0.0", - "collection": f"{collection_id}", - "id": f"{role_id}", - "principal": f"urn:globus:auth:identity:{user_id}", - "role": "activity_monitor", + "DATA_TYPE": "result#1.1.0", + "code": "success", + "data": [ + { + "DATA_TYPE": "role#1.0.0", + "collection": f"{collection_id}", + "id": f"{role_id}", + "principal": f"urn:globus:auth:identity:{user_id}", + "role": "activity_monitor", + } + ], + "detail": "success", + "has_next_page": False, + "http_response_code": 200, + "message": f"Created new role {role_id}", }, ).add() - # ("Role", "activity_monitor"), - # ("ID", role_id), - # ("Principal", username), # now test the command and confirm that a successful role creation is reported run_line( ["globus", "collection", "role", "create", collection_id, role, user_id], search_stdout=[ - "activity_monitor", + ("ID", role_id), ], ) diff --git a/tests/functional/collection/role/test_role_list.py b/tests/functional/collection/role/test_role_list.py index 0360d3aff..21a5bbe31 100644 --- a/tests/functional/collection/role/test_role_list.py +++ b/tests/functional/collection/role/test_role_list.py @@ -47,7 +47,7 @@ def test_successful_gcs_collection_role_list( # now test the command and confirm that output shows the role name and the # username run_line( - ["globus", "gcs", "collection", "role", "list", collection_id], + ["globus", "collection", "role", "list", collection_id], search_stdout=[ ("ID", user_id), ("Role", "administrator"), From 524f90b4ab80fab6c402e9cbc154db4a592c7b20 Mon Sep 17 00:00:00 2001 From: Kube Date: Sat, 27 Sep 2025 19:46:14 -0400 Subject: [PATCH 05/18] Adding Changelog entry --- .../20250927_194304_james_SC_38762_Collection_Role_Create.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelog.d/20250927_194304_james_SC_38762_Collection_Role_Create.md diff --git a/changelog.d/20250927_194304_james_SC_38762_Collection_Role_Create.md b/changelog.d/20250927_194304_james_SC_38762_Collection_Role_Create.md new file mode 100644 index 000000000..0cf7ab625 --- /dev/null +++ b/changelog.d/20250927_194304_james_SC_38762_Collection_Role_Create.md @@ -0,0 +1,4 @@ +### Enhancements + +* Add a new command for interacting with collection roles, + `globus gcs collection role create` From cb39e0d1ec8fa6a695c6a95c4bd7eb28c77d18a0 Mon Sep 17 00:00:00 2001 From: Kube Date: Sat, 27 Sep 2025 19:56:26 -0400 Subject: [PATCH 06/18] Removing unused variable 'identity_username' --- tests/files/api_fixtures/collection_operations.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/files/api_fixtures/collection_operations.yaml b/tests/files/api_fixtures/collection_operations.yaml index e2a73bbd0..a50789c4d 100644 --- a/tests/files/api_fixtures/collection_operations.yaml +++ b/tests/files/api_fixtures/collection_operations.yaml @@ -7,7 +7,6 @@ metadata: gcp_endpoint_id: "06e2c959-d311-4bab-b2ea-25ad77d9fc12" local_username: "recyclops" identity_id: "e926d510-cb98-11e5-a6ac-0b0216052512" - identity_username: "pytest@globus.org" gcs_hostname: "abc.xyz.data.globus.org" guest_display_name: "Happy Fun Guest Collection Name" From 36d728725f2309bee31bcf2c2152c2b2465ee4b2 Mon Sep 17 00:00:00 2001 From: Kube Date: Fri, 3 Oct 2025 19:36:52 -0400 Subject: [PATCH 07/18] Correcting type hints --- src/globus_cli/commands/collection/role/create.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py index 02bcf8d18..309e74b13 100644 --- a/src/globus_cli/commands/collection/role/create.py +++ b/src/globus_cli/commands/collection/role/create.py @@ -28,7 +28,9 @@ def create_command( login_manager: LoginManager, *, collection_id: uuid.UUID, - role: str, + role: t.Literal[ + "access_manager", "activity_manager", "activity_monitor", "administrator" + ], principal: str, principal_type: t.Literal["identity", "group"] | None, ) -> None: From dbfb4cfdffe78029c8b5ed7813ce6414026011f4 Mon Sep 17 00:00:00 2001 From: Kube Date: Thu, 16 Oct 2025 11:37:46 -0400 Subject: [PATCH 08/18] Adding in missing import of annotations --- src/globus_cli/commands/collection/role/create.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py index 309e74b13..762e2960f 100644 --- a/src/globus_cli/commands/collection/role/create.py +++ b/src/globus_cli/commands/collection/role/create.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import typing as t import uuid From a96a780f5765d05fa3eec05ec4ddfe6b6f560121 Mon Sep 17 00:00:00 2001 From: Kube Date: Tue, 21 Oct 2025 18:43:22 -0400 Subject: [PATCH 09/18] Switching display to a fieldset from text --- src/globus_cli/commands/collection/role/create.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py index 762e2960f..d6e2e973f 100644 --- a/src/globus_cli/commands/collection/role/create.py +++ b/src/globus_cli/commands/collection/role/create.py @@ -8,7 +8,7 @@ from globus_cli.login_manager import LoginManager from globus_cli.parsing import collection_id_arg, command -from globus_cli.termio import display +from globus_cli.termio import Field, display from globus_cli.utils import resolve_principal_urn _VALID_ROLES = t.Literal[ @@ -71,4 +71,10 @@ def create_command( ) ) - display(res, simple_text="ID: {}".format(res["id"])) + display( + res, + text_mode=display.RECORD, + fields=[ + Field("Principal", "principal"), + ], + ) From b8e9b1cec10afeaf58029e90dec291a3679d28ab Mon Sep 17 00:00:00 2001 From: Kube Date: Mon, 10 Nov 2025 09:37:14 -0500 Subject: [PATCH 10/18] Correcting tests --- src/globus_cli/commands/collection/role/create.py | 2 +- tests/functional/collection/role/test_role_create.py | 2 +- tests/functional/collection/role/test_role_delete.py | 4 ++-- tests/functional/collection/role/test_role_list.py | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py index d6e2e973f..31c583541 100644 --- a/src/globus_cli/commands/collection/role/create.py +++ b/src/globus_cli/commands/collection/role/create.py @@ -75,6 +75,6 @@ def create_command( res, text_mode=display.RECORD, fields=[ - Field("Principal", "principal"), + Field("ID", "id"), ], ) diff --git a/tests/functional/collection/role/test_role_create.py b/tests/functional/collection/role/test_role_create.py index 34dea849e..9eb858f15 100644 --- a/tests/functional/collection/role/test_role_create.py +++ b/tests/functional/collection/role/test_role_create.py @@ -43,7 +43,7 @@ def test_successful_gcs_collection_role_creation( # now test the command and confirm that a successful role creation is reported run_line( - ["globus", "collection", "role", "create", collection_id, role, user_id], + ["globus", "gcs", "collection", "role", "create", collection_id, role, user_id], search_stdout=[ ("ID", role_id), ], diff --git a/tests/functional/collection/role/test_role_delete.py b/tests/functional/collection/role/test_role_delete.py index 59ac3500c..729e2060f 100644 --- a/tests/functional/collection/role/test_role_delete.py +++ b/tests/functional/collection/role/test_role_delete.py @@ -1,4 +1,4 @@ -from globus_sdk.testing import RegisteredResponse, load_response_set +from globus_sdk._testing import RegisteredResponse, load_response_set def test_successful_gcs_collection_role_delete( @@ -30,7 +30,7 @@ def test_successful_gcs_collection_role_delete( # now test the command and confirm that a successful role deletion is reported run_line( - ["globus", "collection", "role", "delete", collection_id, role_id], + ["globus", "gcs", "collection", "role", "delete", collection_id, role_id], search_stdout=[ "success", ], diff --git a/tests/functional/collection/role/test_role_list.py b/tests/functional/collection/role/test_role_list.py index 0bf6e6694..0360d3aff 100644 --- a/tests/functional/collection/role/test_role_list.py +++ b/tests/functional/collection/role/test_role_list.py @@ -1,6 +1,6 @@ import uuid -from globus_sdk.testing import RegisteredResponse, load_response_set +from globus_sdk._testing import RegisteredResponse, load_response_set def test_successful_gcs_collection_role_list( @@ -47,7 +47,7 @@ def test_successful_gcs_collection_role_list( # now test the command and confirm that output shows the role name and the # username run_line( - ["globus", "collection", "role", "list", collection_id], + ["globus", "gcs", "collection", "role", "list", collection_id], search_stdout=[ ("ID", user_id), ("Role", "administrator"), From 2ff8829db280f1ab04b0ba9bcfc7d85ffe444a8e Mon Sep 17 00:00:00 2001 From: Kube Date: Mon, 10 Nov 2025 10:33:47 -0500 Subject: [PATCH 11/18] Correcting tests --- tests/functional/collection/role/test_role_create.py | 2 +- tests/functional/collection/role/test_role_delete.py | 2 +- tests/functional/collection/role/test_role_list.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/functional/collection/role/test_role_create.py b/tests/functional/collection/role/test_role_create.py index 9eb858f15..35907dba4 100644 --- a/tests/functional/collection/role/test_role_create.py +++ b/tests/functional/collection/role/test_role_create.py @@ -1,4 +1,4 @@ -from globus_sdk._testing import RegisteredResponse, load_response_set +from globus_sdk.testing import RegisteredResponse, load_response_set def test_successful_gcs_collection_role_creation( diff --git a/tests/functional/collection/role/test_role_delete.py b/tests/functional/collection/role/test_role_delete.py index 729e2060f..8cd0d91cb 100644 --- a/tests/functional/collection/role/test_role_delete.py +++ b/tests/functional/collection/role/test_role_delete.py @@ -1,4 +1,4 @@ -from globus_sdk._testing import RegisteredResponse, load_response_set +from globus_sdk.testing import RegisteredResponse, load_response_set def test_successful_gcs_collection_role_delete( diff --git a/tests/functional/collection/role/test_role_list.py b/tests/functional/collection/role/test_role_list.py index 0360d3aff..84a05566d 100644 --- a/tests/functional/collection/role/test_role_list.py +++ b/tests/functional/collection/role/test_role_list.py @@ -1,6 +1,6 @@ import uuid -from globus_sdk._testing import RegisteredResponse, load_response_set +from globus_sdk.testing import RegisteredResponse, load_response_set def test_successful_gcs_collection_role_list( From 6f86379820a23ba06d9cef0f2e957eb5f3b28ee4 Mon Sep 17 00:00:00 2001 From: Kube Date: Mon, 10 Nov 2025 10:33:47 -0500 Subject: [PATCH 12/18] Correcting tests --- .../collection/role/test_role_create.py | 25 +------------------ .../collection/role/test_role_delete.py | 2 +- .../collection/role/test_role_list.py | 2 +- 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/tests/functional/collection/role/test_role_create.py b/tests/functional/collection/role/test_role_create.py index 9eb858f15..fc9c49ff3 100644 --- a/tests/functional/collection/role/test_role_create.py +++ b/tests/functional/collection/role/test_role_create.py @@ -1,4 +1,4 @@ -from globus_sdk._testing import RegisteredResponse, load_response_set +from globus_sdk.testing import load_response_set def test_successful_gcs_collection_role_creation( @@ -18,29 +18,6 @@ def test_successful_gcs_collection_role_creation( role = "activity_monitor" - # mock the responses for the [post] Role API (GCS) - RegisteredResponse( - service="gcs", - path="/roles", - json={ - "DATA_TYPE": "result#1.1.0", - "code": "success", - "data": [ - { - "DATA_TYPE": "role#1.0.0", - "collection": f"{collection_id}", - "id": f"{role_id}", - "principal": f"urn:globus:auth:identity:{user_id}", - "role": "activity_monitor", - } - ], - "detail": "success", - "has_next_page": False, - "http_response_code": 200, - "message": f"Created new role {role_id}", - }, - ).add() - # now test the command and confirm that a successful role creation is reported run_line( ["globus", "gcs", "collection", "role", "create", collection_id, role, user_id], diff --git a/tests/functional/collection/role/test_role_delete.py b/tests/functional/collection/role/test_role_delete.py index 729e2060f..8cd0d91cb 100644 --- a/tests/functional/collection/role/test_role_delete.py +++ b/tests/functional/collection/role/test_role_delete.py @@ -1,4 +1,4 @@ -from globus_sdk._testing import RegisteredResponse, load_response_set +from globus_sdk.testing import RegisteredResponse, load_response_set def test_successful_gcs_collection_role_delete( diff --git a/tests/functional/collection/role/test_role_list.py b/tests/functional/collection/role/test_role_list.py index 0360d3aff..84a05566d 100644 --- a/tests/functional/collection/role/test_role_list.py +++ b/tests/functional/collection/role/test_role_list.py @@ -1,6 +1,6 @@ import uuid -from globus_sdk._testing import RegisteredResponse, load_response_set +from globus_sdk.testing import RegisteredResponse, load_response_set def test_successful_gcs_collection_role_list( From 8daa6c581664ac78c5b6df5e6608b24616b7e126 Mon Sep 17 00:00:00 2001 From: Kube Date: Mon, 10 Nov 2025 11:26:59 -0500 Subject: [PATCH 13/18] Making principal argument optional and looking up currently logged in users primary identity for role assignments target principal --- src/globus_cli/commands/collection/role/create.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py index 31c583541..913ddc9ac 100644 --- a/src/globus_cli/commands/collection/role/create.py +++ b/src/globus_cli/commands/collection/role/create.py @@ -19,7 +19,7 @@ @command("create") @collection_id_arg @click.argument("ROLE", type=click.Choice(t.get_args(_VALID_ROLES)), metavar="ROLE") -@click.argument("PRINCIPAL", type=str) +@click.argument("PRINCIPAL", type=str, required=False) @click.option( "--principal-type", type=click.Choice(["identity", "group"]), @@ -33,7 +33,7 @@ def create_command( role: t.Literal[ "access_manager", "activity_manager", "activity_monitor", "administrator" ], - principal: str, + principal: str | None, principal_type: t.Literal["identity", "group"] | None, ) -> None: """ @@ -47,7 +47,7 @@ def create_command( "activity_monitor" PRINCIPAL must be a username, UUID, or URN associated with a globus identity or - group. + group if specified, otherwise the users primary identity will be used. If UUID, use `--principal-type` to specify the type (defaults to "identity"). """ @@ -55,6 +55,11 @@ def create_command( gcs_client = login_manager.get_gcs_client(collection_id=collection_id) auth_client = login_manager.get_auth_client() + # If Principal argument isn't provided, determine user's primary identity + if principal is None: + userinfo = auth_client.userinfo() + principal = userinfo["sub"] + # Format the principal into a URN principal_urn = resolve_principal_urn( auth_client=auth_client, From 8bd9bc773032cd1bd5c90b6d0cdfca3879982bb3 Mon Sep 17 00:00:00 2001 From: Kube Date: Mon, 10 Nov 2025 16:37:41 -0500 Subject: [PATCH 14/18] Adding verbiage for PRINCIPAL argument handling [default vs explicit value] --- src/globus_cli/commands/collection/role/create.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py index 913ddc9ac..de1699794 100644 --- a/src/globus_cli/commands/collection/role/create.py +++ b/src/globus_cli/commands/collection/role/create.py @@ -46,8 +46,11 @@ def create_command( "activity_manager", "activity_monitor" - PRINCIPAL must be a username, UUID, or URN associated with a globus identity or - group if specified, otherwise the users primary identity will be used. + If a PRINCIPAL value is not provided the primary identity of the logged in user will + be used. + + If a PRINCIPAL value is provided, it must be a username, UUID, or URN associated + with a globus identity or group. If UUID, use `--principal-type` to specify the type (defaults to "identity"). """ From 37e957055542620e5d7543d04a9742eb49cb7eff Mon Sep 17 00:00:00 2001 From: Kube Date: Wed, 12 Nov 2025 08:40:11 -0500 Subject: [PATCH 15/18] Making collection roles classier with _fields.py --- .../commands/collection/role/_fields.py | 43 +++++++++++++++++++ .../commands/collection/role/create.py | 13 +++--- .../commands/collection/role/list.py | 13 ++---- 3 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 src/globus_cli/commands/collection/role/_fields.py diff --git a/src/globus_cli/commands/collection/role/_fields.py b/src/globus_cli/commands/collection/role/_fields.py new file mode 100644 index 000000000..90d9029cb --- /dev/null +++ b/src/globus_cli/commands/collection/role/_fields.py @@ -0,0 +1,43 @@ +import typing as t + +import globus_sdk + +from globus_cli.termio import Field, formatters +from globus_cli.termio.formatters.auth import PrincipalURNFormatter + + +class CollectionRoleFormatter(PrincipalURNFormatter): + """ + A formatter for collection roles + """ + + def __init__( + self, auth_client: globus_sdk.AuthClient, collection_role: dict[str, t.Any] + ) -> None: + super().__init__(auth_client) + self.add_items(collection_role.get("id")) + self.add_items(*collection_role.get("role", ())) + self.add_items(*collection_role.get("principal", ())) + + +def collection_role_format_fields( + auth_client: globus_sdk.AuthClient, + collection_roles: dict[str, t.Any], +) -> list[Field]: + """ + The standard list of fields to render for a collection role. + + :param auth_client: An AuthClient, used to resolve principal URNs. + :param collection_role: The collection role to format + """ + principal = CollectionRoleFormatter(auth_client, collection_roles) + csv_roles_list = formatters.ArrayFormatter( + element_formatter=principal, + delimiter=", ", + ) + + return [ + Field("ID", "id", formatter=csv_roles_list), + Field("Role", "role", formatter=csv_roles_list), + Field("Principal", "principal", formatter=principal), + ] diff --git a/src/globus_cli/commands/collection/role/create.py b/src/globus_cli/commands/collection/role/create.py index de1699794..404ddab6e 100644 --- a/src/globus_cli/commands/collection/role/create.py +++ b/src/globus_cli/commands/collection/role/create.py @@ -6,9 +6,10 @@ import click import globus_sdk +from globus_cli.commands.collection.role._fields import collection_role_format_fields from globus_cli.login_manager import LoginManager from globus_cli.parsing import collection_id_arg, command -from globus_cli.termio import Field, display +from globus_cli.termio import display from globus_cli.utils import resolve_principal_urn _VALID_ROLES = t.Literal[ @@ -79,10 +80,6 @@ def create_command( ) ) - display( - res, - text_mode=display.RECORD, - fields=[ - Field("ID", "id"), - ], - ) + fields = collection_role_format_fields(auth_client, res.data) + + display(res, text_mode=display.RECORD, fields=fields) diff --git a/src/globus_cli/commands/collection/role/list.py b/src/globus_cli/commands/collection/role/list.py index e68b64b61..3a3c55a18 100644 --- a/src/globus_cli/commands/collection/role/list.py +++ b/src/globus_cli/commands/collection/role/list.py @@ -2,10 +2,10 @@ import click +from globus_cli.commands.collection.role._fields import collection_role_format_fields from globus_cli.login_manager import LoginManager from globus_cli.parsing import collection_id_arg, command -from globus_cli.termio import Field, display -from globus_cli.termio.formatters.auth import PrincipalURNFormatter +from globus_cli.termio import display @command("list") @@ -27,14 +27,9 @@ def list_command( else: res = gcs_client.get_role_list(collection_id) + fields = collection_role_format_fields(auth_client, res.data) display( res, text_mode=display.RECORD_LIST, - fields=[ - Field("ID", "id"), - Field("Role", "role"), - Field( - "Principal", "principal", formatter=PrincipalURNFormatter(auth_client) - ), - ], + fields=fields, ) From 02d161e68e54648a4ac13cad00671e06cfacdeb8 Mon Sep 17 00:00:00 2001 From: Kube Date: Thu, 13 Nov 2025 08:54:54 -0500 Subject: [PATCH 16/18] Updating tests and collection_operations.yaml to include and auth response for identity --- .../commands/collection/role/_fields.py | 20 ++++------ .../api_fixtures/collection_operations.yaml | 38 +++++++++++++++++- .../collection/role/test_role_create.py | 3 ++ .../collection/role/test_role_list.py | 40 +++---------------- 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/globus_cli/commands/collection/role/_fields.py b/src/globus_cli/commands/collection/role/_fields.py index 90d9029cb..f771331fe 100644 --- a/src/globus_cli/commands/collection/role/_fields.py +++ b/src/globus_cli/commands/collection/role/_fields.py @@ -2,7 +2,7 @@ import globus_sdk -from globus_cli.termio import Field, formatters +from globus_cli.termio import Field from globus_cli.termio.formatters.auth import PrincipalURNFormatter @@ -16,28 +16,24 @@ def __init__( ) -> None: super().__init__(auth_client) self.add_items(collection_role.get("id")) - self.add_items(*collection_role.get("role", ())) - self.add_items(*collection_role.get("principal", ())) + self.add_items(collection_role.get("role", ())) + self.add_items(collection_role.get("principal")) def collection_role_format_fields( auth_client: globus_sdk.AuthClient, - collection_roles: dict[str, t.Any], + collection_role: dict[str, t.Any], ) -> list[Field]: """ The standard list of fields to render for a collection role. :param auth_client: An AuthClient, used to resolve principal URNs. - :param collection_role: The collection role to format + :param collection_role: The collection role assignment to format """ - principal = CollectionRoleFormatter(auth_client, collection_roles) - csv_roles_list = formatters.ArrayFormatter( - element_formatter=principal, - delimiter=", ", - ) + principal = CollectionRoleFormatter(auth_client, collection_role) return [ - Field("ID", "id", formatter=csv_roles_list), - Field("Role", "role", formatter=csv_roles_list), + Field("ID", "id"), + Field("Role", "role"), Field("Principal", "principal", formatter=principal), ] diff --git a/tests/files/api_fixtures/collection_operations.yaml b/tests/files/api_fixtures/collection_operations.yaml index 172b0f6d7..5c60c36ba 100644 --- a/tests/files/api_fixtures/collection_operations.yaml +++ b/tests/files/api_fixtures/collection_operations.yaml @@ -7,6 +7,7 @@ metadata: gcp_endpoint_id: "06e2c959-d311-4bab-b2ea-25ad77d9fc12" local_username: "recyclops" identity_id: "e926d510-cb98-11e5-a6ac-0b0216052512" + username: "testidentity@globus.org" gcs_hostname: "abc.xyz.data.globus.org" guest_display_name: "Happy Fun Guest Collection Name" @@ -196,7 +197,23 @@ auth: } ] } - + - path: /v2/api/identities + method: get + json: + { + "identities": [ + { + "email": "testidentity@globus.org", + "id": "e926d510-cb98-11e5-a6ac-0b0216052512", + "identity_provider": "927d7238-f917-4eb2-9ace-c523fa9ba34e", + "identity_type": "login", + "name": "Test User", + "organization": "Globus", + "status": "used", + "username": "testidentity@globus.org" + } + ] + } gcs: - path: /collections method: post @@ -431,6 +448,25 @@ gcs: } ] } + - path: /roles + method: get + json: + { + "DATA_TYPE": "result#1.1.0", + "code": "success", + "data": [ + { + "DATA_TYPE": "role#1.0.0", + "collection": "1405823f-0597-4a16-b296-46d4f0ae4b15", + "id": "0174edd0-998c-4147-a123-99ea38068145", + "principal": "urn:globus:auth:identity:e926d510-cb98-11e5-a6ac-0b0216052512", + "role": "activity_monitor" + } + ], + "detail": "success", + "has_next_page": False, + "http_response_code": 200, + } - path: /roles method: post json: diff --git a/tests/functional/collection/role/test_role_create.py b/tests/functional/collection/role/test_role_create.py index fc9c49ff3..4f93bd2b0 100644 --- a/tests/functional/collection/role/test_role_create.py +++ b/tests/functional/collection/role/test_role_create.py @@ -14,6 +14,7 @@ def test_successful_gcs_collection_role_creation( role = meta["role"] role_id = meta["role_id"] user_id = meta["identity_id"] + username = meta["username"] add_gcs_login(endpoint_id) role = "activity_monitor" @@ -23,5 +24,7 @@ def test_successful_gcs_collection_role_creation( ["globus", "gcs", "collection", "role", "create", collection_id, role, user_id], search_stdout=[ ("ID", role_id), + ("Role", role), + ("Principal", username), ], ) diff --git a/tests/functional/collection/role/test_role_list.py b/tests/functional/collection/role/test_role_list.py index 84a05566d..b7025745c 100644 --- a/tests/functional/collection/role/test_role_list.py +++ b/tests/functional/collection/role/test_role_list.py @@ -1,6 +1,4 @@ -import uuid - -from globus_sdk.testing import RegisteredResponse, load_response_set +from globus_sdk.testing import load_response_set def test_successful_gcs_collection_role_list( @@ -14,43 +12,17 @@ def test_successful_gcs_collection_role_list( endpoint_id = meta["endpoint_id"] collection_id = meta["mapped_collection_id"] add_gcs_login(endpoint_id) - - user_id = str(uuid.UUID(int=2)) - - # mock the responses for the Get Role API (GCS) - RegisteredResponse( - service="gcs", - path="/roles", - json={ - "DATA_TYPE": "result#1.1.0", - "code": "success", - "data": [ - { - "DATA_TYPE": "role#1.0.0", - "collection": f"{collection_id}", - "id": f"{user_id}", - "principal": f"urn:globus:auth:identity:{user_id}", - "role": "administrator", - } - ], - "detail": "success", - "has_next_page": False, - "http_response_code": 200, - }, - ).add() - - # Mock the Get Identities API (Auth) - # so that CLI output rendering can show a username - user_meta = get_identities_mocker.configure_one(id=user_id).metadata - username = user_meta["username"] + role = meta["role"] + role_id = meta["role_id"] + username = meta["username"] # now test the command and confirm that output shows the role name and the # username run_line( ["globus", "gcs", "collection", "role", "list", collection_id], search_stdout=[ - ("ID", user_id), - ("Role", "administrator"), + ("ID", role_id), + ("Role", role), ("Principal", username), ], ) From 1dd8494d6aa8629108a8cf27a0b6c84dfa6a39c5 Mon Sep 17 00:00:00 2001 From: Kube Date: Thu, 13 Nov 2025 10:00:31 -0500 Subject: [PATCH 17/18] Adding additional Collection roles routes in support of testing and switching all tests over --- .../commands/collection/role/show.py | 21 ++++++++------- .../api_fixtures/collection_operations.yaml | 24 ++++++++++++++--- .../collection/role/test_role_create.py | 7 ++++- .../collection/role/test_role_list.py | 9 +++++-- .../collection/role/test_role_show.py | 26 +++++-------------- 5 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/globus_cli/commands/collection/role/show.py b/src/globus_cli/commands/collection/role/show.py index 3619d26fd..bdc836d9a 100644 --- a/src/globus_cli/commands/collection/role/show.py +++ b/src/globus_cli/commands/collection/role/show.py @@ -2,10 +2,10 @@ import click +from globus_cli.commands.collection.role._fields import collection_role_format_fields from globus_cli.login_manager import LoginManager from globus_cli.parsing import collection_id_arg, command -from globus_cli.termio import Field, display -from globus_cli.termio.formatters.auth import PrincipalURNFormatter +from globus_cli.termio import display @command("show") @@ -24,14 +24,17 @@ def show_command( res = gcs_client.get_role(role_id) + fields = collection_role_format_fields(auth_client, res.data) + display( res, text_mode=display.RECORD, - fields=[ - Field("ID", "id"), - Field("Role", "role"), - Field( - "Principal", "principal", formatter=PrincipalURNFormatter(auth_client) - ), - ], + fields=fields, ) + # fields=[ + # Field("ID", "id"), + # Field("Role", "role"), + # Field( + # "Principal", "principal", formatter=PrincipalURNFormatter(auth_client) + # ), + # ], diff --git a/tests/files/api_fixtures/collection_operations.yaml b/tests/files/api_fixtures/collection_operations.yaml index 5c60c36ba..770e65700 100644 --- a/tests/files/api_fixtures/collection_operations.yaml +++ b/tests/files/api_fixtures/collection_operations.yaml @@ -7,7 +7,6 @@ metadata: gcp_endpoint_id: "06e2c959-d311-4bab-b2ea-25ad77d9fc12" local_username: "recyclops" identity_id: "e926d510-cb98-11e5-a6ac-0b0216052512" - username: "testidentity@globus.org" gcs_hostname: "abc.xyz.data.globus.org" guest_display_name: "Happy Fun Guest Collection Name" @@ -203,14 +202,14 @@ auth: { "identities": [ { - "email": "testidentity@globus.org", + "email": "shrek@globus.org", "id": "e926d510-cb98-11e5-a6ac-0b0216052512", "identity_provider": "927d7238-f917-4eb2-9ace-c523fa9ba34e", "identity_type": "login", "name": "Test User", "organization": "Globus", "status": "used", - "username": "testidentity@globus.org" + "username": "shrek@globus.org" } ] } @@ -487,6 +486,25 @@ gcs: "http_response_code" : 200, "message": "Created new role 0174edd0-998c-4147-a123-99ea38068145" } + - path: /roles/0174edd0-998c-4147-a123-99ea38068145 + method: get + json: + { + "DATA_TYPE": "result#1.1.0", + "code": "success", + "data": [ + { + "DATA_TYPE": "role#1.0.0", + "collection": "1405823f-0597-4a16-b296-46d4f0ae4b15", + "id": "0174edd0-998c-4147-a123-99ea38068145", + "principal": "urn:globus:auth:identity:e926d510-cb98-11e5-a6ac-0b0216052512", + "role": "activity_monitor" + } + ], + "detail": "success", + "has_next_page": False, + "http_response_code": 200, + } - path: /roles/0174edd0-998c-4147-a123-99ea38068145 method: delete json: diff --git a/tests/functional/collection/role/test_role_create.py b/tests/functional/collection/role/test_role_create.py index 4f93bd2b0..8eda9a3de 100644 --- a/tests/functional/collection/role/test_role_create.py +++ b/tests/functional/collection/role/test_role_create.py @@ -4,6 +4,7 @@ def test_successful_gcs_collection_role_creation( run_line, add_gcs_login, + get_identities_mocker, ): # setup data for the collection_id -> endpoint_id lookup # and create dummy credentials for the test to run against that GCS @@ -14,11 +15,15 @@ def test_successful_gcs_collection_role_creation( role = meta["role"] role_id = meta["role_id"] user_id = meta["identity_id"] - username = meta["username"] add_gcs_login(endpoint_id) role = "activity_monitor" + # Mock the Get Identities API (Auth) + # so that CLI output rendering can show a username + user_meta = get_identities_mocker.configure_one(id=user_id).metadata + username = user_meta["username"] + # now test the command and confirm that a successful role creation is reported run_line( ["globus", "gcs", "collection", "role", "create", collection_id, role, user_id], diff --git a/tests/functional/collection/role/test_role_list.py b/tests/functional/collection/role/test_role_list.py index b7025745c..a8431dc02 100644 --- a/tests/functional/collection/role/test_role_list.py +++ b/tests/functional/collection/role/test_role_list.py @@ -11,10 +11,15 @@ def test_successful_gcs_collection_role_list( meta = load_response_set("cli.collection_operations").metadata endpoint_id = meta["endpoint_id"] collection_id = meta["mapped_collection_id"] - add_gcs_login(endpoint_id) role = meta["role"] role_id = meta["role_id"] - username = meta["username"] + user_id = meta["identity_id"] + add_gcs_login(endpoint_id) + + # Mock the Get Identities API (Auth) + # so that CLI output rendering can show a username + user_meta = get_identities_mocker.configure_one(id=user_id).metadata + username = user_meta["username"] # now test the command and confirm that output shows the role name and the # username diff --git a/tests/functional/collection/role/test_role_show.py b/tests/functional/collection/role/test_role_show.py index 33013363f..77d002bde 100644 --- a/tests/functional/collection/role/test_role_show.py +++ b/tests/functional/collection/role/test_role_show.py @@ -1,6 +1,4 @@ -import uuid - -from globus_sdk.testing import RegisteredResponse, load_response_set +from globus_sdk.testing import load_response_set def test_successful_gcs_collection_role_show( @@ -13,24 +11,11 @@ def test_successful_gcs_collection_role_show( meta = load_response_set("cli.collection_operations").metadata endpoint_id = meta["endpoint_id"] collection_id = meta["mapped_collection_id"] + role = meta["role"] + role_id = meta["role_id"] + user_id = meta["identity_id"] add_gcs_login(endpoint_id) - role_id = str(uuid.UUID(int=1)) - user_id = str(uuid.UUID(int=2)) - - # mock the responses for the Get Role API (GCS) - RegisteredResponse( - service="gcs", - path=f"/roles/{role_id}", - json={ - "DATA_TYPE": "role#1.0.0", - "collection": collection_id, - "id": role_id, - "principal": f"urn:globus:auth:identity:{user_id}", - "role": "administrator", - }, - ).add() - # Mock the Get Identities API (Auth) # so that CLI output rendering can show a username user_meta = get_identities_mocker.configure_one(id=user_id).metadata @@ -41,7 +26,8 @@ def test_successful_gcs_collection_role_show( run_line( ["globus", "gcs", "collection", "role", "show", collection_id, role_id], search_stdout=[ - ("Role", "administrator"), + ("ID", role_id), + ("Role", role), ("Principal", username), ], ) From ad299885144109b4fe940bb58a23dfe4d55bdc2c Mon Sep 17 00:00:00 2001 From: jkube-globus <93537409+jkube-globus@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:50:16 -0500 Subject: [PATCH 18/18] Update src/globus_cli/commands/collection/role/show.py Co-authored-by: Stephen Rosen --- src/globus_cli/commands/collection/role/show.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/globus_cli/commands/collection/role/show.py b/src/globus_cli/commands/collection/role/show.py index bdc836d9a..366bc3de3 100644 --- a/src/globus_cli/commands/collection/role/show.py +++ b/src/globus_cli/commands/collection/role/show.py @@ -31,10 +31,3 @@ def show_command( text_mode=display.RECORD, fields=fields, ) - # fields=[ - # Field("ID", "id"), - # Field("Role", "role"), - # Field( - # "Principal", "principal", formatter=PrincipalURNFormatter(auth_client) - # ), - # ],