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 fc3490cfa..3c9b9fde2 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 ac8be24eb..c0031642c 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 f28dedb0b..40006a67a 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 911356d03..8a35ed162 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")