Pecan controller loads service plugins

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
This commit is contained in:
Brandon Logan 2015-12-29 02:41:48 -06:00 committed by Kevin Benton
parent a6547e9cf0
commit a6ab3badd1
4 changed files with 66 additions and 0 deletions

View 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

View 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:

View File

@ -15,10 +15,12 @@
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):

View 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'))