Add project_id in group snapshots list and show API

Add ``project_id`` to response body of list group snapshots
with detail and show group snapshot detail APIs.

Merging the group and group snapshot response in same MV
was discussed in weekly meeting[1].

[1] http://eavesdrop.openstack.org/meetings/cinder/2019/cinder.2019-02-20-16.00.log.html#l-122
Change-Id: Ided66450b5d7de32551edbce249e94f6174da2eb
Implements: blueprint add-project-id-to-group-groupsnapshot-response
This commit is contained in:
whoami-rajat 2019-02-26 16:55:52 +05:30
parent 8b39e1cee6
commit 6dd3b9c51f
14 changed files with 130 additions and 27 deletions

View File

@ -80,6 +80,7 @@ Response Parameters
- status: status_group_snap
- description: description_group_snap_req
- group_type_id: group_type_id
- project_id: project_id_group_snapshot
Response Example
----------------
@ -135,6 +136,7 @@ Response Parameters
- created_at: created_at
- group_id: group_id
- group_type_id: group_type_id
- project_id: project_id_group_snapshot
Response Example
----------------

View File

@ -2216,7 +2216,14 @@ project_id_group:
description: |
The UUID of the volume group project.
in: body
required: true
required: false
type: string
min_version: 3.58
project_id_group_snapshot:
description: |
The UUID of the volume group snapshot project.
in: body
required: false
type: string
min_version: 3.58
project_id_host:

View File

@ -7,7 +7,8 @@
"created_at": "2015-09-16T09:28:52.000000",
"name": "my_group_snapshot1",
"description": "my first group snapshot",
"group_type_id": "0ef094a2-d9fd-4c79-acfd-ac60a0506b7d"
"group_type_id": "0ef094a2-d9fd-4c79-acfd-ac60a0506b7d",
"project_id": "7ccf4863071f44aeb8f141f65780c51b"
},
{
"id": "aed36625-a6d7-4681-ba59-c7ba3d18c148",
@ -16,7 +17,8 @@
"created_at": "2015-09-16T09:31:15.000000",
"name": "my_group_snapshot2",
"description": "Edited description",
"group_type_id": "7270c56e-6354-4528-8e8b-f54dee2232c8"
"group_type_id": "7270c56e-6354-4528-8e8b-f54dee2232c8",
"project_id": "7ccf4863071f44aeb8f141f65780c51b"
}
]
}

View File

@ -6,6 +6,7 @@
"created_at": "2015-09-16T09:28:52.000000",
"name": "my_group_snapshot1",
"description": "my first group snapshot",
"group_type_id": "7270c56e-6354-4528-8e8b-f54dee2232c8"
"group_type_id": "7270c56e-6354-4528-8e8b-f54dee2232c8",
"project_id": "7ccf4863071f44aeb8f141f65780c51b"
}
}

View File

@ -155,7 +155,7 @@ BACKUP_PROJECT_USER_ID = '3.56'
TRANSFER_WITH_HISTORY = '3.57'
GROUP_PROJECT_ID = '3.58'
GROUP_GROUPSNAPSHOT_PROJECT_ID = '3.58'
SUPPORT_TRANSFER_PAGINATION = '3.59'

View File

@ -132,7 +132,8 @@ REST_API_VERSION_HISTORY = """
* 3.57 - Add 'source_project_id', 'destination_project_id', 'accepted' to
transfer.
* 3.58 - Add ``project_id`` attribute to response body of list groups with
detail and show group detail APIs.
detail, list group snapshots with detail, show group detail and
show group snapshot detail APIs.
* 3.59 - Support volume transfer pagination.
"""

View File

@ -455,8 +455,9 @@ related api (create/show/list detail transfer APIs) responses.
3.58
----
Add ``project_id`` attribute to response body of list groups with detail and
show group detail APIs.
Add ``project_id`` attribute to response body of list groups with detail,
list group snapshots with detail, show group detail and show group snapshot
detail APIs.
3.59
----

View File

