diff --git a/src/azure-cli/HISTORY.rst b/src/azure-cli/HISTORY.rst index 1437a140766..d75f4e26cb6 100644 --- a/src/azure-cli/HISTORY.rst +++ b/src/azure-cli/HISTORY.rst @@ -45,6 +45,7 @@ Release History **Backup** * Add support for cost management settings (#33757) +* `az backup restore files mount-rp`: Fetch ILR mount scripts through the dedicated list action for CHAP credential redaction. **Cognitive Services** diff --git a/src/azure-cli/azure/cli/command_modules/backup/_client_factory.py b/src/azure-cli/azure/cli/command_modules/backup/_client_factory.py index b2cad0e92fd..eb99b3a1ec5 100644 --- a/src/azure-cli/azure/cli/command_modules/backup/_client_factory.py +++ b/src/azure-cli/azure/cli/command_modules/backup/_client_factory.py @@ -20,17 +20,17 @@ def _common_client_factory(cli_ctx, **_): def _backup_client_factory(cli_ctx, **_): - from azure.mgmt.recoveryservicesbackup.activestamp import RecoveryServicesBackupClient + from azure.mgmt.recoveryservicesbackup import RecoveryServicesBackupClient from azure.cli.core.commands.client_factory import get_mgmt_service_client return get_mgmt_service_client(cli_ctx, RecoveryServicesBackupClient) def _backup_passive_client_factory(cli_ctx, **_): - from azure.mgmt.recoveryservicesbackup.passivestamp import RecoveryServicesBackupPassiveClient + from azure.mgmt.recoveryservicesbackup import RecoveryServicesBackupClient from azure.cli.core.commands.client_factory import get_mgmt_service_client - return get_mgmt_service_client(cli_ctx, RecoveryServicesBackupPassiveClient) + return get_mgmt_service_client(cli_ctx, RecoveryServicesBackupClient) # External Deps Client Factories diff --git a/src/azure-cli/azure/cli/command_modules/backup/_validators.py b/src/azure-cli/azure/cli/command_modules/backup/_validators.py index 93e80dea85b..5cc36f866a3 100644 --- a/src/azure-cli/azure/cli/command_modules/backup/_validators.py +++ b/src/azure-cli/azure/cli/command_modules/backup/_validators.py @@ -8,7 +8,7 @@ from datetime import datetime from azure.cli.core.azclierror import RequiredArgumentMissingError, MutuallyExclusiveArgumentError, \ ArgumentUsageError, InvalidArgumentValueError -from azure.mgmt.recoveryservicesbackup.activestamp.models import StorageType +from azure.mgmt.recoveryservicesbackup.models import StorageType # Argument types diff --git a/src/azure-cli/azure/cli/command_modules/backup/custom.py b/src/azure-cli/azure/cli/command_modules/backup/custom.py index bc66eadfa4a..8fee277f189 100644 --- a/src/azure-cli/azure/cli/command_modules/backup/custom.py +++ b/src/azure-cli/azure/cli/command_modules/backup/custom.py @@ -11,7 +11,7 @@ from knack.prompting import prompt_y_n from azure.mgmt.core.tools import is_valid_resource_id -from azure.mgmt.recoveryservicesbackup.activestamp import RecoveryServicesBackupClient +from azure.mgmt.recoveryservicesbackup import RecoveryServicesBackupClient from azure.mgmt.recoveryservices import RecoveryServicesClient from azure.cli.core.commands.client_factory import get_mgmt_service_client, get_subscription_id from azure.cli.core.profiles import ResourceType @@ -21,7 +21,7 @@ AzureMonitorAlertSettings, ClassicAlertSettings, SecuritySettings, ImmutabilitySettings, RestoreSettings, \ CrossSubscriptionRestoreSettings, DeletedVaultUndeleteInputProperties, DeletedVaultUndeleteInput, \ SoftDeleteSettings, CostManagementSettings, ImmutabilityConfiguration -from azure.mgmt.recoveryservicesbackup.activestamp.models import ProtectedItemResource, \ +from azure.mgmt.recoveryservicesbackup.models import ProtectedItemResource, \ AzureIaaSComputeVMProtectedItem, AzureIaaSClassicComputeVMProtectedItem, ProtectionState, IaasVMBackupRequest, \ BackupRequestResource, IaasVMRestoreRequest, RestoreRequestResource, BackupManagementType, WorkloadType, \ ILRRequestResource, IaasVMILRRegistrationRequest, \ @@ -29,11 +29,18 @@ MoveRPAcrossTiersRequest, RecoveryPointRehydrationInfo, IaasVMRestoreWithRehydrationRequest, IdentityInfo, \ BackupStatusRequest, ListRecoveryPointsRecommendedForMoveRequest, IdentityBasedRestoreDetails, ScheduleRunType, \ UnlockDeleteRequest, ResourceGuardProxyBase, ResourceGuardProxyBaseResource, TargetDiskNetworkAccessSettings, \ - SecuredVMDetails -from azure.mgmt.recoveryservicesbackup.passivestamp.models import CrrJobRequest, CrossRegionRestoreRequest + SecuredVMDetails, InstantItemRecoveryOperationResultRequest +from azure.cli.core.util import CLIError + +try: + from azure.mgmt.recoveryservicesbackup.models import CrrJobRequest, CrossRegionRestoreRequest +except ImportError: + def _unavailable_recoveryservicesbackup_model(*_args, **_kwargs): + raise CLIError('This operation is not supported by the installed Recovery Services Backup SDK.') + + CrrJobRequest = CrossRegionRestoreRequest = _unavailable_recoveryservicesbackup_model import azure.cli.command_modules.backup._validators as validators -from azure.cli.core.util import CLIError from azure.core.exceptions import HttpResponseError, ResourceNotFoundError as CoreResourceNotFoundError from azure.cli.core.azclierror import RequiredArgumentMissingError, InvalidArgumentValueError, \ MutuallyExclusiveArgumentError, ArgumentUsageError, ValidationError, ResourceNotFoundError @@ -1701,7 +1708,16 @@ def restore_files_mount_rp(cmd, client, resource_group_name, vault_name, contain result = client.provision(vault_name, resource_group_name, fabric_name, container_uri, item_uri, rp_name, file_restore_request, cls=cust_help.get_pipeline_response) - client_scripts = cust_help.track_backup_ilr(cmd.cli_ctx, result, vault_name, resource_group_name) + operation_id = cust_help.track_backup_ilr(cmd.cli_ctx, result, vault_name, resource_group_name) + mount_script_request = InstantItemRecoveryOperationResultRequest( + provision_instant_item_recovery_operation_id=operation_id) + recovery_target = client.list_instant_item_recovery_operation_result( + resource_group_name=resource_group_name, vault_name=vault_name, fabric_name=fabric_name, + container_name=container_uri, protected_item_name=item_uri, recovery_point_id=rp_name, + body=mount_script_request) + client_scripts = recovery_target.client_scripts if recovery_target else None + if not client_scripts: + raise CLIError('Mount script details were not returned by the backup service.') if client_scripts[0].os_type == os_windows: _run_client_script_for_windows(client_scripts) @@ -1739,7 +1755,7 @@ def disable_protection(cmd, client, resource_group_name, vault_name, item, # ResourceGuard scenario: if we are stopping backup and there is MUA setup for the scenario, # we want to set the appropriate parameters. - if vm_item.properties.protection_state == ProtectionState.protection_stopped: + if vm_item.properties.protection_state == ProtectionState.PROTECTION_STOPPED: if cust_help.has_resource_guard_mapping(cmd.cli_ctx, resource_group_name, vault_name, "RecoveryServicesStopProtection"): # Cross Tenant scenario @@ -1968,9 +1984,9 @@ def _get_disable_protection_request(item, undelete=False, vm_item_properties = _get_vm_item_properties_from_vm_id(item.properties.virtual_machine_id) vm_item_properties.policy_id = '' if retain_recovery_points_as_per_policy: - vm_item_properties.protection_state = ProtectionState.backups_suspended + vm_item_properties.protection_state = ProtectionState.BACKUPS_SUSPENDED else: - vm_item_properties.protection_state = ProtectionState.protection_stopped + vm_item_properties.protection_state = ProtectionState.PROTECTION_STOPPED vm_item_properties.source_resource_id = item.properties.source_resource_id if undelete: vm_item_properties.is_rehydrate = True diff --git a/src/azure-cli/azure/cli/command_modules/backup/custom_afs.py b/src/azure-cli/azure/cli/command_modules/backup/custom_afs.py index 2980a9e37a0..40f96edf81e 100644 --- a/src/azure-cli/azure/cli/command_modules/backup/custom_afs.py +++ b/src/azure-cli/azure/cli/command_modules/backup/custom_afs.py @@ -10,7 +10,7 @@ import azure.cli.command_modules.backup.custom_common as common -from azure.mgmt.recoveryservicesbackup.activestamp.models import ProtectedItemResource, \ +from azure.mgmt.recoveryservicesbackup.models import ProtectedItemResource, \ RestoreRequestResource, BackupRequestResource, RestoreFileSpecs, \ AzureFileShareBackupRequest, AzureFileshareProtectedItem, AzureFileShareRestoreRequest, \ TargetAFSRestoreInfo, ProtectionState, ProtectionContainerResource, AzureStorageContainer @@ -21,7 +21,7 @@ resources_cf, backup_protected_items_cf, protected_items_cf from azure.cli.core.azclierror import ArgumentUsageError, ValidationError -from azure.mgmt.recoveryservicesbackup.activestamp import RecoveryServicesBackupClient +from azure.mgmt.recoveryservicesbackup import RecoveryServicesBackupClient from azure.cli.core.commands.client_factory import get_mgmt_service_client from knack.log import get_logger @@ -440,15 +440,15 @@ def disable_protection(cmd, client, resource_group_name, vault_name, item, afs_item_properties = AzureFileshareProtectedItem() afs_item_properties.policy_id = '' if retain_recovery_points_as_per_policy: - afs_item_properties.protection_state = ProtectionState.backups_suspended + afs_item_properties.protection_state = ProtectionState.BACKUPS_SUSPENDED else: - afs_item_properties.protection_state = ProtectionState.protection_stopped + afs_item_properties.protection_state = ProtectionState.PROTECTION_STOPPED afs_item_properties.source_resource_id = item.properties.source_resource_id afs_item = ProtectedItemResource(properties=afs_item_properties) # ResourceGuard scenario: if we are stopping backup and there is MUA setup for the scenario, # we want to set the appropriate parameters. - if afs_item.properties.protection_state == ProtectionState.protection_stopped: + if afs_item.properties.protection_state == ProtectionState.PROTECTION_STOPPED: if helper.has_resource_guard_mapping(cmd.cli_ctx, resource_group_name, vault_name, "RecoveryServicesStopProtection"): # Cross Tenant scenario diff --git a/src/azure-cli/azure/cli/command_modules/backup/custom_base.py b/src/azure-cli/azure/cli/command_modules/backup/custom_base.py index 826aac1944a..5c79245034e 100644 --- a/src/azure-cli/azure/cli/command_modules/backup/custom_base.py +++ b/src/azure-cli/azure/cli/command_modules/backup/custom_base.py @@ -13,7 +13,7 @@ backup_protection_containers_cf, backup_protectable_items_cf, registered_identities_cf, vaults_cf from azure.cli.core.azclierror import ValidationError, RequiredArgumentMissingError, InvalidArgumentValueError, \ MutuallyExclusiveArgumentError, ArgumentUsageError -from azure.mgmt.recoveryservicesbackup.activestamp import RecoveryServicesBackupClient +from azure.mgmt.recoveryservicesbackup import RecoveryServicesBackupClient from azure.cli.core.commands.client_factory import get_mgmt_service_client, get_subscription_id # pylint: disable=import-error @@ -42,9 +42,9 @@ def reconfigure_backup_protection(cmd, client, resource_group_name, vault_name, raise ValidationError("Multiple items found. Please use native container and item names.") # Item-level validation (state, workload specifics) - from azure.mgmt.recoveryservicesbackup.activestamp.models import ProtectionState - if item.properties.protection_state not in [ProtectionState.protected, - ProtectionState.protection_stopped]: + from azure.mgmt.recoveryservicesbackup.models import ProtectionState + if item.properties.protection_state not in [ProtectionState.PROTECTED, + ProtectionState.PROTECTION_STOPPED]: raise ValidationError(f"Reconfiguration only supported for items in states: Protected or " f"ProtectionStopped. Current state: " f"{item.properties.protection_state}") diff --git a/src/azure-cli/azure/cli/command_modules/backup/custom_common.py b/src/azure-cli/azure/cli/command_modules/backup/custom_common.py index 29941f06e2e..3d82d417fc2 100644 --- a/src/azure-cli/azure/cli/command_modules/backup/custom_common.py +++ b/src/azure-cli/azure/cli/command_modules/backup/custom_common.py @@ -9,9 +9,9 @@ protected_items_cf, backup_protected_items_crr_cf, recovery_points_crr_cf, resource_guard_proxy_cf from azure.cli.core.util import CLIError from azure.cli.core.azclierror import InvalidArgumentValueError, RequiredArgumentMissingError -from azure.mgmt.recoveryservicesbackup.activestamp.models import RecoveryPointTierStatus, RecoveryPointTierType, \ +from azure.mgmt.recoveryservicesbackup.models import RecoveryPointTierStatus, RecoveryPointTierType, \ UnlockDeleteRequest, TieringMode -from azure.mgmt.recoveryservicesbackup.activestamp import RecoveryServicesBackupClient +from azure.mgmt.recoveryservicesbackup import RecoveryServicesBackupClient from azure.cli.core.commands.client_factory import get_mgmt_service_client # pylint: disable=import-error diff --git a/src/azure-cli/azure/cli/command_modules/backup/custom_help.py b/src/azure-cli/azure/cli/command_modules/backup/custom_help.py index ba13c40985c..0fce48e6a86 100644 --- a/src/azure-cli/azure/cli/command_modules/backup/custom_help.py +++ b/src/azure-cli/azure/cli/command_modules/backup/custom_help.py @@ -15,10 +15,15 @@ from azure.mgmt.core.tools import parse_resource_id, is_valid_resource_id -from azure.mgmt.recoveryservicesbackup.activestamp.models import OperationStatusValues, JobStatus -from azure.mgmt.recoveryservicesbackup.passivestamp.models import CrrJobRequest - +from azure.mgmt.recoveryservicesbackup.models import OperationStatusValues from azure.cli.core.util import CLIError + +try: + from azure.mgmt.recoveryservicesbackup.models import CrrJobRequest +except ImportError: + def CrrJobRequest(*_args, **_kwargs): + raise CLIError('This operation is not supported by the installed Recovery Services Backup SDK.') + from azure.cli.core.commands import _is_paged from azure.cli.command_modules.backup._client_factory import ( job_details_cf, protection_container_refresh_operation_results_cf, @@ -413,11 +418,14 @@ def get_target_path(resource_type, path, logical_name, data_directory_paths): # Tracking Utilities # pylint: disable=inconsistent-return-statements def track_backup_ilr(cli_ctx, result, vault_name, resource_group): + operation_id = get_operation_id_from_header(result.http_response.headers['Azure-AsyncOperation']) operation_status = track_backup_operation(cli_ctx, resource_group, result, vault_name) - if operation_status.properties: - recovery_target = operation_status.properties.recovery_target - return recovery_target.client_scripts + if operation_status.status != OperationStatusValues.SUCCEEDED.value: + raise CLIError('Provisioning access to the recovery point failed with status: {}.'.format( + operation_status.status)) + + return operation_id # pylint: disable=inconsistent-return-statements @@ -436,7 +444,7 @@ def track_backup_operation(cli_ctx, resource_group, result, vault_name): operation_id = get_operation_id_from_header(result.http_response.headers['Azure-AsyncOperation']) operation_status = backup_operation_statuses_client.get(vault_name, resource_group, operation_id) - while operation_status.status == OperationStatusValues.in_progress.value: + while operation_status.status == OperationStatusValues.IN_PROGRESS.value: time.sleep(5) operation_status = backup_operation_statuses_client.get(vault_name, resource_group, operation_id) return operation_status @@ -458,7 +466,7 @@ def track_backup_crr_operation(cli_ctx, result, azure_region): operation_id = get_operation_id_from_header(result.http_response.headers['Azure-AsyncOperation']) operation_status = crr_operation_statuses_client.get(azure_region, operation_id) - while operation_status.status == OperationStatusValues.in_progress.value: + while operation_status.status == OperationStatusValues.IN_PROGRESS.value: time.sleep(5) operation_status = crr_operation_statuses_client.get(azure_region, operation_id) return operation_status @@ -507,7 +515,7 @@ def track_inquiry_operation(cli_ctx, result, vault_name, resource_group, contain def job_in_progress(job_status): - return job_status in [JobStatus.in_progress.value, JobStatus.cancelling.value] + return job_status in ['InProgress', 'Cancelling'] # List Utilities diff --git a/src/azure-cli/azure/cli/command_modules/backup/custom_wl.py b/src/azure-cli/azure/cli/command_modules/backup/custom_wl.py index 5d2c4db206d..0a836f67706 100644 --- a/src/azure-cli/azure/cli/command_modules/backup/custom_wl.py +++ b/src/azure-cli/azure/cli/command_modules/backup/custom_wl.py @@ -14,7 +14,7 @@ from knack.log import get_logger -from azure.mgmt.recoveryservicesbackup.activestamp.models import AzureVMAppContainerProtectionContainer, \ +from azure.mgmt.recoveryservicesbackup.models import AzureVMAppContainerProtectionContainer, \ AzureWorkloadBackupRequest, ProtectedItemResource, AzureRecoveryServiceVaultProtectionIntent, TargetRestoreInfo, \ RestoreRequestResource, BackupRequestResource, ProtectionIntentResource, SQLDataDirectoryMapping, \ ProtectionContainerResource, AzureWorkloadSAPHanaRestoreRequest, AzureWorkloadSQLRestoreRequest, \ @@ -26,9 +26,13 @@ UserAssignedManagedIdentityDetails, UserAssignedIdentityProperties, \ AzureVmWorkloadSAPAseDatabaseProtectedItem, MoveRPAcrossTiersRequest -from azure.mgmt.recoveryservicesbackup.passivestamp.models import CrossRegionRestoreRequest - from azure.cli.core.util import CLIError + +try: + from azure.mgmt.recoveryservicesbackup.models import CrossRegionRestoreRequest +except ImportError: + def CrossRegionRestoreRequest(*_args, **_kwargs): + raise CLIError('This operation is not supported by the installed Recovery Services Backup SDK.') from azure.cli.command_modules.backup._validators import datetime_type, validate_wl_restore, validate_log_point_in_time from azure.cli.command_modules.backup._client_factory import protectable_containers_cf, \ backup_protection_containers_cf, backup_protected_items_cf, recovery_points_crr_cf, \ @@ -42,7 +46,7 @@ from azure.cli.core.azclierror import InvalidArgumentValueError, RequiredArgumentMissingError, ValidationError, \ ResourceNotFoundError, ArgumentUsageError, MutuallyExclusiveArgumentError -from azure.mgmt.recoveryservicesbackup.activestamp import RecoveryServicesBackupClient +from azure.mgmt.recoveryservicesbackup import RecoveryServicesBackupClient from azure.cli.core.commands.client_factory import get_mgmt_service_client from azure.cli.core.profiles import ResourceType @@ -608,15 +612,15 @@ def disable_protection(cmd, client, resource_group_name, vault_name, item, properties = _get_protected_item_instance(backup_item_type) if retain_recovery_points_as_per_policy: - properties.protection_state = ProtectionState.backups_suspended + properties.protection_state = ProtectionState.BACKUPS_SUSPENDED else: - properties.protection_state = ProtectionState.protection_stopped + properties.protection_state = ProtectionState.PROTECTION_STOPPED properties.policy_id = '' param = ProtectedItemResource(properties=properties) # ResourceGuard scenario: if we are stopping backup and there is MUA setup for the scenario, # we want to set the appropriate parameters. - if param.properties.protection_state == ProtectionState.protection_stopped: + if param.properties.protection_state == ProtectionState.PROTECTION_STOPPED: if cust_help.has_resource_guard_mapping(cmd.cli_ctx, resource_group_name, vault_name, "RecoveryServicesStopProtection"): # Cross Tenant scenario diff --git a/src/azure-cli/azure/cli/command_modules/backup/tests/latest/test_backup_commands.py b/src/azure-cli/azure/cli/command_modules/backup/tests/latest/test_backup_commands.py index e87b5a9f4f3..d176d004ff6 100644 --- a/src/azure-cli/azure/cli/command_modules/backup/tests/latest/test_backup_commands.py +++ b/src/azure-cli/azure/cli/command_modules/backup/tests/latest/test_backup_commands.py @@ -9,10 +9,11 @@ import unittest import time import random +from unittest import mock from azure.cli.testsdk import ScenarioTest, JMESPathCheckExists, \ KeyVaultPreparer, record_only, live_only -from azure.mgmt.recoveryservicesbackup.activestamp.models import StorageType +from azure.mgmt.recoveryservicesbackup.models import StorageType from azure.cli.testsdk.scenario_tests import AllowLargeResponse from .preparers import VaultPreparer, VMPreparer, ItemPreparer, PolicyPreparer, RPPreparer, \ @@ -156,10 +157,10 @@ def test_backup_vault(self, resource_group, resource_group_location, vault1, vau storage_model_types = [e.value for e in StorageType] vault_properties_redundancy = self.cmd('backup vault show -n {vault1} -g {rg} --query "properties.redundancySettings"').get_output_in_json() - if vault_properties_redundancy['standardTierStorageRedundancy'] == StorageType.geo_redundant.value: - new_storage_model = StorageType.locally_redundant.value + if vault_properties_redundancy['standardTierStorageRedundancy'] == StorageType.GEO_REDUNDANT.value: + new_storage_model = StorageType.LOCALLY_REDUNDANT.value else: - new_storage_model = StorageType.geo_redundant.value + new_storage_model = StorageType.GEO_REDUNDANT.value self.kwargs['model'] = new_storage_model self.cmd('backup vault update -n {vault1} -g {rg} --backup-storage-redundancy {model}') @@ -168,7 +169,7 @@ def test_backup_vault(self, resource_group, resource_group_location, vault1, vau self.check('standardTierStorageRedundancy', new_storage_model) ]) - new_storage_model = StorageType.zone_redundant.value + new_storage_model = StorageType.ZONE_REDUNDANT.value self.kwargs['model'] = new_storage_model self.cmd('backup vault update -n {vault1} -g {rg} --backup-storage-redundancy {model}') time.sleep(300) @@ -1953,5 +1954,75 @@ def test_handles_job_without_properties_or_none(self): self.assertIs(set_job_container_subscription_id(job), job) +class BackupRestoreFilesMountRpTests(unittest.TestCase): + def _run_mount_rp(self, client_scripts, is_active_session=False): + from azure.cli.command_modules.backup import custom + + item = SimpleNamespace( + id='/Subscriptions/sub/resourceGroups/rg/providers/Microsoft.RecoveryServices/vaults/vault/' + 'backupFabrics/Azure/protectionContainers/container/protectedItems/item', + properties=SimpleNamespace(virtual_machine_id='vm-id')) + recovery_point = SimpleNamespace( + properties=SimpleNamespace(is_instant_ilr_session_active=is_active_session)) + client = mock.MagicMock() + client.provision.return_value = 'provision-response' + client.list_instant_item_recovery_operation_result.return_value = SimpleNamespace(client_scripts=client_scripts) + + with mock.patch.object(custom, 'show_item', return_value=item), \ + mock.patch.object(custom.cust_help, 'validate_item'), \ + mock.patch.object(custom, 'backup_protected_items_cf'), \ + mock.patch.object(custom, 'recovery_points_cf') as recovery_points_cf_mock, \ + mock.patch.object(custom.cust_help, 'track_backup_ilr', return_value='provision-operation-id'), \ + mock.patch.object(custom, '_run_client_script_for_linux') as linux_runner_mock, \ + mock.patch.object(custom, '_run_client_script_for_windows') as windows_runner_mock: + recovery_points_cf_mock.return_value.get.return_value = recovery_point + + custom.restore_files_mount_rp( + SimpleNamespace(cli_ctx=SimpleNamespace()), client, 'rg', 'vault', 'container', 'item', 'rp') + + return client, linux_runner_mock, windows_runner_mock, recovery_point + + def test_mount_rp_lists_scripts_after_provision(self): + linux_script = SimpleNamespace(os_type='Linux') + + client, linux_runner_mock, windows_runner_mock, _ = self._run_mount_rp([linux_script]) + + client.provision.assert_called_once() + client.list_instant_item_recovery_operation_result.assert_called_once() + list_kwargs = client.list_instant_item_recovery_operation_result.call_args.kwargs + self.assertEqual( + (list_kwargs['resource_group_name'], list_kwargs['vault_name'], list_kwargs['fabric_name'], + list_kwargs['container_name'], list_kwargs['protected_item_name'], list_kwargs['recovery_point_id']), + ('rg', 'vault', 'Azure', 'container', 'item', 'rp')) + self.assertEqual(list_kwargs['body'].provision_instant_item_recovery_operation_id, 'provision-operation-id') + linux_runner_mock.assert_called_once_with([linux_script]) + windows_runner_mock.assert_not_called() + + def test_mount_rp_list_call_binds_to_installed_sdk_signature(self): + # Guards against SDK param reorder/rename: the new list operation uses + # resource_group_name before vault_name, unlike the legacy provision/revoke order. + import inspect + from azure.mgmt.recoveryservicesbackup.operations import ItemLevelRecoveryConnectionsOperations + + linux_script = SimpleNamespace(os_type='Linux') + client, _, _, _ = self._run_mount_rp([linux_script]) + list_kwargs = client.list_instant_item_recovery_operation_result.call_args.kwargs + + signature = inspect.signature(ItemLevelRecoveryConnectionsOperations.list_instant_item_recovery_operation_result) + # Binding raises TypeError if any keyword is not a real parameter of the installed SDK method. + signature.bind_partial(self=None, **list_kwargs) + + def test_mount_rp_preserves_active_session_renewal(self): + windows_scripts = [SimpleNamespace(os_type='Windows'), SimpleNamespace(os_type='Windows')] + + client, linux_runner_mock, windows_runner_mock, recovery_point = self._run_mount_rp( + windows_scripts, is_active_session=True) + + self.assertTrue(recovery_point.properties.renew_existing_registration) + client.list_instant_item_recovery_operation_result.assert_called_once() + windows_runner_mock.assert_called_once_with(windows_scripts) + linux_runner_mock.assert_not_called() + + if __name__ == '__main__': unittest.main() diff --git a/src/azure-cli/requirements.py3.Darwin.txt b/src/azure-cli/requirements.py3.Darwin.txt index 3e4c2933269..6bf5a5a3702 100644 --- a/src/azure-cli/requirements.py3.Darwin.txt +++ b/src/azure-cli/requirements.py3.Darwin.txt @@ -63,7 +63,7 @@ azure-mgmt-privatedns==1.0.0 azure-mgmt-rdbms==10.2.0b17 azure-mgmt-mysqlflexibleservers==1.1.0b3 azure-mgmt-recoveryservices==4.1.0 -azure-mgmt-recoveryservicesbackup==9.2.0 +azure-mgmt-recoveryservicesbackup==11.1.0 azure-mgmt-redhatopenshift~=3.0.0 azure-mgmt-redis==14.5.0 azure-mgmt-resource==24.0.0 diff --git a/src/azure-cli/requirements.py3.Linux.txt b/src/azure-cli/requirements.py3.Linux.txt index f7a32f909cc..751a9c52597 100644 --- a/src/azure-cli/requirements.py3.Linux.txt +++ b/src/azure-cli/requirements.py3.Linux.txt @@ -63,7 +63,7 @@ azure-mgmt-privatedns==1.0.0 azure-mgmt-rdbms==10.2.0b17 azure-mgmt-mysqlflexibleservers==1.1.0b3 azure-mgmt-recoveryservices==4.1.0 -azure-mgmt-recoveryservicesbackup==9.2.0 +azure-mgmt-recoveryservicesbackup==11.1.0 azure-mgmt-redhatopenshift~=3.0.0 azure-mgmt-redis==14.5.0 azure-mgmt-resource==24.0.0 diff --git a/src/azure-cli/requirements.py3.windows.txt b/src/azure-cli/requirements.py3.windows.txt index 363e700f6f4..5ebbb665f84 100644 --- a/src/azure-cli/requirements.py3.windows.txt +++ b/src/azure-cli/requirements.py3.windows.txt @@ -63,7 +63,7 @@ azure-mgmt-privatedns==1.0.0 azure-mgmt-rdbms==10.2.0b17 azure-mgmt-mysqlflexibleservers==1.1.0b3 azure-mgmt-recoveryservices==4.1.0 -azure-mgmt-recoveryservicesbackup==9.2.0 +azure-mgmt-recoveryservicesbackup==11.1.0 azure-mgmt-redhatopenshift~=3.0.0 azure-mgmt-redis==14.5.0 azure-mgmt-resource==24.0.0 diff --git a/src/azure-cli/setup.py b/src/azure-cli/setup.py index 9681845a703..eb674df8ba5 100644 --- a/src/azure-cli/setup.py +++ b/src/azure-cli/setup.py @@ -107,7 +107,7 @@ 'azure-mgmt-privatedns~=1.0.0', 'azure-mgmt-rdbms==10.2.0b17', 'azure-mgmt-mysqlflexibleservers==1.1.0b3', - 'azure-mgmt-recoveryservicesbackup~=9.2.0', + 'azure-mgmt-recoveryservicesbackup~=11.1.0', 'azure-mgmt-recoveryservices~=4.1.0', 'azure-mgmt-redhatopenshift~=3.0.0', 'azure-mgmt-redis~=14.5.0',