Skip to content
Open
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 @@ -6,10 +6,11 @@
# Base Client Factories


def _resource_client_factory(cli_ctx, **_):
def _resource_client_factory(cli_ctx, subscription_id=None, **_):
from azure.cli.core.profiles import ResourceType
from azure.cli.core.commands.client_factory import get_mgmt_service_client
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES)
return get_mgmt_service_client(
cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES, subscription_id=subscription_id)


def _common_client_factory(cli_ctx, **_):
Expand All @@ -33,24 +34,24 @@ def _backup_passive_client_factory(cli_ctx, **_):
return get_mgmt_service_client(cli_ctx, RecoveryServicesBackupPassiveClient)


def _storage_client_factory(cli_ctx, **_):
def _storage_client_factory(cli_ctx, subscription_id=None, **_):
from azure.cli.core.profiles import ResourceType
from azure.cli.core.commands.client_factory import get_mgmt_service_client

return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_STORAGE)
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_STORAGE, subscription_id=subscription_id)


# External Deps Client Factories
def resources_cf(cli_ctx, *_):
return _resource_client_factory(cli_ctx).resources
def resources_cf(cli_ctx, *_, subscription_id=None):
return _resource_client_factory(cli_ctx, subscription_id=subscription_id).resources


def resource_groups_cf(cli_ctx, *_):
return _resource_client_factory(cli_ctx).resource_groups


def file_shares_cf(cli_ctx, *_):
return _storage_client_factory(cli_ctx).file_shares
def file_shares_cf(cli_ctx, *_, subscription_id=None):
return _storage_client_factory(cli_ctx, subscription_id=subscription_id).file_shares


# Internal Deps Client Factories
Expand Down
19 changes: 14 additions & 5 deletions src/azure-cli/azure/cli/command_modules/backup/_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,20 @@


def transform_container(result):
return OrderedDict([('Name', result['name']),
('Friendly Name', result['properties']['friendlyName']),
('Resource Group', result['resourceGroup']),
('Type', result['properties']['backupManagementType']),
('Registration Status', result['properties']['registrationStatus'])])
columns = [('Name', result['name']),
('Friendly Name', result['properties']['friendlyName']),
('Resource Group', result['resourceGroup']),
('Type', result['properties']['backupManagementType']),
('Registration Status', result['properties']['registrationStatus'])]
access_type = result['properties'].get('accessType')
if access_type:
columns.append(('Access Type', access_type))
identity_info = result['properties'].get('identityInfo')
if identity_info:
identity = ('SystemAssigned' if identity_info.get('isSystemAssignedIdentity')
else identity_info.get('managedIdentityResourceId'))
columns.append(('Managed Identity', identity))
return OrderedDict(columns)


def transform_item(result):
Expand Down
12 changes: 12 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 @@ -32,6 +32,10 @@
examples:
- name: This command allows Azure Backup to convert the 'Resource' to a 'Backup Container' which is then registered to the given Recovery services vault. The Azure Backup service can then discover workloads of the given workload type within this container to be protected later.
text: az backup container register --resource-group MyResourceGroup --vault-name MyVault --resource-id MyResourceId --workload-type MSSQL --backup-management-type AzureWorkload
- name: Register a storage account for Azure Files backup using the vault's system-assigned managed identity.
text: az backup container register --resource-group MyResourceGroup --vault-name MyVault --storage-account MyStorageAccount --workload-type AzureFileShare --backup-management-type AzureStorage --access-type IdentityBased --mi-system-assigned
- name: Re-register a storage account with a user-assigned managed identity without prompting.
text: az backup container register --resource-group MyResourceGroup --vault-name MyVault --storage-account MyStorageAccount --workload-type AzureFileShare --backup-management-type AzureStorage --access-type IdentityBased --mi-user-assigned MyIdentityResourceId --yes
"""

helps['backup container re-register'] = """
Expand Down Expand Up @@ -306,6 +310,8 @@
examples:
- name: Start protecting a previously unprotected Azure File share within an Azure Storage account as per the specified policy to a Recovery services vault. Provide the Azure File share name and the parent storage account name.
text: az backup protection enable-for-azurefileshare --policy-name MyPolicy --resource-group MyResourceGroup --vault-name MyVault --storage-account MyStorageAccount --azure-file-share MyAzureFileShare
- name: Protect an Azure file share using a user-assigned managed identity.
text: az backup protection enable-for-azurefileshare --policy-name MyPolicy --resource-group MyResourceGroup --vault-name MyVault --storage-account MyStorageAccount --azure-file-share MyAzureFileShare --access-type IdentityBased --mi-user-assigned MyIdentityResourceId
"""

helps['backup protection undelete'] = """
Expand Down Expand Up @@ -469,6 +475,10 @@
examples:
- name: Restore backed up Azure file shares to the same file-share or another file-share in registered storage accounts.
text: az backup restore restore-azurefileshare --resource-group MyResourceGroup --vault-name MyVault --container-name MyContainer --item-name MyItem --rp-name recoverypoint --resolve-conflict Overwrite --restore-mode OriginalLocation
- name: Restore an Azure file share to an alternate location using the vault's system-assigned managed identity.
text: az backup restore restore-azurefileshare --resource-group MyResourceGroup --vault-name MyVault --container-name MyContainer --item-name MyItem --rp-name recoverypoint --resolve-conflict Overwrite --restore-mode AlternateLocation --target-storage-account MyTargetStorageAccount --target-file-share MyTargetFileShare --mi-system-assigned
- name: Restore an Azure file share across both region and subscription.
text: az backup restore restore-azurefileshare --resource-group MyResourceGroup --vault-name MyVault --container-name MySecondaryRegionContainer --item-name MySecondaryRegionItem --rp-name MySecondaryRegionRecoveryPoint --resolve-conflict Overwrite --restore-mode AlternateLocation --target-subscription-id MyTargetSubscription --target-resource-group-name MyTargetResourceGroup --target-storage-account MyTargetStorageAccount --target-file-share MyTargetFileShare --use-secondary-region
"""

helps['backup restore restore-azurefiles'] = """
Expand All @@ -477,6 +487,8 @@
examples:
- name: Restore backed up Azure files within a file-share to the same file-share or another file-share in registered storage accounts.
text: az backup restore restore-azurefiles --resource-group MyResourceGroup --vault-name MyVault --container-name MyContainer --item-name MyItem --rp-name recoverypoint --resolve-conflict Overwrite --restore-mode OriginalLocation --source-file-type File --source-file-path Filepath1 Filepath2
- name: Restore selected Azure files using a user-assigned managed identity.
text: az backup restore restore-azurefiles --resource-group MyResourceGroup --vault-name MyVault --container-name MyContainer --item-name MyItem --rp-name recoverypoint --resolve-conflict Overwrite --restore-mode AlternateLocation --target-storage-account MyTargetStorageAccount --target-file-share MyTargetFileShare --source-file-type File --source-file-path Filepath1 --mi-user-assigned MyIdentityResourceId
"""

helps['backup restore restore-azurewl'] = """
Expand Down
40 changes: 39 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 @@ -23,6 +23,7 @@
allowed_container_types = ['AzureIaasVM']
allowed_workload_types = ['VM', 'AzureFileShare', 'SAPHANA', 'SAPASE', 'MSSQL', 'SAPHanaDatabase', 'SQLDataBase', 'SAPAseDatabase', 'SAPHanaDBInstance']
allowed_azure_workload_types = ['MSSQL', 'SAPHANA', 'SAPASE', 'SAPAseDatabase', 'SAPHanaDatabase', 'SQLDataBase', 'SAPHanaDBInstance']
allowed_container_registration_workload_types = allowed_azure_workload_types + ['AzureFileShare']
allowed_backup_management_types = ['AzureIaasVM', 'AzureStorage', 'AzureWorkload']
allowed_extended_backup_management_types = allowed_backup_management_types + ['MAB']
allowed_protectable_item_type = ['SQLAG', 'SQLInstance', 'SQLDatabase', 'HANAInstance', 'SAPAseDatabase', 'SAPHanaDatabase', 'SAPHanaSystem', 'SAPHanaDBInstance']
Expand All @@ -32,6 +33,7 @@
allowed_softdelete_options = ['Enable', 'Disable', 'AlwaysOn']
allowed_immutability_options = ['Disabled', 'Locked', 'Unlocked']
allowed_granularitylevel_options = ['VaultLevel', 'ProtectedItemLevel', 'ProtectedItemWithParentTag']
allowed_afs_access_types = ['KeyBased', 'IdentityBased']
enable_disable_options = ['Enable', 'Disable']
enable_disable_permadisable_options = ['Enable', 'Disable', 'PermanentlyDisable']
allowed_disk_access_options = ['EnablePrivateAccessForAllDisks', 'EnablePublicAccessForAllDisks', 'SameAsOnSourceDisks']
Expand Down Expand Up @@ -66,6 +68,7 @@
extended_backup_management_type = CLIArgumentType(help=backup_management_type_help, arg_type=get_enum_type(allowed_extended_backup_management_types), options_list=['--backup-management-type'])
workload_type = CLIArgumentType(help=workload_type_help, arg_type=get_enum_type(allowed_workload_types), options_list=['--workload-type'])
azure_workload_type = CLIArgumentType(help=workload_type_help, arg_type=get_enum_type(allowed_azure_workload_types), options_list=['--workload-type'])
container_registration_workload_type = CLIArgumentType(help=workload_type_help, arg_type=get_enum_type(allowed_container_registration_workload_types), options_list=['--workload-type'])
restore_mode_type = CLIArgumentType(help=restore_mode_help, arg_type=get_enum_type(['OriginalLocation', 'AlternateLocation']), options_list=['--restore-mode'])
restore_mode_workload_type = CLIArgumentType(help=restore_mode_help, arg_type=get_enum_type(['AlternateWorkloadRestore', 'OriginalWorkloadRestore', 'RestoreAsFiles']), options_list=['--restore-mode'])
resolve_conflict_type = CLIArgumentType(help=resolve_conflict_help, arg_type=get_enum_type(['Overwrite', 'Skip']), options_list=['--resolve-conflict'])
Expand Down Expand Up @@ -205,7 +208,18 @@ def load_arguments(self, _):
c.argument('vault_name', vault_name_type, id_part=None)
c.argument('backup_management_type', backup_management_type)
c.argument('resource_id', resource_id_type)
c.argument('workload_type', azure_workload_type)
c.argument('workload_type', container_registration_workload_type)
c.argument('storage_account', options_list=['--storage-account'],
help='Name of the storage account to register for Azure Files backup.')
c.argument('access_type', options_list=['--access-type'],
arg_type=get_enum_type(allowed_afs_access_types),
help='Authentication type used to access the storage account.')
c.argument('mi_system_assigned', action='store_true',
help="Use the Recovery Services vault's system-assigned managed identity.")
c.argument('mi_user_assigned',
help='ARM ID of a user-assigned managed identity associated with the Recovery Services vault.')
c.argument('yes', options_list=['--yes', '-y'], action='store_true',
help='Do not prompt for confirmation when re-registering the storage account.')