@ -14,6 +14,8 @@
# under the License.
from cinder.api import common
from cinder.api import microversions as mv
from cinder.policies import group_snapshots as policy
class ViewBuilder(common.ViewBuilder):
@ -47,7 +49,7 @@ class ViewBuilder(common.ViewBuilder):
def detail(self, request, group_snapshot):
"""Detailed view of a single group_snapshot."""
return {
group_snapshot_ref = {
'group_snapshot': {
'id': group_snapshot.id,
'group_id': group_snapshot.group_id,
@ -58,6 +60,16 @@ class ViewBuilder(common.ViewBuilder):
'description': group_snapshot.description
}
}
req_version = request.api_version_request
context = request.environ['cinder.context']
if req_version.matches(mv.GROUP_GROUPSNAPSHOT_PROJECT_ID, None):
if context.authorize(policy.GROUP_SNAPSHOT_ATTRIBUTES_POLICY,
fatal=False):
group_snapshot_ref['group_snapshot']['project_id'] = (
group_snapshot.project_id)
return group_snapshot_ref
def _list_view(self, func, request, group_snapshots):
"""Provide a view for a list of group_snapshots."""

View File

@ -80,7 +80,7 @@ class ViewBuilder(common.ViewBuilder):
if req_version.matches(mv.GROUP_REPLICATION, None):
group_ref['group']['replication_status'] = group.replication_status
if req_version.matches(mv.GROUP_PROJECT_ID, None):
if req_version.matches(mv.GROUP_GROUPSNAPSHOT_PROJECT_ID, None):
if context.authorize(policy.GROUP_ATTRIBUTES_POLICY, fatal=False):
group_ref['group']['project_id'] = group.project_id

View File

@ -23,6 +23,7 @@ DELETE_POLICY = 'group:delete_group_snapshot'
UPDATE_POLICY = 'group:update_group_snapshot'
GET_POLICY = 'group:get_group_snapshot'
GET_ALL_POLICY = 'group:get_all_group_snapshots'
GROUP_SNAPSHOT_ATTRIBUTES_POLICY = 'group:group_snapshot_project_attribute'
group_snapshots_policies = [
@ -80,6 +81,21 @@ group_snapshots_policies = [
'path': '/group_snapshots/{group_snapshot_id}'
}
]),
policy.DocumentedRuleDefault(
name=GROUP_SNAPSHOT_ATTRIBUTES_POLICY,
check_str=base.RULE_ADMIN_API,
description="List group snapshots or show group "
"snapshot with project attributes.",
operations=[
{
'method': 'GET',
'path': '/group_snapshots/{group_snapshot_id}'
},
{
'method': 'GET',
'path': '/group_snapshots/detail'
}
]),
]

View File

@ -297,6 +297,43 @@ class GroupSnapshotsAPITestCase(test.TestCase):
self.controller.show,
req, fake.WILL_NOT_BE_FOUND_ID)
def test_show_group_snapshot_with_project_id(self):
group_snapshot = utils.create_group_snapshot(
self.context, group_id=self.group.id)
req = fakes.HTTPRequest.blank(
'/v3/%s/group_snapshots/%s' % (fake.PROJECT_ID,
group_snapshot.id),
version=mv.GROUP_GROUPSNAPSHOT_PROJECT_ID,
use_admin_context=True)
res_dict = self.controller.show(req, group_snapshot.id)
self.assertEqual(1, len(res_dict))
self.assertEqual('test_group_snapshot',
res_dict['group_snapshot']['name'])
self.assertEqual(fake.PROJECT_ID,
res_dict['group_snapshot']['project_id'])
group_snapshot.destroy()
def test_show_group_snapshot_without_project_id(self):
group_snapshot = utils.create_group_snapshot(
self.context, group_id=self.group.id)
# using mv.TRANSFER_WITH_HISTORY (3.57) to test the
# project_id field is not in response before mv 3.58
req = fakes.HTTPRequest.blank(
'/v3/%s/group_snapshots/%s' % (fake.PROJECT_ID,
group_snapshot.id),
version=mv.TRANSFER_WITH_HISTORY,
use_admin_context=True)
res_dict = self.controller.show(req, group_snapshot.id)
self.assertEqual(1, len(res_dict))
self.assertEqual('test_group_snapshot',
res_dict['group_snapshot']['name'])
self.assertNotIn('project_id', res_dict['group_snapshot'])
group_snapshot.destroy()
@ddt.data(True, False)
def test_list_group_snapshots_json(self, is_detail):
if is_detail:
@ -324,6 +361,29 @@ class GroupSnapshotsAPITestCase(test.TestCase):
self.assertNotIn('description',
res_dict['group_snapshots'][2 - index].keys())
@ddt.data(True, False)
def test_list_group_snapshots_with_project_id(self, is_detail):
if is_detail:
request_url = '/v3/%s/group_snapshots/detail'
else:
request_url = '/v3/%s/group_snapshots'
req = fakes.HTTPRequest.blank(
request_url % fake.PROJECT_ID,
version=mv.GROUP_GROUPSNAPSHOT_PROJECT_ID,
use_admin_context=True)
if is_detail:
res_dict = self.controller.detail(req)
else:
res_dict = self.controller.index(req)
self.assertEqual(1, len(res_dict))
self.assertEqual(3, len(res_dict['group_snapshots']))
for group in res_dict['group_snapshots']:
if is_detail:
self.assertIsNotNone(group['project_id'])
else:
self.assertNotIn('project_id', group)
@mock.patch('cinder.db.volume_type_get')
@mock.patch('cinder.quota.VolumeTypeQuotaEngine.reserve')
def test_create_group_snapshot_json(self, mock_quota, mock_vol_type):

