Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RecoveryServices Backup]Added disk exclusion Feature for IAASVM #11717

Merged
merged 4 commits into from
Jan 2, 2020
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
1 change: 1 addition & 0 deletions src/azure-cli/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Release History

* Added new command 'backup protection undelete' to enable soft-delete feature for IaasVM workload
* Added new parameter '--soft-delete-feature-state' to set backup-properties command
* Added disk exclusion support for IaasVM workload

**Compute**

Expand Down
8 changes: 8 additions & 0 deletions src/azure-cli/azure/cli/command_modules/backup/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,14 @@
text: az backup protection resume --vault-name MyVault --resource-group MyResourceGroup --container-name MyContainer --item-name MyItem --policy-name MyPolicy
"""

helps['backup protection update-for-vm'] = """
type: command
short-summary: Update disk exclusion settings associated with a backed up VM item.
examples:
- name: Update disk exclusion settings associated with a backed up VM item.
text: az backup protection update-for-vm --vault-name MyVault --resource-group MyResourceGroup --container-name MyContainer --item-name MyItem --disk-list-setting exclude --diskslist 1
"""

helps['backup recoveryconfig'] = """
type: group
short-summary: Manage recovery configuration of an Azure workload backed up item.
Expand Down
15 changes: 14 additions & 1 deletion src/azure-cli/azure/cli/command_modules/backup/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
protectable_item_name_type_help = """Specify the resource name to be protected by Azure Backup service."""
backup_type_help = """'Full, Differential, Log, Copy-only-full' for backup Item type 'MSSQL'. 'Full, Differential' for backup item type 'SAPHANA'."""
retain_until_help = """The date until which this backed up copy will be available for retrieval, in UTC (d-m-Y). For SAPHANA and SQL workload, retain-until parameter value will be overridden by the underlying policy."""
diskslist_help = """List of disks to be excluded or included."""
sambitratha marked this conversation as resolved.
Show resolved Hide resolved
disk_list_setting_help = """option to decide whether to include or exclude the disk or reset any previous settings to default behavior"""

vault_name_type = CLIArgumentType(help='Name of the Recovery services vault.', options_list=['--vault-name', '-v'], completer=get_resource_name_completion_list('Microsoft.RecoveryServices/vaults'))
container_name_type = CLIArgumentType(help=container_name_help, options_list=['--container-name', '-c'])
Expand All @@ -53,6 +55,7 @@
protectable_item_type = CLIArgumentType(help=workload_type_help, options_list=['--protectable-item-type'], arg_type=get_enum_type(allowed_protectable_item_type))
target_server_type = CLIArgumentType(help=target_server_type_help, options_list=['--target-server-type'], arg_type=get_enum_type(allowed_protectable_item_type))
protectable_item_name_type = CLIArgumentType(help=protectable_item_name_type_help, options_list=['--protectable-item-name'])
diskslist_type = CLIArgumentType(nargs='+', help=diskslist_help)


# pylint: disable=too-many-statements
Expand Down Expand Up @@ -173,7 +176,7 @@ def load_arguments(self, _):
c.argument('policy_name', policy_name_type)

# TODO: Need to use item.id once https://github.com/Azure/msrestazure-for-python/issues/80 is fixed.
for command in ['backup-now', 'disable', 'auto-disable-for-azurewl', 'resume', 'undelete']:
for command in ['backup-now', 'disable', 'auto-disable-for-azurewl', 'resume', 'undelete', 'update-for-vm']:
with self.argument_context('backup protection ' + command) as c:
c.argument('container_name', container_name_type)
c.argument('item_name', item_name_type)
Expand All @@ -193,6 +196,14 @@ def load_arguments(self, _):
with self.argument_context('backup protection check-vm') as c:
c.argument('vm_id', help='ID of the virtual machine to be checked for protection.')

with self.argument_context('backup protection enable-for-vm') as c:
c.argument('diskslist', diskslist_type)
c.argument('disk_list_setting', arg_type=get_enum_type(['include', 'exclude']), options_list=['--disk-list-setting'], help=disk_list_setting_help)

with self.argument_context('backup protection update-for-vm') as c:
c.argument('diskslist', diskslist_type)
c.argument('disk_list_setting', arg_type=get_enum_type(['include', 'exclude', 'resetexclusionsettings']), options_list=['--disk-list-setting'], help=disk_list_setting_help)

