Skip to content

Commit b8a4855

Browse files
committed
add tests
1 parent 5d3068b commit b8a4855

4 files changed

Lines changed: 251 additions & 3 deletions

File tree

src/azure-cli/azure/cli/command_modules/role/_help.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,8 +793,14 @@
793793
type: command
794794
short-summary: List role assignments.
795795
long-summary: >-
796-
By default, only assignments scoped to subscription will be displayed.
797-
To view assignments scoped by resource or group, use `--all`.
796+
By default, the scope is the current subscription. Specifying the scope with `--scope` is recommended.
797+
798+
799+
By default, only role assignments exactly at the scope are included, not including role assignments at
800+
parent scopes or sub-scopes. For example, when `--scope` is a subscription, role assignments at management
801+
groups or resource groups are not included.
802+
To include role assignments at parent scopes, use `--include-inherited`.
803+
To include role assignments at parent scopes and sub-scopes, use `--at-scope false`.
798804
799805
800806
[WARNING] Azure classic subscription administrators will be retired on August 31, 2024.

src/azure-cli/azure/cli/command_modules/role/_params.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ def load_arguments(self, _):
334334
deprecate_info=c.deprecate(target='--all'),
335335
help="Show all assignments under the current subscription. This argument is deprecated. "
336336
"Use '--at-scope false' instead.")
337-
c.argument('include_inherited', action='store_true', help='include assignments applied on parent scopes')
337+
c.argument('include_inherited', action='store_true',
338+
help='Include role assignments at parent scopes. This argument only takes effect when --at-scope is true.')
338339
c.argument('can_delegate', action='store_true', help='when set, the assignee will be able to create further role assignments to the same role')
339340
c.argument('assignee', help='represent a user, group, or service principal. supported format: object id, user sign-in name, or service principal name')
340341
c.argument('assignee_object_id',
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
interactions:
2+
- request:
3+
body: '{"location": "westus"}'
4+
headers:
5+
Accept:
6+
- application/json
7+
Accept-Encoding:
8+
- gzip, deflate
9+
CommandName:
10+
- identity create
11+
Connection:
12+
- keep-alive
13+
Content-Length:
14+
- '22'
15+
Content-Type:
16+
- application/json
17+
ParameterSetName:
18+
- -g -n --location
19+
User-Agent:
20+
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.12.10 (Windows-11-10.0.26100-SP0)
21+
method: PUT
22+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_role_assign000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/clitest000002?api-version=2023-01-31
23+
response:
24+
body:
25+
string: '{"location":"westus","tags":{},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_role_assign000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/clitest000002","name":"clitest000002","type":"Microsoft.ManagedIdentity/userAssignedIdentities","properties":{"tenantId":"54826b22-38d6-4fb2-bad9-b7b93a3e9c5a","principalId":"88c53162-584e-4c98-984b-62149c2e9bca","clientId":"8cc2fab2-7cc6-4863-aae8-9ee986d5a5ac"}}'
26+
headers:
27+
cache-control:
28+
- no-cache
29+
content-length:
30+
- '449'
31+
content-type:
32+
- application/json; charset=utf-8
33+
date:
34+
- Mon, 14 Apr 2025 08:54:23 GMT
35+
expires:
36+
- '-1'
37+
location:
38+
- /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_role_assign000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/clitest000002
39+
pragma:
40+
- no-cache
41+
strict-transport-security:
42+
- max-age=31536000; includeSubDomains
43+
x-cache:
44+
- CONFIG_NOCACHE
45+
x-content-type-options:
46+
- nosniff
47+
x-ms-operation-identifier:
48+
- tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=0d504196-1423-4569-9a6e-15149656f0ee/japanwest/90ea6275-c25c-4d73-ba0a-55e6fbe522bb
49+
x-ms-ratelimit-remaining-subscription-global-writes:
50+
- '2999'
51+
x-ms-ratelimit-remaining-subscription-writes:
52+
- '199'
53+
x-msedge-ref:
54+
- 'Ref A: 4359A8C8A1DE4A538CC6C54BFB82E1A0 Ref B: TYO201100114011 Ref C: 2025-04-14T08:54:21Z'
55+
status:
56+
code: 201
57+
message: Created
58+
- request:
59+
body: '{"properties": {"roleDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",
60+
"principalId": "88c53162-584e-4c98-984b-62149c2e9bca", "principalType": "ServicePrincipal"}}'
61+
headers:
62+
Accept:
63+
- application/json
64+
Accept-Encoding:
65+
- gzip, deflate
66+
CommandName:
67+
- role assignment create
68+
Connection:
69+
- keep-alive
70+
Content-Length:
71+
- '270'
72+
Content-Type:
73+
- application/json
74+
ParameterSetName:
75+
- --assignee-object-id --assignee-principal-type --role --scope
76+
User-Agent:
77+
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.12.10 (Windows-11-10.0.26100-SP0)
78+
method: PUT
79+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_role_assign000001/providers/Microsoft.Authorization/roleAssignments/88888888-0000-0000-0000-000000000001?api-version=2022-04-01
80+
response:
81+
body:
82+
string: '{"properties":{"roleDefinitionId":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7","principalId":"88c53162-584e-4c98-984b-62149c2e9bca","principalType":"ServicePrincipal","scope":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_role_assign000001","condition":null,"conditionVersion":null,"createdOn":"2025-04-14T08:54:25.8958593Z","updatedOn":"2025-04-14T08:54:26.7153899Z","createdBy":null,"updatedBy":"0d504196-1423-4569-9a6e-15149656f0ee","delegatedManagedIdentityResourceId":null,"description":null},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_role_assign000001/providers/Microsoft.Authorization/roleAssignments/88888888-0000-0000-0000-000000000001","type":"Microsoft.Authorization/roleAssignments","name":"88888888-0000-0000-0000-000000000001"}'
83+
headers:
84+
cache-control:
85+
- no-cache
86+
content-length:
87+
- '897'
88+
content-type:
89+
- application/json; charset=utf-8
90+
date:
91+
- Mon, 14 Apr 2025 08:54:30 GMT
92+
expires:
93+
- '-1'
94+
pragma:
95+
- no-cache
96+
strict-transport-security:
97+
- max-age=31536000; includeSubDomains
98+
x-cache:
99+
- CONFIG_NOCACHE
100+
x-content-type-options:
101+
- nosniff
102+
x-ms-operation-identifier:
103+
- tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=0d504196-1423-4569-9a6e-15149656f0ee/japaneast/5aef1660-efc8-4259-ada4-ff3377587bdb
104+
x-ms-ratelimit-remaining-subscription-global-writes:
105+
- '2999'
106+
x-ms-ratelimit-remaining-subscription-writes:
107+
- '199'
108+
x-msedge-ref:
109+
- 'Ref A: 06485B5DC8264B9C917E7D0942EDE412 Ref B: TYO201151002025 Ref C: 2025-04-14T08:54:25Z'
110+
status:
111+
code: 201
112+
message: Created
113+
- request:
114+
body: null
115+
headers:
116+
Accept:
117+
- application/json
118+
Accept-Encoding:
119+
- gzip, deflate
120+
CommandName:
121+
- role assignment list
122+
Connection:
123+
- keep-alive
124+
ParameterSetName:
125+
- --scope --at-scope --assignee-object-id --fill-role-definition-name --fill-principal-name
126+
User-Agent:
127+
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.12.10 (Windows-11-10.0.26100-SP0)
128+
method: GET
129+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleAssignments?$filter=principalId%20eq%20'88c53162-584e-4c98-984b-62149c2e9bca'&api-version=2022-04-01
130+
response:
131+
body:
132+
string: '{"value":[{"properties":{"roleDefinitionId":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7","principalId":"88c53162-584e-4c98-984b-62149c2e9bca","principalType":"ServicePrincipal","scope":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_role_assign000001","condition":null,"conditionVersion":null,"createdOn":"2025-04-14T08:54:26.7153899Z","updatedOn":"2025-04-14T08:54:26.7153899Z","createdBy":"0d504196-1423-4569-9a6e-15149656f0ee","updatedBy":"0d504196-1423-4569-9a6e-15149656f0ee","delegatedManagedIdentityResourceId":null,"description":null},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_role_assign000001/providers/Microsoft.Authorization/roleAssignments/88888888-0000-0000-0000-000000000001","type":"Microsoft.Authorization/roleAssignments","name":"88888888-0000-0000-0000-000000000001"}]}'
133+
headers:
134+
cache-control:
135+
- no-cache
136+
content-length:
137+
- '943'
138+
content-type:
139+
- application/json; charset=utf-8
140+
date:
141+
- Mon, 14 Apr 2025 08:54:31 GMT
142+
expires:
143+
- '-1'
144+
pragma:
145+
- no-cache
146+
strict-transport-security:
147+
- max-age=31536000; includeSubDomains
148+
x-cache:
149+
- CONFIG_NOCACHE
150+
x-content-type-options:
151+
- nosniff
152+
x-ms-operation-identifier:
153+
- tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=0d504196-1423-4569-9a6e-15149656f0ee/japaneast/4f3785c6-7da5-4a37-9e9a-37b877a366e0
154+
x-ms-ratelimit-remaining-subscription-global-reads:
155+
- '3749'
156+
x-msedge-ref:
157+
- 'Ref A: F01D790831084190BDA2FD89661CF517 Ref B: TYO201151001054 Ref C: 2025-04-14T08:54:31Z'
158+
status:
159+
code: 200
160+
message: OK
161+
- request:
162+
body: null
163+
headers:
164+
Accept:
165+
- application/json
166+
Accept-Encoding:
167+
- gzip, deflate
168+
CommandName:
169+
- role assignment list
170+
Connection:
171+
- keep-alive
172+
ParameterSetName:
173+
- --scope --at-scope --assignee-object-id --fill-role-definition-name --fill-principal-name
174+
User-Agent:
175+
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.12.10 (Windows-11-10.0.26100-SP0)
176+
method: GET
177+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_role_assign000001/providers/Microsoft.Authorization/roleAssignments?$filter=principalId%20eq%20'88c53162-584e-4c98-984b-62149c2e9bca'&api-version=2022-04-01
178+
response:
179+
body:
180+
string: '{"value":[{"properties":{"roleDefinitionId":"/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7","principalId":"88c53162-584e-4c98-984b-62149c2e9bca","principalType":"ServicePrincipal","scope":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_role_assign000001","condition":null,"conditionVersion":null,"createdOn":"2025-04-14T08:54:26.7153899Z","updatedOn":"2025-04-14T08:54:26.7153899Z","createdBy":"0d504196-1423-4569-9a6e-15149656f0ee","updatedBy":"0d504196-1423-4569-9a6e-15149656f0ee","delegatedManagedIdentityResourceId":null,"description":null},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_role_assign000001/providers/Microsoft.Authorization/roleAssignments/88888888-0000-0000-0000-000000000001","type":"Microsoft.Authorization/roleAssignments","name":"88888888-0000-0000-0000-000000000001"}]}'
181+
headers:
182+
cache-control:
183+
- no-cache
184+
content-length:
185+
- '943'
186+
content-type:
187+
- application/json; charset=utf-8
188+
date:
189+
- Mon, 14 Apr 2025 08:54:31 GMT
190+
expires:
191+
- '-1'
192+
pragma:
193+
- no-cache
194+
strict-transport-security:
195+
- max-age=31536000; includeSubDomains
196+
x-cache:
197+
- CONFIG_NOCACHE
198+
x-content-type-options:
199+
- nosniff
200+
x-ms-operation-identifier:
201+
- tenantId=54826b22-38d6-4fb2-bad9-b7b93a3e9c5a,objectId=0d504196-1423-4569-9a6e-15149656f0ee/japaneast/b891f240-fe35-43fb-a8ef-cd9597db7f7e
202+
x-ms-ratelimit-remaining-subscription-global-reads:
203+
- '3749'
204+
x-msedge-ref:
205+
- 'Ref A: 0DD953D8592F4F9796E6678A325D0EAB Ref B: TYO201151002025 Ref C: 2025-04-14T08:54:32Z'
206+
status:
207+
code: 200
208+
message: OK
209+
version: 1