View File

@ -1423,10 +1423,10 @@ class GroupsAPITestCase(test.TestCase):
def test_show_group_with_project_id(self):
# If the microversion >= 3.58 and "is_admin=True", "project_id" should
# be contained in the response body.
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' %
(fake.PROJECT_ID, self.group1.id),
version=mv.GROUP_PROJECT_ID,
use_admin_context=True)
req = fakes.HTTPRequest.blank(
'/v3/%s/groups/%s' % (fake.PROJECT_ID, self.group1.id),
version=mv.GROUP_GROUPSNAPSHOT_PROJECT_ID,
use_admin_context=True)
res_dict = self.controller.show(req, self.group1.id)
self.assertEqual(1, len(res_dict))
self.assertEqual(fake.PROJECT_ID,
@ -1437,7 +1437,7 @@ class GroupsAPITestCase(test.TestCase):
req = fakes.HTTPRequest.blank(
'/v3/%s/groups/%s' %
(fake.PROJECT_ID, self.group1.id),
version=mv.get_prior_version(mv.GROUP_PROJECT_ID),
version=mv.get_prior_version(mv.GROUP_GROUPSNAPSHOT_PROJECT_ID),
use_admin_context=True)
res_dict = self.controller.show(req, self.group1.id)
self.assertEqual(1, len(res_dict))
@ -1450,10 +1450,10 @@ class GroupsAPITestCase(test.TestCase):
self.group2.group_type_id = fake.GROUP_TYPE2_ID
self.group2.save()
req = fakes.HTTPRequest.blank(('/v3/%s/groups/detail'
% self.ctxt.project_id),
version=mv.GROUP_PROJECT_ID,
use_admin_context=True)
req = fakes.HTTPRequest.blank(
'/v3/%s/groups/detail' % self.ctxt.project_id,
version=mv.GROUP_GROUPSNAPSHOT_PROJECT_ID,
use_admin_context=True)
res_dict = self.controller.detail(req)
self.assertEqual(1, len(res_dict))
@ -1465,9 +1465,9 @@ class GroupsAPITestCase(test.TestCase):
def test_show_group_without_project_id(self):
# If the microversion >= 3.58 and "is_admin=False", "project_id" should
# not be contained in the response body.
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' %
(fake.PROJECT_ID, self.group3.id),
version=mv.GROUP_PROJECT_ID)
req = fakes.HTTPRequest.blank(
'/v3/%s/groups/%s' % (fake.PROJECT_ID, self.group3.id),
version=mv.GROUP_GROUPSNAPSHOT_PROJECT_ID)
res_dict = self.controller.show(req, self.group1.id)
self.assertEqual(1, len(res_dict))
self.assertNotIn('project_id', res_dict['group'])

View File

@ -0,0 +1,6 @@
---
features:
- |
Added ``project_id`` attribute to response body of list groups with detail,
list group snapshots with detail, show group detail and show group snapshot
detail APIs since microversion "3.58".

View File

@ -1,5 +0,0 @@
---
features:
- |
Added ``project_id`` attribute to response body of list groups with detail
and show group detail APIs since microversion "3.58".