From df63cd03d5733c7779a67bfbdbaa312b6224352c Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanino Date: Tue, 19 Apr 2016 15:41:46 -0400 Subject: [PATCH] Support name option for volume restore Volume restore API supports name option to specify volume name for new volume creation, but CLI doesn't support this option. This change simply add name option for backup-restore command. Change-Id: I22ccc303c86b958cb21862f718ef89f57234a027 Partial-Bug: #1539667 --- cinderclient/tests/unit/v2/test_shell.py | 18 ++++++++++++++++-- .../tests/unit/v2/test_volume_backups.py | 10 ++++++++++ cinderclient/v3/shell.py | 16 ++++++++++++++-- cinderclient/v3/volume_backups_restore.py | 5 +++-- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/cinderclient/tests/unit/v2/test_shell.py b/cinderclient/tests/unit/v2/test_shell.py index fc3490c..3c9b9fd 100644 --- a/cinderclient/tests/unit/v2/test_shell.py +++ b/cinderclient/tests/unit/v2/test_shell.py @@ -424,6 +424,17 @@ class ShellTest(utils.TestCase): self.run_command('backup-restore 1234') self.assert_called('POST', '/backups/1234/restore') + def test_restore_with_name(self): + self.run_command('backup-restore 1234 --name restore_vol') + expected = {'restore': {'volume_id': None, 'name': 'restore_vol'}} + self.assert_called('POST', '/backups/1234/restore', + body=expected) + + def test_restore_with_name_error(self): + self.assertRaises(exceptions.CommandError, self.run_command, + 'backup-restore 1234 --volume fake_vol --name ' + 'restore_vol') + @mock.patch('cinderclient.utils.print_dict') @mock.patch('cinderclient.utils.find_volume') def test_do_backup_restore(self, @@ -431,9 +442,11 @@ class ShellTest(utils.TestCase): mock_print_dict): backup_id = '1234' volume_id = '5678' + name = None input = { 'backup': backup_id, - 'volume': volume_id + 'volume': volume_id, + 'name': None } args = self._make_args(input) @@ -445,7 +458,8 @@ class ShellTest(utils.TestCase): test_shell.do_backup_restore(self.cs, args) mocked_restore.assert_called_once_with( input['backup'], - volume_id) + volume_id, + name) self.assertTrue(mock_print_dict.called) def test_record_export(self): diff --git a/cinderclient/tests/unit/v2/test_volume_backups.py b/cinderclient/tests/unit/v2/test_volume_backups.py index ac8be24..c003164 100644 --- a/cinderclient/tests/unit/v2/test_volume_backups.py +++ b/cinderclient/tests/unit/v2/test_volume_backups.py @@ -100,6 +100,16 @@ class VolumeBackupsTest(utils.TestCase): volume_backups_restore.VolumeBackupsRestore) self._assert_request_id(info) + def test_restore_with_name(self): + backup_id = '76a17945-3c6f-435c-975b-b5685db10b62' + name = 'restore_vol' + info = cs.restores.restore(backup_id, name=name) + expected_body = {'restore': {'volume_id': None, 'name': name}} + cs.assert_called('POST', '/backups/%s/restore' % backup_id, + body=expected_body) + self.assertIsInstance(info, + volume_backups_restore.VolumeBackupsRestore) + def test_reset_state(self): b = cs.backups.list()[0] api = '/backups/76a17945-3c6f-435c-975b-b5685db10b62/action' diff --git a/cinderclient/v3/shell.py b/cinderclient/v3/shell.py index f28dedb..40006a6 100644 --- a/cinderclient/v3/shell.py +++ b/cinderclient/v3/shell.py @@ -1483,7 +1483,14 @@ def do_backup_delete(cs, args): help=argparse.SUPPRESS) @utils.arg('--volume', metavar='', default=None, - help='Name or ID of volume to which to restore. ' + help='Name or ID of existing volume to which to restore. ' + 'This is mutually exclusive with --name and takes priority. ' + 'Default=None.') +@utils.arg('--name', metavar='', + default=None, + help='Use the name for new volume creation to restore. ' + 'This is mutually exclusive with --volume (or the deprecated ' + '--volume-id) and --volume (or --volume-id) takes priority. ' 'Default=None.') @utils.service_type('volumev3') def do_backup_restore(cs, args): @@ -1491,10 +1498,15 @@ def do_backup_restore(cs, args): vol = args.volume or args.volume_id if vol: volume_id = utils.find_volume(cs, vol).id + if args.name: + args.name = None + print('Mutually exclusive options are specified simultaneously: ' + '"--volume (or the deprecated --volume-id) and --name". ' + 'The --volume (or --volume-id) option takes priority.') else: volume_id = None - restore = cs.restores.restore(args.backup, volume_id) + restore = cs.restores.restore(args.backup, volume_id, args.name) info = {"backup_id": args.backup} info.update(restore._info) diff --git a/cinderclient/v3/volume_backups_restore.py b/cinderclient/v3/volume_backups_restore.py index 911356d..8a35ed1 100644 --- a/cinderclient/v3/volume_backups_restore.py +++ b/cinderclient/v3/volume_backups_restore.py @@ -31,13 +31,14 @@ class VolumeBackupRestoreManager(base.Manager): """Manage :class:`VolumeBackupsRestore` resources.""" resource_class = VolumeBackupsRestore - def restore(self, backup_id, volume_id=None): + def restore(self, backup_id, volume_id=None, name=None): """Restore a backup to a volume. :param backup_id: The ID of the backup to restore. :param volume_id: The ID of the volume to restore the backup to. + :param name : The name for new volume creation to restore. :rtype: :class:`Restore` """ - body = {'restore': {'volume_id': volume_id}} + body = {'restore': {'volume_id': volume_id, 'name': name}} return self._create("/backups/%s/restore" % backup_id, body, "restore")