[Change Safety] Az.Accounts: AutoRest AcquirePolicyToken pipeline step (Stage A) - #29840
Conversation
| Thanks for your contribution! The pull request validation has started. Please revisit this comment for updated status. |
There was a problem hiding this comment.
Pull request overview
This PR extends the Az.Accounts “Change Safety” infrastructure to AutoRest-generated cmdlets by wiring new runtime hooks into the generated cmdlet VTable and HTTP pipeline, and adding unit tests plus release notes to document the groundwork.
Changes:
- Adds a conditional HTTP pipeline step that stamps an Azure Policy token onto outgoing write requests when Change Safety parameters are bound.
- Introduces a new VTable delegate for supplying Change Safety dynamic parameters and wires it through
Register-AzModule. - Adds unit tests for pipeline-step gating and dynamic-parameter gating, and updates the Accounts changelog.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Accounts/Accounts/CommonModule/VTable.cs | Adds a new GetDynamicParameters delegate contract for Stage C generated modules. |
| src/Accounts/Accounts/CommonModule/RegisterAzModule.cs | Wires the new GetDynamicParameters delegate from ContextAdapter into the exported VTable. |
| src/Accounts/Accounts/CommonModule/ContextAdapter.cs | Appends the conditional AcquirePolicyToken pipeline step and implements Change Safety dynamic parameter building/gating. |
| src/Accounts/Accounts/ChangeLog.md | Documents upcoming Change Safety plumbing for AutoRest cmdlets. |
| src/Accounts/Accounts.Test/UnitTest/AcquirePolicyTokenHandlerTests.cs | Adds unit coverage for step-append gating based on bound Change Safety parameters. |
| src/Accounts/Accounts.Test/ChangeSafetyDynamicParametersTests.cs | Adds tests for dynamic parameter exposure on write verbs and exclusion on read verbs. |
Yabo Hu (VeryEarly)
left a comment
There was a problem hiding this comment.
you can keep trying this direction, but I have a concern about this design:
Essentially, we will get delegates at runtime to:
- function to add dynamic parameters
- http pipeline step to add dynamic parameter values to header
But for generated modules, in order to expose dynamic parameters, the public object GetDynamicParameters() need to be implemented in each cmdlet instance, which will be injected in generator logic. And in order to get that value, the cmdlet needs to call the call the getparametervalue delegate explicitly by name which will also be injected in generator logic. That will make codegen logic depends on a runtime wired delegate. Which is not generally the best practice. And I'll argue whether this increased or decreased the complexity.
Keeping the http pipeline step is fine, because it append/prepend the step into pipeline in module level, no cmdlet level changes required.
Please consider my concern unless you plan to do it differently.
I will explore and compare with changing generator to generate self-contained static parameters on write cmdlets |
|
Azure Pipelines: Successfully started running 1 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
c925719 to
3c24ae4
Compare
Match the generated module VTable slot rename and the Add...Handler naming convention. Delegate alias AcquirePolicyTokenDelegate -> ChangeSafetyPolicyTokenDelegate; ContextAdapter wrapper method renamed to match. Also add missing using for MemoryDataStore in the change-safety unit test.
|
/azp run |
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
|
/azp run |
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
…ty-autorest-accounts
Merge AddChangeSafetyPolicyTokenHandler and AddAcquirePolicyTokenHandler into a single InvocationInfo-based method, and update unit tests to construct an InvocationInfo via its non-public BoundParameters setter.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
src/Accounts/Accounts/ChangeLog.md:26
- This dependency bump belongs under the "## Upcoming Release" section per the changelog header instructions. Leaving it under "## Version 5.5.2" makes the changelog misleading about what changed in that already-versioned release section.
## Version 5.5.2
* Upgraded `Azure.Core` dependency from 1.56.0 to 1.57.0.
* Upgraded `System.ClientModel` dependency from 1.12.0 to 1.13.0.
* Upgraded common library to `1.3.114-preview`.
|
/azp run |
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
|
/azp run |
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/Accounts/Accounts/ChangeLog.md:26
- The change log guidance at the top of this file says changes for the next release should go under "## Upcoming Release", but this new entry is currently filed under "## Version 5.5.2" (which reads like a past release). Please move the common-library upgrade bullet into the Upcoming Release section so the release notes remain chronologically accurate.
## Version 5.5.2
* Upgraded `Azure.Core` dependency from 1.56.0 to 1.57.0.
* Upgraded `System.ClientModel` dependency from 1.12.0 to 1.13.0.
* Upgraded common library to `1.3.114-preview`.
Summary
Change Safety for AutoRest-generated cmdlets — the Az.Accounts (processing) half. Adds a VTable slot
AddChangeSafetyPolicyTokenHandler(delegate typeChangeSafetyPolicyTokenDelegate) that the generated module invokes right afterOnNewRequest.ContextAdapter.AddChangeSafetyPolicyTokenHandler(invocationInfo, appendStep)reads-AcquirePolicyToken/-ChangeReferencefrom the cmdlet'sBoundParametersand, when requested, appends a single step that calls the sharedPolicyTokenAcquirerand stamps thex-ms-policy-external-evaluationsheader on write requests.AutoRest cmdlets don't inherit
AzurePSCmdlet, so the handler is injected centrally via theRegister-AzModuleVTable, mirroring how auth, telemetry, and completers are wired. The generator (Azure/autorest.powershell#1549) surfaces the two parameters via an inlineIDynamicParametersimplementation; their values flow to this step throughBoundParameters.-WhatIfthe write cmdlet'sShouldProcessgate skips the HTTP call.RegisterAzModuleregisters the slot alongsideOnNewRequest(un-combined).Scope
src/Accounts/Accounts/CommonModule/VTable.cs—ChangeSafetyPolicyTokenDelegatealias +AddChangeSafetyPolicyTokenHandlerslot.src/Accounts/Accounts/CommonModule/ContextAdapter.cs— the singleAddChangeSafetyPolicyTokenHandler(invocationInfo, appendStep)method that readsBoundParametersand conditionally appends the acquire step (gating core; no separate wrapper).src/Accounts/Accounts/CommonModule/RegisterAzModule.cs— wires the delegate as a separate VTable slot.src/Accounts/Accounts.Test/UnitTest/AcquirePolicyTokenHandlerTests.cs,ChangeSafetyParameterContractTests.cs— tests.tools/Common.Netcore.Dependencies.targets,src/Accounts/Accounts/ChangeLog.md— bump common to1.3.114-preview.Tests
10 unit tests pass locally:
AcquirePolicyTokenHandlerTests— step-append gating from the cmdlet's bound parameters: no step when the feature is off (parameters absent/null,-AcquirePolicyToken:$false, or empty/whitespace-ChangeReference); a single step when-AcquirePolicyTokenis present,-ChangeReferenceis set, or both (dedup to one). Tests drive the handler through anInvocationInfobuilt with its bound parameters. Write-verb gate and header/wire behavior are covered byPolicyTokenAcquirertests in azure-powershell-common.ChangeSafetyParameterContractTests— pins the parameter names and help text to the values the generator emits.Paired generator output check (Azure/autorest.powershell#1549): a fresh regen +
build-module.ps1ofAz.ManagedServiceIdentity(exit 0) confirms the write cmdlets surface-AcquirePolicyToken(SwitchParameter) /-ChangeReference(string) — the values this handler reads fromBoundParameters— while read (Get-*) cmdlets do not. Parameter names/help match this PR'sChangeSafetyParameters(kept in sync byChangeSafetyParameterContractTests).Live end-to-end test (real Azure)
Re-validated on the latest
upstream/main(merged into this branch) after rebuilding this Stage A Az.Accounts. Ran against an opted-in AutoRest module (Az.ManagedServiceIdentity) regenerated by the paired generator PR (Azure/autorest.powershell#1549) withenable-change-safety.Command
-AcquirePolicyTokenbound and flowed intoBoundParameters; theAddChangeSafetyPolicyTokenHandlerVTable slot appended the acquire step, which stampedx-ms-policy-external-evaluationson the write. The identity was created (HTTP 200/201).Pipeline trace (temporary token-safe debug hook in
ContextAdapter; only metadata + a one-way SHA-256 hash of the stamped header are logged — never the raw token)Acquisition fails closed (
StampPolicyTokenAsyncthrows before the write on any non-200 / missing token), so a successful write proves a valid token was obtained and stamped.Dependencies
PolicyTokenAcquirer+ChangeSafetyParameters), consumed via the1.3.114-previewcommon package.