Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/dataprotection/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Release History
===============

1.12.0
++++++
* Added dataprotection support for the AzureElasticSAN (Elastic SAN volume group) workload: new manifest (Microsoft.ElasticSan/elasticSans/volumeGroups), registration in supported datasource types and datasource map. New backup configuration via ``az dataprotection backup-instance initialize-backupconfig --datasource-type AzureElasticSAN --resource-selectors`` (GenericBackupDatasourceParameters) and restore configuration via ``az dataprotection backup-instance initialize-restoreconfig --datasource-type AzureElasticSAN --resource-identifiers/--resource-name-overrides`` (GenericRestoreDatasourceCriteria), with data-recovery and item-recovery restore wiring plus help/examples. The AzureElasticSAN backup-instance operations are pinned to the GA 2026-06-01 DataProtection API, which defines GenericBackupDatasourceParameters/GenericRestoreDatasourceCriteria natively.

1.11.5
++++++
* `az dataprotection enable-backup trigger`: Fixed AKS backup vault discovery to scope the lookup to `backupResourceGroupId` instead of the whole subscription, preventing concurrent enable-backup runs from racing over a shared, tag-matched vault. Also wait for a newly created vault's `provisioningState` to reach a terminal state before proceeding.
Expand Down
84 changes: 84 additions & 0 deletions src/dataprotection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,90 @@ az dataprotection backup-instance validate-for-restore --name "testInstance1" --
az dataprotection backup-instance restore trigger -g sarath-rg --vault-name sarath-vault \
--backup-instance-name {backup_instance_name} --restore=request-object restore_request.json
```

#### Azure Elastic SAN (preview) configure and restore scripts ####
##### Configure backup for Elastic SAN volumes #####
```
# 1) Create backup configuration for selected source volumes in the chosen volume group
az dataprotection backup-instance initialize-backupconfig \
--datasource-type AzureElasticSAN \
--resource-selectors volume001 > esan_backup_config.json

# 2) Initialize backup instance payload (datasource-id is the source volume group ARM ID)
az dataprotection backup-instance initialize \
--datasource-type AzureElasticSAN \
--datasource-location {location} \
--datasource-id {source_volume_group_id} \
--policy-id {esan_policy_id} \
--friendly-name esan-bi \
--backup-configuration @esan_backup_config.json > esan_backup_instance.json

# 3) Grant missing backup permissions to vault MSI (Elastic SAN Snapshot Exporter + Disk Snapshot Contributor)
az dataprotection backup-instance update-msi-permissions \
--datasource-type AzureElasticSAN \
--operation Backup \
--permissions-scope Resource \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance @esan_backup_instance.json

# 4) Validate and configure backup
az dataprotection backup-instance validate-for-backup \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance @esan_backup_instance.json

az dataprotection backup-instance create \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance @esan_backup_instance.json
```

##### Restore Elastic SAN backup #####
```
# 1) Build restore configuration: select source volumes and optional target names
az dataprotection backup-instance initialize-restoreconfig \
--datasource-type AzureElasticSAN \
--resource-identifiers source-vol1 \
--resource-name-overrides '{"source-vol1":"restored-vol1"}' > esan_restore_config.json

# 2) Initialize restore request (target-resource-id is target volume group ARM ID).
# Elastic SAN supports alternate-location restore only, so pass --target-resource-id
# (do not pass --backup-instance-id; the two are mutually exclusive).
az dataprotection backup-instance restore initialize-for-item-recovery \
--datasource-type AzureElasticSAN \
--source-datastore OperationalStore \
--restore-location {location} \
--recovery-point-id {recovery_point_id} \
--target-resource-id {target_volume_group_id} \
--restore-configuration @esan_restore_config.json > esan_restore_request.json

# 3) Grant missing restore permissions to vault MSI
# - Elastic SAN Volume Importer on target Elastic SAN
# - Reader on snapshot resource group (pass --snapshot-resource-group-id)
az dataprotection backup-instance update-msi-permissions \
--datasource-type AzureElasticSAN \
--operation Restore \
--permissions-scope Resource \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--restore-request-object @esan_restore_request.json \
--snapshot-resource-group-id {snapshot_rg_id}

# 4) Validate and trigger restore
az dataprotection backup-instance validate-for-restore \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance-name {backup_instance_name} \
--restore-request-object @esan_restore_request.json

