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:
parent
8b39e1cee6
commit
6dd3b9c51f
@ -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
|
||||
----------------
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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.
|
||||
"""
|
||||
|
||||
|
@ -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
|
||||
----
|
||||
|
@ -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."""
|
||||
|
@ -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
|
||||
|
||||
|
@ -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'
|
||||
}
|
||||
]),
|
||||
]
|
||||
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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'])
|
||||
|
@ -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".
|
@ -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".
|
Loading…
Reference in New Issue
Block a user