Skip to content

[dataprotection] Add Cosmos DB item-level recovery - #10486

Merged
JaysonTaiMicrosoft merged 8 commits into
Azure:mainfrom
Shashank1306s:feature/cosmosdb-item-level-recovery
Oct 26, 2026
Merged

JaysonTaiMicrosoft merged 8 commits into
Azure:mainfrom
Shashank1306s:feature/cosmosdb-item-level-recovery

Conversation

@Shashank1306s

@Shashank1306s Shashank Singh (Shashank1306s) commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

🤖 PR Validation — ⚠️ Review suggested

Breaking Changes Suppressions
️✔️ None ⚠️ 1 added

This PR adds warning or check suppressions. Fix the underlying warning where possible and justify each remaining suppression in a code comment or the PR description.

1 added suppression
File Line Kind Code
src/dataprotection/azext_dataprotection/manual/helpers.py 750 pylint # pylint: disable=chained-comparison

Related commands

az dataprotection backup-instance initialize-restoreconfig --datasource-type AzureCosmosDB

az dataprotection backup-instance restore initialize-for-item-recovery --datasource-type AzureCosmosDB

Summary

Adds AzureCosmosDB item-level (database/container) restore, following the existing AzureElasticSAN pattern:

  • Enable item-level recovery in the AzureCosmosDB manifest.
  • initialize-restoreconfig --datasource-type AzureCosmosDB --resource-identifiers ... returns GenericRestoreDatasourceCriteria with ResourceListSelectionCriteria; identifiers are passed through unchanged. --resource-identifiers is required, as for AzureElasticSAN.
  • restore initialize-for-item-recovery --datasource-type AzureCosmosDB --restore-configuration ... uses that configuration as the restore criteria. --restore-configuration is required, as for AzureElasticSAN.
  • Help examples, a README script section, HISTORY and version 1.14.0.

No client-side limits, naming rules or target-type checks are added; the selection and target are validated by the service (validate-for-restore). Identity, MSI permission and restore transport handling are reused unchanged.

Other datasources' logic is unchanged. helpers.py only gains a file-level # pylint: disable=chained-comparison because CI lints the whole module and flags pre-existing Blob prefix-range lines; the Blob code is identical to main.

Validation

  • CI (this head, 4ebb7cca): all checks pass, including azdev style/linter, the breaking change test and integration tests on Python 3.10-3.14.
  • Offline: Cosmos test module (+2 tests) and the 11-module replay regression set: 87 passed, 24 existing skips, 0 failed (network blocked).
  • Live, this head (ECY / eastus2euap, locally built wheel): item-level restore of a single container (db1/col1) from a VaultStore recovery point into an empty account restored only that container; its documents match the recovery point exactly, and the unselected containers and databases were not restored.
  • Live, earlier head (East Asia): 7 restores completed with data verification - full account, single container, single database, mixed containers + database, multiple containers, multiple databases (system-assigned identity) and single container with a user-assigned identity. See the live-results comment. The requests generated by this head are JSON-identical to those (13/13).

General Guidelines

  • Extension version follows schema
  • Upstream style/linter/integration checks pass on this head
  • Live item-level restore cases completed with data verification

@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 19, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown
Contributor

Thank you for your contribution Shashank Singh (@Shashank1306s)! We will review the pull request and get back to you soon.

@yonzhan

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

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

@Shashank1306s

Copy link
Copy Markdown
Contributor Author

Final validation update (commit 3230471)

Upstream azdev-style, azdev-linter, release-version calculation/output and CLA checks are now successful. Credential Scan and Policy Check are successful too. The remaining Azure integration/build checks are still pending/unknown; the PR remains draft.

Addressed the initial missing-final-newline finding and two pre-existing chained-comparison warnings. The latter change is behavior-equivalent: the actual old/new Blob prefix validators returned identical acceptance/errors across 225 range combinations.

Revalidated the published code:

  • Source: 840 tests + 131 subtests passed.
  • Rebuilt/private-installed final wheel: 840 + 131 passed with source discovery disabled.
  • Existing completed regression selection: 85 passed, 24 existing skips.
  • Standard local index checks: 7 passed, 2 CI-only skips.
  • Clean local worktree; final branch pushed without force.

Live native CLI restore/data-exclusion acceptance is still not executed: exact fresh-target/RBAC/cost authorization was not supplied. No live resource/role/data/vault-setting writes were performed. Four old recorded modules still have the same bounded-timeout outcome on both untouched upstream and this branch; no full-suite-green claim is made.

@Shashank1306s

Copy link
Copy Markdown
Contributor Author

Real-data wheel acceptance: all seven cases passed

Tested the local dataprotection 1.14.0 wheel, built from current PR head bc67e9b, against the existing real-data NoSQL fixture in East Asia. Isolated wheel import/discovery and SHA256 were verified; no source shadowing.

