From b079d1a022e916822aff391fe0282d10f6c2a905 Mon Sep 17 00:00:00 2001 From: whoami-rajat Date: Thu, 27 Dec 2018 17:22:41 +0000 Subject: [PATCH] Add project_id in group list and show API Add ``project_id`` to response body of list groups with detail and show group detail APIs. Depends-On: I190cc67a001ffce2a533480e6e39e26cd3f981df Change-Id: I3bc34a30b02f8a1ec2c5fecbcde6bd369c8e4a76 Implements: blueprint add-project-id-to-group-response --- api-ref/source/v3/groups.inc | 2 + api-ref/source/v3/parameters.yaml | 7 +++ .../v3/samples/group-show-response.json | 3 +- .../groups-list-detailed-response.json | 6 ++- .../versions/version-show-response.json | 2 +- .../samples/versions/versions-response.json | 2 +- cinder/api/microversions.py | 2 + cinder/api/openstack/api_version_request.py | 4 +- .../openstack/rest_api_version_history.rst | 5 ++ cinder/api/v3/views/groups.py | 6 +++ cinder/policies/groups.py | 15 ++++++ cinder/tests/unit/api/v3/test_groups.py | 52 +++++++++++++++++++ ...id-to-group-response-512013e95a80784a.yaml | 5 ++ 13 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/add-project-id-to-group-response-512013e95a80784a.yaml diff --git a/api-ref/source/v3/groups.inc b/api-ref/source/v3/groups.inc index 5a02456a3f6..63a02fbf5b9 100644 --- a/api-ref/source/v3/groups.inc +++ b/api-ref/source/v3/groups.inc @@ -165,6 +165,7 @@ Response Parameters - name: group_name - volumes: volume_ids - replication_status: group_replication_status + - project_id: project_id_group Response Example ---------------- @@ -316,6 +317,7 @@ Response Parameters - id: group_id_path - name: name - volumes: volume_ids + - project_id: project_id_group Response Example ---------------- diff --git a/api-ref/source/v3/parameters.yaml b/api-ref/source/v3/parameters.yaml index 6b5e9aa7a2c..16885c2fb40 100644 --- a/api-ref/source/v3/parameters.yaml +++ b/api-ref/source/v3/parameters.yaml @@ -2148,6 +2148,13 @@ project_id: in: body required: true type: string +project_id_group: + description: | + The UUID of the volume group project. + in: body + required: true + type: string + min_version: 3.58 project_id_host: description: | The Project ID which the host resource belongs to. diff --git a/api-ref/source/v3/samples/group-show-response.json b/api-ref/source/v3/samples/group-show-response.json index 8ad822eacb2..48cb15ad51b 100644 --- a/api-ref/source/v3/samples/group-show-response.json +++ b/api-ref/source/v3/samples/group-show-response.json @@ -12,6 +12,7 @@ ], "volumes": ["a2cdf1ad-5497-4e57-bd7d-f573768f3d03"], "group_snapshot_id": null, - "source_group_id": null + "source_group_id": null, + "project_id": "7ccf4863071f44aeb8f141f65780c51b" } } diff --git a/api-ref/source/v3/samples/groups-list-detailed-response.json b/api-ref/source/v3/samples/groups-list-detailed-response.json index 65747a44c67..b9d517c03c6 100644 --- a/api-ref/source/v3/samples/groups-list-detailed-response.json +++ b/api-ref/source/v3/samples/groups-list-detailed-response.json @@ -12,7 +12,8 @@ "4e9e6d23-eed0-426d-b90a-28f87a94b6fe", "a3d55d15-eeb1-4816-ada9-bf82decc09b3" ], - "volumes": ["a2cdf1ad-5497-4e57-bd7d-f573768f3d03"] + "volumes": ["a2cdf1ad-5497-4e57-bd7d-f573768f3d03"], + "project_id": "7ccf4863071f44aeb8f141f65780c51b" }, { "id": "aed36625-a6d7-4681-ba59-c7ba3d18c148", @@ -25,7 +26,8 @@ "volume_types": [ "c4daaf47-c530-4901-b28e-f5f0a359c4e6" ], - "volumes": ["a2cdf1ad-5497-4e57-bd7d-f573768f3d03"] + "volumes": ["a2cdf1ad-5497-4e57-bd7d-f573768f3d03"], + "project_id": "7ccf4863071f44aeb8f141f65780c51b" } ] } diff --git a/api-ref/source/v3/samples/versions/version-show-response.json b/api-ref/source/v3/samples/versions/version-show-response.json index b1f51dc27cb..263d05f7225 100644 --- a/api-ref/source/v3/samples/versions/version-show-response.json +++ b/api-ref/source/v3/samples/versions/version-show-response.json @@ -22,7 +22,7 @@ "min_version": "3.0", "status": "CURRENT", "updated": "2018-07-17T00:00:00Z", - "version": "3.57" + "version": "3.58" } ] } \ No newline at end of file diff --git a/api-ref/source/v3/samples/versions/versions-response.json b/api-ref/source/v3/samples/versions/versions-response.json index bafff49f234..add28806b3f 100644 --- a/api-ref/source/v3/samples/versions/versions-response.json +++ b/api-ref/source/v3/samples/versions/versions-response.json @@ -46,7 +46,7 @@ "min_version": "3.0", "status": "CURRENT", "updated": "2018-07-17T00:00:00Z", - "version": "3.57" + "version": "3.58" } ] } \ No newline at end of file diff --git a/cinder/api/microversions.py b/cinder/api/microversions.py index fdea162396d..efff9130186 100644 --- a/cinder/api/microversions.py +++ b/cinder/api/microversions.py @@ -155,6 +155,8 @@ BACKUP_PROJECT_USER_ID = '3.56' TRANSFER_WITH_HISTORY = '3.57' +GROUP_PROJECT_ID = '3.58' + def get_mv_header(version): """Gets a formatted HTTP microversion header. diff --git a/cinder/api/openstack/api_version_request.py b/cinder/api/openstack/api_version_request.py index e2207de19d2..064b7c92c71 100644 --- a/cinder/api/openstack/api_version_request.py +++ b/cinder/api/openstack/api_version_request.py @@ -131,6 +131,8 @@ REST_API_VERSION_HISTORY = """ detail and show backup detail APIs. * 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. """ # The minimum and maximum versions of the API supported @@ -138,7 +140,7 @@ REST_API_VERSION_HISTORY = """ # minimum version of the API supported. # Explicitly using /v2 endpoints will still work _MIN_API_VERSION = "3.0" -_MAX_API_VERSION = "3.57" +_MAX_API_VERSION = "3.58" _LEGACY_API_VERSION2 = "2.0" UPDATED = "2018-07-17T00:00:00Z" diff --git a/cinder/api/openstack/rest_api_version_history.rst b/cinder/api/openstack/rest_api_version_history.rst index 3f3b0b86dad..1bd6de7b74b 100644 --- a/cinder/api/openstack/rest_api_version_history.rst +++ b/cinder/api/openstack/rest_api_version_history.rst @@ -452,3 +452,8 @@ backup detail APIs. Expanded volume transfer record details by adding ``source_project_id``, ``destination_project_id`` and ``accepted`` fields to ``transfer`` table and 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. diff --git a/cinder/api/v3/views/groups.py b/cinder/api/v3/views/groups.py index 90461f3d507..b5fffb8df7b 100644 --- a/cinder/api/v3/views/groups.py +++ b/cinder/api/v3/views/groups.py @@ -15,6 +15,7 @@ from cinder.api import common from cinder.api import microversions as mv +from cinder.policies import groups as policy from cinder import utils @@ -46,6 +47,7 @@ class ViewBuilder(common.ViewBuilder): def detail(self, request, group): """Detailed view of a single group.""" + context = request.environ['cinder.context'] group_ref = { 'group': { 'id': group.id, @@ -78,6 +80,10 @@ 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 context.authorize(policy.GROUP_ATTRIBUTES_POLICY, fatal=False): + group_ref['group']['project_id'] = group.project_id + return group_ref def _list_view(self, func, request, groups): diff --git a/cinder/policies/groups.py b/cinder/policies/groups.py index 6d983e1dc3d..e815b9cbdde 100644 --- a/cinder/policies/groups.py +++ b/cinder/policies/groups.py @@ -21,6 +21,7 @@ CREATE_POLICY = 'group:create' UPDATE_POLICY = 'group:update' GET_POLICY = 'group:get' GET_ALL_POLICY = 'group:get_all' +GROUP_ATTRIBUTES_POLICY = 'group:group_project_attribute' groups_policies = [ @@ -68,6 +69,20 @@ groups_policies = [ 'path': '/groups/{group_id}' } ]), + policy.DocumentedRuleDefault( + name=GROUP_ATTRIBUTES_POLICY, + check_str=base.RULE_ADMIN_API, + description="List groups or show group with project attributes.", + operations=[ + { + 'method': 'GET', + 'path': '/groups/{group_id}' + }, + { + 'method': 'GET', + 'path': '/groups/detail' + } + ]), ] diff --git a/cinder/tests/unit/api/v3/test_groups.py b/cinder/tests/unit/api/v3/test_groups.py index 8f844995050..6682a9a57c2 100644 --- a/cinder/tests/unit/api/v3/test_groups.py +++ b/cinder/tests/unit/api/v3/test_groups.py @@ -1419,3 +1419,55 @@ class GroupsAPITestCase(test.TestCase): self.assertIn('replication_targets', response) self.assertEqual('lvm_backend_1', response['replication_targets'][0]['backend_id']) + + 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) + res_dict = self.controller.show(req, self.group1.id) + self.assertEqual(1, len(res_dict)) + self.assertEqual(fake.PROJECT_ID, + res_dict['group']['project_id']) + + # If the microversion < 3.58, "project_id" should not be + # contained in the response body. + req = fakes.HTTPRequest.blank( + '/v3/%s/groups/%s' % + (fake.PROJECT_ID, self.group1.id), + version=mv.get_prior_version(mv.GROUP_PROJECT_ID), + use_admin_context=True) + res_dict = self.controller.show(req, self.group1.id) + self.assertEqual(1, len(res_dict)) + self.assertIsNone(res_dict['group'].get('project_id', None)) + + def test_list_groups_with_project_id(self): + self.group1.group_type_id = fake.GROUP_TYPE_ID + self.group1.save() + + 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) + res_dict = self.controller.detail(req) + + self.assertEqual(1, len(res_dict)) + self.assertEqual(self.group1.project_id, + res_dict['groups'][0]['project_id']) + self.assertEqual(self.group2.project_id, + res_dict['groups'][1]['project_id']) + + 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) + res_dict = self.controller.show(req, self.group1.id) + self.assertEqual(1, len(res_dict)) + self.assertNotIn('project_id', res_dict['group']) diff --git a/releasenotes/notes/add-project-id-to-group-response-512013e95a80784a.yaml b/releasenotes/notes/add-project-id-to-group-response-512013e95a80784a.yaml new file mode 100644 index 00000000000..e97faa18a52 --- /dev/null +++ b/releasenotes/notes/add-project-id-to-group-response-512013e95a80784a.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added ``project_id`` attribute to response body of list groups with detail + and show group detail APIs.