From 8ad2cb7a2ca93e2e8646e18c3e0d86238ba767cf Mon Sep 17 00:00:00 2001 From: Yasufumi Ogawa <yasufum.o@gmail.com> Date: Tue, 18 Jun 2024 19:12:11 +0900 Subject: [PATCH] Fix issue of the paging of v1 vnflcm list - When Enhanced Tacker Policy is enabled, the paging of v1 vnflcm list does not work properly. - As the result, all the vnf instances that match the condition of Enhanced Tacker Policy cannot be shown in the vnflcm list. - Fix so that nextpage is properly set when Enhanced Tacker Policy is enabled. Closes-Bug: #2069392 Change-Id: I1731106f4a66f9bd7166f94c2815c7acd0e02994 Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com> Co-Authored-By: Takahiro Miyajima <fj6257jz@fujitsu.com> --- tacker/api/vnflcm/v1/controller.py | 6 ++- tacker/api/vnfpkgm/v1/controller.py | 6 ++- tacker/tests/unit/vnflcm/test_controller.py | 41 ++++++++++++++++ tacker/tests/unit/vnfpkgm/test_controller.py | 49 ++++++++++++++++++++ 4 files changed, 100 insertions(+), 2 deletions(-) diff --git a/tacker/api/vnflcm/v1/controller.py b/tacker/api/vnflcm/v1/controller.py index cac9dde19..3def7fcd9 100644 --- a/tacker/api/vnflcm/v1/controller.py +++ b/tacker/api/vnflcm/v1/controller.py @@ -660,7 +660,8 @@ class VnfLcmController(wsgi.Controller): # get maximum record size per page if allrecords != 'yes': - limit = CONF.vnf_lcm.vnf_instance_num + if not CONF.oslo_policy.enhanced_tacker_policy: + limit = CONF.vnf_lcm.vnf_instance_num # get next page marker object from nextpage id if nextpage: @@ -682,6 +683,9 @@ class VnfLcmController(wsgi.Controller): vnf_lcm_policies.VNFLCM % 'index', target=self._get_policy_target(vnf_instance), fatal=False)] + if allrecords != 'yes': + limit = CONF.vnf_lcm.vnf_instance_num + result = result[:limit] result = self._view_builder.index(result) diff --git a/tacker/api/vnfpkgm/v1/controller.py b/tacker/api/vnfpkgm/v1/controller.py index e9392547a..a07847eb9 100644 --- a/tacker/api/vnfpkgm/v1/controller.py +++ b/tacker/api/vnfpkgm/v1/controller.py @@ -181,7 +181,8 @@ class VnfPkgmController(wsgi.Controller): marker_obj = None if allrecords != 'yes': - limit = CONF.vnf_package.vnf_package_num + if not CONF.oslo_policy.enhanced_tacker_policy: + limit = CONF.vnf_package.vnf_package_num # get next page marker object from nextpage id if nextpage: @@ -204,6 +205,9 @@ class VnfPkgmController(wsgi.Controller): vnf_package_policies.VNFPKGM % 'index', target=self._get_policy_target(vnf_package), fatal=False)] + if allrecords != 'yes': + limit = CONF.vnf_package.vnf_package_num + result = result[:limit] results = self._view_builder.index(result, all_fields=all_fields, diff --git a/tacker/tests/unit/vnflcm/test_controller.py b/tacker/tests/unit/vnflcm/test_controller.py index e84659f77..22907a365 100644 --- a/tacker/tests/unit/vnflcm/test_controller.py +++ b/tacker/tests/unit/vnflcm/test_controller.py @@ -28,6 +28,7 @@ from webob import exc from oslo_config import cfg from oslo_policy import policy as oslo_policy from oslo_serialization import jsonutils +from oslo_utils import uuidutils from tacker.api.views import vnf_subscriptions as vnf_subscription_view from tacker.api.vnflcm.v1 import controller @@ -43,6 +44,7 @@ from tacker.manager import TackerManager from tacker import objects from tacker.objects import fields from tacker.objects import vnf_lcm_subscriptions as subscription_obj +from tacker.policies import vnf_lcm as vnf_lcm_policies from tacker import policy from tacker.tests import constants from tacker.tests.unit import base @@ -5598,6 +5600,45 @@ class TestControllerEnhancedPolicy(TestController): self.assertEqual( expected_vnf_inst_ids, [inst.get('id') for inst in resp.json]) + @mock.patch.object(objects.VnfInstance, "get_by_id") + @mock.patch.object(objects.VnfInstanceList, "get_by_marker_filter") + def test_index_enhanced_policy_paging(self, mock_vnf_list, mock_vnf_by_id): + cfg.CONF.set_override('vnf_instance_num', 1, group='vnf_lcm') + inst_a_1 = fakes.make_vnf_instance('openstack', 'provider_A', + area='area_A@region_A', tenant='tenant_A') + inst_a_2 = copy.deepcopy(inst_a_1) + inst_a_2.id = uuidutils.generate_uuid() + inst_b = fakes.make_vnf_instance('openstack', 'provider_B', + area='area_B@region_B', tenant='tenant_B') + rules = {vnf_lcm_policies.VNFLCM % 'index': + "area:%(area)s and vendor:%(vendor)s and tenant:%(tenant)s"} + roles = ['AREA_area_A@region_A', 'VENDOR_provider_A', + 'TENANT_tenant_A'] + policy.set_rules(oslo_policy.Rules.from_dict(rules), overwrite=True) + ctx = context.Context('fake', 'fake', roles=roles) + + # first request + mock_vnf_list.return_value = [inst_a_1, inst_b, inst_a_2] + req = fake_request.HTTPRequest.blank('/vnf_instances') + req.headers['Content-Type'] = 'application/json' + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app_v1(fake_auth_context=ctx)) + self.assertEqual(http_client.OK, resp.status_code) + self.assertEqual( + [inst_a_1.id], [inst.get('id') for inst in resp.json]) + + # second request with nextpage_opaque_marker + mock_vnf_list.return_value = [inst_b, inst_a_2] + mock_vnf_by_id.return_value = inst_a_1 + req = fake_request.HTTPRequest.blank('/vnf_instances?' + f'nextpage_opaque_marker={inst_a_1.id}') + req.headers['Content-Type'] = 'application/json' + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app_v1(fake_auth_context=ctx)) + self.assertEqual(http_client.OK, resp.status_code) + self.assertEqual( + [inst_a_2.id], [inst.get('id') for inst in resp.json]) + @mock.patch.object(TackerManager, 'get_service_plugins', return_value={'VNFM': FakeVNFMPlugin()}) @mock.patch('tacker.api.vnflcm.v1.controller.VnfLcmController.' diff --git a/tacker/tests/unit/vnfpkgm/test_controller.py b/tacker/tests/unit/vnfpkgm/test_controller.py index 9e1c085c6..9480daeff 100644 --- a/tacker/tests/unit/vnfpkgm/test_controller.py +++ b/tacker/tests/unit/vnfpkgm/test_controller.py @@ -14,6 +14,7 @@ # under the License. +import copy import ddt from http import client as http_client import json @@ -26,6 +27,7 @@ from webob import exc from oslo_config import cfg from oslo_policy import policy as oslo_policy from oslo_serialization import jsonutils +from oslo_utils import uuidutils from tacker._i18n import _ from tacker.api.vnfpkgm.v1 import controller @@ -1726,3 +1728,50 @@ class TestControllerEnhancedPolicy(TestController): self.assertEqual(http_client.OK, resp.status_code) self.assertEqual( expected_pkg_ids, [pkg.get('id') for pkg in resp.json]) + + @mock.patch.object(vnf_package.VnfPackage, "get_by_id") + @mock.patch.object(VnfPackagesList, "get_by_marker_filter") + def test_index_enhanced_policy_paging(self, mock_pkg_list, mock_pkg_by_id): + cfg.CONF.set_override('vnf_package_num', 1, group='vnf_package') + pkg_a_1 = fakes.return_vnfpkg_obj( + vnf_package_updates={'id': uuidutils.generate_uuid()}, + vnfd_updates={ + 'vnf_provider': 'provider_A', + 'id': uuidutils.generate_uuid(), + }) + pkg_a_2 = copy.deepcopy(pkg_a_1) + pkg_a_2.id = uuidutils.generate_uuid() + pkg_a_2.vnfd.id = uuidutils.generate_uuid() + pkg_b = fakes.return_vnfpkg_obj( + vnf_package_updates={'id': uuidutils.generate_uuid()}, + vnfd_updates={ + 'vnf_provider': 'provider_B', + 'id': uuidutils.generate_uuid(), + }) + rules = { + vnf_package_policies.VNFPKGM % 'index': "vendor:%(vendor)s"} + roles = ['VENDOR_provider_A'] + policy.set_rules(oslo_policy.Rules.from_dict(rules), overwrite=True) + ctx = context.Context('fake', 'fake', roles=roles) + + # first request + mock_pkg_list.return_value = [pkg_a_1, pkg_b, pkg_a_2] + req = fake_request.HTTPRequest.blank('/vnf_packages') + req.headers['Content-Type'] = 'application/json' + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app_v1(fake_auth_context=ctx)) + self.assertEqual(http_client.OK, resp.status_code) + self.assertEqual( + [pkg_a_1.id], [pkg.get('id') for pkg in resp.json]) + + # second request with nextpage_opaque_marker + mock_pkg_list.return_value = [pkg_b, pkg_a_2] + mock_pkg_by_id.return_value = pkg_a_1 + req = fake_request.HTTPRequest.blank('/vnf_packages?' + f'nextpage_opaque_marker={pkg_a_1.id}') + req.headers['Content-Type'] = 'application/json' + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app_v1(fake_auth_context=ctx)) + self.assertEqual(http_client.OK, resp.status_code) + self.assertEqual( + [pkg_a_2.id], [pkg.get('id') for pkg in resp.json])