diff --git a/src/dataprotection/HISTORY.rst b/src/dataprotection/HISTORY.rst index 1204567e8b5..81a31859a51 100644 --- a/src/dataprotection/HISTORY.rst +++ b/src/dataprotection/HISTORY.rst @@ -2,6 +2,10 @@ Release History =============== +1.8.0 ++++++ +* `az dataprotection backup-instance update`: New parameter: `--backup-configuration` to update AKS datasource parameters. +* Fix in `helpers.py` to correctly prepare/normalize AKS backup-configuration payloads passed via the CLI. 1.7.1 +++++ diff --git a/src/dataprotection/azext_dataprotection/manual/_help.py b/src/dataprotection/azext_dataprotection/manual/_help.py index a9e1ea527b7..8774ac429f5 100644 --- a/src/dataprotection/azext_dataprotection/manual/_help.py +++ b/src/dataprotection/azext_dataprotection/manual/_help.py @@ -31,6 +31,8 @@ examples: - name: Update backed up containers for a vaulted blob backup instance text: az dataprotection backup-instance update --backup-instance-name MyDisk1 --vaulted-blob-container-list {backup_configuration} -g MyResourceGroup --vault-name MyVault + - name: Update backed up namespaces for an aks backup instance + text: az dataprotection backup-instance update --backup-instance-name MyAKSCluster1 --aks-backup-configuration {aks_backup_configuration} -g MyResourceGroup --vault-name MyVault """ helps['dataprotection backup-instance update-policy'] = """ diff --git a/src/dataprotection/azext_dataprotection/manual/_params.py b/src/dataprotection/azext_dataprotection/manual/_params.py index 4d230c7a27d..0dc23ec5fd0 100644 --- a/src/dataprotection/azext_dataprotection/manual/_params.py +++ b/src/dataprotection/azext_dataprotection/manual/_params.py @@ -134,6 +134,9 @@ def load_arguments(self, _): c.argument('vaulted_blob_container_list', type=validate_file_or_dict, options_list=['--vaulted-blob-container-list', '--container-blob-list'], help="Enter the container list to modify a vaulted blob backup. The output for " "'az dataprotection backup-instance initialize-backupconfig' needs to be provided as input") + c.argument('aks_backup_configuration', type=validate_file_or_dict, options_list=['--aks-backup-configuration', '--aks-config'], + help="Enter the AKS backup configuration to modify AKS backup datasource parameters. " + "The output for 'az dataprotection backup-instance initialize-backupconfig --datasource-type AzureKubernetesService' needs to be provided as input.") c.argument('use_system_assigned_identity', options_list=['--system-assigned', '--use-system-identity', '--use-system-assigned-identity'], arg_type=get_three_state_flag(), help="Use system assigned identity") c.argument('user_assigned_identity_arm_url', options_list=['--user-assigned', '--user-assigned-identity-arm-url', '--uami'], type=str, help="ARM ID of the User Assigned Managed Identity") diff --git a/src/dataprotection/azext_dataprotection/manual/custom.py b/src/dataprotection/azext_dataprotection/manual/custom.py index e1857a44b48..670c15ff5a4 100644 --- a/src/dataprotection/azext_dataprotection/manual/custom.py +++ b/src/dataprotection/azext_dataprotection/manual/custom.py @@ -14,6 +14,7 @@ # pylint: disable=no-else-continue # pylint: disable=no-else-raise import time +import json from azure.cli.core.azclierror import ( RequiredArgumentMissingError, InvalidArgumentValueError, @@ -246,7 +247,7 @@ def dataprotection_backup_instance_validate_for_update(cmd, resource_group_name, def dataprotection_backup_instance_update(cmd, resource_group_name, vault_name, backup_instance_name, - vaulted_blob_container_list=None, no_wait=False, + vaulted_blob_container_list=None, aks_backup_configuration=None, no_wait=False, use_system_assigned_identity=None, user_assigned_identity_arm_url=None): from azext_dataprotection.aaz.latest.dataprotection.backup_instance import Show as BackupInstanceShow backup_instance = BackupInstanceShow(cli_ctx=cmd.cli_ctx)(command_args={ @@ -266,10 +267,36 @@ def dataprotection_backup_instance_update(cmd, resource_group_name, vault_name, identity_details = helper.get_identity_details(use_system_assigned_identity, user_assigned_identity_arm_url) backup_instance["properties"]["identityDetails"] = identity_details - # Policy changes - updating the vaulted blob container list for vaulted blob backups - if vaulted_blob_container_list is not None: - backup_instance['properties']['policyInfo']['policyParameters']['backupDatasourceParametersList'] = \ - [vaulted_blob_container_list,] + # Policy changes + # - Updating the vaulted blob container list for vaulted blob backups + # - Updating the backup datasource parameters for AKS backups + datasource_type = backup_instance["properties"]["dataSourceInfo"]["datasourceType"] + + # If user provided any of the datasource parameter update inputs, handle according to datasource type + if vaulted_blob_container_list is not None or aks_backup_configuration is not None: + if datasource_type == "Microsoft.ContainerService/managedClusters": + # AKS scenario (only --aks-backup-configuration is valid) + if vaulted_blob_container_list is not None: + raise InvalidArgumentValueError(f'Invalid argument --vaulted-blob-container-list for AKS datasource type: {datasource_type}. Use --aks-backup-configuration instead.') + elif aks_backup_configuration is not None: + # Allow passing JSON string or already-parsed object for AKS backup configuration + if isinstance(aks_backup_configuration, str): + try: + aks_backup_configuration = json.loads(aks_backup_configuration) + except json.JSONDecodeError: + raise InvalidArgumentValueError("Provided --aks-backup-configuration is not valid JSON.") + except Exception: + raise InvalidArgumentValueError("Provided --aks-backup-configuration is not valid.") + backup_instance['properties']['policyInfo']['policyParameters']['backupDatasourceParametersList'] = [aks_backup_configuration] + elif datasource_type == "Microsoft.Storage/storageAccounts/blobServices": + # Blob scenario (only --vaulted-blob-container-list is valid) + if aks_backup_configuration is not None: + raise InvalidArgumentValueError(f'Invalid argument --aks-backup-configuration for Blob datasource type: {datasource_type}. Use --vaulted-blob-container-list instead.') + elif vaulted_blob_container_list is not None: + backup_instance['properties']['policyInfo']['policyParameters']['backupDatasourceParametersList'] = [vaulted_blob_container_list] + else: + raise InvalidArgumentValueError(f"Setting backup datasource parameters is not supported for datasource type: {datasource_type}.\n " + "Supported datasource types are Microsoft.ContainerService/managedClusters (AKS) and Microsoft.Storage/storageAccounts/blobServices (Blob).") backup_instance = helper.convert_backup_instance_show_to_input(backup_instance) diff --git a/src/dataprotection/azext_dataprotection/manual/helpers.py b/src/dataprotection/azext_dataprotection/manual/helpers.py index 4ba090b9e3b..543cc9a3592 100644 --- a/src/dataprotection/azext_dataprotection/manual/helpers.py +++ b/src/dataprotection/azext_dataprotection/manual/helpers.py @@ -997,6 +997,16 @@ def convert_backup_instance_show_to_input(backup_instance): del backup_instance['properties']['protectionStatus'] if 'provisioningState' in backup_instance['properties']: del backup_instance['properties']['provisioningState'] + # Cleaning up resourceProperties if objectType is null to avoid schema validation error + for datasource_property in ['dataSourceInfo', 'dataSourceSetInfo']: + if datasource_property in backup_instance['properties']: + datasource_info = backup_instance['properties'][datasource_property] + if (isinstance(datasource_info, dict) and + 'resourceProperties' in datasource_info and + isinstance(datasource_info['resourceProperties'], dict)): + if datasource_info['resourceProperties'].get('objectType') is None: + # Cleaning up resourceProperties when objectType is null to avoid schema validation error + del backup_instance['properties'][datasource_property]['resourceProperties'] return backup_instance diff --git a/src/dataprotection/azext_dataprotection/tests/latest/recordings/test_dataprotection_backup_instance_update_aks_configuration.yaml b/src/dataprotection/azext_dataprotection/tests/latest/recordings/test_dataprotection_backup_instance_update_aks_configuration.yaml new file mode 100644 index 00000000000..90b73d7ab1b --- /dev/null +++ b/src/dataprotection/azext_dataprotection/tests/latest/recordings/test_dataprotection_backup_instance_update_aks_configuration.yaml @@ -0,0 +1,340 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - dataprotection backup-instance show + Connection: + - keep-alive + ParameterSetName: + - -g --vault-name --name + User-Agent: + - AZURECLI/2.81.0 azsdk-python-core/1.35.0 Python/3.13.9 (Windows-11-10.0.26200-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c?api-version=2025-07-01 + response: + body: + string: '{"properties":{"friendlyName":"clitest-cluster1-donotdelete\\clitestsabidonotdelete","dataSourceInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","resourceProperties":{"objectType":null},"objectType":"Datasource"},"dataSourceSetInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","objectType":"DatasourceSet"},"policyInfo":{"policyId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupPolicies/akspolicy","policyVersion":"","policyParameters":{"dataStoreParametersList":[{"dataStoreType":"OperationalStore","objectType":"AzureOperationalStoreParameters","resourceGroupId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg"}],"backupDatasourceParametersList":[{"objectType":"KubernetesClusterBackupDatasourceParameters","excludedResourceTypes":["ResourceX"],"includeClusterScopeResources":false,"includedNamespaces":["nsA","nsB"],"labelSelectors":["app=web"],"snapshotVolumes":false,"excludedNamespaces":null,"includedResourceTypes":null,"includedVolumeTypes":null,"backupHookReferences":null}]}},"protectionStatus":{"status":"ProtectionConfigured"},"currentProtectionState":"ProtectionConfigured","provisioningState":"Succeeded","identityDetails":{"useSystemAssignedIdentity":true},"objectType":"BackupInstance"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","name":"clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","type":"Microsoft.DataProtection/backupVaults/backupInstances"}' + headers: + cache-control: + - no-cache + content-length: + - '2848' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Dec 2025 07:27:23 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=e927f4b9-3591-42c4-a0c4-05508605bfeb/centralindia/71ade053-d098-43d8-90f8-7e48665672ca + x-ms-ratelimit-remaining-subscription-resource-requests: + - '1099' + x-msedge-ref: + - 'Ref A: 5A07A187D8D248C3A2A41595491E45B2 Ref B: MAA201060516021 Ref C: 2025-12-03T07:27:21Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - dataprotection backup-instance update + Connection: + - keep-alive + ParameterSetName: + - -g --vault-name --backup-instance-name --aks-backup-configuration + User-Agent: + - AZURECLI/2.81.0 azsdk-python-core/1.35.0 Python/3.13.9 (Windows-11-10.0.26200-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c?api-version=2025-07-01 + response: + body: + string: '{"properties":{"friendlyName":"clitest-cluster1-donotdelete\\clitestsabidonotdelete","dataSourceInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","resourceProperties":{"objectType":null},"objectType":"Datasource"},"dataSourceSetInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","objectType":"DatasourceSet"},"policyInfo":{"policyId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupPolicies/akspolicy","policyVersion":"","policyParameters":{"dataStoreParametersList":[{"dataStoreType":"OperationalStore","objectType":"AzureOperationalStoreParameters","resourceGroupId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg"}],"backupDatasourceParametersList":[{"objectType":"KubernetesClusterBackupDatasourceParameters","excludedResourceTypes":["ResourceX"],"includeClusterScopeResources":false,"includedNamespaces":["nsA","nsB"],"labelSelectors":["app=web"],"snapshotVolumes":false,"excludedNamespaces":null,"includedResourceTypes":null,"includedVolumeTypes":null,"backupHookReferences":null}]}},"protectionStatus":{"status":"ProtectionConfigured"},"currentProtectionState":"ProtectionConfigured","provisioningState":"Succeeded","identityDetails":{"useSystemAssignedIdentity":true},"objectType":"BackupInstance"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","name":"clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","type":"Microsoft.DataProtection/backupVaults/backupInstances"}' + headers: + cache-control: + - no-cache + content-length: + - '2848' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Dec 2025 07:27:25 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=e927f4b9-3591-42c4-a0c4-05508605bfeb/centralindia/a8ab83b5-7a48-40d2-a53d-70e0e9a73547 + x-ms-ratelimit-remaining-subscription-resource-requests: + - '1099' + x-msedge-ref: + - 'Ref A: CBB05B0513164B1BA41A090CD8035053 Ref B: MAA201060514035 Ref C: 2025-12-03T07:27:23Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"dataSourceInfo": {"datasourceType": "Microsoft.ContainerService/managedClusters", + "objectType": "Datasource", "resourceID": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete", + "resourceLocation": "eastus2euap", "resourceName": "clitest-cluster1-donotdelete", + "resourceType": "Microsoft.ContainerService/managedClusters", "resourceUri": + "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete"}, + "dataSourceSetInfo": {"datasourceType": "Microsoft.ContainerService/managedClusters", + "objectType": "DatasourceSet", "resourceID": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete", + "resourceLocation": "eastus2euap", "resourceName": "clitest-cluster1-donotdelete", + "resourceType": "Microsoft.ContainerService/managedClusters", "resourceUri": + "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete"}, + "friendlyName": "clitest-cluster1-donotdelete\\clitestsabidonotdelete", "identityDetails": + {"useSystemAssignedIdentity": true}, "objectType": "BackupInstance", "policyInfo": + {"policyId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupPolicies/akspolicy", + "policyParameters": {"backupDatasourceParametersList": [{"objectType": "KubernetesClusterBackupDatasourceParameters", + "excludedResourceTypes": ["ResourceX"], "includeClusterScopeResources": false, + "includedNamespaces": ["nsA", "nsB"], "labelSelectors": ["app=web"], "snapshotVolumes": + false}], "dataStoreParametersList": [{"dataStoreType": "OperationalStore", "objectType": + "AzureOperationalStoreParameters", "resourceGroupId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg"}]}}}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - dataprotection backup-instance update + Connection: + - keep-alive + Content-Length: + - '2158' + Content-Type: + - application/json + ParameterSetName: + - -g --vault-name --backup-instance-name --aks-backup-configuration + User-Agent: + - AZURECLI/2.81.0 azsdk-python-core/1.35.0 Python/3.13.9 (Windows-11-10.0.26200-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c?api-version=2025-07-01 + response: + body: + string: '{"properties":{"friendlyName":"clitest-cluster1-donotdelete\\clitestsabidonotdelete","dataSourceInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","resourceProperties":{"objectType":null},"objectType":"Datasource"},"dataSourceSetInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","objectType":"DatasourceSet"},"policyInfo":{"policyId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupPolicies/akspolicy","policyVersion":"","policyParameters":{"dataStoreParametersList":[{"dataStoreType":"OperationalStore","objectType":"AzureOperationalStoreParameters","resourceGroupId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg"}],"backupDatasourceParametersList":[{"objectType":"KubernetesClusterBackupDatasourceParameters","excludedResourceTypes":["ResourceX"],"includeClusterScopeResources":false,"includedNamespaces":["nsA","nsB"],"labelSelectors":["app=web"],"snapshotVolumes":false,"excludedNamespaces":null,"includedResourceTypes":null,"includedVolumeTypes":null,"backupHookReferences":null}]}},"protectionStatus":{"status":"ProtectionConfigured"},"currentProtectionState":"ProtectionConfigured","provisioningState":"Succeeded","identityDetails":{"useSystemAssignedIdentity":true},"objectType":"BackupInstance"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","name":"clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","type":"Microsoft.DataProtection/backupVaults/backupInstances"}' + headers: + cache-control: + - no-cache + content-length: + - '2848' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Dec 2025 07:27:26 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=e927f4b9-3591-42c4-a0c4-05508605bfeb/centraluseuap/91cd3d70-144f-455d-bbe9-cf4da200c6fb + x-ms-ratelimit-remaining-subscription-resource-requests: + - '799' + x-ms-throttling-version: + - v1 + x-msedge-ref: + - 'Ref A: 3A1D3C3356A04C8F91442427EDE2315B Ref B: MAA201060513049 Ref C: 2025-12-03T07:27:25Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - dataprotection backup-instance show + Connection: + - keep-alive + ParameterSetName: + - -g --vault-name --name + User-Agent: + - AZURECLI/2.81.0 azsdk-python-core/1.35.0 Python/3.13.9 (Windows-11-10.0.26200-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c?api-version=2025-07-01 + response: + body: + string: '{"properties":{"friendlyName":"clitest-cluster1-donotdelete\\clitestsabidonotdelete","dataSourceInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","resourceProperties":{"objectType":null},"objectType":"Datasource"},"dataSourceSetInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","objectType":"DatasourceSet"},"policyInfo":{"policyId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupPolicies/akspolicy","policyVersion":"","policyParameters":{"dataStoreParametersList":[{"dataStoreType":"OperationalStore","objectType":"AzureOperationalStoreParameters","resourceGroupId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg"}],"backupDatasourceParametersList":[{"objectType":"KubernetesClusterBackupDatasourceParameters","excludedResourceTypes":["ResourceX"],"includeClusterScopeResources":false,"includedNamespaces":["nsA","nsB"],"labelSelectors":["app=web"],"snapshotVolumes":false,"excludedNamespaces":null,"includedResourceTypes":null,"includedVolumeTypes":null,"backupHookReferences":null}]}},"protectionStatus":{"status":"ProtectionConfigured"},"currentProtectionState":"ProtectionConfigured","provisioningState":"Succeeded","identityDetails":{"useSystemAssignedIdentity":true},"objectType":"BackupInstance"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","name":"clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","type":"Microsoft.DataProtection/backupVaults/backupInstances"}' + headers: + cache-control: + - no-cache + content-length: + - '2848' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Dec 2025 07:27:28 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=e927f4b9-3591-42c4-a0c4-05508605bfeb/centraluseuap/98d5e016-df4b-4300-884d-bfc8c75a215b + x-ms-ratelimit-remaining-subscription-resource-requests: + - '1099' + x-ms-throttling-version: + - v1 + x-msedge-ref: + - 'Ref A: C18481BAE40C416AB7FE942FFE5BECCB Ref B: MAA201060516053 Ref C: 2025-12-03T07:27:27Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - dataprotection backup-instance update + Connection: + - keep-alive + ParameterSetName: + - -g --vault-name --backup-instance-name --aks-backup-configuration + User-Agent: + - AZURECLI/2.81.0 azsdk-python-core/1.35.0 Python/3.13.9 (Windows-11-10.0.26200-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c?api-version=2025-07-01 + response: + body: + string: '{"properties":{"friendlyName":"clitest-cluster1-donotdelete\\clitestsabidonotdelete","dataSourceInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","resourceProperties":{"objectType":null},"objectType":"Datasource"},"dataSourceSetInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","objectType":"DatasourceSet"},"policyInfo":{"policyId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupPolicies/akspolicy","policyVersion":"","policyParameters":{"dataStoreParametersList":[{"dataStoreType":"OperationalStore","objectType":"AzureOperationalStoreParameters","resourceGroupId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg"}],"backupDatasourceParametersList":[{"objectType":"KubernetesClusterBackupDatasourceParameters","excludedResourceTypes":["ResourceX"],"includeClusterScopeResources":false,"includedNamespaces":["nsA","nsB"],"labelSelectors":["app=web"],"snapshotVolumes":false,"excludedNamespaces":null,"includedResourceTypes":null,"includedVolumeTypes":null,"backupHookReferences":null}]}},"protectionStatus":{"status":"ProtectionConfigured"},"currentProtectionState":"ProtectionConfigured","provisioningState":"Succeeded","identityDetails":{"useSystemAssignedIdentity":true},"objectType":"BackupInstance"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","name":"clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","type":"Microsoft.DataProtection/backupVaults/backupInstances"}' + headers: + cache-control: + - no-cache + content-length: + - '2848' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Dec 2025 07:27:29 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=e927f4b9-3591-42c4-a0c4-05508605bfeb/centraluseuap/db6d9ffa-d653-4dde-8472-3855fe21d22f + x-ms-ratelimit-remaining-subscription-resource-requests: + - '1099' + x-ms-throttling-version: + - v1 + x-msedge-ref: + - 'Ref A: 00F5030AC09844E8B067BE8FABC90137 Ref B: MAA201060515033 Ref C: 2025-12-03T07:27:29Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"dataSourceInfo": {"datasourceType": "Microsoft.ContainerService/managedClusters", + "objectType": "Datasource", "resourceID": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete", + "resourceLocation": "eastus2euap", "resourceName": "clitest-cluster1-donotdelete", + "resourceType": "Microsoft.ContainerService/managedClusters", "resourceUri": + "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete"}, + "dataSourceSetInfo": {"datasourceType": "Microsoft.ContainerService/managedClusters", + "objectType": "DatasourceSet", "resourceID": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete", + "resourceLocation": "eastus2euap", "resourceName": "clitest-cluster1-donotdelete", + "resourceType": "Microsoft.ContainerService/managedClusters", "resourceUri": + "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete"}, + "friendlyName": "clitest-cluster1-donotdelete\\clitestsabidonotdelete", "identityDetails": + {"useSystemAssignedIdentity": true}, "objectType": "BackupInstance", "policyInfo": + {"policyId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupPolicies/akspolicy", + "policyParameters": {"backupDatasourceParametersList": [{"objectType": "KubernetesClusterBackupDatasourceParameters", + "excludedResourceTypes": ["ResourceX"], "includeClusterScopeResources": false, + "includedNamespaces": ["nsA", "nsB"], "labelSelectors": ["app=web"], "snapshotVolumes": + false}], "dataStoreParametersList": [{"dataStoreType": "OperationalStore", "objectType": + "AzureOperationalStoreParameters", "resourceGroupId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg"}]}}}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - dataprotection backup-instance update + Connection: + - keep-alive + Content-Length: + - '2158' + Content-Type: + - application/json + ParameterSetName: + - -g --vault-name --backup-instance-name --aks-backup-configuration + User-Agent: + - AZURECLI/2.81.0 azsdk-python-core/1.35.0 Python/3.13.9 (Windows-11-10.0.26200-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c?api-version=2025-07-01 + response: + body: + string: '{"properties":{"friendlyName":"clitest-cluster1-donotdelete\\clitestsabidonotdelete","dataSourceInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","resourceProperties":{"objectType":null},"objectType":"Datasource"},"dataSourceSetInfo":{"resourceID":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","resourceUri":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete","datasourceType":"Microsoft.ContainerService/managedClusters","resourceName":"clitest-cluster1-donotdelete","resourceType":"Microsoft.ContainerService/managedClusters","resourceLocation":"eastus2euap","objectType":"DatasourceSet"},"policyInfo":{"policyId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupPolicies/akspolicy","policyVersion":"","policyParameters":{"dataStoreParametersList":[{"dataStoreType":"OperationalStore","objectType":"AzureOperationalStoreParameters","resourceGroupId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg"}],"backupDatasourceParametersList":[{"objectType":"KubernetesClusterBackupDatasourceParameters","excludedResourceTypes":["ResourceX"],"includeClusterScopeResources":false,"includedNamespaces":["nsA","nsB"],"labelSelectors":["app=web"],"snapshotVolumes":false,"excludedNamespaces":null,"includedResourceTypes":null,"includedVolumeTypes":null,"backupHookReferences":null}]}},"protectionStatus":{"status":"ProtectionConfigured"},"currentProtectionState":"ProtectionConfigured","provisioningState":"Succeeded","identityDetails":{"useSystemAssignedIdentity":true},"objectType":"BackupInstance"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupInstances/clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","name":"clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c","type":"Microsoft.DataProtection/backupVaults/backupInstances"}' + headers: + cache-control: + - no-cache + content-length: + - '2848' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Dec 2025 07:27:30 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=e927f4b9-3591-42c4-a0c4-05508605bfeb/centraluseuap/c4864009-89a4-49f9-9911-c18b4891916a + x-ms-ratelimit-remaining-subscription-resource-requests: + - '799' + x-ms-throttling-version: + - v1 + x-msedge-ref: + - 'Ref A: D8264EA51EC34B6393B512F478771F31 Ref B: MAA201060513035 Ref C: 2025-12-03T07:27:29Z' + status: + code: 200 + message: OK +version: 1 diff --git a/src/dataprotection/azext_dataprotection/tests/latest/test_dataprotection_backup_instance_operations.py b/src/dataprotection/azext_dataprotection/tests/latest/test_dataprotection_backup_instance_operations.py index 45c281d7ac2..dfb24c2adb5 100644 --- a/src/dataprotection/azext_dataprotection/tests/latest/test_dataprotection_backup_instance_operations.py +++ b/src/dataprotection/azext_dataprotection/tests/latest/test_dataprotection_backup_instance_operations.py @@ -279,3 +279,52 @@ def test_dataprotection_backup_instance_softdelete(test): # Once protection elsewhere is stopped, we can resume protection on the undeleted BI time.sleep(60) reset_softdelete_base_state(test) + + @AllowLargeResponse() + def test_dataprotection_backup_instance_update_aks_configuration(test): + # Update with AKS backup configuration using simple az CLI commands. + test.kwargs.update({ + 'location': 'eastus2euap', + 'rg': 'clitest-dpp-rg', + 'vaultName': 'clitest-bkp-vault-aks-donotdelete', + 'policyId': '/subscriptions/38304e13-357e-405e-9e9a-220351dcce8c/resourceGroups/clitest-dpp-rg/providers/Microsoft.DataProtection/backupVaults/clitest-bkp-vault-aks-donotdelete/backupPolicies/akspolicy', + 'dataSourceType': 'AzureKubernetesService', + 'aksClusterName': 'clitest-cluster1-donotdelete', + 'aksClusterId': '/subscriptions/38304e13-357e-405e-9e9a-220351dcce8c/resourceGroups/oss-clitest-rg/providers/Microsoft.ContainerService/managedClusters/clitest-cluster1-donotdelete', + 'friendlyName': 'clitest-cluster1-donotdelete\\clitestsabidonotdelete', + 'backupInstanceName': 'clitest-cluster1-donotdelete-clitest-cluster1-donotdelete-bd3ae6fd-0d5f-4f76-85b4-8d7f0fe7006c' + }) + + # Fetch original BI backupDatasourceParametersList (if any) to allow resetting later + original_bi = test.cmd('az dataprotection backup-instance show -g "{rg}" --vault-name "{vaultName}" --name "{backupInstanceName}"').get_output_in_json() + originalBackupConfig = original_bi['properties']['policyInfo']['policyParameters'].get('backupDatasourceParametersList')[0] + test.kwargs.update({ + 'backupConfig': originalBackupConfig + }) + + # Generate the AKS backup configuration with specific values in a single command to make the change observable + new_backup_config_json = test.cmd('az dataprotection backup-instance initialize-backupconfig --datasource-type AzureKubernetesService ' + '--included-namespaces "nsA" "nsB" --label-selectors "app=web" --excluded-resource-types "ResourceX" ' + '--include-cluster-scope-resources false --snapshot-volumes false').get_output_in_json() + test.kwargs.update({ + 'tempBackupConfig': new_backup_config_json + }) + + # Apply temp configuration + test.cmd('az dataprotection backup-instance update -g "{rg}" --vault-name "{vaultName}" --backup-instance-name "{backupInstanceName}" --aks-backup-configuration "{tempBackupConfig}"', checks=[ + test.check('name', "{backupInstanceName}") + ]) + + # Fetch the BI and verify that the backupDatasourceParametersList was updated to reflect the AKS config + test.cmd('az dataprotection backup-instance show -g "{rg}" --vault-name "{vaultName}" --name "{backupInstanceName}"', checks=[ + test.check("properties.policyInfo.policyParameters.backupDatasourceParametersList[0].includedNamespaces", ['nsA', 'nsB']), + test.check("properties.policyInfo.policyParameters.backupDatasourceParametersList[0].labelSelectors", ['app=web']), + test.check("properties.policyInfo.policyParameters.backupDatasourceParametersList[0].excludedResourceTypes", ['ResourceX']), + test.check("properties.policyInfo.policyParameters.backupDatasourceParametersList[0].includeClusterScopeResources", False), + test.check("properties.policyInfo.policyParameters.backupDatasourceParametersList[0].snapshotVolumes", False) + ]) + + # Reset to original configuration + test.cmd('az dataprotection backup-instance update -g "{rg}" --vault-name "{vaultName}" --backup-instance-name "{backupInstanceName}" --aks-backup-configuration "{backupConfig}"', checks=[ + test.check('name', "{backupInstanceName}") + ]) \ No newline at end of file diff --git a/src/dataprotection/setup.py b/src/dataprotection/setup.py index b00e9c8218d..0af4bc59016 100644 --- a/src/dataprotection/setup.py +++ b/src/dataprotection/setup.py @@ -10,7 +10,7 @@ from setuptools import setup, find_packages # HISTORY.rst entry. -VERSION = '1.7.1' +VERSION = '1.8.0' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers