Skip to content

[Resiliency] Add resiliency extension 1.0.0 for Microsoft.AzureResilienceManagement api-version 2026-10-01 - #10530

Open
krtcodee wants to merge 3 commits into
Azure:mainfrom
krtcodee:resiliency-2026-10-01-aazdev
Open

krtcodee wants to merge 3 commits into
Azure:mainfrom
krtcodee:resiliency-2026-10-01-aazdev

Conversation

@krtcodee

@krtcodee krtcodee commented Oct 28, 2026 •

Copy link
Copy Markdown

Summary

New extension resiliency 1.0.0 (GA) providing az resiliency commands for Microsoft.AzureResilienceManagement api-version 2026-10-01 (stable).

Changes

  • src/resiliency/ – new extension (generated aaz/ code, setup.py, HISTORY.rst, README.md with full command reference).
  • GA metadata: VERSION = 1.0.0, Development Status :: 5 - Production/Stable, azext.isPreview: false.
  • src/service_name.json – added az resiliency → "Azure Resiliency".
  • Command examples on 80 commands, generated from swagger x-ms-examples (5 invalid swagger values corrected: drill-run stage Fault → FaultInjection; unsupported --type/--user-assigned-identities replaced by --user-assigned or removed).
  • src/resiliency/linter_exclusions.yml – excludes require_wait_command_if_no_wait for
    resiliency drill drill-run and resiliency recovery-plan recovery-job: their POST actions
    return no provisioningState, so aaz-dev cannot generate a wait command for these groups.

Testing

  • Scenario tests (tests/latest/test_resiliency.py): usage-plan CRUD, enrollment CRUD, drill list, recovery-plan list – each with output assertions.
  • Recorded live against the service (4/4 passed); replay run 4/4 passed.
  • azdev linter resiliency --min-severity medium: all rules pass.
  • azdev style resiliency: pylint and flake8 pass.
  • GitHub-style example check (azdev linter EXT --src <branch> --tgt <merge-base> --rules missing_command_example): pass.

Copilot AI balanced review requested due to automatic review settings October 28, 2026 08:08
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the customer-reported Issues that are reported by GitHub users external to the Azure organization. label Oct 28, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown
Contributor

Thank you for your contribution krtcodee! We will review the pull request and get back to you soon.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The command redacts the secret-marked downloadUrl during output deserialization, preventing users from receiving a usable report link even when the service succeeds.

1 open issue
What changed in this PR

Adds the GA resiliency 1.0.0 Azure CLI extension for managing Azure Resilience Management resources using API version 2026-10-01.

Changes:

  • Introduces generated command groups for drills, recovery plans, goal assignments, usage plans, and operation status.
  • Adds extension packaging, GA metadata, command documentation, and targeted linter exclusions.
  • Adds scenario tests and recorded service responses.