with self.argument_context('backup protection enable-for-azurefileshare') as c:
c.argument('azure_file_share', options_list=['--azure-file-share'], help='Name of the Azure FileShare.')
c.argument('storage_account', options_list=['--storage-account'], help='Name of the Storage Account of the FileShare.')
Expand Down Expand Up @@ -227,6 +238,8 @@ def load_arguments(self, _):
c.argument('storage_account', help='Name or ID of the staging storage account. The VM configuration will be restored to this storage account. See the help for --restore-to-staging-storage-account parameter for more info.')
c.argument('restore_to_staging_storage_account', arg_type=get_three_state_flag(), help='Use this flag when you want disks to be restored to the staging storage account using the --storage-account parameter. When not specified, disks will be restored to their original storage accounts. Default: false.')
c.argument('target_resource_group', options_list=['--target-resource-group', '-t'], help='Use this to specify the target resource group in which the restored disks will be saved')
c.argument('diskslist', diskslist_type)
sambitratha marked this conversation as resolved.
Show resolved Hide resolved
c.argument('restore_only_osdisk', arg_type=get_three_state_flag(), help='Use this flag to restore only OS disks of a backed up VM.')

with self.argument_context('backup restore restore-azurefileshare') as c:
c.argument('resolve_conflict', resolve_conflict_type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def load_command_table(self, _):
with self.command_group('backup protection', backup_custom_base, client_factory=protected_items_cf) as g:
g.command('check-vm', 'check_protection_enabled_for_vm')
g.command('enable-for-vm', 'enable_protection_for_vm')
g.command('update-for-vm', 'update_protection_for_vm')

with self.command_group('backup protection', custom_command_type=backup_custom_base, client_factory=protected_items_cf) as g:
g.custom_command('backup-now', 'backup_now', client_factory=backups_cf)
Expand Down
71 changes: 66 additions & 5 deletions src/azure-cli/azure/cli/command_modules/backup/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import os
from datetime import datetime, timedelta
from six.moves.urllib.parse import urlparse # pylint: disable=import-error

# pylint: disable=too-many-lines
from knack.log import get_logger

from msrest.paging import Paged
Expand All @@ -20,7 +20,7 @@
AzureIaaSClassicComputeVMProtectedItem, ProtectionState, IaasVMBackupRequest, BackupRequestResource, \
IaasVMRestoreRequest, RestoreRequestResource, BackupManagementType, WorkloadType, OperationStatusValues, \
JobStatus, ILRRequestResource, IaasVMILRRegistrationRequest, BackupResourceConfig, BackupResourceConfigResource, \
BackupResourceVaultConfig, BackupResourceVaultConfigResource
BackupResourceVaultConfig, BackupResourceVaultConfigResource, DiskExclusionProperties, ExtendedProperties

from azure.cli.core.util import CLIError, sdk_no_wait
from azure.cli.command_modules.backup._client_factory import (
Expand Down Expand Up @@ -195,7 +195,8 @@ def check_protection_enabled_for_vm(cmd, vm_id):
return None


def enable_protection_for_vm(cmd, client, resource_group_name, vault_name, vm, policy_name):
def enable_protection_for_vm(cmd, client, resource_group_name, vault_name, vm, policy_name, diskslist=None,
disk_list_setting=None):
vm_name, vm_rg = _get_resource_name_and_rg(resource_group_name, vm)
vm = virtual_machines_cf(cmd.cli_ctx).get(vm_rg, vm_name)
vault = vaults_cf(cmd.cli_ctx).get(resource_group_name, vault_name)
Expand Down Expand Up @@ -234,6 +235,49 @@ def enable_protection_for_vm(cmd, client, resource_group_name, vault_name, vm, p
vm_item_properties = _get_vm_item_properties_from_vm_type(vm.type)
vm_item_properties.policy_id = policy.id
vm_item_properties.source_resource_id = protectable_item.properties.virtual_machine_id

if disk_list_setting is not None:
if diskslist is None:
raise CLIError("Please provide LUNs of disks that will be included or excluded.")
is_inclusion_list = False
if disk_list_setting == "include":
is_inclusion_list = True
disk_exclusion_properties = DiskExclusionProperties(disk_lun_list=diskslist,
is_inclusion_list=is_inclusion_list)
extended_properties = ExtendedProperties(disk_exclusion_properties=disk_exclusion_properties)
vm_item_properties.extended_properties = extended_properties

vm_item = ProtectedItemResource(properties=vm_item_properties)

# Trigger enable protection and wait for completion
result = sdk_no_wait(True, client.create_or_update,
vault_name, resource_group_name, fabric_name, container_uri, item_uri, vm_item)
return _track_backup_job(cmd.cli_ctx, result, vault_name, resource_group_name)


def update_protection_for_vm(cmd, client, resource_group_name, vault_name, item, diskslist=None,
disk_list_setting=None):
container_uri = _get_protection_container_uri_from_id(item.id)
item_uri = item.name
vm_type = '/'.join(item.properties.virtual_machine_id.split('/')[-3:-1])
vm_item_properties = _get_vm_item_properties_from_vm_type(vm_type)
vm_item_properties.policy_id = item.properties.policy_id
vm_item_properties.source_resource_id = item.properties.virtual_machine_id

if disk_list_setting is not None:
if disk_list_setting.lower() == "resetexclusionsettings":
disk_exclusion_properties = None
else:
if diskslist is None:
raise CLIError("Please provide LUNs of disks that will be included or excluded.")
is_inclusion_list = False
if disk_list_setting.lower() == "include":
is_inclusion_list = True
disk_exclusion_properties = DiskExclusionProperties(disk_lun_list=diskslist,
is_inclusion_list=is_inclusion_list)
extended_properties = ExtendedProperties(disk_exclusion_properties=disk_exclusion_properties)
vm_item_properties.extended_properties = extended_properties

vm_item = ProtectedItemResource(properties=vm_item_properties)

# Trigger enable protection and wait for completion
Expand Down Expand Up @@ -379,8 +423,10 @@ def _should_use_original_storage_account(recovery_point, restore_to_staging_stor
return use_original_storage_account


# pylint: disable=too-many-locals
def restore_disks(cmd, client, resource_group_name, vault_name, container_name, item_name, rp_name, storage_account,
target_resource_group=None, restore_to_staging_storage_account=None):
target_resource_group=None, restore_to_staging_storage_account=None, restore_only_osdisk=None,
diskslist=None):
item = show_item(cmd, backup_protected_items_cf(cmd.cli_ctx), resource_group_name, vault_name, container_name,
item_name, "AzureIaasVM", "VM")
_validate_item(item)
Expand Down Expand Up @@ -410,14 +456,24 @@ def restore_disks(cmd, client, resource_group_name, vault_name, container_name,
target_rg_id = None
if recovery_point.properties.is_managed_virtual_machine and target_resource_group is not None:
target_rg_id = '/'.join(_source_resource_id.split('/')[:4]) + "/" + target_resource_group

_validate_restore_disk_parameters(restore_only_osdisk, diskslist)
restore_disk_lun_list = None
if restore_only_osdisk:
restore_disk_lun_list = []

if diskslist:
restore_disk_lun_list = diskslist

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,
source_resource_id=_source_resource_id,
target_resource_group_id=target_rg_id,
original_storage_account_option=use_original_storage_account)
original_storage_account_option=use_original_storage_account,
restore_disk_lun_list=restore_disk_lun_list)
trigger_restore_request = RestoreRequestResource(properties=trigger_restore_properties)

# Trigger restore
Expand Down Expand Up @@ -756,6 +812,11 @@ def _validate_object(obj, error_message):
raise ValueError(error_message)


def _validate_restore_disk_parameters(restore_only_osdisk, diskslist):
if restore_only_osdisk and diskslist is not None:
logger.warning("Value of diskslist parameter will be ignored as restore-only-osdisk is set to be true.")


# Tracking Utilities
# pylint: disable=inconsistent-return-statements
def _track_backup_ilr(cli_ctx, result, vault_name, resource_group):
Expand Down
25 changes: 21 additions & 4 deletions src/azure-cli/azure/cli/command_modules/backup/custom_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,23 @@ def check_protection_enabled_for_vm(cmd, vm_id):
return custom.check_protection_enabled_for_vm(cmd, vm_id)


def enable_protection_for_vm(cmd, client, resource_group_name, vault_name, vm, policy_name):
return custom.enable_protection_for_vm(cmd, client, resource_group_name, vault_name, vm, policy_name)
def enable_protection_for_vm(cmd, client, resource_group_name, vault_name, vm, policy_name, diskslist=None,
disk_list_setting=None):
return custom.enable_protection_for_vm(cmd, client, resource_group_name, vault_name, vm, policy_name,
diskslist, disk_list_setting)


def update_protection_for_vm(cmd, client, resource_group_name, vault_name, container_name, item_name, diskslist,
disk_list_setting):
items_client = backup_protected_items_cf(cmd.cli_ctx)
item = show_item(cmd, items_client, resource_group_name, vault_name, container_name, item_name,
"AzureIaasVM", "VM")
custom_help.validate_item(item)

if isinstance(item, list):
raise CLIError("Multiple items found. Please give native names instead.")
return custom.update_protection_for_vm(cmd, client, resource_group_name, vault_name, item, diskslist,
disk_list_setting)


def enable_protection_for_azure_wl(cmd, client, resource_group_name, vault_name, policy_name, protectable_item_type,
Expand Down Expand Up @@ -273,9 +288,11 @@ def disable_auto_for_azure_wl(client, resource_group_name, vault_name, item_name


def restore_disks(cmd, client, resource_group_name, vault_name, container_name, item_name, rp_name, storage_account,
target_resource_group=None, restore_to_staging_storage_account=None):
target_resource_group=None, restore_to_staging_storage_account=None, restore_only_osdisk=None,
diskslist=None):
return custom.restore_disks(cmd, client, resource_group_name, vault_name, container_name, item_name, rp_name,
storage_account, target_resource_group, restore_to_staging_storage_account)
storage_account, target_resource_group, restore_to_staging_storage_account,
restore_only_osdisk, diskslist)


def enable_for_azurefileshare(cmd, client, resource_group_name, vault_name, policy_name, storage_account,
Expand Down
Loading