Native restore scenario DBs / containers / documents Result
Full-account, SAMI 3 / 7 / 14 Completed + exact data verified
Single container, SAMI 1 / 1 / 2 Completed + exact data verified
Whole database, SAMI 1 / 2 / 4 Completed + exact data verified
Mixed containers/database, SAMI 2 / 4 / 8 Completed + exact data verified
Multiple containers, SAMI 1 / 2 / 4 Completed + exact data verified
Multiple databases, SAMI 2 / 6 / 12 Completed + exact data verified
Attached UAMI 1 / 1 / 2 Completed + exact data verified

Every lifecycle step used native az dataprotection: config -> full/item initialization -> MSI permissions -> validation -> one restore trigger -> specific job show. All seven jobs were independently re-queried as Completed, with the correct backup instance and Restore operation/category.

Verified exact selected inventory, partition keys, document IDs/values/nested objects/array order and exclusions against the frozen recovery point. Post-backup data was excluded. Source remained unchanged (3 DBs / 8 containers / 15 documents). Completed 2026-10-19 12:25 UTC.

Only fresh tagged targets and narrow target/verification roles were created. No source, existing vault/policy/retention/network/identity changes or cleanup. Targets remain billable. Detailed evidence stays local, not added to the product diff.

Scope: seven positive NoSQL full/ILR cases in one region. No new backup/protection lifecycle or live negative/50-selector/other-region/API certification is claimed. This supersedes earlier comments saying live acceptance was pending.

@Shashank1306s
Shashank Singh (Shashank1306s) marked this pull request as ready for review October 19, 2026 15:43
Copilot AI balanced review requested due to automatic review settings October 19, 2026 15:43

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.

🔵 Needs a closer look

The data-recovery workflow needs human sign-off and confirmation of pending upstream validation for the current revision.

No open issues 🎉

What changed in this PR

Adds Cosmos DB for NoSQL database/container recovery to the existing dataprotection restore workflow, reusing shared identity, permission, and transport handling.

Changes:

  • Enables item-level recovery with validated selectors and alternate-account targets.
  • Adds focused configuration, request, and validation tests.
  • Documents recovery workflows and bumps the extension to 1.14.0.
File Description
src/​dataprotection/​setup.py Bumps version to 1.14.0.
src/​dataprotection/​README.md Documents Cosmos recovery and identity usage.
src/​dataprotection/​HISTORY.rst Records the new recovery capability.
src/​dataprotection/​azext_dataprotection/​tests/​latest/​test_dataprotection_cosmosdb.py Tests selectors, configuration, requests, and validation.
src/​dataprotection/​azext_dataprotection/​manual/​Manifests/​AzureCosmosDB.py Enables item-level recovery.
src/​dataprotection/​azext_dataprotection/​manual/​helpers.py Validates Cosmos selections and constructs restore criteria.
src/​dataprotection/​azext_dataprotection/​manual/​custom.py Integrates Cosmos configuration and target checks.
src/​dataprotection/​azext_dataprotection/​manual/​_params.py Updates restore argument descriptions.
src/​dataprotection/​azext_dataprotection/​manual/​_help.py Adds Cosmos command guidance and examples.

Review effort: Balanced

…ing the AzureElasticSAN pattern

- Remove client-side checks not backed by the service or live ILR testing: selector count cap, character/duplicate/overlap rules, strict restore-configuration schema checks and target ARM-type checks.

- initialize-restoreconfig and get_resource_criteria_list now mirror AzureElasticSAN: require --resource-identifiers / --restore-configuration and pass them through.

- Revert shared-path changes: Cosmos rejection in initialize-for-data-recovery, unsupported-datasource error text, and the Blob prefix-range comparison (byte-identical to main; pre-existing chained-comparison lint suppressed at file level).

- Generic help, README and HISTORY wording; tests cover the live-validated request shape and the required inputs only.
Comment thread src/dataprotection/azext_dataprotection/manual/custom.py
Comment thread src/dataprotection/azext_dataprotection/manual/helpers.py
Comment thread src/dataprotection/azext_dataprotection/manual/_params.py
Comment thread src/dataprotection/azext_dataprotection/manual/helpers.py Outdated
…estore inputs

- initialize-restoreconfig (AzureCosmosDB): reject AKS-only arguments and
  --resource-name-overrides; reject empty/whitespace identifiers and empty
  path segments (e.g. "db1/ "); strip identifiers (AzureElasticSAN parity).
- initialize-for-item-recovery (AzureCosmosDB): reject --container-list,
  --from/--to-prefix-pattern and --vaulted-blob-prefix-pattern; require a
  GenericRestoreDatasourceCriteria restore configuration.
- --resource-identifiers help: datasource-neutral first sentence.
- helpers.py: scope the chained-comparison suppression to the existing Blob
  prefix-overlap check instead of the whole module.
