]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Pecan controller loads service plugins
authorBrandon Logan <brandon.logan@rackspace.com>
Tue, 29 Dec 2015 08:41:48 +0000 (02:41 -0600)
committerKevin Benton <blak111@gmail.com>
Tue, 12 Jan 2016 20:28:54 +0000 (12:28 -0800)
The pecan controllers were not parsing out the case when a service
plugin is being used that changes the URI to
/v2.0/service_plugin/resource

This will check to see if the first resource after v2.0 is an
extension to a service plugin, and if it is it'll check the next
resource for a controller.

Change-Id: I9b6bd7afbbe91f1c8f0c1835b320dc41bfccff3f

neutron/manager.py
neutron/pecan_wsgi/controllers/root.py
neutron/tests/functional/pecan_wsgi/test_functional.py
neutron/tests/unit/test_manager.py

index 65b31ac3c8934e1c17e8a8048a0872645be84e3d..fcbf78ac2ca86b737d2d7f146018c7693ef1de8c 100644 (file)
@@ -254,3 +254,11 @@ class NeutronManager(object):
     @classmethod
     def get_controller_for_resource(cls, resource):
         return cls.get_instance().resource_controller_mappings.get(resource)
+
+    @classmethod
+    def get_service_plugin_by_path_prefix(cls, path_prefix):
+        service_plugins = cls.get_unique_service_plugins()
+        for service_plugin in service_plugins:
+            plugin_path_prefix = getattr(service_plugin, 'path_prefix', None)
+            if plugin_path_prefix and plugin_path_prefix == path_prefix:
+                return service_plugin
index 15b509d5e1ac08e85e176e6cd28a18823275f801..e796112febde6986ff958ba4426b3fa573473b2a 100644 (file)
@@ -104,6 +104,15 @@ class V2Controller(object):
 
     @expose()
     def _lookup(self, collection, *remainder):
+        # if collection exists in the extension to service plugins map then
+        # we are assuming that collection is the service plugin and
+        # needs to be remapped.
+        # Example: https://neutron.endpoint/v2.0/lbaas/loadbalancers
+        if (remainder and
+                manager.NeutronManager.get_service_plugin_by_path_prefix(
+                    collection)):
+            collection = remainder[0]
+            remainder = remainder[1:]
         controller = manager.NeutronManager.get_controller_for_resource(
             collection)
         if not controller:
index 96c4207494b088e5150ed3bf4f01b78d6c1bbd51..69e68c6239152fed31f43c90013eee7dbb7a0488 100644 (file)
 
 import os
 
+from collections import namedtuple
 import mock
 from oslo_config import cfg
 from oslo_serialization import jsonutils
 from oslo_utils import uuidutils
+import pecan
 from pecan import request
 from pecan import set_config
 from pecan.testing import load_test_app
@@ -32,6 +34,20 @@ from neutron import manager
 from neutron.pecan_wsgi.controllers import root as controllers
 from neutron.tests.unit import testlib_api
 
+_SERVICE_PLUGIN_RESOURCE = 'serviceplugin'
+_SERVICE_PLUGIN_COLLECTION = _SERVICE_PLUGIN_RESOURCE + 's'
+_SERVICE_PLUGIN_INDEX_BODY = {_SERVICE_PLUGIN_COLLECTION: []}
+
+
+class FakeServicePluginController(object):
+    resource = _SERVICE_PLUGIN_RESOURCE
+
+    @pecan.expose(generic=True,
+                  content_type='application/json',
+                  template='json')
+    def index(self):
+        return _SERVICE_PLUGIN_INDEX_BODY
+
 
 class PecanFunctionalTest(testlib_api.SqlTestCase):
 
@@ -42,6 +58,7 @@ class PecanFunctionalTest(testlib_api.SqlTestCase):
         self.addCleanup(set_config, {}, overwrite=True)
         self.set_config_overrides()
         self.setup_app()
+        self.setup_service_plugin()
 
     def setup_app(self):
         self.app = load_test_app(os.path.join(
@@ -67,6 +84,10 @@ class PecanFunctionalTest(testlib_api.SqlTestCase):
     def set_config_overrides(self):
         cfg.CONF.set_override('auth_strategy', 'noauth')
 
+    def setup_service_plugin(self):
+        manager.NeutronManager.set_controller_for_resource(
+            _SERVICE_PLUGIN_COLLECTION, FakeServicePluginController())
+
 
 class TestV2Controller(PecanFunctionalTest):
 
@@ -104,6 +125,15 @@ class TestV2Controller(PecanFunctionalTest):
         response = self.app.get('/v2.0/extensions/allowed-address-pairs.json')
         self.assertEqual(response.status_int, 200)
 
+    def test_service_plugin_uri(self):
+        service_plugin = namedtuple('DummyServicePlugin', 'path_prefix')
+        service_plugin.path_prefix = 'dummy'
+        nm = manager.NeutronManager.get_instance()
+        nm.service_plugins['dummy_sp'] = service_plugin
+        response = self.app.get('/v2.0/dummy/serviceplugins.json')
+        self.assertEqual(200, response.status_int)
+        self.assertEqual(_SERVICE_PLUGIN_INDEX_BODY, response.json_body)
+
 
 class TestErrors(PecanFunctionalTest):
 
index 80b0a31a03aa11a53d516922cdcb10e945a20751..c90d040513292e1469b7ec6c535cbb793b56231e 100644 (file)
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import weakref
+
 import fixtures
 from oslo_config import cfg
 
@@ -147,3 +149,20 @@ class NeutronManagerTestCase(base.BaseTestCase):
         with testlib_api.ExpectedException(ImportError):
             manager.NeutronManager.load_class_for_provider(
                     'neutron.core_plugins', 'ml2XXXXXX')
+
+    def test_get_service_plugin_by_path_prefix_3(self):
+        cfg.CONF.set_override("core_plugin", DB_PLUGIN_KLASS)
+        nm = manager.NeutronManager.get_instance()
+
+        class pclass(object):
+            def __init__(self, path_prefix):
+                self.path_prefix = path_prefix
+
+        x_plugin, y_plugin = pclass('xpa'), pclass('ypa')
+        nm.service_plugins['x'], nm.service_plugins['y'] = x_plugin, y_plugin
+
+        self.assertEqual(weakref.proxy(x_plugin),
+                         nm.get_service_plugin_by_path_prefix('xpa'))
+        self.assertEqual(weakref.proxy(y_plugin),
+                         nm.get_service_plugin_by_path_prefix('ypa'))
+        self.assertIsNone(nm.get_service_plugin_by_path_prefix('abc'))