From 6dac83660dd650ad650739d7c141d5d6a9d84101 Mon Sep 17 00:00:00 2001 From: zhongjun Date: Thu, 2 Nov 2017 16:29:49 +0800 Subject: [PATCH] Add count info in /shares and /shares/detail response Added support for display count info in share list&detail APIs: 1. /v2/{project_id}/shares?with_count=True 2. /v2/{project_id}/shares/detail?with_count=True Partially-Implements bp add-amount-info-in-list-api Change-Id: I12c41a46140b04f26565d8934e0326480477c612 --- manila/api/openstack/api_version_request.py | 3 ++- .../openstack/rest_api_version_history.rst | 4 ++++ manila/api/v1/shares.py | 18 +++++++++++++++-- manila/api/v2/shares.py | 3 +++ manila/api/views/shares.py | 12 ++++++----- manila/tests/api/v2/test_shares.py | 20 +++++++++++++++++-- manila_tempest_tests/config.py | 2 +- .../tests/api/test_shares_actions.py | 8 ++++++++ ...-count-info-in-share-21a6b36c0f4c87b9.yaml | 3 +++ 9 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 releasenotes/notes/add-count-info-in-share-21a6b36c0f4c87b9.yaml diff --git a/manila/api/openstack/api_version_request.py b/manila/api/openstack/api_version_request.py index c8067582b7..d0ef62c38c 100644 --- a/manila/api/openstack/api_version_request.py +++ b/manila/api/openstack/api_version_request.py @@ -112,13 +112,14 @@ REST_API_VERSION_HISTORY = """ * 2.39 - Added share-type quotas. * 2.40 - Added share group and share group snapshot quotas. * 2.41 - Added 'description' in share type create/list APIs. + * 2.42 - Added ``with_count`` in share list API to get total count info. """ # The minimum and maximum versions of the API supported # The default api version request is defined to be the # minimum version of the API supported. _MIN_API_VERSION = "2.0" -_MAX_API_VERSION = "2.41" +_MAX_API_VERSION = "2.42" DEFAULT_API_VERSION = _MIN_API_VERSION diff --git a/manila/api/openstack/rest_api_version_history.rst b/manila/api/openstack/rest_api_version_history.rst index 5a2f22b181..512001b3e1 100644 --- a/manila/api/openstack/rest_api_version_history.rst +++ b/manila/api/openstack/rest_api_version_history.rst @@ -230,3 +230,7 @@ user documentation. 2.41 ---- Added 'description' in share type create/list APIs. + +2.42 +---- + Added ``with_count`` in share list API to get total count info. diff --git a/manila/api/v1/shares.py b/manila/api/v1/shares.py index a5adabe108..362bc43a3e 100644 --- a/manila/api/v1/shares.py +++ b/manila/api/v1/shares.py @@ -34,6 +34,7 @@ from manila import exception from manila.i18n import _ from manila import share from manila.share import share_types +from manila import utils LOG = log.getLogger(__name__) @@ -105,6 +106,7 @@ class ShareMixin(object): req.GET.pop('name~', None) req.GET.pop('description~', None) req.GET.pop('description', None) + req.GET.pop('with_count', None) return self._get_shares(req, is_detail=False) def detail(self, req): @@ -114,6 +116,7 @@ class ShareMixin(object): req.GET.pop('name~', None) req.GET.pop('description~', None) req.GET.pop('description', None) + req.GET.pop('with_count', None) return self._get_shares(req, is_detail=True) def _get_shares(self, req, is_detail): @@ -129,6 +132,12 @@ class ShareMixin(object): sort_key = search_opts.pop('sort_key', 'created_at') sort_dir = search_opts.pop('sort_dir', 'desc') + show_count = False + if 'with_count' in search_opts: + show_count = utils.get_bool_from_api_params( + 'with_count', search_opts) + search_opts.pop('with_count') + # Deserialize dicts if 'metadata' in search_opts: search_opts['metadata'] = ast.literal_eval(search_opts['metadata']) @@ -160,13 +169,18 @@ class ShareMixin(object): shares = self.share_api.get_all( context, search_opts=search_opts, sort_key=sort_key, sort_dir=sort_dir) + total_count = None + if show_count: + total_count = len(shares) limited_list = common.limited(shares, req) if is_detail: - shares = self._view_builder.detail_list(req, limited_list) + shares = self._view_builder.detail_list(req, limited_list, + total_count) else: - shares = self._view_builder.summary_list(req, limited_list) + shares = self._view_builder.summary_list(req, limited_list, + total_count) return shares def _get_share_search_options(self): diff --git a/manila/api/v2/shares.py b/manila/api/v2/shares.py index 33a60a1450..e333360de3 100644 --- a/manila/api/v2/shares.py +++ b/manila/api/v2/shares.py @@ -429,6 +429,9 @@ class ShareController(shares.ShareMixin, req.GET.pop('description~', None) req.GET.pop('description', None) + if req.api_version_request < api_version.APIVersionRequest("2.42"): + req.GET.pop('with_count', None) + return self._get_shares(req, is_detail=False) @wsgi.Controller.api_version("2.0") diff --git a/manila/api/views/shares.py b/manila/api/views/shares.py index 7d51297e5e..0bfa914770 100644 --- a/manila/api/views/shares.py +++ b/manila/api/views/shares.py @@ -36,13 +36,13 @@ class ViewBuilder(common.ViewBuilder): "add_mount_snapshot_support_field", ] - def summary_list(self, request, shares): + def summary_list(self, request, shares, count=None): """Show a list of shares without many details.""" - return self._list_view(self.summary, request, shares) + return self._list_view(self.summary, request, shares, count) - def detail_list(self, request, shares): + def detail_list(self, request, shares, count=None): """Detailed view of a list of shares.""" - return self._list_view(self.detail, request, shares) + return self._list_view(self.detail, request, shares, count) def summary(self, request, share): """Generic, non-detailed view of a share.""" @@ -170,7 +170,7 @@ class ViewBuilder(common.ViewBuilder): share_dict['mount_snapshot_support'] = share.get( 'mount_snapshot_support') - def _list_view(self, func, request, shares): + def _list_view(self, func, request, shares, count=None): """Provide a view for a list of shares.""" shares_list = [func(request, share)['share'] for share in shares] shares_links = self._get_collection_links(request, @@ -178,6 +178,8 @@ class ViewBuilder(common.ViewBuilder): self._collection_name) shares_dict = dict(shares=shares_list) + if count: + shares_dict['count'] = count if shares_links: shares_dict['shares_links'] = shares_links diff --git a/manila/tests/api/v2/test_shares.py b/manila/tests/api/v2/test_shares.py index 19ed6ed72d..e7437e55cf 100644 --- a/manila/tests/api/v2/test_shares.py +++ b/manila/tests/api/v2/test_shares.py @@ -1502,7 +1502,9 @@ class ShareAPITest(test.TestCase): {'use_admin_context': True, 'version': '2.35'}, {'use_admin_context': False, 'version': '2.35'}, {'use_admin_context': True, 'version': '2.36'}, - {'use_admin_context': False, 'version': '2.36'}) + {'use_admin_context': False, 'version': '2.36'}, + {'use_admin_context': True, 'version': '2.42'}, + {'use_admin_context': False, 'version': '2.42'}) @ddt.unpack def test_share_list_summary_with_search_opts(self, use_admin_context, version): @@ -1528,6 +1530,9 @@ class ShareAPITest(test.TestCase): search_opts.update( {'display_name~': 'fake', 'display_description~': 'fake'}) + if (api_version.APIVersionRequest(version) >= + api_version.APIVersionRequest('2.42')): + search_opts.update({'with_count': 'true'}) if use_admin_context: search_opts['host'] = 'fake_host' # fake_key should be filtered for non-admin @@ -1583,6 +1588,9 @@ class ShareAPITest(test.TestCase): self.assertEqual(shares[1]['id'], result['shares'][0]['id']) self.assertEqual( shares[1]['display_name'], result['shares'][0]['name']) + if (api_version.APIVersionRequest(version) >= + api_version.APIVersionRequest('2.42')): + self.assertEqual(3, result['count']) def test_share_list_summary(self): self.mock_object(share_api.API, 'get_all', @@ -1612,7 +1620,9 @@ class ShareAPITest(test.TestCase): @ddt.data({'use_admin_context': False, 'version': '2.4'}, {'use_admin_context': True, 'version': '2.4'}, {'use_admin_context': True, 'version': '2.35'}, - {'use_admin_context': False, 'version': '2.35'}) + {'use_admin_context': False, 'version': '2.35'}, + {'use_admin_context': True, 'version': '2.42'}, + {'use_admin_context': False, 'version': '2.42'}) @ddt.unpack def test_share_list_detail_with_search_opts(self, use_admin_context, version): @@ -1633,6 +1643,9 @@ class ShareAPITest(test.TestCase): 'export_location_id': 'fake_export_location_id', 'export_location_path': 'fake_export_location_path', } + if (api_version.APIVersionRequest(version) >= + api_version.APIVersionRequest('2.42')): + search_opts.update({'with_count': 'true'}) if use_admin_context: search_opts['host'] = 'fake_host' # fake_key should be filtered for non-admin @@ -1710,6 +1723,9 @@ class ShareAPITest(test.TestCase): self.assertEqual( shares[1]['instance']['share_network_id'], result['shares'][0]['share_network_id']) + if (api_version.APIVersionRequest(version) >= + api_version.APIVersionRequest('2.42')): + self.assertEqual(3, result['count']) def _list_detail_common_expected(self, admin=False): share_dict = { diff --git a/manila_tempest_tests/config.py b/manila_tempest_tests/config.py index ab76f8f43f..e33dba8b34 100644 --- a/manila_tempest_tests/config.py +++ b/manila_tempest_tests/config.py @@ -30,7 +30,7 @@ ShareGroup = [ help="The minimum api microversion is configured to be the " "value of the minimum microversion supported by Manila."), cfg.StrOpt("max_api_microversion", - default="2.41", + default="2.42", help="The maximum api microversion is configured to be the " "value of the latest microversion supported by Manila."), cfg.StrOpt("region", diff --git a/manila_tempest_tests/tests/api/test_shares_actions.py b/manila_tempest_tests/tests/api/test_shares_actions.py index cf179bf340..7d28d8372e 100644 --- a/manila_tempest_tests/tests/api/test_shares_actions.py +++ b/manila_tempest_tests/tests/api/test_shares_actions.py @@ -389,6 +389,14 @@ class SharesActionsTest(base.BaseSharesTest): for share in shares: self.assertEqual(project_id, share["project_id"]) + @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) + @base.skip_if_microversion_lt("2.42") + def test_list_shares_with_detail_with_count(self): + # list shares by name, at least one share is expected + params = {"with_count": 'true'} + shares = self.shares_v2_client.list_shares_with_detail(params) + self.assertGreater(shares["count"], 0) + @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) def test_list_shares_public_with_detail(self): public_share = self.create_share( diff --git a/releasenotes/notes/add-count-info-in-share-21a6b36c0f4c87b9.yaml b/releasenotes/notes/add-count-info-in-share-21a6b36c0f4c87b9.yaml new file mode 100644 index 0000000000..5ec295eee7 --- /dev/null +++ b/releasenotes/notes/add-count-info-in-share-21a6b36c0f4c87b9.yaml @@ -0,0 +1,3 @@ +--- +features: + - Added total count info in Manila's /shares and /shares/detail APIs.