summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuriy Nesenenko <ynesenenko@mirantis.com>2015-07-30 16:57:39 +0300
committerYuriy Nesenenko <ynesenenko@mirantis.com>2015-08-19 18:05:34 +0300
commit8cc3ee2782260498cfb3d36f5469e7086b4fe6f5 (patch)
treeff956a8ac50a535db8e50e2531172cf4c43063d3
parentbae0bb3276f08b7b4a5441d8178a38e0dfc1e3e6 (diff)
downloadpython-cinderclient-8cc3ee2782260498cfb3d36f5469e7086b4fe6f5.tar.gz
Add support '--all-tenants' for cinder backup-list
Also added support '--name', '--status', '--volume-id' arguments for cinder backup-list. DocImpact Closes-Bug: #1422046 Depends On: I73f6377c7d6fd92d0464d13f9c8dd6682fef78e3 Change-Id: I5f2ab6370a8333a9ee498c6158037b0433f36a23
-rw-r--r--cinderclient/tests/unit/v2/test_shell.py32
-rw-r--r--cinderclient/v2/shell.py37
-rw-r--r--cinderclient/v2/volume_backups.py16
3 files changed, 79 insertions, 6 deletions
diff --git a/cinderclient/tests/unit/v2/test_shell.py b/cinderclient/tests/unit/v2/test_shell.py
index b80c911..ba5fcc7 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 5b0eb2b..8a969dc 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='<all_tenants>',
+ 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='<name>',
+ default=None,
+ help='Filters results by a name. Default=None.')
+@utils.arg('--status',
+ metavar='<status>',
+ default=None,
+ help='Filters results by a status. Default=None.')
+@utils.arg('--volume-id',
+ metavar='<volume-id>',
+ 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 26a6b22..59f0724 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.