Add New-AzDenyAssignment and Remove-AzDenyAssignment cmdlets#29340
Add New-AzDenyAssignment and Remove-AzDenyAssignment cmdlets#29340jruttle wants to merge 6 commits intoAzure:mainfrom
Conversation
| Thanks for your contribution! The pull request validation has started. Please revisit this comment for updated status. |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Adds authoring support for user-assigned deny assignments in Az.Resources by introducing New-AzDenyAssignment and Remove-AzDenyAssignment, backed by the regenerated Authorization.Management.Sdk targeting 2024-07-01-preview.
Changes:
- Added new cmdlets and a create-options model for deny assignment CRUD.
- Extended
AuthorizationClient/ extension mapping to support new deny assignment principal model types. - Added LiveOnly scenario tests plus session recordings; updated SDK regeneration README and generated SDK code.
Reviewed changes
Copilot reviewed 21 out of 36 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Resources/Resources/Models.Authorization/CreateDenyAssignmentOptions.cs | New options model used to build deny assignment create payloads / input file format. |
| src/Resources/Resources/Models.Authorization/AuthorizationClientExtensions.cs | Adds principal mapping overloads for the regenerated deny assignment principal types. |
| src/Resources/Resources/Models.Authorization/AuthorizationClient.cs | Implements create/delete operations for deny assignments using regenerated SDK APIs. |
| src/Resources/Resources/DenyAssignments/NewAzureDenyAssignmentCommand.cs | New New-AzDenyAssignment cmdlet implementation. |
| src/Resources/Resources/DenyAssignments/RemoveAzureDenyAssignmentCommand.cs | New Remove-AzDenyAssignment cmdlet implementation. |
| src/Resources/Resources/Az.Resources.psd1 | Exports the newly added cmdlets. |
| src/Resources/Resources.Test/ScenarioTests/DenyAssignmentCrudTests.ps1 | Adds LiveOnly scenario test scripts for deny assignment CRUD and negative cases. |
| src/Resources/Resources.Test/ScenarioTests/DenyAssignmentCrudTests.cs | Adds C# test harness wiring to run the new scenario scripts. |
| src/Resources/Resources.Test/SessionRecords/DenyAssignmentCrudTests/.json | Adds session recordings for the new tests. |
| src/Resources/Authorization.Management.Sdk/README.md | Updates swagger commit reference and input-file paths used for SDK regeneration. |
| src/Resources/Authorization.Management.Sdk/Generated/* | Regenerated SDK with deny assignment CRUD, updated models, and supporting types. |
src/Resources/Resources/Models.Authorization/AuthorizationClient.cs
Outdated
Show resolved
Hide resolved
src/Resources/Resources/Models.Authorization/AuthorizationClientExtensions.cs
Show resolved
Hide resolved
src/Resources/Resources.Test/ScenarioTests/DenyAssignmentCrudTests.ps1
Outdated
Show resolved
Hide resolved
src/Resources/Resources/DenyAssignments/RemoveAzureDenyAssignmentCommand.cs
Show resolved
Hide resolved
src/Resources/Resources/DenyAssignments/RemoveAzureDenyAssignmentCommand.cs
Outdated
Show resolved
Hide resolved
src/Resources/Resources/DenyAssignments/NewAzureDenyAssignmentCommand.cs
Outdated
Show resolved
Hide resolved
src/Resources/Resources/DenyAssignments/NewAzureDenyAssignmentCommand.cs
Outdated
Show resolved
Hide resolved
src/Resources/Resources/DenyAssignments/NewAzureDenyAssignmentCommand.cs
Show resolved
Hide resolved
…, typed helpers - Fix Azure#4: Pass Force.IsPresent to ConfirmAction so -Force suppresses prompt - Fix Azure#7/Azure#8: Remove unused ProjectResources aliases (CS8019) - Fix Azure#1/Azure#9: Remove PrincipalId param, reject non-Everyone principals with clear error - Fix Azure#10: Add InputFile validation for ExcludePrincipalIds - Fix Azure#5: Remove stale scaffolded TODO comment - Fix Azure#6: Throw when multiple DAs match by name (disambiguate by ID) - Fix Azure#2: Replace dynamic ToPSPrincipalsCore with generic typed helper - Fix Azure#3: Update ExcludePrincipals test to use multiple principals with per-type array Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
src/Resources/Resources.Test/ScenarioTests/DenyAssignmentCrudTests.ps1
Outdated
Show resolved
Hide resolved
src/Resources/Resources/DenyAssignments/RemoveAzureDenyAssignmentCommand.cs
Outdated
Show resolved
Hide resolved
src/Resources/Resources/DenyAssignments/NewAzureDenyAssignmentCommand.cs
Show resolved
Hide resolved
|
@jruttle please support should process for new/update cmdlets: |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
Thanks @VeryEarly - this was addressed in commit da9de1f (the 4th push). New-AzDenyAssignment now has SupportsShouldProcess = true on the [Cmdlet] attribute and the create call is wrapped in a ShouldProcess() guard. Remove-AzDenyAssignment already had it from the initial implementation. |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
| var excludePrincipals = new List<DenyAssignmentPrincipal>(); | ||
| var excludeIds = options.ExcludePrincipalIds ?? new List<string>(); | ||
| var excludeTypes = options.ExcludePrincipalTypes; | ||
| var defaultType = options.ExcludePrincipalType ?? "User"; | ||
|
|
||
| for (int i = 0; i < excludeIds.Count; i++) | ||
| { | ||
| var type = (excludeTypes != null && i < excludeTypes.Count) | ||
| ? excludeTypes[i] | ||
| : defaultType; | ||
| excludePrincipals.Add(new DenyAssignmentPrincipal { Id = excludeIds[i], Type = type }); | ||
| } |
There was a problem hiding this comment.
ExcludePrincipalTypes is intended to support either one type applied to all ExcludePrincipalIds or one per ID (as described by the cmdlet help/validation), but the current mapping only uses excludeTypes[i] when i < excludeTypes.Count. If the caller supplies a single ExcludePrincipalType value with multiple IDs, only the first excluded principal gets that type and the rest fall back to ExcludePrincipalType (legacy) / "User". Update the mapping so that when ExcludePrincipalTypes.Count == 1, that value is applied to every excluded principal (and consider validating mismatched counts > 1).
| $excludeUser = Get-TestExcludePrincipalId | ||
| $spId = "c090fe3f-66fa-4e18-8142-107d8f4cd0e4" # DenyAssignmentTestApp | ||
| $daName = "Test-DA-ExcludePrincipals-" + [Guid]::NewGuid().ToString().Substring(0, 8) | ||
|
|
||
| try | ||
| { | ||
| # Exclude both the user and the test service principal | ||
| $da = New-AzDenyAssignment ` | ||
| -DenyAssignmentName $daName ` | ||
| -Description "Test deny assignment with multiple exclude principals" ` | ||
| -Scope $subscriptionScope ` | ||
| -Action "Microsoft.Storage/storageAccounts/write" ` | ||
| -ExcludePrincipalId @($excludeUser, $spId) ` | ||
| -ExcludePrincipalType @("User", "ServicePrincipal") | ||
|
|
||
| Assert-NotNull $da | ||
| Assert-True { $da.ExcludePrincipals.Count -ge 2 } | ||
| } |
There was a problem hiding this comment.
This test claims to exclude both a user and a service principal, but $spId is set to an application/client ID value. The cmdlet parameter and API expect principal object IDs, so this may not actually be validating multi-principal exclusion (and may be tenant-dependent). Consider resolving the service principal object ID (or making it configurable via an environment variable) and ensure the assertion reflects the actual excluded principals returned.
| "696" | ||
| ] | ||
| }, | ||
| "RequestBody": "{\r\n \"properties\": {\r\n \"denyAssignmentName\": \"Test-DA-ExcludePrincipals-15a41d72\",\r\n \"description\": \"Test deny assignment with multiple exclude principals\",\r\n \"permissions\": [\r\n {\r\n \"actions\": [\r\n \"Microsoft.Storage/storageAccounts/write\"\r\n ],\r\n \"notActions\": [],\r\n \"dataActions\": [],\r\n \"notDataActions\": []\r\n }\r\n ],\r\n \"doNotApplyToChildScopes\": false,\r\n \"principals\": [\r\n {\r\n \"id\": \"00000000-0000-0000-0000-000000000000\",\r\n \"type\": \"SystemDefined\"\r\n }\r\n ],\r\n \"excludePrincipals\": [\r\n {\r\n \"id\": \"1840cc0e-55b5-442d-bbf6-52c0c7e27302\",\r\n \"type\": \"User\"\r\n }\r\n ]\r\n }\r\n}", |
There was a problem hiding this comment.
The session recording for the "multiple exclude principals" scenario only contains a single entry in excludePrincipals (the user). This is inconsistent with the corresponding test (Test-NewDaWithExcludePrincipals) which passes two excluded principals and asserts ExcludePrincipals.Count -ge 2. Please re-record/update this session file (or adjust the test) so the recording reflects the current scenario intent.
| "RequestBody": "{\r\n \"properties\": {\r\n \"denyAssignmentName\": \"Test-DA-ExcludePrincipals-15a41d72\",\r\n \"description\": \"Test deny assignment with multiple exclude principals\",\r\n \"permissions\": [\r\n {\r\n \"actions\": [\r\n \"Microsoft.Storage/storageAccounts/write\"\r\n ],\r\n \"notActions\": [],\r\n \"dataActions\": [],\r\n \"notDataActions\": []\r\n }\r\n ],\r\n \"doNotApplyToChildScopes\": false,\r\n \"principals\": [\r\n {\r\n \"id\": \"00000000-0000-0000-0000-000000000000\",\r\n \"type\": \"SystemDefined\"\r\n }\r\n ],\r\n \"excludePrincipals\": [\r\n {\r\n \"id\": \"1840cc0e-55b5-442d-bbf6-52c0c7e27302\",\r\n \"type\": \"User\"\r\n }\r\n ]\r\n }\r\n}", | |
| "RequestBody": "{\r\n \"properties\": {\r\n \"denyAssignmentName\": \"Test-DA-ExcludePrincipals-15a41d72\",\r\n \"description\": \"Test deny assignment with multiple exclude principals\",\r\n \"permissions\": [\r\n {\r\n \"actions\": [\r\n \"Microsoft.Storage/storageAccounts/write\"\r\n ],\r\n \"notActions\": [],\r\n \"dataActions\": [],\r\n \"notDataActions\": []\r\n }\r\n ],\r\n \"doNotApplyToChildScopes\": false,\r\n \"principals\": [\r\n {\r\n \"id\": \"00000000-0000-0000-0000-000000000000\",\r\n \"type\": \"SystemDefined\"\r\n }\r\n ],\r\n \"excludePrincipals\": [\r\n {\r\n \"id\": \"1840cc0e-55b5-442d-bbf6-52c0c7e27302\",\r\n \"type\": \"User\"\r\n },\r\n {\r\n \"id\": \"8c1e7f2e-4f5a-4f4c-9f3a-2c8f5d9b7a11\",\r\n \"type\": \"ServicePrincipal\"\r\n }\r\n ]\r\n }\r\n}", |
| // PP1 client-side validation: DataActions not supported | ||
| if (DataAction != null && DataAction.Length > 0) | ||
| { | ||
| throw new PSArgumentException( | ||
| "DataActions are not supported for PP1 user-assigned deny assignments. " + |
There was a problem hiding this comment.
Client-side PP1 validation currently blocks -DataAction but not -NotDataAction, even though NotDataAction is also a data-action list and the cmdlet help says data actions are not supported in PP1. This allows unsupported input through and yields inconsistent (service-side) failures. Consider adding the same validation for NotDataAction (and optionally for input-file scenarios if consistent behavior is desired).
Description
Add
New-AzDenyAssignmentandRemove-AzDenyAssignmentcmdlets for user-assigned deny assignments using the2024-07-01-previewAuthorization API.Cmdlets Added
Key Design Decisions (PP1 Model)
SystemDefinedwithGuid.Empty) — this is the only supported principal type in PP1ExcludePrincipalIdis required (at least one principal must be excluded when denying Everyone)DoNotApplyToChildScopesare not supported — tests validate these are rejected with proper errorsChanges
31fb4b3e)AuthorizationClient.cs(create/remove logic),Az.Resources.psd1(exports), SDK README (commit hash)Tests
Related
2024-07-01-preview