# Item
with self.argument_context('backup item') as c:
Expand Down Expand Up @@ -377,6 +391,15 @@ def load_arguments(self, _):
c.argument('vault_name', vault_name_type, id_part=None)
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.')
c.argument('access_type', options_list=['--access-type'],
arg_type=get_enum_type(allowed_afs_access_types),
help='Authentication type used to access the storage account.')
c.argument('mi_system_assigned', action='store_true',
help="Use the Recovery Services vault's system-assigned managed identity.")
c.argument('mi_user_assigned',
help='ARM ID of a user-assigned managed identity associated with the Recovery Services vault.')
c.argument('yes', options_list=['--yes', '-y'], action='store_true',
help='Do not prompt for confirmation when re-registering the storage account.')

for command in ["enable-for-azurewl", "auto-enable-for-azurewl", 'auto-disable-for-azurewl']:
with self.argument_context('backup protection ' + command) as c:
Expand Down Expand Up @@ -447,6 +470,12 @@ def load_arguments(self, _):
c.argument('target_resource_group_name',
options_list=['--target-resource-group-name', '--target-rg-name'],
help='Resource group of the destination storage account to which the content will be restored, needed if it is different from the vault resource group')
c.argument('target_subscription_id',
help='Subscription ID of the destination storage account for cross-subscription restore.')
c.argument('mi_system_assigned', action='store_true',
help="Use the Recovery Services vault's system-assigned managed identity for restore.")
c.argument('mi_user_assigned',
help='ARM ID of the user-assigned managed identity to use for restore.')
c.argument('tenant_id', help='ID of the tenant if the Resource Guard protecting the vault exists in a different tenant.')
c.argument('use_secondary_region', action='store_true', help='Use this flag to restore from a recovery point in secondary region. Supports only Alternate Location Restore.')

Expand All @@ -456,6 +485,15 @@ def load_arguments(self, _):
c.argument('target_file_share', options_list=['--target-file-share'], help='Destination file share to which content will be restored')
c.argument('target_folder', options_list=['--target-folder'], help='Destination folder to which content will be restored. To restore content to root , leave the folder name empty')
c.argument('target_storage_account', options_list=['--target-storage-account'], help='Destination storage account to which content will be restored')
c.argument('target_resource_group_name',
options_list=['--target-resource-group-name', '--target-rg-name'],
help='Resource group of the destination storage account to which the content will be restored, needed if it is different from the vault resource group')
c.argument('target_subscription_id',
help='Subscription ID of the destination storage account for cross-subscription restore.')
c.argument('mi_system_assigned', action='store_true',
help="Use the Recovery Services vault's system-assigned managed identity for restore.")
c.argument('mi_user_assigned',
help='ARM ID of the user-assigned managed identity to use for restore.')
c.argument('source_file_type', arg_type=get_enum_type(['File', 'Directory']), options_list=['--source-file-type'], help='Specify the source file type to be selected')
c.argument('source_file_path', options_list=['--source-file-path'], nargs='+', help="""The absolute path of the file, to be restored within the file share, as a string. This path is the same path used in the 'az storage file download' or 'az storage file show' CLI commands.""")
c.argument('tenant_id', help='ID of the tenant if the Resource Guard protecting the vault exists in a different tenant.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def load_command_table(self, _):
with self.command_group('backup container', custom_command_type=backup_custom_base, client_factory=protection_containers_cf, exception_handler=backup_exception_handler) as g:
g.custom_command('unregister', 'unregister_container', confirmation=True)
g.custom_command('re-register', 're_register_wl_container', confirmation=True)
g.custom_command('register', 'register_wl_container')
g.custom_command('register', 'register_container')

with self.command_group('backup policy', backup_custom_base, client_factory=protection_policies_cf, exception_handler=backup_exception_handler) as g:
g.command('get-default-for-vm', 'get_default_policy_for_vm')
Expand Down
Loading
Loading