src/azure-cli/azure/cli/command_modules/role/tests/latest/test_role.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,38 @@ def test_role_assignment_no_graph(self, resource_group):
757757
self.cmd('role assignment list --all --assignee-object-id {uami_object_id}',
758758
checks=self.check("length([])", 0))
759759

760+
@ResourceGroupPreparer(name_prefix='cli_role_assign')
761+
def test_role_assignment_at_scope(self, resource_group):
762+
with mock.patch('azure.cli.command_modules.role.custom._gen_guid', side_effect=self.create_guid):
763+
self.kwargs.update({
764+
'uami': self.create_random_name('clitest', 15), # user-assigned managed identity
765+
# https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles
766+
'role_reader_guid': 'acdd72a7-3385-48ef-bd42-f606fba81ae7'
767+
})
768+
self._prepare_scope_kwargs()
769+
770+
uami = self.cmd('identity create -g {rg} -n {uami} --location westus').get_output_in_json()
771+
self.kwargs['uami_object_id'] = uami['principalId']
772+
773+
self.cmd('role assignment create '
774+
'--assignee-object-id {uami_object_id} --assignee-principal-type ServicePrincipal '
775+
'--role {role_reader_guid} --scope {rg_id}')
776+
# Verify atScope() is not bound to scope,
777+
# and when atScope() is not specified, scope can be used with `principalId eq '{}'` filter
778+
self.cmd('role assignment list --scope {sub_id} --at-scope false '
779+
'--assignee-object-id {uami_object_id} '
780+
'--fill-role-definition-name false --fill-principal-name false',
781+
checks=[
782+
self.check("length([])", 1),
783+
self.check("[0].scope", '{rg_id}'),
784+
])
785+
self.cmd('role assignment list --scope {rg_id} --at-scope false '
786+
'--assignee-object-id {uami_object_id} '
787+
'--fill-role-definition-name false --fill-principal-name false',
788+
checks=[
789+
self.check("length([])", 1),
790+
self.check("[0].scope", '{rg_id}'),
791+
])
760792

761793
class RoleAssignmentWithConfigScenarioTest(RoleScenarioTestBase):
762794

0 commit comments

Comments
 (0)