Improvement to get group detail(Part 2)

This feature allows users to query group details
with volume ids which are in this group.

According to the spec, this is part 2 to implement the whole bp.
This patch add the "volumes" field to group detail and group
show if user specifies the querying argument 'list_volume=True'.

This change will add a new version "3.25".

APIImpact
GET /v3/{project_id}/groups/{group_id}?list_volume=True
RESP BODY: {"group": {"status": "XXX",
                      "id": "XXX",
                      ...,
                      "volumes":['volume_id1',
                                 ...,
                                 'volume_idn']
                     }
           }

Co-Authored-By: wanghao<sxmatch1986@gmail.com>
Change-Id: Ica1afd07cd022bab168b6894b9cf43a5b18e34d4
Implements: blueprint improvement-to-query-consistency-group-detail
This commit is contained in:
wangxiyuan 2016-12-12 17:36:04 +08:00
parent c50d38349a
commit 5e0393b26d
5 changed files with 61 additions and 1 deletions

View File

@ -74,6 +74,7 @@ REST_API_VERSION_HISTORY = """
* 3.22 - Add filtering based on metadata for snapshot listing. * 3.22 - Add filtering based on metadata for snapshot listing.
* 3.23 - Allow passing force parameter to volume delete. * 3.23 - Allow passing force parameter to volume delete.
* 3.24 - Add workers/cleanup endpoint. * 3.24 - Add workers/cleanup endpoint.
* 3.25 - Add ``volumes`` field to group list/detail and group show.
""" """
# The minimum and maximum versions of the API supported # The minimum and maximum versions of the API supported
@ -81,7 +82,7 @@ REST_API_VERSION_HISTORY = """
# minimum version of the API supported. # minimum version of the API supported.
# Explicitly using /v1 or /v2 enpoints will still work # Explicitly using /v1 or /v2 enpoints will still work
_MIN_API_VERSION = "3.0" _MIN_API_VERSION = "3.0"
_MAX_API_VERSION = "3.24" _MAX_API_VERSION = "3.25"
_LEGACY_API_VERSION1 = "1.0" _LEGACY_API_VERSION1 = "1.0"
_LEGACY_API_VERSION2 = "2.0" _LEGACY_API_VERSION2 = "2.0"

View File

@ -264,3 +264,7 @@ user documentation.
``id``, ``host``, ``binary``, and ``cluster_name``. These are not the ``id``, ``host``, ``binary``, and ``cluster_name``. These are not the
services that will be performing the cleanup, but the services that will be services that will be performing the cleanup, but the services that will be
cleaned up or couldn't be cleaned up. cleaned up or couldn't be cleaned up.
3.25
----
Add ``volumes`` field to group list/detail and group show.

View File

@ -14,6 +14,7 @@
# under the License. # under the License.
from cinder.api import common from cinder.api import common
from cinder import utils
class ViewBuilder(common.ViewBuilder): class ViewBuilder(common.ViewBuilder):
@ -64,6 +65,12 @@ class ViewBuilder(common.ViewBuilder):
group_ref['group']['group_snapshot_id'] = group.group_snapshot_id group_ref['group']['group_snapshot_id'] = group.group_snapshot_id
group_ref['group']['source_group_id'] = group.source_group_id group_ref['group']['source_group_id'] = group.source_group_id
# Add volumes if min version is greater than or equal to 3.25.
if req_version.matches("3.25", None):
if utils.get_bool_param('list_volume', request.params):
group_ref['group']['volumes'] = [volume.id
for volume in group.volumes]
return group_ref return group_ref
def _list_view(self, func, request, groups): def _list_view(self, func, request, groups):

View File

@ -144,6 +144,49 @@ class GroupsAPITestCase(test.TestCase):
self.assertEqual([fake.VOLUME_TYPE_ID], self.assertEqual([fake.VOLUME_TYPE_ID],
res_dict['group']['volume_types']) res_dict['group']['volume_types'])
@mock.patch('cinder.objects.volume_type.VolumeTypeList.get_all_by_group')
@mock.patch('cinder.objects.volume.VolumeList.get_all_by_generic_group')
def test_show_group_with_list_volume(self, mock_vol_get_all_by_group,
mock_vol_type_get_all_by_group):
volume_objs = [objects.Volume(context=self.ctxt, id=i)
for i in [fake.VOLUME_ID]]
volumes = objects.VolumeList(context=self.ctxt, objects=volume_objs)
mock_vol_get_all_by_group.return_value = volumes
vol_type_objs = [objects.VolumeType(context=self.ctxt, id=i)
for i in [fake.VOLUME_TYPE_ID]]
vol_types = objects.VolumeTypeList(context=self.ctxt,
objects=vol_type_objs)
mock_vol_type_get_all_by_group.return_value = vol_types
# If the microversion >= 3.25 and "list_volume=True", "volumes" should
# be contained in the response body.
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s?list_volume=True' %
(fake.PROJECT_ID, self.group1.id),
version='3.25')
res_dict = self.controller.show(req, self.group1.id)
self.assertEqual(1, len(res_dict))
self.assertEqual([fake.VOLUME_ID],
res_dict['group']['volumes'])
# If the microversion >= 3.25 but "list_volume" is missing, "volumes"
# should not be contained in the response body.
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' %
(fake.PROJECT_ID, self.group1.id),
version='3.25')
res_dict = self.controller.show(req, self.group1.id)
self.assertEqual(1, len(res_dict))
self.assertIsNone(res_dict['group'].get('volumes', None))
# If the microversion < 3.25, "volumes" should not be contained in the
# response body.
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s?list_volume=True' %
(fake.PROJECT_ID, self.group1.id),
version='3.24')
res_dict = self.controller.show(req, self.group1.id)
self.assertEqual(1, len(res_dict))
self.assertIsNone(res_dict['group'].get('volumes', None))
def test_show_group_with_group_NotFound(self): def test_show_group_with_group_NotFound(self):
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' % req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' %
(fake.PROJECT_ID, (fake.PROJECT_ID,

View File

@ -0,0 +1,5 @@
---
features:
- Added support for querying group details with volume ids
which are in this group.
For example, "groups/{group_id}?list_volume=True".