az dataprotection backup-instance restore trigger \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance-name {backup_instance_name} \
--restore-request-object @esan_restore_request.json
```

#### dataprotection backup-vault ####
##### Create #####
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ class Create(AAZCommand):
"""

_aaz_info = {
"version": "2026-03-01",
"version": "2026-06-01",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.dataprotection/backupvaults/{}/backupinstances/{}", "2026-03-01"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.dataprotection/backupvaults/{}/backupinstances/{}", "2026-06-01"],
]
}

Expand Down Expand Up @@ -224,7 +224,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2026-03-01",
"api-version", "2026-06-01",
required=True,
),
}
Expand Down Expand Up @@ -481,6 +481,15 @@ def _build_schema_on_200_201(cls):
)
_CreateHelper._build_schema_blob_backup_rule_based_auto_protection_settings_read(disc_blob_backup_datasource_parameters_for_auto_protection.auto_protection_settings)

disc_generic_backup_datasource_parameters = cls._schema_on_200_201.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "GenericBackupDatasourceParameters")
disc_generic_backup_datasource_parameters.resource_selectors = AAZListType(
serialized_name="resourceSelectors",
flags={"required": True},
)

resource_selectors = cls._schema_on_200_201.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "GenericBackupDatasourceParameters").resource_selectors
resource_selectors.Element = AAZStrType()

disc_kubernetes_cluster_backup_datasource_parameters = cls._schema_on_200_201.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "KubernetesClusterBackupDatasourceParameters")
disc_kubernetes_cluster_backup_datasource_parameters.backup_hook_references = AAZListType(
serialized_name="backupHookReferences",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class Update(AAZCommand):
"""

_aaz_info = {
"version": "2026-03-01",
"version": "2026-06-01",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.dataprotection/backupvaults/{}/backupinstances/{}", "2026-03-01"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.dataprotection/backupvaults/{}/backupinstances/{}", "2026-06-01"],
]
}

Expand Down Expand Up @@ -298,6 +298,9 @@ def _build_arguments_schema(cls, *args, **kwargs):
_element.blob_backup_datasource_parameters_for_auto_protection = AAZObjectArg(
options=["blob-backup-datasource-parameters-for-auto-protection"],
)
_element.generic_backup_datasource_parameters = AAZObjectArg(
options=["generic-backup-datasource-parameters"],
)
_element.kubernetes_cluster_backup_datasource_parameters = AAZObjectArg(
options=["kubernetes-cluster-backup-datasource-parameters"],
)
Expand Down Expand Up @@ -338,6 +341,17 @@ def _build_arguments_schema(cls, *args, **kwargs):
)
cls._build_args_blob_backup_rule_based_auto_protection_settings_update(blob_backup_datasource_parameters_for_auto_protection.auto_protection_settings)

generic_backup_datasource_parameters = cls._args_schema.policy_info.policy_parameters.backup_datasource_parameters_list.Element.generic_backup_datasource_parameters
generic_backup_datasource_parameters.resource_selectors = AAZListArg(
options=["resource-selectors"],
help="List of resource selectors to be backed up during configuration of backup",
)

resource_selectors = cls._args_schema.policy_info.policy_parameters.backup_datasource_parameters_list.Element.generic_backup_datasource_parameters.resource_selectors
resource_selectors.Element = AAZStrArg(
nullable=True,
)

kubernetes_cluster_backup_datasource_parameters = cls._args_schema.policy_info.policy_parameters.backup_datasource_parameters_list.Element.kubernetes_cluster_backup_datasource_parameters
kubernetes_cluster_backup_datasource_parameters.backup_hook_references = AAZListArg(
options=["backup-hook-references"],
Expand Down Expand Up @@ -611,7 +625,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2026-03-01",
"api-version", "2026-06-01",
required=True,
),
}
Expand Down Expand Up @@ -714,7 +728,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2026-03-01",
"api-version", "2026-06-01",
required=True,
),
}
Expand Down Expand Up @@ -849,11 +863,13 @@ def _update_instance(self, instance):
_elements.set_const("objectType", "AdlsBlobBackupDatasourceParametersForAutoProtection", AAZStrType, ".adls_blob_backup_datasource_parameters_for_auto_protection", typ_kwargs={"flags": {"required": True}})
_elements.set_const("objectType", "BlobBackupDatasourceParameters", AAZStrType, ".blob_backup_datasource_parameters", typ_kwargs={"flags": {"required": True}})
_elements.set_const("objectType", "BlobBackupDatasourceParametersForAutoProtection", AAZStrType, ".blob_backup_datasource_parameters_for_auto_protection", typ_kwargs={"flags": {"required": True}})
_elements.set_const("objectType", "GenericBackupDatasourceParameters", AAZStrType, ".generic_backup_datasource_parameters", typ_kwargs={"flags": {"required": True}})
_elements.set_const("objectType", "KubernetesClusterBackupDatasourceParameters", AAZStrType, ".kubernetes_cluster_backup_datasource_parameters", typ_kwargs={"flags": {"required": True}})
_elements.discriminate_by("objectType", "AdlsBlobBackupDatasourceParameters")
_elements.discriminate_by("objectType", "AdlsBlobBackupDatasourceParametersForAutoProtection")
_elements.discriminate_by("objectType", "BlobBackupDatasourceParameters")
_elements.discriminate_by("objectType", "BlobBackupDatasourceParametersForAutoProtection")
_elements.discriminate_by("objectType", "GenericBackupDatasourceParameters")
_elements.discriminate_by("objectType", "KubernetesClusterBackupDatasourceParameters")

disc_adls_blob_backup_datasource_parameters = _builder.get(".properties.policyInfo.policyParameters.backupDatasourceParametersList[]{objectType:AdlsBlobBackupDatasourceParameters}")
Expand All @@ -880,6 +896,14 @@ def _update_instance(self, instance):
if disc_blob_backup_datasource_parameters_for_auto_protection is not None:
_UpdateHelper._build_schema_blob_backup_rule_based_auto_protection_settings_update(disc_blob_backup_datasource_parameters_for_auto_protection.set_prop("autoProtectionSettings", AAZObjectType, ".blob_backup_datasource_parameters_for_auto_protection.auto_protection_settings", typ_kwargs={"flags": {"required": True}}))

disc_generic_backup_datasource_parameters = _builder.get(".properties.policyInfo.policyParameters.backupDatasourceParametersList[]{objectType:GenericBackupDatasourceParameters}")
if disc_generic_backup_datasource_parameters is not None:
disc_generic_backup_datasource_parameters.set_prop("resourceSelectors", AAZListType, ".generic_backup_datasource_parameters.resource_selectors", typ_kwargs={"flags": {"required": True}})

resource_selectors = _builder.get(".properties.policyInfo.policyParameters.backupDatasourceParametersList[]{objectType:GenericBackupDatasourceParameters}.resourceSelectors")
if resource_selectors is not None:
resource_selectors.set_elements(AAZStrType, ".")

disc_kubernetes_cluster_backup_datasource_parameters = _builder.get(".properties.policyInfo.policyParameters.backupDatasourceParametersList[]{objectType:KubernetesClusterBackupDatasourceParameters}")
if disc_kubernetes_cluster_backup_datasource_parameters is not None:
disc_kubernetes_cluster_backup_datasource_parameters.set_prop("backupHookReferences", AAZListType, ".kubernetes_cluster_backup_datasource_parameters.backup_hook_references")
Expand Down Expand Up @@ -1213,6 +1237,15 @@ def _build_schema_backup_instance_resource_read(cls, _schema):
)
cls._build_schema_blob_backup_rule_based_auto_protection_settings_read(disc_blob_backup_datasource_parameters_for_auto_protection.auto_protection_settings)

disc_generic_backup_datasource_parameters = _schema_backup_instance_resource_read.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "GenericBackupDatasourceParameters")
disc_generic_backup_datasource_parameters.resource_selectors = AAZListType(
serialized_name="resourceSelectors",
flags={"required": True},
)

resource_selectors = _schema_backup_instance_resource_read.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "GenericBackupDatasourceParameters").resource_selectors
resource_selectors.Element = AAZStrType()

disc_kubernetes_cluster_backup_datasource_parameters = _schema_backup_instance_resource_read.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "KubernetesClusterBackupDatasourceParameters")
disc_kubernetes_cluster_backup_datasource_parameters.backup_hook_references = AAZListType(
serialized_name="backupHookReferences",
Expand Down
Loading
Loading