File Description
src/​service_name.json Registers the Azure Resiliency service mapping.
src/​resiliency/​setup.py Defines extension packaging and GA version.
src/​resiliency/​setup.cfg Adds a setup configuration placeholder.
src/​resiliency/​README.md Documents installation, usage, and commands.
src/​resiliency/​linter_exclusions.yml Exempts two groups from wait-command requirements.
src/​resiliency/​HISTORY.rst Records the initial release.
src/​resiliency/​azext_resiliency/​tests/​latest/​test_resiliency.py Adds usage-plan, enrollment, and list scenarios.
src/​resiliency/​azext_resiliency/​tests/​latest/​recordings/​test_resiliency_recovery_plan_list.yaml Records recovery-plan list responses.
src/​resiliency/​azext_resiliency/​tests/​latest/​__init__.py Initializes the latest test package.
src/​resiliency/​azext_resiliency/​tests/​__init__.py Initializes the test package.
src/​resiliency/​azext_resiliency/​custom.py Adds custom-command scaffolding.
src/​resiliency/​azext_resiliency/​commands.py Adds the custom command-table hook.
src/​resiliency/​azext_resiliency/​azext_metadata.json Declares GA status and minimum CLI version.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​usage_plan/​enrollment/​_list.py Lists enrollments with pagination.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​usage_plan/​enrollment/​_delete.py Deletes enrollments with asynchronous polling.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​usage_plan/​enrollment/​__init__.py Imports enrollment commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​usage_plan/​enrollment/​__cmd_group.py Registers the enrollment command group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​usage_plan/​_wait.py Waits for usage-plan conditions.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​usage_plan/​_show.py Retrieves a usage plan.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​usage_plan/​_delete.py Deletes a usage plan.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​usage_plan/​__init__.py Imports usage-plan commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​usage_plan/​__cmd_group.py Registers the usage-plan command group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​unified_resilience_item/​__init__.py Imports unified resilience item commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​unified_resilience_item/​__cmd_group.py Registers the unified resilience item group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​recovery_resource/​__init__.py Imports recovery-resource commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​recovery_resource/​__cmd_group.py Registers the recovery-resource group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​recovery_job/​recovery_job_resource/​__init__.py Imports recovery-job resource commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​recovery_job/​recovery_job_resource/​__cmd_group.py Registers the recovery-job resource group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​recovery_job/​_retry.py Retries failed recovery-job resources.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​recovery_job/​__init__.py Imports recovery-job commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​recovery_job/​__cmd_group.py Registers the recovery-job group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​identity/​__init__.py Imports recovery-plan identity commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​identity/​__cmd_group.py Registers recovery-plan identity management.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​_test_failover_cleanup.py Triggers test-failover cleanup.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​_reprotect.py Triggers recovery-plan reprotection.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​_finalize.py Finalizes recovery-plan configuration.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​_failover_commit.py Commits recovery-plan failover.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​_delete.py Deletes a recovery plan.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​_check_readiness.py Triggers recovery readiness checks.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​__init__.py Imports recovery-plan commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​recovery_plan/​__cmd_group.py Registers the recovery-plan group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​operation_status/​_show.py Retrieves asynchronous operation status.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​operation_status/​__init__.py Imports operation-status commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​operation_status/​__cmd_group.py Registers the operation-status group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​goal_resource/​_show.py Retrieves a goal resource.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​goal_resource/​_list.py Lists goal resources with pagination.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​goal_resource/​__init__.py Imports goal-resource commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​goal_resource/​__cmd_group.py Registers the goal-resource group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​_wait.py Waits for goal-assignment conditions.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​_refresh_goal_resource.py Refreshes resources within a goal assignment.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​_recommend_capacity.py Requests capacity recommendations.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​_delete.py Deletes a goal assignment.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​__init__.py Imports goal-assignment commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​goal_assignment/​__cmd_group.py Registers the goal-assignment group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​identity/​__init__.py Imports drill identity commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​identity/​__cmd_group.py Registers drill identity management.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_run/​drill_run_resource/​__init__.py Imports drill-run resource commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_run/​drill_run_resource/​__cmd_group.py Registers the drill-run resource group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_run/​_resume.py Resumes a paused drill-run workflow.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_run/​_reprotect.py Triggers drill-run reprotection.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_run/​_mark_as_complete.py Marks a drill-run stage complete.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_run/​_list_report_download_url.py Retrieves a report download URL.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_run/​_add_note.py Adds notes to a drill run.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_run/​__init__.py Imports drill-run commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_run/​__cmd_group.py Registers the drill-run group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_resource/​__init__.py Imports drill-resource commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​drill_resource/​__cmd_group.py Registers the drill-resource group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​_start.py Starts a drill instance.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​_resync_readiness_check.py Triggers resource and permission drift checks.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​_end.py Ends a drill with attestation details.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​_delete.py Deletes a drill.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​__init__.py Imports drill commands.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​drill/​__cmd_group.py Registers the drill group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​__init__.py Imports the root command group.
src/​resiliency/​azext_resiliency/​aaz/​latest/​resiliency/​__cmd_group.py Registers az resiliency.
src/​resiliency/​azext_resiliency/​aaz/​latest/​__init__.py Initializes the latest generated package.
src/​resiliency/​azext_resiliency/​aaz/​__init__.py Initializes the generated command package.
src/​resiliency/​azext_resiliency/​_params.py Adds the custom argument-loading hook.
src/​resiliency/​azext_resiliency/​_help.py Adds custom-help scaffolding.
src/​resiliency/​azext_resiliency/​__init__.py Connects generated commands to the extension loader.

Review effort: Balanced

pass

def _output(self, *args, **kwargs):
result = self.deserialize_output(self.ctx.vars.instance, client_flatten=True)
@yonzhan

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).

@krtcodee krtcodee changed the title [Resiliency] Add resiliency extension 1.0.0 for Microsoft.AzureResili… [Resiliency] Add resiliency extension 1.0.0 for Microsoft.AzureResilienceManagement api-version 2026-10-01 Oct 28, 2026
@JaysonTaiMicrosoft JaysonTaiMicrosoft added the Request X Engineering Agent Ask the agent to triage this issue or review this PR label Oct 29, 2026
@x-engineering-agent

x-engineering-agent Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

X Engineering Agent Pull request review: Comments

krtcodee

Check Status Detail
Upstream CI Passed Snapshot: 1 check passed; 0 failed; 0 pending.
Agent live tests Not run This is a review-only PR.
Regression coverage Not applicable Not applicable to the changed files.
Findings 3 high findings 3 high
Risk Risk 100/100 Critical Critical; owner review required

To address

