diff --git a/cinderclient/tests/unit/v2/test_shell.py b/cinderclient/tests/unit/v2/test_shell.py index b80c91143..ba5fcc778 100644 --- a/cinderclient/tests/unit/v2/test_shell.py +++ b/cinderclient/tests/unit/v2/test_shell.py @@ -947,3 +947,35 @@ class ShellTest(utils.TestCase): expected = {"os-unset_image_metadata": {"key": "key1"}} self.assert_called('POST', '/volumes/1234/action', body=expected) + + def _get_params_from_stack(self, pos=-1): + method, url = self.shell.cs.client.callstack[pos][0:2] + path, query = parse.splitquery(url) + params = parse.parse_qs(query) + return path, params + + def test_backup_list_all_tenants(self): + self.run_command('backup-list --all-tenants=1 --name=bc ' + '--status=available --volume-id=1234') + expected = { + 'all_tenants': ['1'], + 'name': ['bc'], + 'status': ['available'], + 'volume_id': ['1234'], + } + + path, params = self._get_params_from_stack() + + self.assertEqual('/backups/detail', path) + self.assertEqual(4, len(params)) + + for k in params.keys(): + self.assertEqual(expected[k], params[k]) + + def test_backup_list_volume_id(self): + self.run_command('backup-list --volume-id=1234') + self.assert_called('GET', '/backups/detail?volume_id=1234') + + def test_backup_list(self): + self.run_command('backup-list') + self.assert_called('GET', '/backups/detail') diff --git a/cinderclient/v2/shell.py b/cinderclient/v2/shell.py index 5b0eb2bf6..8a969dc44 100644 --- a/cinderclient/v2/shell.py +++ b/cinderclient/v2/shell.py @@ -1229,10 +1229,45 @@ def do_backup_show(cs, args): utils.print_dict(info) +@utils.arg('--all-tenants', + metavar='', + nargs='?', + type=int, + const=1, + default=0, + help='Shows details for all tenants. Admin only.') +@utils.arg('--all_tenants', + nargs='?', + type=int, + const=1, + help=argparse.SUPPRESS) +@utils.arg('--name', + metavar='', + default=None, + help='Filters results by a name. Default=None.') +@utils.arg('--status', + metavar='', + default=None, + help='Filters results by a status. Default=None.') +@utils.arg('--volume-id', + metavar='', + default=None, + help='Filters results by a volume ID. Default=None.') +@utils.arg('--volume_id', + help=argparse.SUPPRESS) @utils.service_type('volumev2') def do_backup_list(cs, args): """Lists all backups.""" - backups = cs.backups.list() + + search_opts = { + 'all_tenants': args.all_tenants, + 'name': args.name, + 'status': args.status, + 'volume_id': args.volume_id, + } + + backups = cs.backups.list(search_opts=search_opts) + _translate_volume_snapshot_keys(backups) columns = ['ID', 'Volume ID', 'Status', 'Name', 'Size', 'Object Count', 'Container'] utils.print_list(backups, columns) diff --git a/cinderclient/v2/volume_backups.py b/cinderclient/v2/volume_backups.py index 26a6b2226..59f07242d 100644 --- a/cinderclient/v2/volume_backups.py +++ b/cinderclient/v2/volume_backups.py @@ -16,7 +16,7 @@ """ Volume Backups interface (1.1 extension). """ - +from six.moves.urllib.parse import urlencode from cinderclient import base @@ -68,10 +68,16 @@ class VolumeBackupManager(base.ManagerWithFind): :rtype: list of :class:`VolumeBackup` """ - if detailed is True: - return self._list("/backups/detail", "backups") - else: - return self._list("/backups", "backups") + search_opts = search_opts or {} + + qparams = dict((key, val) for key, val in search_opts.items() if val) + + query_string = ("?%s" % urlencode(qparams)) if qparams else "" + + detail = '/detail' if detailed else '' + + return self._list("/backups%s%s" % (detail, query_string), + "backups") def delete(self, backup): """Delete a volume backup.