- Tests: add a Cosmos input-validation test.
@Shashank1306s

Copy link
Copy Markdown
Contributor Author

Hi Yong Zhang (@yonzhan) , please help merge this PR at the earliest, I've addressed the comments and have tested the commands e2e. We want this to be released in the current milestone. Please let me know if anything is needed

@JaysonTaiMicrosoft JaysonTaiMicrosoft added the Request X Engineering Agent Ask the agent to triage this issue or review this PR label Oct 25, 2026
@x-engineering-agent

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

Copy link
Copy Markdown

X Engineering Agent Pull request review: Comments

Shashank Singh (@Shashank1306s)

No significant defects confirmed

The Cosmos DB item-level request preserves the selected resources through the existing REST serialization and targets MSI permissions at the destination account. The added scenario exercises the item-level path and checks both selected resources and exclusions.

Upstream CI

The supplied upstream snapshot has 23 completed checks: 22 passed, 0 failed, 0 pending. This does not establish execution of the live-only scenario.

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.

Semantic coverage clarification: The automated applicability classification above does not describe the extension's actual tests. At the reviewed head, test_dataprotection_cosmosdb.py:188–260 asserts exact selection/configuration, request target and identity, and missing/invalid-input errors. These are initializer-output assertions, not HTTP-body assertions.

The item-level scenario:492–569 invokes MSI permissions, restore validation and restore trigger, waits for job completion, then checks the exact restored database/container inventory. It is live-only and has no replay recording. The author reports that this added scenario passed on a82357e in 23m50s. That is author-provided execution evidence, not an Agent run or independently inspected execution logs.

⚖️ Risk assessment — 37/100 · Medium

The Medium rating is driven by public CLI behavior, dependency or supply chain.

  • Change scope: 10 changed files, 287 changed lines (+279 / -8), including 6 production files.
  • Affected components: dataprotection
  • Risk drivers: public CLI behavior (+18); dependency or supply chain (+18)
  • Regression evidence: Changed regression tests are included, reducing risk.
  • Confidence: High because changed-line patches were available for every production file.
  • Required review: Owning-squad review is required for dataprotection before merge.

X Engineering Agent · Reviewer · react 👍 / 👎 to train the agent

@x-engineering-agent x-engineering-agent Bot added the X Engineering Agent Reviewed Agent reviewed this PR label Oct 25, 2026
Add test_dataprotection_backup_and_restore_cosmosdb_item_level (@live_only),
modeled on the AzureElasticSAN live scenario. It takes an adhoc backup,
restores db1/col1 and db2 to an empty target account through
initialize-restoreconfig, initialize-for-item-recovery, validate-for-restore
and restore trigger, asserts that only the selected resources were restored,
and empties the target afterwards.
@Shashank1306s

Copy link
Copy Markdown
Contributor Author

Replying to the X Engineering Agent report above.

F1 – identifier validation: Not changing this. Identifier validation is left to the service, which rejects invalid identifiers with a user error, so the CLI does not duplicate those rules. The CLI only rejects empty or whitespace identifiers (added for an earlier review comment). This also matches Az.DataProtection (Azure/azure-powershell#30300), which passes identifiers through unchanged.

F2 – item-level coverage: Added test_dataprotection_backup_and_restore_cosmosdb_item_level in a82357e, a @live_only() scenario modeled on the Elastic SAN one. It takes an adhoc backup, restores db1/col1 and db2 to an empty target account through initialize-restoreconfig → initialize-for-item-recovery → validate-for-restore → restore trigger, and asserts that only db1/col1 and db2 (c1, c2) were restored, not db1/col2 or db3. It then empties the target for the next run.

Ran it live in eastus2euap: passed in 23m50s (backup job 918b03ac-fb20-48cb-af50-35209603d1f9, restore job d87739da-fbac-4b65-9d15-ed6bdfacf5ec).

@x-engineering-agent x-engineering-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@x-engineering-agent x-engineering-agent Bot removed the Request X Engineering Agent Ask the agent to triage this issue or review this PR label Oct 26, 2026
…ve test

Build the target account ID from the subscription the test runs under
instead of a hard-coded subscription, and remove the subscription from
the fixture comment.
@JaysonTaiMicrosoft
JaysonTaiMicrosoft merged commit 629b126 into Azure:main Oct 26, 2026
24 checks passed
@azclibot

Copy link
Copy Markdown
Collaborator

[Release] Update index.json for extension [ dataprotection-1.14.0 ] : https://dev.azure.com/msazure/One/_build/results?buildId=187700007&view=results

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

act-codegen-extensibility-squad Auto-Assign Auto assign by bot CosmosDB customer-reported Issues that are reported by GitHub users external to the Azure organization. Data Protection X Engineering Agent Reviewed Agent reviewed this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants