@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
@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:
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
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):
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(
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):
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):
# License for the specific language governing permissions and limitations
# under the License.
+import weakref
+
import fixtures
from oslo_config import cfg
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'))