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
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,19 @@ def _common_client_factory(cli_ctx, **_):


def _backup_client_factory(cli_ctx, **_):
from azure.mgmt.recoveryservicesbackup import RecoveryServicesBackupClient
from azure.mgmt.recoveryservicesbackup.activestamp 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.cli.core.commands.client_factory import get_mgmt_service_client

return get_mgmt_service_client(cli_ctx, RecoveryServicesBackupPassiveClient)


# External Deps Client Factories
def virtual_machines_cf(cli_ctx, *_):
return _compute_client_factory(cli_ctx).virtual_machines
Expand All @@ -55,7 +62,7 @@ def registered_identities_cf(cli_ctx, *_):


def backup_storage_configs_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).backup_resource_storage_configs
return _backup_passive_client_factory(cli_ctx).backup_resource_storage_configs


def backup_storage_configs_non_crr_cf(cli_ctx, *_):
Expand Down Expand Up @@ -117,15 +124,15 @@ def backup_protected_items_cf(cli_ctx, *_):


def backup_protected_items_crr_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).backup_protected_items_crr
return _backup_passive_client_factory(cli_ctx).backup_protected_items_crr


def backup_operation_statuses_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).backup_operation_statuses


def crr_operation_status_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).crr_operation_status
return _backup_passive_client_factory(cli_ctx).crr_operation_status


def backups_cf(cli_ctx, *_):
Expand All @@ -137,7 +144,7 @@ def backup_jobs_cf(cli_ctx, *_):


def backup_crr_jobs_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).backup_crr_jobs
return _backup_passive_client_factory(cli_ctx).backup_crr_jobs


def backup_workload_items_cf(cli_ctx, *_):
Expand All @@ -150,7 +157,7 @@ def job_details_cf(cli_ctx, *_):


def backup_crr_job_details_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).backup_crr_job_details
return _backup_passive_client_factory(cli_ctx).backup_crr_job_details


def job_cancellations_cf(cli_ctx, *_):
Expand All @@ -167,15 +174,19 @@ def recovery_points_recommended_cf(cli_ctx, *_):


def recovery_points_crr_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).recovery_points_crr
return _backup_passive_client_factory(cli_ctx).recovery_points_crr


def recovery_points_passive_cf(cli_ctx, *_):
return _backup_passive_client_factory(cli_ctx).recovery_points


def restores_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).restores


def cross_region_restore_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).cross_region_restore
return _backup_passive_client_factory(cli_ctx).cross_region_restore


def item_level_recovery_connections_cf(cli_ctx, *_):
Expand All @@ -192,4 +203,4 @@ def backup_resource_encryption_config_cf(cli_ctx, *_):

# Azure Active Directory Client Factories
def aad_properties_cf(cli_ctx, *_):
return _backup_client_factory(cli_ctx).aad_properties
return _backup_passive_client_factory(cli_ctx).aad_properties
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ def load_arguments(self, _):

with self.argument_context('backup protectable-item show') as c:
c.argument('vault_name', vault_name_type, id_part='name')
c.argument('name', options_list=['--name'], help='Name of the protectable item.', id_part='child_name_3')
c.argument('name', options_list=['--name', '-n'], help='Name of the protectable item.', id_part='child_name_3')
c.argument('server_name', options_list=['--server-name'], help='Parent Server name of the item.')
c.argument('protectable_item_type', protectable_item_type)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from datetime import datetime
from azure.cli.core.azclierror import RequiredArgumentMissingError, MutuallyExclusiveArgumentError, \
ArgumentUsageError, InvalidArgumentValueError
from azure.mgmt.recoveryservicesbackup.models import StorageType
from azure.mgmt.recoveryservicesbackup.activestamp.models import StorageType
# Argument types


Expand Down
28 changes: 18 additions & 10 deletions src/azure-cli/azure/cli/command_modules/backup/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@

from azure.mgmt.recoveryservices.models import Vault, VaultProperties, Sku, SkuName, PatchVault, IdentityData, \
CmkKeyVaultProperties, CmkKekIdentity, VaultPropertiesEncryption, UserIdentity
from azure.mgmt.recoveryservicesbackup.models import ProtectedItemResource, AzureIaaSComputeVMProtectedItem, \
AzureIaaSClassicComputeVMProtectedItem, ProtectionState, IaasVMBackupRequest, BackupRequestResource, \
IaasVMRestoreRequest, RestoreRequestResource, BackupManagementType, WorkloadType, \
from azure.mgmt.recoveryservicesbackup.activestamp.models import ProtectedItemResource, \
AzureIaaSComputeVMProtectedItem, AzureIaaSClassicComputeVMProtectedItem, ProtectionState, IaasVMBackupRequest, \
BackupRequestResource, IaasVMRestoreRequest, RestoreRequestResource, BackupManagementType, WorkloadType, \
ILRRequestResource, IaasVMILRRegistrationRequest, BackupResourceConfig, BackupResourceConfigResource, \
BackupResourceVaultConfig, BackupResourceVaultConfigResource, DiskExclusionProperties, ExtendedProperties, \
MoveRPAcrossTiersRequest, RecoveryPointRehydrationInfo, IaasVMRestoreWithRehydrationRequest, IdentityInfo, \
CrossRegionRestoreRequest, BackupStatusRequest, CrrJobRequest, ListRecoveryPointsRecommendedForMoveRequest
BackupStatusRequest, ListRecoveryPointsRecommendedForMoveRequest, IdentityBasedRestoreDetails
from azure.mgmt.recoveryservicesbackup.passivestamp.models import CrrJobRequest, CrossRegionRestoreRequest

import azure.cli.command_modules.backup._validators as validators
from azure.cli.core.util import CLIError
Expand All @@ -32,7 +33,7 @@
protected_items_cf, backup_resource_vault_config_cf, recovery_points_crr_cf, aad_properties_cf,
cross_region_restore_cf, backup_crr_job_details_cf, backup_crr_jobs_cf, backup_protected_items_crr_cf,
_backup_client_factory, recovery_points_recommended_cf, backup_resource_encryption_config_cf, backup_status_cf,
backup_storage_configs_non_crr_cf)
backup_storage_configs_non_crr_cf, recovery_points_passive_cf)

import azure.cli.command_modules.backup.custom_common as common
import azure.cli.command_modules.backup.custom_help as cust_help
Expand Down Expand Up @@ -852,12 +853,17 @@ def _get_trigger_restore_properties(rp_name, vault_location, storage_account_id,
raise InvalidArgumentValueError("disk_encryption_set_id can't be specified")

identity_info = None
identity_based_restore_details = None
target_storage_account_id = storage_account_id
if mi_system_assigned or mi_user_assigned:
if not recovery_point.properties.is_managed_virtual_machine:
raise InvalidArgumentValueError("MI based restore is not supported for unmanaged VMs.")
identity_info = IdentityInfo(
is_system_assigned_identity=mi_system_assigned is not None,
managed_identity_resource_id=mi_user_assigned)
identity_based_restore_details = IdentityBasedRestoreDetails(
target_storage_account_id=target_storage_account_id)
target_storage_account_id = None

if tier == 'VaultArchive':
rehyd_duration = 'P' + str(rehydration_duration) + 'D'
Expand All @@ -869,28 +875,30 @@ def _get_trigger_restore_properties(rp_name, vault_location, storage_account_id,
recovery_point_id=rp_name,
recovery_type='RestoreDisks',
region=vault_location,
storage_account_id=storage_account_id,
storage_account_id=target_storage_account_id,
source_resource_id=source_resource_id,
target_resource_group_id=target_rg_id,
original_storage_account_option=use_original_storage_account,
restore_disk_lun_list=restore_disk_lun_list,
recovery_point_rehydration_info=rehydration_info,
disk_encryption_set_id=disk_encryption_set_id,
identity_info=identity_info)
identity_info=identity_info,
identity_based_restore_details=identity_based_restore_details)

else:
trigger_restore_properties = IaasVMRestoreRequest(
create_new_cloud_service=True,
recovery_point_id=rp_name,
recovery_type='RestoreDisks',
region=vault_location,
storage_account_id=storage_account_id,
storage_account_id=target_storage_account_id,
source_resource_id=source_resource_id,
target_resource_group_id=target_rg_id,
original_storage_account_option=use_original_storage_account,
restore_disk_lun_list=restore_disk_lun_list,
disk_encryption_set_id=disk_encryption_set_id,
identity_info=identity_info)
identity_info=identity_info,
identity_based_restore_details=identity_based_restore_details)

return trigger_restore_properties

Expand Down Expand Up @@ -1228,7 +1236,7 @@ def _get_backup_request(workload_type, retain_until):
def _get_crr_access_token(cmd, azure_region, vault_name, resource_group_name, container_uri, item_uri, rp_name):
aad_client = aad_properties_cf(cmd.cli_ctx)
aad_result = aad_client.get(azure_region)
rp_client = recovery_points_cf(cmd.cli_ctx)
rp_client = recovery_points_passive_cf(cmd.cli_ctx)
crr_access_token = rp_client.get_access_token(vault_name, resource_group_name, fabric_name, container_uri,
item_uri, rp_name, aad_result).properties
crr_access_token.object_type = "CrrAccessToken"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import azure.cli.command_modules.backup.custom_common as common

from azure.mgmt.recoveryservicesbackup.models import ProtectedItemResource, \
from azure.mgmt.recoveryservicesbackup.activestamp.models import ProtectedItemResource, \
RestoreRequestResource, BackupRequestResource, RestoreFileSpecs, \
AzureFileShareBackupRequest, AzureFileshareProtectedItem, AzureFileShareRestoreRequest, \
TargetAFSRestoreInfo, ProtectionState, ProtectionContainerResource, AzureStorageContainer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ def list_protectable_items(cmd, client, resource_group_name, vault_name, workloa
Multiple containers with same Friendly Name found. Please give native names instead.
""")
container_uri = container.name
return custom_wl.list_protectable_items(client, resource_group_name, vault_name, workload_type,
return custom_wl.list_protectable_items(cmd, client, resource_group_name, vault_name, workload_type,
backup_management_type, container_uri, protectable_item_type, server_name)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
protected_items_cf, backup_protected_items_crr_cf, recovery_points_crr_cf
from azure.cli.core.util import CLIError
from azure.cli.core.azclierror import InvalidArgumentValueError, RequiredArgumentMissingError
from azure.mgmt.recoveryservicesbackup.models import RecoveryPointTierStatus, RecoveryPointTierType
from azure.mgmt.recoveryservicesbackup.activestamp.models import RecoveryPointTierStatus, RecoveryPointTierType
# pylint: disable=import-error

fabric_name = "Azure"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

from azure.mgmt.core.tools import parse_resource_id, is_valid_resource_id

from azure.mgmt.recoveryservicesbackup.models import OperationStatusValues, JobStatus, CrrJobRequest
from azure.mgmt.recoveryservicesbackup.activestamp.models import OperationStatusValues, JobStatus
from azure.mgmt.recoveryservicesbackup.passivestamp.models import CrrJobRequest

from azure.cli.core.util import CLIError
from azure.cli.core.commands import _is_paged
Expand Down Expand Up @@ -413,7 +414,8 @@ def validate_and_extract_container_type(container_name, backup_management_type):

container_type = container_name.split(";")[0].lower()
container_type_mappings = {"iaasvmcontainer": "AzureIaasVM", "storagecontainer": "AzureStorage",
"vmappcontainer": "AzureWorkload", "windows": "MAB"}
"vmappcontainer": "AzureWorkload", "windows": "MAB",
"sqlagworkloadcontainer": "AzureWorkload"}

if container_type in container_type_mappings:
return container_type_mappings[container_type]
Expand Down
59 changes: 48 additions & 11 deletions src/azure-cli/azure/cli/command_modules/backup/custom_wl.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,23 @@

from knack.log import get_logger

from azure.mgmt.recoveryservicesbackup.models import AzureVMAppContainerProtectionContainer, \
from azure.mgmt.recoveryservicesbackup.activestamp.models import AzureVMAppContainerProtectionContainer, \
AzureWorkloadBackupRequest, ProtectedItemResource, AzureRecoveryServiceVaultProtectionIntent, TargetRestoreInfo, \
RestoreRequestResource, BackupRequestResource, ProtectionIntentResource, SQLDataDirectoryMapping, \
ProtectionContainerResource, AzureWorkloadSAPHanaRestoreRequest, AzureWorkloadSQLRestoreRequest, \
AzureWorkloadSAPHanaPointInTimeRestoreRequest, AzureWorkloadSQLPointInTimeRestoreRequest, \
AzureVmWorkloadSAPHanaDatabaseProtectedItem, AzureVmWorkloadSQLDatabaseProtectedItem, MoveRPAcrossTiersRequest, \
RecoveryPointRehydrationInfo, AzureWorkloadSAPHanaRestoreWithRehydrateRequest, \
AzureWorkloadSQLRestoreWithRehydrateRequest, CrossRegionRestoreRequest
AzureWorkloadSQLRestoreWithRehydrateRequest

from azure.mgmt.recoveryservicesbackup.passivestamp.models import CrossRegionRestoreRequest

from azure.cli.core.util import CLIError
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 backup_workload_items_cf, \
protectable_containers_cf, backup_protection_containers_cf, backup_protected_items_cf, recovery_points_crr_cf, \
_backup_client_factory, recovery_points_cf, vaults_cf, aad_properties_cf, cross_region_restore_cf, \
backup_protection_intent_cf
backup_protection_intent_cf, recovery_points_passive_cf, protection_containers_cf

import azure.cli.command_modules.backup.custom_help as cust_help
import azure.cli.command_modules.backup.custom_common as common
Expand Down Expand Up @@ -301,7 +303,7 @@ def show_protectable_instance(items, server_name, protectable_item_type):
return cust_help.get_none_one_or_many(filtered_items)


def list_protectable_items(client, resource_group_name, vault_name, workload_type,
def list_protectable_items(cmd, client, resource_group_name, vault_name, workload_type,
backup_management_type="AzureWorkload", container_uri=None, protectable_item_type=None,
server_name=None):

Expand All @@ -326,8 +328,11 @@ def list_protectable_items(client, resource_group_name, vault_name, workload_typ
paged_items = [item for item in paged_items if hasattr(item.properties, 'server_name') and
item.properties.server_name.lower() == server_name.lower()]
if container_uri:
return [item for item in paged_items if
cust_help.get_protection_container_uri_from_id(item.id).lower() == container_uri.lower()]
# Container URI filter
paged_items = [item for item in paged_items if
cust_help.get_protection_container_uri_from_id(item.id).lower() == container_uri.lower()]

_fetch_nodes_list_and_auto_protection_policy(cmd, paged_items, resource_group_name, vault_name)

return paged_items

Expand Down Expand Up @@ -519,10 +524,10 @@ def auto_enable_for_azure_wl(client, resource_group_name, vault_name, policy_obj
protectable_item_object = protectable_item
item_id = protectable_item_object.id
protectable_item_type = protectable_item_object.properties.protectable_item_type
if protectable_item_type.lower() != 'sqlinstance':
if protectable_item_type.lower() not in ['sqlinstance', 'sqlavailabilitygroupcontainer']:
raise CLIError(
"""
Protectable Item can only be of type SQLInstance.
Protectable Item can only be of type SQLInstance or SQLAG.
""")

policy_id = policy_object.id
Expand All @@ -546,10 +551,10 @@ def disable_auto_for_azure_wl(cmd, client, resource_group_name, vault_name, prot
protectable_item_type = protectable_item_object.properties.protectable_item_type
protectable_item_name = protectable_item_object.properties.friendly_name
container_name = cust_help.get_protection_container_uri_from_id(item_id)
if protectable_item_type.lower() != 'sqlinstance':
if protectable_item_type.lower() not in ['sqlinstance', 'sqlavailabilitygroupcontainer']:
raise CLIError(
"""
Protectable Item can only be of type SQLInstance.
Protectable Item can only be of type SQLInstance or SQLAG.
""")

filter_string = cust_help.get_filter_string({
Expand Down Expand Up @@ -683,7 +688,7 @@ def restore_azure_wl(cmd, client, resource_group_name, vault_name, recovery_conf
aad_client = aad_properties_cf(cmd.cli_ctx)
filter_string = cust_help.get_filter_string({'backupManagementType': 'AzureWorkload'})
aad_result = aad_client.get(azure_region, filter_string)
rp_client = recovery_points_cf(cmd.cli_ctx)
rp_client = recovery_points_passive_cf(cmd.cli_ctx)
crr_access_token = rp_client.get_access_token(vault_name, resource_group_name, fabric_name, container_uri,
item_uri, recovery_point_id, aad_result).properties
crr_client = cross_region_restore_cf(cmd.cli_ctx)
Expand Down Expand Up @@ -807,6 +812,38 @@ def show_recovery_config(cmd, client, resource_group_name, vault_name, restore_m
'alternate_directory_paths': alternate_directory_paths}


def _fetch_nodes_list_and_auto_protection_policy(cmd, paged_items, resource_group_name, vault_name):
protection_intent_client = backup_protection_intent_cf(cmd.cli_ctx)
protection_containers_client = protection_containers_cf(cmd.cli_ctx)

for item in paged_items:
item_id = item.id
protectable_item_type = item.properties.protectable_item_type
protectable_item_name = item.properties.friendly_name
container_name = cust_help.get_protection_container_uri_from_id(item_id)

# fetch AutoProtectionPolicy for SQLInstance and SQLAG
if protectable_item_type and protectable_item_type.lower() in ['sqlinstance', 'sqlavailabilitygroupcontainer']:
setattr(item.properties, "auto_protection_policy", None)
filter_string = cust_help.get_filter_string({
'backupManagementType': "AzureWorkload",
'itemType': protectable_item_type,
'itemName': protectable_item_name,
'parentName': container_name})
protection_intents = protection_intent_client.list(vault_name, resource_group_name, filter_string)
paged_protection_intents = cust_help.get_list_from_paged_response(protection_intents)

if paged_protection_intents:
item.properties.auto_protection_policy = paged_protection_intents[0].properties.policy_id

# fetch NodesList for SQLAG
if protectable_item_type and protectable_item_type.lower() == 'sqlavailabilitygroupcontainer':
setattr(item.properties, "nodes_list", None)
container = protection_containers_client.get(vault_name, resource_group_name, fabric_name, container_name)
if container.properties.extended_info:
item.properties.nodes_list = container.properties.extended_info.nodes_list


def _get_log_time_range(cmd, resource_group_name, vault_name, item, use_secondary_region):
container_uri = cust_help.get_protection_container_uri_from_id(item.id)
item_uri = cust_help.get_protected_item_uri_from_id(item.id)
Expand Down
Loading