Tick each item as you address it.

  • High Generated code ownership checker

    Details and fix

    src/resiliency/azext_resiliency/aaz/latest/__init__.py:1, src/resiliency/azext_resiliency/aaz/latest/resiliency/__cmd_group.py:1, src/resiliency/azext_resiliency/aaz/latest/resiliency/__init__.py:1, src/resiliency/azext_resiliency/aaz/latest/resiliency/drill/__cmd_group.py:1, src/resiliency/azext_resiliency/aaz/latest/resiliency/drill/__init__.py:1 and 117 more location(s): A generated file changed without an open or merged Azure/aaz pull request containing the durable command-model change.

    Remediation: Make the durable command-model change in Azure/aaz, link that PR in this description, then regenerate the downstream aaz/<profile> output.

    Verify: Regenerate from a clean checkout and confirm the resulting diff contains this change and the linked source PR is open or merged.

  • High Report download URL is omitted

    Details and fix

    src/resiliency/azext_resiliency/aaz/latest/resiliency/drill/drill_run/_list_report_download_url.py:103 uses default secret-hiding output serialization, while lines 221-223 mark downloadUrl secret. In the supported minimum Azure CLI 2.75.0, src/azure-cli-core/azure/cli/core/aaz/_command.py:189,214-216 defaults secret_hidden=True and omits secret properties. Thus a successful report response cannot yield the promised download link, including through a query. Copilot comment 4398287339 is confirmed and remains unresolved at this head.

    Remediation: Pass secret_hidden=False for this explicit retrieval command while retaining the schema's secret flag; preserve the fix through the durable generation/customization path.

    Verify: Add focused response/output coverage asserting the exact synthetic downloadUrl, expiry and format survive both immediate success and completed polling; keep ordinary secret-hiding behavior unchanged elsewhere.

  • High Removing one identity removes all

    Details and fix

    src/resiliency/azext_resiliency/aaz/latest/resiliency/drill/identity/_remove.py:323-328 forwards a single requested identity as a removal list. The GET/update/PUT sequence at lines 88-92 uses AAZIdentityObjectType (lines 321,377) and serializes the updated identity at lines 284-290. Azure CLI 2.75.0 and 2.85.0 src/azure-cli-core/azure/cli/core/aaz/_field_value.py:458-464 subtract selected identities only when the list length is greater than one; a one-element list clears all user-assigned identities. With identities A and B attached, --user-assigned A therefore sends an identity update removing B too. This is an existing framework defect newly reached by this command.

    Remediation: Ensure every nonempty selection subtracts only the requested IDs, reserving remove-all for the explicit empty selection. Use a supported customization or corrected core dependency/version floor rather than an untracked generated edit.

    Verify: Add focused outgoing-PUT assertions for removing A from {A,B}, multiple selections and explicit remove-all, with and without a system identity; verify unselected identities survive.

Review details

Upstream CI

Snapshot: 1 check passed; 0 failed; 0 pending. No outstanding human changes-requested reviews were returned.

Test validation

  • Agent live test: Not run; this is a review-only PR. Check author-provided test evidence and upstream CI separately.
  • Regression coverage: Not applicable to the changed files.
  • Focused evidence: Author scenarios in src/resiliency/azext_resiliency/tests/latest/test_resiliency.py:161-307 exercise usage-plan/enrollment CRUD and empty drill/recovery-plan lists. Two author recordings accompany them; these do not establish report-download output or selective identity-removal coverage. No tests, builds, lints or live workflows were run by this review.

Risk assessment

100/100 · Critical

The Critical rating is driven by security-sensitive behavior, public CLI behavior, dependency or supply chain and 2 additional signal(s).

  • Change scope: 140 changed files, 29563 changed lines (+29563 / -0), including 129 production files.
  • Affected components: resiliency
  • Risk drivers: security-sensitive behavior (+28); public CLI behavior (+18); dependency or supply chain (+18); failure-handling behavior (+12); generated output (+12)
  • Regression evidence: Changed regression tests are included, reducing risk.
  • Confidence: Medium because changed-line patches were available for 100 of 129 production files.
  • Required review: Owning-squad review is required for resiliency before merge.

Ask the Agent

Tick a box to queue an action. Requires write access to this repository.

  • Re-review this PR
  • Run Agent live tests on this PR

X Engineering Agent · Reviewer · React with +1 or -1 to train the agent

@x-engineering-agent x-engineering-agent Bot added the X Engineering Agent Reviewed Agent reviewed this PR label Oct 29, 2026
self.greater_than('length(@)', 0),
]
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This life cycle is missing update

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added it now

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

krtcodee there are a number of commands being added. please ensure we have lifecycle scenario tests for all of them to ensure we have sufficient coverage.

Comment on lines +18 to +20
TEST_RESOURCE_GROUP = 'cli-testing'
TEST_SERVICE_GROUP = 'azcmdlet-testing'
TEST_SUBSCRIPTION = '30233210-6bf4-4c4f-9e00-7cdcc1a176ec'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

krtcodee These look like pre-existing resources. Please refer to https://github.com/Azure/azure-cli/blob/dev/doc/authoring_tests.md#automating-tests-for-azure-cli for guidance. We should ensure that scenario tests are self contained and replicable

…date to lifecycle

- Create RG (policy-required tags), service group, usage plan and enrollment in-test with random names; no pre-existing resources

- Enrollment lifecycle covers create/show/list/update/delete; usage plan lifecycle covers create/show/list/update/delete with post-delete checks

- Drill/recovery-plan list run against the test service group, retrying while the service group's role assignment propagates

- Scrub x-ms-operation-identifier (tenant/object IDs) from recordings; remove recordings for dropped tests

- Re-recorded live; replay passes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

customer-reported Issues that are reported by GitHub users external to the Azure organization. Request X Engineering Agent Ask the agent to triage this issue or review this PR X Engineering Agent Reviewed Agent reviewed this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants