Merge "Support list-volume for group show"

This commit is contained in:
Jenkins 2017-06-14 18:45:36 +00:00 committed by Gerrit Code Review
commit 22c386fcec
9 changed files with 86 additions and 11 deletions

View File

@ -403,9 +403,14 @@ class ManagerWithFind(six.with_metaclass(abc.ABCMeta, Manager)):
search_opts['display_name'] = kwargs['display_name']
found = common_base.ListWithMeta([], None)
# list_volume is used for group query, it's not resource's property.
list_volume = kwargs.pop('list_volume', False)
searches = kwargs.items()
listing = self.list(search_opts=search_opts)
if list_volume:
listing = self.list(search_opts=search_opts,
list_volume=list_volume)
else:
listing = self.list(search_opts=search_opts)
found.append_request_ids(listing.request_ids)
# Not all resources attributes support filters on server side
# (e.g. 'human_id' doesn't), so when doing findall some client

View File

@ -85,9 +85,10 @@ def find_consistencygroup(cs, consistencygroup):
return utils.find_resource(cs.consistencygroups, consistencygroup)
def find_group(cs, group):
def find_group(cs, group, **kwargs):
"""Gets a group by name or ID."""
return utils.find_resource(cs.groups, group)
kwargs['is_group'] = True
return utils.find_resource(cs.groups, group, **kwargs)
def find_cgsnapshot(cs, cgsnapshot):

View File

@ -55,13 +55,13 @@ class FakeManager(base.ManagerWithFind):
FakeResource('5678', {'name': '9876'})
]
def get(self, resource_id):
def get(self, resource_id, **kwargs):
for resource in self.resources:
if resource.id == str(resource_id):
return resource
raise exceptions.NotFound(resource_id)
def list(self, search_opts):
def list(self, search_opts, **kwargs):
return common_base.ListWithMeta(self.resources, fakes.REQUEST_ID)
@ -134,6 +134,18 @@ class FindResourceTestCase(test_utils.TestCase):
output = utils.find_resource(display_manager, 'entity_three')
self.assertEqual(display_manager.get('4242'), output)
def test_find_by_group_id(self):
output = utils.find_resource(self.manager, 1234, is_group=True,
list_volume=True)
self.assertEqual(self.manager.get('1234', list_volume=True), output)
def test_find_by_group_name(self):
display_manager = FakeDisplayManager(None)
output = utils.find_resource(display_manager, 'entity_three',
is_group=True, list_volume=True)
self.assertEqual(display_manager.get('4242', list_volume=True),
output)
class CaptureStdout(object):
"""Context manager for capturing stdout from statements in its block."""

View File

@ -101,6 +101,11 @@ class GroupsTest(utils.TestCase):
cs.assert_called('GET', '/groups/detail?foo=bar')
self._assert_request_id(lst)
def test_list_group_with_volume(self):
lst = cs.groups.list(list_volume=True)
cs.assert_called('GET', '/groups/detail?list_volume=True')
self._assert_request_id(lst)
def test_list_group_with_empty_search_opt(self):
lst = cs.groups.list(
search_opts={'foo': 'bar', 'abc': None}
@ -114,6 +119,12 @@ class GroupsTest(utils.TestCase):
cs.assert_called('GET', '/groups/%s' % group_id)
self._assert_request_id(grp)
def test_get_group_with_list_volume(self):
group_id = '1234'
grp = cs.groups.get(group_id, list_volume=True)
cs.assert_called('GET', '/groups/%s?list_volume=True' % group_id)
self._assert_request_id(grp)
def test_create_group_from_src_snap(self):
grp = cs.groups.create_from_src('5678', None, name='group')
expected = {

View File

@ -427,6 +427,11 @@ class ShellTest(utils.TestCase):
'group-show 1234')
self.assert_called('GET', '/groups/1234')
def test_group_show_with_list_volume(self):
self.run_command('--os-volume-api-version 3.25 '
'group-show 1234 --list-volume')
self.assert_called('GET', '/groups/1234?list_volume=True')
@ddt.data(True, False)
def test_group_delete(self, delete_vol):
cmd = '--os-volume-api-version 3.13 group-delete 1234'

View File

@ -220,11 +220,14 @@ def print_dict(d, property="Property", formatters=None):
_print(pt, property)
def find_resource(manager, name_or_id):
def find_resource(manager, name_or_id, **kwargs):
"""Helper for the _find_* methods."""
is_group = kwargs.pop('is_group', False)
# first try to get entity as integer id
try:
if isinstance(name_or_id, int) or name_or_id.isdigit():
if is_group:
return manager.get(int(name_or_id), **kwargs)
return manager.get(int(name_or_id))
except exceptions.NotFound:
pass
@ -232,6 +235,8 @@ def find_resource(manager, name_or_id):
# now try to get entity as uuid
try:
uuid.UUID(name_or_id)
if is_group:
return manager.get(name_or_id, **kwargs)
return manager.get(name_or_id)
except (ValueError, exceptions.NotFound):
pass
@ -243,12 +248,18 @@ def find_resource(manager, name_or_id):
try:
resource = getattr(manager, 'resource_class', None)
name_attr = resource.NAME_ATTR if resource else 'name'
if is_group:
kwargs[name_attr] = name_or_id
return manager.find(**kwargs)
return manager.find(**{name_attr: name_or_id})
except exceptions.NotFound:
pass
# finally try to find entity by human_id
try:
if is_group:
kwargs['human_id'] = name_or_id
return manager.find(**kwargs)
return manager.find(human_id=name_or_id)
except exceptions.NotFound:
msg = "No %s with a name or ID of '%s' exists." % \

View File

@ -14,6 +14,7 @@
# under the License.
"""Group interface (v3 extension)."""
from six.moves.urllib import parse
from cinderclient import api_versions
from cinderclient import base
@ -106,20 +107,31 @@ class GroupManager(base.ManagerWithFind):
"/groups/action", body=body)
return common_base.DictWithMeta(body['group'], resp)
def get(self, group_id):
def get(self, group_id, **kwargs):
"""Get a group.
:param group_id: The ID of the group to get.
:rtype: :class:`Group`
"""
return self._get("/groups/%s" % group_id,
query_params = utils.unicode_key_value_to_string(kwargs)
query_string = ""
if query_params:
params = sorted(query_params.items(), key=lambda x: x[0])
query_string = "?%s" % parse.urlencode(params)
return self._get("/groups/%s" % group_id + query_string,
"group")
def list(self, detailed=True, search_opts=None):
def list(self, detailed=True, search_opts=None, list_volume=False):
"""Lists all groups.
:rtype: list of :class:`Group`
"""
if list_volume:
if not search_opts:
search_opts = {}
search_opts['list_volume'] = True
query_string = utils.build_query_param(search_opts)
detail = ""

View File

@ -992,13 +992,26 @@ def do_group_list(cs, args):
@api_versions.wraps('3.13')
@utils.arg('--list-volume',
dest='list_volume',
metavar='<False|True>',
nargs='?',
type=bool,
const=True,
default=False,
help='Shows volumes included in the group.',
start_version='3.25')
@utils.arg('group',
metavar='<group>',
help='Name or ID of a group.')
def do_group_show(cs, args):
"""Shows details of a group."""
info = dict()
group = shell_utils.find_group(cs, args.group)
if getattr(args, 'list_volume', None):
group = shell_utils.find_group(cs, args.group,
list_volume=args.list_volume)
else:
group = shell_utils.find_group(cs, args.group)
info.update(group._info)
info.pop('links', None)

View File

@ -0,0 +1,5 @@
---
features:
- |
Support show group with ``list-volume`` argument.
The command is : cinder group-show {group_id} --list-volume