Hello community, here is the log from the commit of package azure-cli-backup for openSUSE:Factory checked in at 2018-02-14 09:29:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/azure-cli-backup (Old) and /work/SRC/openSUSE:Factory/.azure-cli-backup.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "azure-cli-backup" Wed Feb 14 09:29:48 2018 rev:2 rq:574796 version:1.0.6 Changes: -------- --- /work/SRC/openSUSE:Factory/azure-cli-backup/azure-cli-backup.changes 2017-11-10 14:52:07.835507178 +0100 +++ /work/SRC/openSUSE:Factory/.azure-cli-backup.new/azure-cli-backup.changes 2018-02-14 09:29:52.123291967 +0100 @@ -1,0 +2,10 @@ +Wed Feb 7 14:41:29 UTC 2018 - [email protected] + +- New upstream release + + Version 1.0.6 + + For detailed information about changes see the + HISTORY.rst file provided with this package +- Install HISTORY.rst into doc directory +- Update Requires from setup.py + +------------------------------------------------------------------- Old: ---- azure-cli-backup-1.0.1.tar.gz New: ---- azure-cli-backup-1.0.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ azure-cli-backup.spec ++++++ --- /var/tmp/diff_new_pack.ZSYnGj/_old 2018-02-14 09:29:53.263250658 +0100 +++ /var/tmp/diff_new_pack.ZSYnGj/_new 2018-02-14 09:29:53.263250658 +0100 @@ -1,7 +1,7 @@ # # spec file for package azure-cli-backup # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -15,8 +15,9 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # + Name: azure-cli-backup -Version: 1.0.1 +Version: 1.0.6 Release: 0 Summary: Microsoft Azure CLI 'backup' Command Module License: MIT @@ -24,17 +25,17 @@ Url: https://github.com/Azure/azure-cli Source: https://files.pythonhosted.org/packages/source/a/azure-cli-backup/azure-cli-backup-%{version}.tar.gz Source1: LICENSE.txt -BuildRequires: python3-devel -BuildRequires: python3-setuptools -BuildRequires: unzip BuildRequires: azure-cli-command-modules-nspkg BuildRequires: azure-cli-nspkg BuildRequires: python3-azure-nspkg +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: unzip Requires: azure-cli-command-modules-nspkg Requires: azure-cli-nspkg -Requires: python3-azure-nspkg Requires: python3-azure-mgmt-recoveryservices >= 0.1.0 Requires: python3-azure-mgmt-recoveryservicesbackup >= 0.1.1 +Requires: python3-azure-nspkg Conflicts: azure-cli < 2.0.0 BuildArch: noarch @@ -63,7 +64,8 @@ %files %defattr(-,root,root,-) -%doc LICENSE.txt README.rst +%doc HISTORY.rst LICENSE.txt README.rst %{python3_sitelib}/azure/cli/command_modules/backup %{python3_sitelib}/azure_cli_backup-*.egg-info + %changelog ++++++ azure-cli-backup-1.0.1.tar.gz -> azure-cli-backup-1.0.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/HISTORY.rst new/azure-cli-backup-1.0.6/HISTORY.rst --- old/azure-cli-backup-1.0.1/HISTORY.rst 2017-09-23 01:47:00.000000000 +0200 +++ new/azure-cli-backup-1.0.6/HISTORY.rst 2018-01-12 18:25:22.000000000 +0100 @@ -2,6 +2,30 @@ Release History =============== + +1.0.6 ++++++ +* New feature: 'az backup item list' command now has '--container-name' parameter as optional instead of mandatory and output contains item health details. +* New feature: Added original storage account option in 'az backup restore restore-disks' command. +* Bugs fixed: VM and vault location check must be case insensitive in 'az backup protection enable-for-vm' command. + +1.0.5 ++++++ +* When a non-existent name is supplied for a container, commands will not fail with a stack trace. Partially fixes #4502. +* az backup item list update: 'Health Status' of an item is now visible in the default table view. + +1.0.4 ++++++ +* Minor fixes. + +1.0.3 ++++++ +* Minor fixes. + +1.0.2 ++++++ +* no changes + 1.0.1 (2017-09-22) ++++++++++++++++++ * Preview release. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/PKG-INFO new/azure-cli-backup-1.0.6/PKG-INFO --- old/azure-cli-backup-1.0.1/PKG-INFO 2017-09-23 01:47:41.000000000 +0200 +++ new/azure-cli-backup-1.0.6/PKG-INFO 2018-01-12 18:26:09.000000000 +0100 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: azure-cli-backup -Version: 1.0.1 +Version: 1.0.6 Summary: Microsoft Azure Command-Line Tools Recovery Services Command Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation Author-email: [email protected] License: MIT -Description-Content-Type: UNKNOWN Description: Microsoft Azure CLI 'backup' Command Module =========================================== @@ -20,6 +19,30 @@ Release History =============== + + 1.0.6 + +++++ + * New feature: 'az backup item list' command now has '--container-name' parameter as optional instead of mandatory and output contains item health details. + * New feature: Added original storage account option in 'az backup restore restore-disks' command. + * Bugs fixed: VM and vault location check must be case insensitive in 'az backup protection enable-for-vm' command. + + 1.0.5 + +++++ + * When a non-existent name is supplied for a container, commands will not fail with a stack trace. Partially fixes #4502. + * az backup item list update: 'Health Status' of an item is now visible in the default table view. + + 1.0.4 + +++++ + * Minor fixes. + + 1.0.3 + +++++ + * Minor fixes. + + 1.0.2 + +++++ + * no changes + 1.0.1 (2017-09-22) ++++++++++++++++++ * Preview release. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/__init__.py new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/__init__.py --- old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/__init__.py 2017-09-23 01:47:00.000000000 +0200 +++ new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/__init__.py 2018-01-12 18:25:22.000000000 +0100 @@ -3,12 +3,28 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -import azure.cli.command_modules.backup._help # pylint: disable=unused-import +from azure.cli.core import AzCommandsLoader +from azure.cli.command_modules.backup._help import helps # pylint: disable=unused-import -def load_params(_): - import azure.cli.command_modules.backup._params # pylint: disable=redefined-outer-name, unused-variable +class BackupCommandsLoader(AzCommandsLoader): -def load_commands(): - import azure.cli.command_modules.backup.commands # pylint: disable=redefined-outer-name, unused-variable + def __init__(self, cli_ctx=None): + from azure.cli.core.commands import CliCommandType + backup_custom = CliCommandType(operations_tmpl='azure.cli.command_modules.backup.custom#{}') + super(BackupCommandsLoader, self).__init__(cli_ctx=cli_ctx, + min_profile='2017-03-10-profile', + custom_command_type=backup_custom) + + def load_command_table(self, args): + from azure.cli.command_modules.backup.commands import load_command_table + load_command_table(self, args) + return self.command_table + + def load_arguments(self, command): + from azure.cli.command_modules.backup._params import load_arguments + load_arguments(self, command) + + +COMMAND_LOADER_CLS = BackupCommandsLoader diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/_client_factory.py new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/_client_factory.py --- old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/_client_factory.py 2017-09-23 01:47:00.000000000 +0200 +++ new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/_client_factory.py 2018-01-12 18:25:22.000000000 +0100 @@ -6,119 +6,113 @@ # Base Client Factories -def _resource_client_factory(**_): +def _resource_client_factory(cli_ctx, **_): from azure.cli.core.profiles import ResourceType from azure.cli.core.commands.client_factory import get_mgmt_service_client - return get_mgmt_service_client(ResourceType.MGMT_RESOURCE_RESOURCES) + return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES) -def _compute_client_factory(): +def _compute_client_factory(cli_ctx, **_): from azure.cli.core.profiles import ResourceType from azure.cli.core.commands.client_factory import get_mgmt_service_client - return get_mgmt_service_client(ResourceType.MGMT_COMPUTE) + return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_COMPUTE) -def _common_client_factory(): +def _common_client_factory(cli_ctx, **_): from azure.mgmt.recoveryservices import RecoveryServicesClient from azure.cli.core.commands.client_factory import get_mgmt_service_client - return get_mgmt_service_client(RecoveryServicesClient) + return get_mgmt_service_client(cli_ctx, RecoveryServicesClient) -def _backup_client_factory(): +def _backup_client_factory(cli_ctx, **_): from azure.mgmt.recoveryservicesbackup import RecoveryServicesBackupClient from azure.cli.core.commands.client_factory import get_mgmt_service_client - return get_mgmt_service_client(RecoveryServicesBackupClient) + return get_mgmt_service_client(cli_ctx, RecoveryServicesBackupClient) -# External Deps Client Factories +# External Deps Client Factories +def virtual_machines_cf(cli_ctx, *_): + return _compute_client_factory(cli_ctx).virtual_machines -def virtual_machines_cf(): - return _compute_client_factory().virtual_machines +def resources_cf(cli_ctx, *_): + return _resource_client_factory(cli_ctx).resources -def resources_cf(): - return _resource_client_factory().resources # Internal Deps Client Factories +def vaults_cf(cli_ctx, *_): + return _common_client_factory(cli_ctx).vaults -def vaults_cf(_): - return _common_client_factory().vaults +def backup_storage_configs_cf(cli_ctx, *_): + return _common_client_factory(cli_ctx).backup_storage_configs -def backup_storage_configs_cf(_): - return _common_client_factory().backup_storage_configs - # Protection Client Factories +def protection_policies_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).protection_policies -def protection_policies_cf(_): - return _backup_client_factory().protection_policies - +def protection_containers_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).protection_containers -def protection_containers_cf(): - return _backup_client_factory().protection_containers +def protection_container_refresh_operation_results_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).protection_container_refresh_operation_results -def protection_container_refresh_operation_results_cf(): - return _backup_client_factory().protection_container_refresh_operation_results +def protected_items_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).protected_items -def protected_items_cf(_): - return _backup_client_factory().protected_items # Backup Client Factories +def backup_policies_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).backup_policies -def backup_policies_cf(_): - return _backup_client_factory().backup_policies +def backup_protection_containers_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).backup_protection_containers -def backup_protection_containers_cf(_): - return _backup_client_factory().backup_protection_containers +def backup_protectable_items_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).backup_protectable_items -def backup_protectable_items_cf(): - return _backup_client_factory().backup_protectable_items +def backup_protected_items_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).backup_protected_items -def backup_protected_items_cf(_): - return _backup_client_factory().backup_protected_items +def backup_operation_statuses_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).backup_operation_statuses -def backup_operation_statuses_cf(): - return _backup_client_factory().backup_operation_statuses +def backups_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).backups -def backups_cf(_): - return _backup_client_factory().backups +def backup_jobs_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).backup_jobs -def backup_jobs_cf(_): - return _backup_client_factory().backup_jobs - # Job Client Factories +def job_details_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).job_details -def job_details_cf(_): - return _backup_client_factory().job_details - +def job_cancellations_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).job_cancellations -def job_cancellations_cf(_): - return _backup_client_factory().job_cancellations # Recovery Client Factories +def recovery_points_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).recovery_points -def recovery_points_cf(_): - return _backup_client_factory().recovery_points - - -def restores_cf(_): - return _backup_client_factory().restores +def restores_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).restores -def item_level_recovery_connections_cf(_): - return _backup_client_factory().item_level_recovery_connections +def item_level_recovery_connections_cf(cli_ctx, *_): + return _backup_client_factory(cli_ctx).item_level_recovery_connections diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/_format.py new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/_format.py --- old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/_format.py 1970-01-01 01:00:00.000000000 +0100 +++ new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/_format.py 2018-01-12 18:25:22.000000000 +0100 @@ -0,0 +1,73 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from collections import OrderedDict + + +def transform_container(result): + return OrderedDict([('Name', result['properties']['friendlyName']), + ('Resource Group', result['resourceGroup']), + ('Type', result['properties']['backupManagementType']), + ('Registration Status', result['properties']['registrationStatus'])]) + + +def transform_item(result): + columns = [] + columns.append(('Name', result['properties']['friendlyName'])) + columns.append(('Resource Group', result['resourceGroup'])) + columns.append(('Type', result['properties']['workloadType'])) + columns.append(('Last Backup Status', result['properties']['lastBackupStatus'])) + columns.append(('Last Recovery Point', result['properties']['lastRecoveryPoint'])) + columns.append(('Protection Status', result['properties']['protectionStatus'])) + columns.append(('Health Status', result['properties']['healthStatus'])) + + if result['properties']['healthDetails'] is not None: + recommendations = [] + for health_detail in result['properties']['healthDetails']: + recommendations.append(', '.join(health_detail['recommendations'])) + columns.append(('Recommendations', ', '.join(recommendations))) + + return OrderedDict(columns) + + +def transform_job(result): + return OrderedDict([('Name', result['name']), + ('Operation', result['properties']['operation']), + ('Status', result['properties']['status']), + ('Item Name', result['properties']['entityFriendlyName']), + ('Start Time UTC', result['properties']['startTime']), + ('Duration', result['properties']['duration'])]) + + +def transform_policy(result): + return OrderedDict([('Name', result['name']), + ('Resource Group', result['resourceGroup']), + ('Type', result['properties']['backupManagementType'])]) + + +def transform_recovery_point(result): + return OrderedDict([('Name', result['name']), + ('Time', result['properties']['recoveryPointTime']), + ('Consistency', result['properties']['recoveryPointType'])]) + + +def transform_container_list(container_list): + return [transform_container(c) for c in container_list] + + +def transform_item_list(item_list): + return [transform_item(i) for i in item_list] + + +def transform_job_list(job_list): + return [transform_job(j) for j in job_list] + + +def transform_policy_list(policy_list): + return [transform_policy(p) for p in policy_list] + + +def transform_recovery_point_list(recovery_point_list): + return [transform_recovery_point(rp) for rp in recovery_point_list] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/_help.py new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/_help.py --- old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/_help.py 2017-09-23 01:47:00.000000000 +0200 +++ new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/_help.py 2018-01-12 18:25:22.000000000 +0100 @@ -3,7 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from azure.cli.core.help_files import helps +from knack.help_files import helps helps['backup'] = """ type: group diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/_params.py new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/_params.py --- old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/_params.py 2017-09-23 01:47:00.000000000 +0200 +++ new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/_params.py 2018-01-12 18:25:22.000000000 +0100 @@ -6,99 +6,128 @@ # pylint: disable=line-too-long from argcomplete.completers import FilesCompleter -from azure.cli.core.commands import \ - (register_cli_argument, CliArgumentType) + +from knack.arguments import CLIArgumentType + from azure.cli.core.commands.parameters import \ - (get_resource_name_completion_list, file_type, location_type, three_state_flag, - enum_choice_list, ignore_type) + (get_resource_name_completion_list, file_type, get_location_type, get_three_state_flag, + get_enum_type) from azure.cli.command_modules.backup._validators import \ (datetime_type) + # ARGUMENT DEFINITIONS allowed_container_types = ['AzureIaasVM'] allowed_workload_types = ['VM'] -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='Name of the container.', options_list=('--container-name', '-c')) -item_name_type = CliArgumentType(help='Name of the backed up item.', options_list=('--item-name', '-i')) -policy_name_type = CliArgumentType(help='Name of the backup policy.', options_list=('--policy-name', '-p')) -job_name_type = CliArgumentType(help='Name of the job.', options_list=('--name', '-n')) -rp_name_type = CliArgumentType(help='Name of the recovery point.', options_list=('--rp-name', '-r')) - -register_cli_argument('backup', 'container_type', ignore_type) -register_cli_argument('backup', 'item_type', ignore_type) - -# Vault -register_cli_argument('backup vault', 'vault_name', vault_name_type, options_list=('--name', '-n')) -register_cli_argument('backup vault', 'region', location_type) - -register_cli_argument('backup vault backup-properties set', 'backup_storage_redundancy', help='Sets backup storage properties for a Recovery Services vault.', **enum_choice_list(['GeoRedundant', 'LocallyRedundant'])) - -# Container -register_cli_argument('backup container', 'vault_name', vault_name_type) -register_cli_argument('backup container', 'status', ignore_type) - -register_cli_argument('backup container show', 'name', container_name_type, options_list=('--name', '-n'), help='Name of the container. You can use the backup container list command to get the name of a container.') - -# Item -register_cli_argument('backup item', 'vault_name', vault_name_type) -register_cli_argument('backup item', 'container_name', container_name_type) - -register_cli_argument('backup item show', 'name', item_name_type, options_list=('--name', '-n'), help='Name of the backed up item. You can use the backup item list command to get the name of a backed up item.') - -register_cli_argument('backup item set-policy', 'item_name', item_name_type, options_list=('--name', '-n'), help='Name of the backed up item. You can use the backup item list command to get the name of a backed up item.') -register_cli_argument('backup item set-policy', 'policy_name', policy_name_type, help='Name of the Backup policy. You can use the backup policy list command to get the name of a backup policy.') - -# Policy -register_cli_argument('backup policy', 'vault_name', vault_name_type) - -for command in ['show', 'delete', 'list-associated-items']: - register_cli_argument('backup policy {}'.format(command), 'name', policy_name_type, options_list=('--name', '-n'), help='Name of the backup policy. You can use the backup policy list command to get the name of a policy.') - -register_cli_argument('backup policy set', 'policy', type=file_type, help='JSON encoded policy definition. Use the show command with JSON output to obtain a policy object. Modify the values using a file editor and pass the object.', completer=FilesCompleter()) - -# Recovery Point -register_cli_argument('backup recoverypoint', 'vault_name', vault_name_type) -register_cli_argument('backup recoverypoint', 'container_name', container_name_type) -register_cli_argument('backup recoverypoint', 'item_name', item_name_type) - -register_cli_argument('backup recoverypoint list', 'start_date', type=datetime_type, help='The start date of the range in UTC (d-m-Y).') -register_cli_argument('backup recoverypoint list', 'end_date', type=datetime_type, help='The end date of the range in UTC (d-m-Y).') - -register_cli_argument('backup recoverypoint show', 'name', rp_name_type, options_list=('--name', '-n'), help='Name of the recovery point. You can use the backup recovery point list command to get the name of a backed up item.') - -# Protection -register_cli_argument('backup protection', 'vault_name', vault_name_type) -register_cli_argument('backup protection enable-for-vm', 'vm', help='Name or ID of the Virtual Machine to be protected.') -register_cli_argument('backup protection enable-for-vm', 'policy_name', policy_name_type) - -for command in ['backup-now', 'disable']: - register_cli_argument('backup protection {}'.format(command), 'container_name', container_name_type) - register_cli_argument('backup protection {}'.format(command), 'item_name', item_name_type) - -register_cli_argument('backup protection backup-now', 'retain_until', type=datetime_type, help='The date until which this backed up copy will be available for retrieval, in UTC (d-m-Y).') - -register_cli_argument('backup protection disable', 'delete_backup_data', help='Option to delete existing backed up data in the Recovery services vault.', **three_state_flag()) - -# Restore -for command in ['restore-disks', 'files']: - register_cli_argument('backup restore {}'.format(command), 'vault_name', vault_name_type) - register_cli_argument('backup restore {}'.format(command), 'container_name', container_name_type) - register_cli_argument('backup restore {}'.format(command), 'item_name', item_name_type) - register_cli_argument('backup restore {}'.format(command), 'rp_name', rp_name_type) - -register_cli_argument('backup restore restore-disks', 'storage_account', help='Name or ID of the storge account to which disks are restored.') - -# Job -register_cli_argument('backup job', 'vault_name', vault_name_type) - -for command in ['show', 'stop', 'wait']: - register_cli_argument('backup job {}'.format(command), 'name', job_name_type, help='Name of the job. You can use the backup job list command to get the name of a job.') - -register_cli_argument('backup job list', 'status', help='Status of the Job.', **enum_choice_list(['Cancelled', 'Completed', 'CompletedWithWarnings', 'Failed', 'InProgress'])) -register_cli_argument('backup job list', 'operation', help='User initiated operation.', **enum_choice_list(['Backup', 'ConfigureBackup', 'DeleteBackupData', 'DisableBackup', 'Restore'])) -register_cli_argument('backup job list', 'start_date', type=datetime_type, help='The start date of the range in UTC (d-m-Y).') -register_cli_argument('backup job list', 'end_date', type=datetime_type, help='The end date of the range in UTC (d-m-Y).') +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='Name of the container.', options_list=['--container-name', '-c']) +item_name_type = CLIArgumentType(help='Name of the backed up item.', options_list=['--item-name', '-i']) +policy_name_type = CLIArgumentType(help='Name of the backup policy.', options_list=['--policy-name', '-p']) +job_name_type = CLIArgumentType(help='Name of the job.', options_list=['--name', '-n']) +rp_name_type = CLIArgumentType(help='Name of the recovery point.', options_list=['--rp-name', '-r']) + + +# pylint: disable=too-many-statements +def load_arguments(self, _): + + with self.argument_context('backup') as c: + c.ignore('container_type', 'item_type') + c.argument('force', action='store_true', help='Force completion of the requested action.') + + # Vault + with self.argument_context('backup vault') as c: + c.argument('vault_name', vault_name_type, options_list=['--name', '-n']) + c.argument('region', get_location_type(self.cli_ctx)) + + with self.argument_context('backup vault backup-properties set') as c: + c.argument('backup_storage_redundancy', arg_type=get_enum_type(['GeoRedundant', 'LocallyRedundant']), help='Sets backup storage properties for a Recovery Services vault.') + + # Container + with self.argument_context('backup container') as c: + c.argument('vault_name', vault_name_type) + c.ignore('status') + + with self.argument_context('backup container show') as c: + c.argument('name', container_name_type, options_list=['--name', '-n'], help='Name of the container. You can use the backup container list command to get the name of a container.') + + # Item + with self.argument_context('backup item') as c: + c.argument('vault_name', vault_name_type) + c.argument('container_name', container_name_type) + + with self.argument_context('backup item show') as c: + c.argument('name', item_name_type, options_list=['--name', '-n'], help='Name of the backed up item. You can use the backup item list command to get the name of a backed up item.') + + with self.argument_context('backup item set-policy') as c: + c.argument('item_name', item_name_type, options_list=['--name', '-n'], help='Name of the backed up item. You can use the backup item list command to get the name of a backed up item.') + c.argument('policy_name', policy_name_type, help='Name of the Backup policy. You can use the backup policy list command to get the name of a backup policy.') + + # Policy + with self.argument_context('backup policy') as c: + c.argument('vault_name', vault_name_type) + + for command in ['show', 'delete', 'list-associated-items']: + with self.argument_context('backup policy ' + command) as c: + c.argument('name', policy_name_type, options_list=['--name', '-n'], help='Name of the backup policy. You can use the backup policy list command to get the name of a policy.') + + with self.argument_context('backup policy set') as c: + c.argument('policy', type=file_type, help='JSON encoded policy definition. Use the show command with JSON output to obtain a policy object. Modify the values using a file editor and pass the object.', completer=FilesCompleter()) + + # Recovery Point + with self.argument_context('backup recoverypoint') as c: + c.argument('vault_name', vault_name_type) + c.argument('container_name', container_name_type) + c.argument('item_name', item_name_type) + + with self.argument_context('backup recoverypoint list') as c: + c.argument('start_date', type=datetime_type, help='The start date of the range in UTC (d-m-Y).') + c.argument('end_date', type=datetime_type, help='The end date of the range in UTC (d-m-Y).') + + with self.argument_context('backup recoverypoint show') as c: + c.argument('name', rp_name_type, options_list=['--name', '-n'], help='Name of the recovery point. You can use the backup recovery point list command to get the name of a backed up item.') + + # Protection + with self.argument_context('backup protection') as c: + c.argument('vault_name', vault_name_type) + c.argument('vm', help='Name or ID of the Virtual Machine to be protected.') + c.argument('policy_name', policy_name_type) + + for command in ['backup-now', 'disable']: + with self.argument_context('backup protection ' + command) as c: + c.argument('container_name', container_name_type) + c.argument('item_name', item_name_type) + + with self.argument_context('backup protection backup-now') as c: + c.argument('retain_until', type=datetime_type, help='The date until which this backed up copy will be available for retrieval, in UTC (d-m-Y).') + + with self.argument_context('backup protection disable') as c: + c.argument('delete_backup_data', arg_type=get_three_state_flag(), help='Option to delete existing backed up data in the Recovery services vault.') + # Restore + with self.argument_context('backup restore') as c: + c.argument('vault_name', vault_name_type) + c.argument('container_name', container_name_type) + c.argument('item_name', item_name_type) + c.argument('rp_name', rp_name_type) + + with self.argument_context('backup restore restore-disks') as c: + 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.') + + # Job + with self.argument_context('backup job') as c: + c.argument('vault_name', vault_name_type) + + for command in ['show', 'stop', 'wait']: + with self.argument_context('backup job ' + command) as c: + c.argument('name', job_name_type, help='Name of the job. You can use the backup job list command to get the name of a job.') + + with self.argument_context('backup job list') as c: + c.argument('status', arg_type=get_enum_type(['Cancelled', 'Completed', 'CompletedWithWarnings', 'Failed', 'InProgress']), help='Status of the Job.') + c.argument('operation', arg_type=get_enum_type(['Backup', 'ConfigureBackup', 'DeleteBackupData', 'DisableBackup', 'Restore']), help='User initiated operation.') + c.argument('start_date', type=datetime_type, help='The start date of the range in UTC (d-m-Y).') + c.argument('end_date', type=datetime_type, help='The end date of the range in UTC (d-m-Y).') -register_cli_argument('backup job wait', 'timeout', type=int, help='Maximum time, in seconds, to wait before aborting.') + with self.argument_context('backup job wait') as c: + c.argument('timeout', type=int, help='Maximum time, in seconds, to wait before aborting.') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/commands.py new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/commands.py --- old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/commands.py 2017-09-23 01:47:00.000000000 +0200 +++ new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/commands.py 2018-01-12 18:25:22.000000000 +0100 @@ -3,107 +3,72 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -# pylint: disable=line-too-long - -from collections import OrderedDict - -from azure.cli.core.commands import cli_command +from azure.cli.core.commands import CliCommandType from azure.cli.command_modules.backup._client_factory import vaults_cf, backup_protection_containers_cf, \ protection_policies_cf, backup_policies_cf, protected_items_cf, backups_cf, backup_jobs_cf, \ job_details_cf, job_cancellations_cf, recovery_points_cf, restores_cf, backup_storage_configs_cf, \ item_level_recovery_connections_cf, backup_protected_items_cf # pylint: disable=unused-variable +from azure.cli.command_modules.backup._format import ( + transform_container_list, transform_policy_list, transform_item_list, transform_job_list, + transform_recovery_point_list) -def transform_container(result): - return OrderedDict([('Name', result['properties']['friendlyName']), - ('Resource Group', result['resourceGroup']), - ('Type', result['properties']['backupManagementType']), - ('Registration Status', result['properties']['registrationStatus'])]) - - -def transform_item(result): - return OrderedDict([('Name', result['properties']['friendlyName']), - ('Resource Group', result['resourceGroup']), - ('Type', result['properties']['workloadType']), - ('Last Backup Status', result['properties']['lastBackupStatus']), - ('Last Recovery Point', result['properties']['lastRecoveryPoint']), - ('Protection Status', result['properties']['protectionStatus'])]) - - -def transform_job(result): - return OrderedDict([('Name', result['name']), - ('Operation', result['properties']['operation']), - ('Status', result['properties']['status']), - ('Item Name', result['properties']['entityFriendlyName']), - ('Start Time UTC', result['properties']['startTime']), - ('Duration', result['properties']['duration'])]) - - -def transform_policy(result): - return OrderedDict([('Name', result['name']), - ('Resource Group', result['resourceGroup']), - ('Type', result['properties']['backupManagementType'])]) - - -def transform_recovery_point(result): - return OrderedDict([('Name', result['name']), - ('Time', result['properties']['recoveryPointTime']), - ('Consistency', result['properties']['recoveryPointType'])]) - - -def transform_container_list(container_list): - return [transform_container(c) for c in container_list] - - -def transform_item_list(item_list): - return [transform_item(i) for i in item_list] - - -def transform_job_list(job_list): - return [transform_job(j) for j in job_list] - - -def transform_policy_list(policy_list): - return [transform_policy(p) for p in policy_list] - - -def transform_recovery_point_list(recovery_point_list): - return [transform_recovery_point(rp) for rp in recovery_point_list] - - -cli_command(__name__, 'backup vault create', 'azure.cli.command_modules.backup.custom#create_vault', vaults_cf) -cli_command(__name__, 'backup vault show', 'azure.mgmt.recoveryservices.operations.vaults_operations#VaultsOperations.get', vaults_cf) -cli_command(__name__, 'backup vault list', 'azure.cli.command_modules.backup.custom#list_vaults', vaults_cf) -cli_command(__name__, 'backup vault backup-properties show', 'azure.mgmt.recoveryservices.operations.backup_storage_configs_operations#BackupStorageConfigsOperations.get', vaults_cf) -cli_command(__name__, 'backup vault backup-properties set', 'azure.cli.command_modules.backup.custom#set_backup_properties', backup_storage_configs_cf) -cli_command(__name__, 'backup vault delete', 'azure.mgmt.recoveryservices.operations.vaults_operations#VaultsOperations.delete', vaults_cf, confirmation=True) - -cli_command(__name__, 'backup container show', 'azure.cli.command_modules.backup.custom#show_container', backup_protection_containers_cf) -cli_command(__name__, 'backup container list', 'azure.cli.command_modules.backup.custom#list_containers', backup_protection_containers_cf, table_transformer=transform_container_list) - -cli_command(__name__, 'backup policy get-default-for-vm', 'azure.cli.command_modules.backup.custom#get_default_policy_for_vm', protection_policies_cf) -cli_command(__name__, 'backup policy show', 'azure.cli.command_modules.backup.custom#show_policy', protection_policies_cf) -cli_command(__name__, 'backup policy list', 'azure.cli.command_modules.backup.custom#list_policies', backup_policies_cf, table_transformer=transform_policy_list) -cli_command(__name__, 'backup policy list-associated-items', 'azure.cli.command_modules.backup.custom#list_associated_items_for_policy', backup_protected_items_cf, table_transformer=transform_item_list) -cli_command(__name__, 'backup policy set', 'azure.cli.command_modules.backup.custom#set_policy', protection_policies_cf) -cli_command(__name__, 'backup policy delete', 'azure.cli.command_modules.backup.custom#delete_policy', protection_policies_cf) - -cli_command(__name__, 'backup protection enable-for-vm', 'azure.cli.command_modules.backup.custom#enable_protection_for_vm', protected_items_cf) -cli_command(__name__, 'backup protection backup-now', 'azure.cli.command_modules.backup.custom#backup_now', backups_cf) -cli_command(__name__, 'backup protection disable', 'azure.cli.command_modules.backup.custom#disable_protection', protected_items_cf, confirmation=True) - -cli_command(__name__, 'backup item show', 'azure.cli.command_modules.backup.custom#show_item', backup_protected_items_cf) -cli_command(__name__, 'backup item list', 'azure.cli.command_modules.backup.custom#list_items', backup_protected_items_cf, table_transformer=transform_item_list) -cli_command(__name__, 'backup item set-policy', 'azure.cli.command_modules.backup.custom#update_policy_for_item', protected_items_cf) - -cli_command(__name__, 'backup job list', 'azure.cli.command_modules.backup.custom#list_jobs', backup_jobs_cf, table_transformer=transform_job_list) -cli_command(__name__, 'backup job show', 'azure.cli.command_modules.backup.custom#show_job', job_details_cf) -cli_command(__name__, 'backup job stop', 'azure.cli.command_modules.backup.custom#stop_job', job_cancellations_cf) -cli_command(__name__, 'backup job wait', 'azure.cli.command_modules.backup.custom#wait_for_job', job_details_cf) +# pylint: disable=line-too-long +def load_command_table(self, _): -cli_command(__name__, 'backup recoverypoint show', 'azure.cli.command_modules.backup.custom#show_recovery_point', recovery_points_cf) -cli_command(__name__, 'backup recoverypoint list', 'azure.cli.command_modules.backup.custom#list_recovery_points', recovery_points_cf, table_transformer=transform_recovery_point_list) + backup_custom = CliCommandType(operations_tmpl='azure.cli.command_modules.backup.custom#{}') -cli_command(__name__, 'backup restore restore-disks', 'azure.cli.command_modules.backup.custom#restore_disks', restores_cf) -cli_command(__name__, 'backup restore files mount-rp', 'azure.cli.command_modules.backup.custom#restore_files_mount_rp', item_level_recovery_connections_cf) -cli_command(__name__, 'backup restore files unmount-rp', 'azure.cli.command_modules.backup.custom#restore_files_unmount_rp', item_level_recovery_connections_cf) + backup_vaults_sdk = CliCommandType( + operations_tmpl='azure.mgmt.recoveryservices.operations.vaults_operations#VaultsOperations.{}', + client_factory=vaults_cf) + + backup_storage_config_sdk = CliCommandType( + operations_tmpl='azure.mgmt.recoveryservices.operations.backup_storage_configs_operations#BackupStorageConfigsOperations.{}', + client_factory=vaults_cf) + + with self.command_group('backup vault', backup_vaults_sdk, client_factory=vaults_cf) as g: + g.custom_command('create', 'create_vault') + g.command('show', 'get') + g.custom_command('list', 'list_vaults') + g.command('backup-properties show', 'get', command_type=backup_storage_config_sdk) + g.custom_command('backup-properties set', 'set_backup_properties', client_factory=backup_storage_configs_cf) + g.custom_command('delete', 'delete_vault', confirmation=True) + + with self.command_group('backup container', backup_custom, client_factory=backup_protection_containers_cf) as g: + g.command('show', 'show_container') + g.command('list', 'list_containers', table_transformer=transform_container_list) + + with self.command_group('backup policy', backup_custom, client_factory=protection_policies_cf) as g: + g.command('get-default-for-vm', 'get_default_policy_for_vm') + g.command('show', 'show_policy') + g.command('list', 'list_policies', client_factory=backup_policies_cf, table_transformer=transform_policy_list) + g.command('list-associated-items', 'list_associated_items_for_policy', client_factory=backup_protected_items_cf, table_transformer=transform_item_list) + g.command('set', 'set_policy') + g.command('delete', 'delete_policy') + + with self.command_group('backup protection', backup_custom, client_factory=protected_items_cf) as g: + g.command('enable-for-vm', 'enable_protection_for_vm') + g.command('backup-now', 'backup_now', client_factory=backups_cf) + g.command('disable', 'disable_protection', confirmation=True) + + with self.command_group('backup item', backup_custom, client_factory=backup_protected_items_cf) as g: + g.command('show', 'show_item') + g.command('list', 'list_items', table_transformer=transform_item_list) + g.command('set-policy', 'update_policy_for_item', client_factory=protected_items_cf) + + with self.command_group('backup job', backup_custom, client_factory=job_details_cf) as g: + g.command('list', 'list_jobs', client_factory=backup_jobs_cf, table_transformer=transform_job_list) + g.command('show', 'show_job') + g.command('stop', 'stop_job', client_factory=job_cancellations_cf) + g.command('wait', 'wait_for_job') + + with self.command_group('backup recoverypoint', backup_custom, client_factory=recovery_points_cf) as g: + g.command('show', 'show_recovery_point') + g.command('list', 'list_recovery_points', table_transformer=transform_recovery_point_list) + + with self.command_group('backup restore', backup_custom, client_factory=restores_cf) as g: + g.command('restore-disks', 'restore_disks') + + with self.command_group('backup restore files', backup_custom, client_factory=item_level_recovery_connections_cf) as g: + g.command('mount-rp', 'restore_files_mount_rp') + g.command('unmount-rp', 'restore_files_unmount_rp') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/custom.py new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/custom.py --- old/azure-cli-backup-1.0.1/azure/cli/command_modules/backup/custom.py 2017-09-23 01:47:00.000000000 +0200 +++ new/azure-cli-backup-1.0.6/azure/cli/command_modules/backup/custom.py 2018-01-12 18:25:22.000000000 +0100 @@ -9,7 +9,11 @@ import os from datetime import datetime, timedelta from six.moves.urllib.parse import urlparse # pylint: disable=import-error + +from knack.log import get_logger + from msrest.paging import Paged +from msrestazure.tools import parse_resource_id, is_valid_resource_id from azure.mgmt.recoveryservices.models import Vault, VaultProperties, Sku, SkuName, BackupStorageConfig from azure.mgmt.recoveryservicesbackup.models import ProtectedItemResource, AzureIaaSComputeVMProtectedItem, \ @@ -17,16 +21,14 @@ IaasVMRestoreRequest, RestoreRequestResource, BackupManagementType, WorkloadType, OperationStatusValues, \ JobStatus, ILRRequestResource, IaasVMILRRegistrationRequest -import azure.cli.core.azlogging as azlogging from azure.cli.core.util import CLIError -from azure.cli.core.commands.arm import parse_resource_id, is_valid_resource_id +from azure.cli.command_modules.backup._client_factory import ( + vaults_cf, backup_protected_items_cf, protection_policies_cf, virtual_machines_cf, recovery_points_cf, + protection_containers_cf, backup_protectable_items_cf, resources_cf, backup_operation_statuses_cf, + job_details_cf, protection_container_refresh_operation_results_cf, backup_protection_containers_cf, + protected_items_cf) -from azure.cli.command_modules.backup._client_factory import vaults_cf, backup_protected_items_cf, \ - protection_policies_cf, virtual_machines_cf, recovery_points_cf, protection_containers_cf, \ - backup_protectable_items_cf, resources_cf, backup_operation_statuses_cf, job_details_cf, \ - protection_container_refresh_operation_results_cf, backup_protection_containers_cf - -logger = azlogging.get_az_logger(__name__) +logger = get_logger(__name__) fabric_name = "Azure" default_policy_name = "DefaultPolicy" @@ -40,18 +42,51 @@ vault_sku = Sku(SkuName.standard) vault_properties = VaultProperties() vault = Vault(region, sku=vault_sku, properties=vault_properties) - return client.create_or_update(resource_group_name, vault_name, vault, custom_headers=_get_custom_headers()) + return client.create_or_update(resource_group_name, vault_name, vault) + + +def _force_delete_vault(cmd, vault_name, resource_group_name): + logger.warning('Attemping to force delete vault: %s', vault_name) + container_client = backup_protection_containers_cf(cmd.cli_ctx) + backup_item_client = backup_protected_items_cf(cmd.cli_ctx) + item_client = protected_items_cf(cmd.cli_ctx) + vault_client = vaults_cf(cmd.cli_ctx) + containers = _get_containers( + container_client, 'AzureIaasVM', 'Registered', + resource_group_name, vault_name) + for container in containers: + container_name = container.name.rsplit(';', 1)[1] + items = list_items( + cmd, backup_item_client, resource_group_name, vault_name, container_name) + for item in items: + item_name = item.name.rsplit(';', 1)[1] + logger.warning("Deleting backup item '%s' in container '%s'", + item_name, container_name) + disable_protection(cmd, item_client, resource_group_name, vault_name, + container.name, item_name, delete_backup_data=True) + # now delete the vault + vault_client.delete(resource_group_name, vault_name) + + +def delete_vault(cmd, client, vault_name, resource_group_name, force=False): + try: + client.delete(resource_group_name, vault_name) + except Exception as ex: # pylint: disable=broad-except + if 'existing resources within the vault' in ex.message and force: # pylint: disable=no-member + _force_delete_vault(cmd, vault_name, resource_group_name) + else: + raise ex def list_vaults(client, resource_group_name=None): if resource_group_name: - return client.list_by_resource_group(resource_group_name, custom_headers=_get_custom_headers()) - return client.list_by_subscription_id(custom_headers=_get_custom_headers()) + return client.list_by_resource_group(resource_group_name) + return client.list_by_subscription_id() def set_backup_properties(client, vault_name, resource_group_name, backup_storage_redundancy): backup_storage_config = BackupStorageConfig(storage_model_type=backup_storage_redundancy) - client.update(resource_group_name, vault_name, backup_storage_config, custom_headers=_get_custom_headers()) + client.update(resource_group_name, vault_name, backup_storage_config) def get_default_policy_for_vm(client, resource_group_name, vault_name): @@ -59,47 +94,46 @@ def show_policy(client, resource_group_name, vault_name, name): - return client.get(vault_name, resource_group_name, name, custom_headers=_get_custom_headers()) + return client.get(vault_name, resource_group_name, name) def list_policies(client, resource_group_name, vault_name): - policies = client.list(vault_name, resource_group_name, custom_headers=_get_custom_headers()) + policies = client.list(vault_name, resource_group_name) return _get_list_from_paged_response(policies) def list_associated_items_for_policy(client, resource_group_name, vault_name, name): filter_string = _get_filter_string({ 'policyName': name}) - items = client.list(vault_name, resource_group_name, filter_string, custom_headers=_get_custom_headers()) + items = client.list(vault_name, resource_group_name, filter_string) return _get_list_from_paged_response(items) def set_policy(client, resource_group_name, vault_name, policy): policy_object = _get_policy_from_json(client, policy) - return client.create_or_update(vault_name, resource_group_name, policy_object.name, policy_object, - custom_headers=_get_custom_headers()) + return client.create_or_update(vault_name, resource_group_name, policy_object.name, policy_object) def delete_policy(client, resource_group_name, vault_name, name): - client.delete(vault_name, resource_group_name, name, custom_headers=_get_custom_headers()) + client.delete(vault_name, resource_group_name, name) def show_container(client, name, resource_group_name, vault_name, container_type="AzureIaasVM", status="Registered"): - return _get_one_or_many(_get_containers(client, container_type, status, resource_group_name, vault_name, name)) + return _get_none_one_or_many(_get_containers(client, container_type, status, resource_group_name, vault_name, name)) def list_containers(client, resource_group_name, vault_name, container_type="AzureIaasVM", status="Registered"): return _get_containers(client, container_type, status, resource_group_name, vault_name) -def enable_protection_for_vm(client, resource_group_name, vault_name, vm, policy_name): +def enable_protection_for_vm(cmd, client, resource_group_name, vault_name, vm, policy_name): vm_name, vm_rg = _get_resource_name_and_rg(resource_group_name, vm) - vm = virtual_machines_cf().get(vm_rg, vm_name) - vault = vaults_cf(None).get(resource_group_name, vault_name) - policy = show_policy(protection_policies_cf(None), resource_group_name, vault_name, policy_name) + vm = virtual_machines_cf(cmd.cli_ctx).get(vm_rg, vm_name) + vault = vaults_cf(cmd.cli_ctx).get(resource_group_name, vault_name) + policy = show_policy(protection_policies_cf(cmd.cli_ctx), resource_group_name, vault_name, policy_name) - if vm.location != vault.location: + if vm.location.lower() != vault.location.lower(): raise CLIError( """ The VM should be in the same location as that of the Recovery Services vault to enable protection. @@ -113,7 +147,7 @@ """) # Get protectable item. - protectable_item = _get_protectable_item_for_vm(vault_name, resource_group_name, vm_name, vm_rg) + protectable_item = _get_protectable_item_for_vm(cmd.cli_ctx, vault_name, resource_group_name, vm_name, vm_rg) if protectable_item is None: raise CLIError( """ @@ -136,38 +170,44 @@ # Trigger enable protection and wait for completion result = client.create_or_update(vault_name, resource_group_name, fabric_name, container_uri, item_uri, vm_item, - raw=True, custom_headers=_get_custom_headers()) - return _track_backup_job(result, vault_name, resource_group_name) + raw=True) + return _track_backup_job(cmd.cli_ctx, result, vault_name, resource_group_name) -def show_item(client, resource_group_name, vault_name, container_name, name, container_type="AzureIaasVM", +def show_item(cmd, client, resource_group_name, vault_name, container_name, name, container_type="AzureIaasVM", item_type="VM"): - items = list_items(client, resource_group_name, vault_name, container_name, container_type, item_type) + items = list_items(cmd, client, resource_group_name, vault_name, container_name, container_type, item_type) - return _get_one_or_many([item for item in items if item.properties.friendly_name == name]) + return _get_none_one_or_many([item for item in items if item.properties.friendly_name == name]) -def list_items(client, resource_group_name, vault_name, container_name, container_type="AzureIaasVM", item_type="VM"): +def list_items(cmd, client, resource_group_name, vault_name, container_name=None, container_type="AzureIaasVM", + item_type="VM"): filter_string = _get_filter_string({ 'backupManagementType': container_type, 'itemType': item_type}) - items = client.list(vault_name, resource_group_name, filter_string, custom_headers=_get_custom_headers()) + items = client.list(vault_name, resource_group_name, filter_string) paged_items = _get_list_from_paged_response(items) - container = show_container(backup_protection_containers_cf(None), container_name, resource_group_name, vault_name, - container_type) - return [item for item in paged_items if item.properties.container_name.lower() in container.name.lower()] + if container_name is not None: + container = show_container(backup_protection_containers_cf(cmd.cli_ctx), container_name, resource_group_name, + vault_name, container_type) + _validate_container(container) + return [item for item in paged_items if item.properties.container_name.lower() in container.name.lower()] + return paged_items -def update_policy_for_item(client, resource_group_name, vault_name, container_name, item_name, policy_name, + +def update_policy_for_item(cmd, client, resource_group_name, vault_name, container_name, item_name, policy_name, container_type="AzureIaasVM", item_type="VM"): # Client factories - backup_protected_items_client = backup_protected_items_cf(None) + backup_protected_items_client = backup_protected_items_cf(cmd.cli_ctx) # Get objects from JSON files - item = show_item(backup_protected_items_client, resource_group_name, vault_name, container_name, item_name, + item = show_item(cmd, backup_protected_items_client, resource_group_name, vault_name, container_name, item_name, container_type, item_type) - policy = show_policy(protection_policies_cf(None), resource_group_name, vault_name, policy_name) + policy = show_policy(protection_policies_cf(cmd.cli_ctx), resource_group_name, vault_name, policy_name) + _validate_policy(policy) if item.properties.backup_management_type != policy.properties.backup_management_type: raise CLIError( @@ -188,14 +228,15 @@ # Update policy result = client.create_or_update(vault_name, resource_group_name, fabric_name, container_uri, item_uri, vm_item, - raw=True, custom_headers=_get_custom_headers()) - return _track_backup_job(result, vault_name, resource_group_name) + raw=True) + return _track_backup_job(cmd.cli_ctx, result, vault_name, resource_group_name) -def backup_now(client, resource_group_name, vault_name, container_name, item_name, retain_until, +def backup_now(cmd, client, resource_group_name, vault_name, container_name, item_name, retain_until, container_type="AzureIaasVM", item_type="VM"): - item = show_item(backup_protected_items_cf(None), resource_group_name, vault_name, container_name, item_name, - container_type, item_type) + item = show_item(cmd, backup_protected_items_cf(cmd.cli_ctx), resource_group_name, vault_name, container_name, + item_name, container_type, item_type) + _validate_item(item) # Get container and item URIs container_uri = _get_protection_container_uri_from_id(item.id) @@ -204,27 +245,28 @@ # Trigger backup result = client.trigger(vault_name, resource_group_name, fabric_name, container_uri, item_uri, - trigger_backup_request, raw=True, custom_headers=_get_custom_headers()) - return _track_backup_job(result, vault_name, resource_group_name) + trigger_backup_request, raw=True) + return _track_backup_job(cmd.cli_ctx, result, vault_name, resource_group_name) -def show_recovery_point(client, resource_group_name, vault_name, container_name, item_name, name, # pylint: disable=redefined-builtin +def show_recovery_point(cmd, client, resource_group_name, vault_name, container_name, item_name, name, # pylint: disable=redefined-builtin container_type="AzureIaasVM", item_type="VM"): - item = show_item(backup_protected_items_cf(None), resource_group_name, vault_name, container_name, item_name, - container_type, item_type) + item = show_item(cmd, backup_protected_items_cf(cmd.cli_ctx), resource_group_name, vault_name, container_name, + item_name, container_type, item_type) + _validate_item(item) # Get container and item URIs container_uri = _get_protection_container_uri_from_id(item.id) item_uri = _get_protected_item_uri_from_id(item.id) - return client.get(vault_name, resource_group_name, fabric_name, container_uri, item_uri, name, - custom_headers=_get_custom_headers()) + return client.get(vault_name, resource_group_name, fabric_name, container_uri, item_uri, name) -def list_recovery_points(client, resource_group_name, vault_name, container_name, item_name, +def list_recovery_points(cmd, client, resource_group_name, vault_name, container_name, item_name, container_type="AzureIaasVM", item_type="VM", start_date=None, end_date=None): - item = show_item(backup_protected_items_cf(None), resource_group_name, vault_name, container_name, item_name, - container_type, item_type) + item = show_item(cmd, backup_protected_items_cf(cmd.cli_ctx), resource_group_name, vault_name, container_name, + item_name, container_type, item_type) + _validate_item(item) # Get container and item URIs container_uri = _get_protection_container_uri_from_id(item.id) @@ -237,44 +279,89 @@ 'endDate': query_end_date}) # Get recovery points - recovery_points = client.list(vault_name, resource_group_name, fabric_name, container_uri, item_uri, filter_string, - custom_headers=_get_custom_headers()) + recovery_points = client.list(vault_name, resource_group_name, fabric_name, container_uri, item_uri, filter_string) paged_recovery_points = _get_list_from_paged_response(recovery_points) return paged_recovery_points -def restore_disks(client, resource_group_name, vault_name, container_name, item_name, rp_name, storage_account): - item = show_item(backup_protected_items_cf(None), resource_group_name, vault_name, container_name, item_name, - "AzureIaasVM", "VM") - vault = vaults_cf(None).get(resource_group_name, vault_name, custom_headers=_get_custom_headers()) +def _should_use_original_storage_account(recovery_point, restore_to_staging_storage_account): + if restore_to_staging_storage_account is None: + # No intent given by user. Treat it as False. Try OSA = True + # pylint: disable=simplifiable-if-statement + if recovery_point.properties.original_storage_account_option: + # RP is enabled for OSA. + use_original_storage_account = True + else: + # RP is not enabled for OSA. Go ahead with OSA = False + use_original_storage_account = False + else: + # User gave explicit intent + if restore_to_staging_storage_account is True: + # User explicitly intended to not use OSA. Go ahead with OSA = False + use_original_storage_account = False + else: + # User explicitly intended to use OSA. Try with OSA = True + if recovery_point.properties.original_storage_account_option: + # RP supports OSA. Go ahead with OSA = True + use_original_storage_account = True + else: + # RP doesn't support OSA. + raise CLIError( + """ + This recovery point doesn't have the capability to restore disks to their original storage + accounts. The disks and the VM config file will be uploaded to the given storage account. + """) + return use_original_storage_account + + +def restore_disks(cmd, client, resource_group_name, vault_name, container_name, item_name, rp_name, storage_account, + restore_to_staging_storage_account=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) + recovery_point = show_recovery_point(cmd, recovery_points_cf(cmd.cli_ctx), resource_group_name, vault_name, + container_name, item_name, rp_name, "AzureIaasVM", "VM") + vault = vaults_cf(cmd.cli_ctx).get(resource_group_name, vault_name) vault_location = vault.location # Get container and item URIs container_uri = _get_protection_container_uri_from_id(item.id) item_uri = _get_protected_item_uri_from_id(item.id) + # Original Storage Account Restore Logic + use_original_storage_account = _should_use_original_storage_account(recovery_point, + restore_to_staging_storage_account) + if use_original_storage_account: + logger.warning( + """ + The disks will be restored to their original storage accounts. The VM config file will be uploaded to given + storage account. + """) + # Construct trigger restore request object sa_name, sa_rg = _get_resource_name_and_rg(resource_group_name, storage_account) - _storage_account_id = _get_storage_account_id(sa_name, sa_rg) + _storage_account_id = _get_storage_account_id(cmd.cli_ctx, sa_name, sa_rg) _source_resource_id = item.properties.source_resource_id 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) + source_resource_id=_source_resource_id, + original_storage_account_option=use_original_storage_account) trigger_restore_request = RestoreRequestResource(properties=trigger_restore_properties) # Trigger restore result = client.trigger(vault_name, resource_group_name, fabric_name, container_uri, item_uri, rp_name, - trigger_restore_request, raw=True, custom_headers=_get_custom_headers()) - return _track_backup_job(result, vault_name, resource_group_name) + trigger_restore_request, raw=True) + return _track_backup_job(cmd.cli_ctx, result, vault_name, resource_group_name) -def restore_files_mount_rp(client, resource_group_name, vault_name, container_name, item_name, rp_name): - item = show_item(backup_protected_items_cf(None), resource_group_name, vault_name, container_name, item_name, - "AzureIaasVM", "VM") +def restore_files_mount_rp(cmd, client, resource_group_name, vault_name, container_name, item_name, rp_name): + 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) # Get container and item URIs container_uri = _get_protection_container_uri_from_id(item.id) @@ -286,16 +373,16 @@ virtual_machine_id=_virtual_machine_id) file_restore_request = ILRRequestResource(properties=file_restore_request_properties) - recovery_point = recovery_points_cf(None).get(vault_name, resource_group_name, fabric_name, container_uri, - item_uri, rp_name, custom_headers=_get_custom_headers()) + recovery_point = recovery_points_cf(cmd.cli_ctx).get(vault_name, resource_group_name, fabric_name, + container_uri, item_uri, rp_name) if recovery_point.properties.is_instant_ilr_session_active: recovery_point.properties.renew_existing_registration = True result = client.provision(vault_name, resource_group_name, fabric_name, container_uri, item_uri, rp_name, - file_restore_request, raw=True, custom_headers=_get_custom_headers()) + file_restore_request, raw=True) - client_scripts = _track_backup_ilr(result, vault_name, resource_group_name) + client_scripts = _track_backup_ilr(cmd.cli_ctx, result, vault_name, resource_group_name) if client_scripts[0].os_type == os_windows: _run_client_script_for_windows(client_scripts) @@ -303,27 +390,29 @@ _run_client_script_for_linux(client_scripts) -def restore_files_unmount_rp(client, resource_group_name, vault_name, container_name, item_name, rp_name): - item = show_item(backup_protected_items_cf(None), resource_group_name, vault_name, container_name, item_name, - "AzureIaasVM", "VM") +def restore_files_unmount_rp(cmd, client, resource_group_name, vault_name, container_name, item_name, rp_name): + 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) # Get container and item URIs container_uri = _get_protection_container_uri_from_id(item.id) item_uri = _get_protected_item_uri_from_id(item.id) - recovery_point = recovery_points_cf(None).get(vault_name, resource_group_name, fabric_name, container_uri, - item_uri, rp_name, custom_headers=_get_custom_headers()) + recovery_point = recovery_points_cf(cmd.cli_ctx).get(vault_name, resource_group_name, fabric_name, + container_uri, item_uri, rp_name) if recovery_point.properties.is_instant_ilr_session_active: result = client.revoke(vault_name, resource_group_name, fabric_name, container_uri, item_uri, rp_name, - raw=True, custom_headers=_get_custom_headers()) - _track_backup_operation(resource_group_name, result, vault_name) + raw=True) + _track_backup_operation(cmd.cli_ctx, resource_group_name, result, vault_name) -def disable_protection(client, resource_group_name, vault_name, container_name, item_name, # pylint: disable=unused-argument +def disable_protection(cmd, client, resource_group_name, vault_name, container_name, item_name, # pylint: disable=unused-argument container_type="AzureIaasVM", item_type="VM", delete_backup_data=False, **kwargs): - item = show_item(backup_protected_items_cf(None), resource_group_name, vault_name, container_name, item_name, - container_type, item_type) + item = show_item(cmd, backup_protected_items_cf(cmd.cli_ctx), resource_group_name, vault_name, container_name, + item_name, container_type, item_type) + _validate_item(item) # Get container and item URIs container_uri = _get_protection_container_uri_from_id(item.id) @@ -331,15 +420,14 @@ # Trigger disable protection and wait for completion if delete_backup_data: - result = client.delete(vault_name, resource_group_name, fabric_name, container_uri, item_uri, raw=True, - custom_headers=_get_custom_headers()) - return _track_backup_job(result, vault_name, resource_group_name) + result = client.delete(vault_name, resource_group_name, fabric_name, container_uri, item_uri, raw=True) + return _track_backup_job(cmd.cli_ctx, result, vault_name, resource_group_name) vm_item = _get_disable_protection_request(item) result = client.create_or_update(vault_name, resource_group_name, fabric_name, container_uri, item_uri, vm_item, - raw=True, custom_headers=_get_custom_headers()) - return _track_backup_job(result, vault_name, resource_group_name) + raw=True) + return _track_backup_job(cmd.cli_ctx, result, vault_name, resource_group_name) def list_jobs(client, resource_group_name, vault_name, status=None, operation=None, start_date=None, end_date=None): @@ -351,29 +439,28 @@ 'startTime': query_start_date, 'endTime': query_end_date}) - return _get_list_from_paged_response(client.list(vault_name, resource_group_name, filter_string, - custom_headers=_get_custom_headers())) + return _get_list_from_paged_response(client.list(vault_name, resource_group_name, filter_string)) def show_job(client, resource_group_name, vault_name, name): - return client.get(vault_name, resource_group_name, name, custom_headers=_get_custom_headers()) + return client.get(vault_name, resource_group_name, name) def stop_job(client, resource_group_name, vault_name, name): - client.trigger(vault_name, resource_group_name, name, custom_headers=_get_custom_headers()) + client.trigger(vault_name, resource_group_name, name) def wait_for_job(client, resource_group_name, vault_name, name, timeout=None): - logger.warning("Waiting for job '{}' ...".format(name)) + logger.warning("Waiting for job '%s' ...", name) start_timestamp = datetime.utcnow() - job_details = client.get(vault_name, resource_group_name, name, custom_headers=_get_custom_headers()) + job_details = client.get(vault_name, resource_group_name, name) while _job_in_progress(job_details.properties.status): if timeout: elapsed_time = datetime.utcnow() - start_timestamp if elapsed_time.seconds > timeout: - logger.warning("Command timed out while waiting for job '{}'".format(name)) + logger.warning("Command timed out while waiting for job '%s'", name) break - job_details = client.get(vault_name, resource_group_name, name, custom_headers=_get_custom_headers()) + job_details = client.get(vault_name, resource_group_name, name) time.sleep(30) return job_details @@ -389,31 +476,29 @@ filter_dict['friendlyName'] = container_name filter_string = _get_filter_string(filter_dict) - containers = client.list(vault_name, resource_group_name, filter_string, custom_headers=_get_custom_headers()) + containers = client.list(vault_name, resource_group_name, filter_string) return _get_list_from_paged_response(containers) -def _get_protectable_item_for_vm(vault_name, vault_rg, vm_name, vm_rg): - protection_containers_client = protection_containers_cf() +def _get_protectable_item_for_vm(cli_ctx, vault_name, vault_rg, vm_name, vm_rg): + protection_containers_client = protection_containers_cf(cli_ctx) - protectable_item = _try_get_protectable_item_for_vm(vault_name, vault_rg, vm_name, vm_rg) + protectable_item = _try_get_protectable_item_for_vm(cli_ctx, vault_name, vault_rg, vm_name, vm_rg) if protectable_item is None: # Protectable item not found. Trigger discovery. - refresh_result = protection_containers_client.refresh(vault_name, vault_rg, fabric_name, raw=True, - custom_headers=_get_custom_headers()) - _track_refresh_operation(refresh_result, vault_name, vault_rg) - protectable_item = _try_get_protectable_item_for_vm(vault_name, vault_rg, vm_name, vm_rg) + refresh_result = protection_containers_client.refresh(vault_name, vault_rg, fabric_name, raw=True) + _track_refresh_operation(cli_ctx, refresh_result, vault_name, vault_rg) + protectable_item = _try_get_protectable_item_for_vm(cli_ctx, vault_name, vault_rg, vm_name, vm_rg) return protectable_item -def _try_get_protectable_item_for_vm(vault_name, vault_rg, vm_name, vm_rg): - backup_protectable_items_client = backup_protectable_items_cf() +def _try_get_protectable_item_for_vm(cli_ctx, vault_name, vault_rg, vm_name, vm_rg): + backup_protectable_items_client = backup_protectable_items_cf(cli_ctx) filter_string = _get_filter_string({ 'backupManagementType': 'AzureIaasVM'}) - protectable_items_paged = backup_protectable_items_client.list(vault_name, vault_rg, filter_string, - custom_headers=_get_custom_headers()) + protectable_items_paged = backup_protectable_items_client.list(vault_name, vault_rg, filter_string) protectable_items = _get_list_from_paged_response(protectable_items_paged) for protectable_item in protectable_items: @@ -431,8 +516,8 @@ return trigger_backup_request -def _get_storage_account_id(storage_account_name, storage_account_rg): - resources_client = resources_cf() +def _get_storage_account_id(cli_ctx, storage_account_name, storage_account_rg): + resources_client = resources_cf(cli_ctx) classic_storage_resource_namespace = 'Microsoft.ClassicStorage' storage_resource_namespace = 'Microsoft.Storage' parent_resource_path = 'storageAccounts' @@ -451,6 +536,7 @@ return storage_account.id +# pylint: disable=inconsistent-return-statements def _get_disable_protection_request(item): if item.properties.workload_type == WorkloadType.vm.value: vm_item_properties = _get_vm_item_properties_from_vm_id(item.properties.virtual_machine_id) @@ -461,6 +547,7 @@ return vm_item +# pylint: disable=inconsistent-return-statements def _get_vm_item_properties_from_vm_type(vm_type): if vm_type == 'Microsoft.Compute/virtualMachines': return AzureIaaSComputeVMProtectedItem() @@ -468,6 +555,7 @@ return AzureIaaSClassicComputeVMProtectedItem() +# pylint: disable=inconsistent-return-statements def _get_vm_item_properties_from_vm_id(vm_id): if 'Microsoft.Compute/virtualMachines' in vm_id: return AzureIaaSComputeVMProtectedItem() @@ -475,15 +563,14 @@ return AzureIaaSClassicComputeVMProtectedItem() -def _get_associated_vm_item(container_uri, item_uri, resource_group, vault_name): +def _get_associated_vm_item(cli_ctx, container_uri, item_uri, resource_group, vault_name): container_name = container_uri.split(';')[-1] item_name = item_uri.split(';')[-1] filter_string = _get_filter_string({ 'backupManagementType': BackupManagementType.azure_iaas_vm.value, 'itemType': WorkloadType.vm.value}) - items = backup_protected_items_cf(None).list(vault_name, resource_group, filter_string, - custom_headers=_get_custom_headers()) + items = backup_protected_items_cf(cli_ctx).list(vault_name, resource_group, filter_string) paged_items = _get_list_from_paged_response(items) filtered_items = [item for item in paged_items @@ -529,7 +616,7 @@ with urlopen(windows_script.url) as response, open(file_name, 'wb') as out_file: shutil.copyfileobj(response, out_file) - logger.warning('File downloaded: {}. Use password {}'.format(file_name, password)) + logger.warning('File downloaded: %s. Use password %s', file_name, password) def _run_client_script_for_linux(client_scripts): @@ -549,13 +636,7 @@ with open(file_name, 'w') as out_file: out_file.write(script_content) - logger.warning('File downloaded: {}. Use password {}'.format(file_name, password)) - - -def _get_custom_headers(): - import uuid - - return {'x-ms-client-request-id': str(uuid.uuid1()) + '-Cli'} + logger.warning('File downloaded: %s. Use password %s', file_name, password) def _get_resource_name_and_rg(resource_group_name, name_or_id): @@ -568,53 +649,67 @@ resource_group = resource_group_name return name, resource_group -# Tracking Utilities + +def _validate_container(container): + _validate_object(container, "Container not found. Please provide a valid container_name.") -def _track_backup_ilr(result, vault_name, resource_group): - operation_status = _track_backup_operation(resource_group, result, vault_name) +def _validate_item(item): + _validate_object(item, "Item not found. Please provide a valid item_name.") + + +def _validate_policy(policy): + _validate_object(policy, "Policy not found. Please provide a valid policy_name.") + + +def _validate_object(obj, error_message): + if obj is None: + raise ValueError(error_message) + + +# Tracking Utilities +# pylint: disable=inconsistent-return-statements +def _track_backup_ilr(cli_ctx, result, vault_name, resource_group): + 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 -def _track_backup_job(result, vault_name, resource_group): - job_details_client = job_details_cf(None) +# pylint: disable=inconsistent-return-statements +def _track_backup_job(cli_ctx, result, vault_name, resource_group): + job_details_client = job_details_cf(cli_ctx) - operation_status = _track_backup_operation(resource_group, result, vault_name) + operation_status = _track_backup_operation(cli_ctx, resource_group, result, vault_name) if operation_status.properties: job_id = operation_status.properties.job_id - job_details = job_details_client.get(vault_name, resource_group, job_id, custom_headers=_get_custom_headers()) + job_details = job_details_client.get(vault_name, resource_group, job_id) return job_details -def _track_backup_operation(resource_group, result, vault_name): - backup_operation_statuses_client = backup_operation_statuses_cf() +def _track_backup_operation(cli_ctx, resource_group, result, vault_name): + backup_operation_statuses_client = backup_operation_statuses_cf(cli_ctx) operation_id = _get_operation_id_from_header(result.response.headers['Azure-AsyncOperation']) - operation_status = backup_operation_statuses_client.get(vault_name, resource_group, operation_id, - custom_headers=_get_custom_headers()) + operation_status = backup_operation_statuses_client.get(vault_name, resource_group, operation_id) while operation_status.status == OperationStatusValues.in_progress.value: time.sleep(1) - operation_status = backup_operation_statuses_client.get(vault_name, resource_group, operation_id, - custom_headers=_get_custom_headers()) + operation_status = backup_operation_statuses_client.get(vault_name, resource_group, operation_id) return operation_status -def _track_refresh_operation(result, vault_name, resource_group): - protection_container_refresh_operation_results_client = protection_container_refresh_operation_results_cf() +def _track_refresh_operation(cli_ctx, result, vault_name, resource_group): + protection_container_refresh_operation_results_client = protection_container_refresh_operation_results_cf(cli_ctx) operation_id = _get_operation_id_from_header(result.response.headers['Location']) result = protection_container_refresh_operation_results_client.get(vault_name, resource_group, fabric_name, - operation_id, raw=True, - custom_headers=_get_custom_headers()) + operation_id, raw=True) while result.response.status_code == 202: time.sleep(1) result = protection_container_refresh_operation_results_client.get(vault_name, resource_group, fabric_name, - operation_id, raw=True, - custom_headers=_get_custom_headers()) + operation_id, raw=True) def _job_in_progress(job_status): @@ -627,8 +722,12 @@ return list(obj_list) if isinstance(obj_list, Paged) else obj_list -def _get_one_or_many(obj_list): - return obj_list[0] if len(obj_list) == 1 else obj_list +def _get_none_one_or_many(obj_list): + if not obj_list: + return None + elif len(obj_list) == 1: + return obj_list[0] + return obj_list def _get_filter_string(filter_dict): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure_cli_backup.egg-info/PKG-INFO new/azure-cli-backup-1.0.6/azure_cli_backup.egg-info/PKG-INFO --- old/azure-cli-backup-1.0.1/azure_cli_backup.egg-info/PKG-INFO 2017-09-23 01:47:41.000000000 +0200 +++ new/azure-cli-backup-1.0.6/azure_cli_backup.egg-info/PKG-INFO 2018-01-12 18:26:09.000000000 +0100 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: azure-cli-backup -Version: 1.0.1 +Version: 1.0.6 Summary: Microsoft Azure Command-Line Tools Recovery Services Command Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation Author-email: [email protected] License: MIT -Description-Content-Type: UNKNOWN Description: Microsoft Azure CLI 'backup' Command Module =========================================== @@ -20,6 +19,30 @@ Release History =============== + + 1.0.6 + +++++ + * New feature: 'az backup item list' command now has '--container-name' parameter as optional instead of mandatory and output contains item health details. + * New feature: Added original storage account option in 'az backup restore restore-disks' command. + * Bugs fixed: VM and vault location check must be case insensitive in 'az backup protection enable-for-vm' command. + + 1.0.5 + +++++ + * When a non-existent name is supplied for a container, commands will not fail with a stack trace. Partially fixes #4502. + * az backup item list update: 'Health Status' of an item is now visible in the default table view. + + 1.0.4 + +++++ + * Minor fixes. + + 1.0.3 + +++++ + * Minor fixes. + + 1.0.2 + +++++ + * no changes + 1.0.1 (2017-09-22) ++++++++++++++++++ * Preview release. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure_cli_backup.egg-info/SOURCES.txt new/azure-cli-backup-1.0.6/azure_cli_backup.egg-info/SOURCES.txt --- old/azure-cli-backup-1.0.1/azure_cli_backup.egg-info/SOURCES.txt 2017-09-23 01:47:41.000000000 +0200 +++ new/azure-cli-backup-1.0.6/azure_cli_backup.egg-info/SOURCES.txt 2018-01-12 18:26:09.000000000 +0100 @@ -8,6 +8,7 @@ azure/cli/command_modules/__init__.py azure/cli/command_modules/backup/__init__.py azure/cli/command_modules/backup/_client_factory.py +azure/cli/command_modules/backup/_format.py azure/cli/command_modules/backup/_help.py azure/cli/command_modules/backup/_params.py azure/cli/command_modules/backup/_validators.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/azure_cli_backup.egg-info/requires.txt new/azure-cli-backup-1.0.6/azure_cli_backup.egg-info/requires.txt --- old/azure-cli-backup-1.0.1/azure_cli_backup.egg-info/requires.txt 2017-09-23 01:47:41.000000000 +0200 +++ new/azure-cli-backup-1.0.6/azure_cli_backup.egg-info/requires.txt 2018-01-12 18:26:09.000000000 +0100 @@ -1,4 +1,3 @@ azure-mgmt-recoveryservices==0.1.0 azure-mgmt-recoveryservicesbackup==0.1.1 azure-cli-core -azure-cli-command-modules-nspkg>=2.0.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-backup-1.0.1/setup.py new/azure-cli-backup-1.0.6/setup.py --- old/azure-cli-backup-1.0.1/setup.py 2017-09-23 01:47:41.000000000 +0200 +++ new/azure-cli-backup-1.0.6/setup.py 2018-01-12 18:25:22.000000000 +0100 @@ -13,7 +13,7 @@ logger.warn("Wheel is not available, disabling bdist_wheel hook") cmdclass = {} -VERSION = "1.0.1" +VERSION = "1.0.6" # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers
