diff --git a/neutron/plugins/bigswitch/l3_router_plugin.py b/neutron/plugins/bigswitch/l3_router_plugin.py new file mode 100644 index 0000000000..2b2529e444 --- /dev/null +++ b/neutron/plugins/bigswitch/l3_router_plugin.py @@ -0,0 +1,304 @@ +# Copyright 2014 Big Switch Networks, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +""" +Neutron L3 REST Proxy Plugin for Big Switch and Floodlight Controllers. + +This plugin handles the L3 router calls for Big Switch Floodlight deployments. +It is intended to be used in conjunction with the Big Switch ML2 driver or the +Big Switch core plugin. +""" + +from oslo.config import cfg + +from neutron.api import extensions as neutron_extensions +from neutron.common import exceptions +from neutron.common import log +from neutron.common import utils +from neutron.db import l3_db +from neutron.extensions import l3 +from neutron.openstack.common import excutils +from neutron.openstack.common import log as logging +from neutron.plugins.bigswitch import extensions +from neutron.plugins.bigswitch import plugin as cplugin +from neutron.plugins.bigswitch import routerrule_db +from neutron.plugins.bigswitch import servermanager +from neutron.plugins.common import constants + +# number of fields in a router rule string +ROUTER_RULE_COMPONENT_COUNT = 5 +LOG = logging.getLogger(__name__) +put_context_in_serverpool = cplugin.put_context_in_serverpool + + +class L3RestProxy(cplugin.NeutronRestProxyV2Base, + routerrule_db.RouterRule_db_mixin): + + supported_extension_aliases = ["router", "router_rules"] + + @staticmethod + def get_plugin_type(): + return constants.L3_ROUTER_NAT + + @staticmethod + def get_plugin_description(): + return _("L3 Router Service Plugin for Big Switch fabric") + + def __init__(self): + # Include the Big Switch Extensions path in the api_extensions + neutron_extensions.append_api_extensions_path(extensions.__path__) + super(L3RestProxy, self).__init__() + self.servers = servermanager.ServerPool.get_instance() + + @put_context_in_serverpool + @log.log + def create_router(self, context, router): + self._warn_on_state_status(router['router']) + + tenant_id = self._get_tenant_id_for_create(context, router["router"]) + + # set default router rules + rules = self._get_tenant_default_router_rules(tenant_id) + router['router']['router_rules'] = rules + + with context.session.begin(subtransactions=True): + # create router in DB + new_router = super(L3RestProxy, self).create_router(context, + router) + mapped_router = self._map_state_and_status(new_router) + self.servers.rest_create_router(tenant_id, mapped_router) + + # return created router + return new_router + + @put_context_in_serverpool + @log.log + def update_router(self, context, router_id, router): + self._warn_on_state_status(router['router']) + + orig_router = super(L3RestProxy, self).get_router(context, router_id) + tenant_id = orig_router["tenant_id"] + with context.session.begin(subtransactions=True): + new_router = super(L3RestProxy, + self).update_router(context, router_id, router) + router = self._map_state_and_status(new_router) + + # update router on network controller + self.servers.rest_update_router(tenant_id, router, router_id) + + # return updated router + return new_router + + # NOTE(kevinbenton): workaround for eventlet/mysql deadlock. + # delete_router ends up calling _delete_port instead of delete_port. + @utils.synchronized('bsn-port-barrier') + @put_context_in_serverpool + @log.log + def delete_router(self, context, router_id): + with context.session.begin(subtransactions=True): + orig_router = self._get_router(context, router_id) + tenant_id = orig_router["tenant_id"] + + # Ensure that the router is not used + router_filter = {'router_id': [router_id]} + fips = self.get_floatingips_count(context.elevated(), + filters=router_filter) + if fips: + raise l3.RouterInUse(router_id=router_id) + + device_owner = l3_db.DEVICE_OWNER_ROUTER_INTF + device_filter = {'device_id': [router_id], + 'device_owner': [device_owner]} + ports = self.get_ports_count(context.elevated(), + filters=device_filter) + if ports: + raise l3.RouterInUse(router_id=router_id) + super(L3RestProxy, self).delete_router(context, router_id) + + # delete from network controller + self.servers.rest_delete_router(tenant_id, router_id) + + @put_context_in_serverpool + @log.log + def add_router_interface(self, context, router_id, interface_info): + # Validate args + router = self._get_router(context, router_id) + tenant_id = router['tenant_id'] + + with context.session.begin(subtransactions=True): + # create interface in DB + new_intf_info = super(L3RestProxy, + self).add_router_interface(context, + router_id, + interface_info) + port = self._get_port(context, new_intf_info['port_id']) + net_id = port['network_id'] + subnet_id = new_intf_info['subnet_id'] + # we will use the port's network id as interface's id + interface_id = net_id + intf_details = self._get_router_intf_details(context, + interface_id, + subnet_id) + + # create interface on the network controller + self.servers.rest_add_router_interface(tenant_id, router_id, + intf_details) + return new_intf_info + + @put_context_in_serverpool + @log.log + def remove_router_interface(self, context, router_id, interface_info): + # Validate args + router = self._get_router(context, router_id) + tenant_id = router['tenant_id'] + + # we will first get the interface identifier before deleting in the DB + if not interface_info: + msg = _("Either subnet_id or port_id must be specified") + raise exceptions.BadRequest(resource='router', msg=msg) + if 'port_id' in interface_info: + port = self._get_port(context, interface_info['port_id']) + interface_id = port['network_id'] + elif 'subnet_id' in interface_info: + subnet = self._get_subnet(context, interface_info['subnet_id']) + interface_id = subnet['network_id'] + else: + msg = _("Either subnet_id or port_id must be specified") + raise exceptions.BadRequest(resource='router', msg=msg) + + with context.session.begin(subtransactions=True): + # remove router in DB + del_ret = super(L3RestProxy, + self).remove_router_interface(context, + router_id, + interface_info) + + # create router on the network controller + self.servers.rest_remove_router_interface(tenant_id, router_id, + interface_id) + return del_ret + + @put_context_in_serverpool + @log.log + def create_floatingip(self, context, floatingip): + with context.session.begin(subtransactions=True): + # create floatingip in DB + new_fl_ip = super(L3RestProxy, + self).create_floatingip(context, floatingip) + + # create floatingip on the network controller + try: + if 'floatingip' in self.servers.get_capabilities(): + self.servers.rest_create_floatingip( + new_fl_ip['tenant_id'], new_fl_ip) + else: + self._send_floatingip_update(context) + except servermanager.RemoteRestError as e: + with excutils.save_and_reraise_exception(): + LOG.error( + _("NeutronRestProxyV2: Unable to create remote " + "floating IP: %s"), e) + # return created floating IP + return new_fl_ip + + @put_context_in_serverpool + @log.log + def update_floatingip(self, context, id, floatingip): + with context.session.begin(subtransactions=True): + # update floatingip in DB + new_fl_ip = super(L3RestProxy, + self).update_floatingip(context, id, floatingip) + + # update network on network controller + if 'floatingip' in self.servers.get_capabilities(): + self.servers.rest_update_floatingip(new_fl_ip['tenant_id'], + new_fl_ip, id) + else: + self._send_floatingip_update(context) + return new_fl_ip + + @put_context_in_serverpool + @log.log + def delete_floatingip(self, context, id): + with context.session.begin(subtransactions=True): + # delete floating IP in DB + old_fip = super(L3RestProxy, self).get_floatingip(context, id) + super(L3RestProxy, self).delete_floatingip(context, id) + + # update network on network controller + if 'floatingip' in self.servers.get_capabilities(): + self.servers.rest_delete_floatingip(old_fip['tenant_id'], id) + else: + self._send_floatingip_update(context) + + @put_context_in_serverpool + @log.log + def disassociate_floatingips(self, context, port_id, do_notify=True): + router_ids = super(L3RestProxy, self).disassociate_floatingips( + context, port_id, do_notify=do_notify) + self._send_floatingip_update(context) + return router_ids + + # overriding method from l3_db as original method calls + # self.delete_floatingip() which in turn calls self.delete_port() which + # is locked with 'bsn-port-barrier' + @put_context_in_serverpool + def delete_disassociated_floatingips(self, context, network_id): + query = self._model_query(context, l3_db.FloatingIP) + query = query.filter_by(floating_network_id=network_id, + fixed_port_id=None, + router_id=None) + for fip in query: + context.session.delete(fip) + self._delete_port(context.elevated(), fip['floating_port_id']) + + def _send_floatingip_update(self, context): + try: + ext_net_id = self.get_external_network_id(context) + if ext_net_id: + # Use the elevated state of the context for the ext_net query + admin_context = context.elevated() + ext_net = super(L3RestProxy, + self).get_network(admin_context, ext_net_id) + # update external network on network controller + self._send_update_network(ext_net, admin_context) + except exceptions.TooManyExternalNetworks: + # get_external_network can raise errors when multiple external + # networks are detected, which isn't supported by the Plugin + LOG.error(_("NeutronRestProxyV2: too many external networks")) + + def _get_tenant_default_router_rules(self, tenant): + rules = cfg.CONF.ROUTER.tenant_default_router_rule + default_set = [] + tenant_set = [] + for rule in rules: + items = rule.split(':') + # put an empty string on the end if nexthops wasn't specified + if len(items) < ROUTER_RULE_COMPONENT_COUNT: + items.append('') + try: + (tenant_id, source, destination, action, nexthops) = items + except ValueError: + continue + parsed_rule = {'source': source, + 'destination': destination, 'action': action, + 'nexthops': [hop for hop in nexthops.split(',') + if hop]} + if tenant_id == '*': + default_set.append(parsed_rule) + if tenant_id == tenant: + tenant_set.append(parsed_rule) + return tenant_set if tenant_set else default_set diff --git a/neutron/plugins/bigswitch/plugin.py b/neutron/plugins/bigswitch/plugin.py index 78ed005c7b..728a5dd0cd 100644 --- a/neutron/plugins/bigswitch/plugin.py +++ b/neutron/plugins/bigswitch/plugin.py @@ -77,18 +77,16 @@ from neutron.db import securitygroups_rpc_base as sg_db_rpc from neutron.extensions import allowedaddresspairs as addr_pair from neutron.extensions import external_net from neutron.extensions import extra_dhcp_opt as edo_ext -from neutron.extensions import l3 from neutron.extensions import portbindings from neutron import manager -from neutron.openstack.common import excutils from neutron.openstack.common import importutils from neutron.openstack.common import log as logging from neutron.plugins.bigswitch import config as pl_config from neutron.plugins.bigswitch.db import porttracker_db from neutron.plugins.bigswitch import extensions -from neutron.plugins.bigswitch import routerrule_db from neutron.plugins.bigswitch import servermanager from neutron.plugins.bigswitch import version +from neutron.plugins.common import constants as pconst LOG = logging.getLogger(__name__) @@ -154,12 +152,16 @@ class SecurityGroupServerRpcMixin(sg_db_rpc.SecurityGroupServerRpcMixin): class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2, - external_net_db.External_net_db_mixin, - routerrule_db.RouterRule_db_mixin): + external_net_db.External_net_db_mixin): supported_extension_aliases = ["binding"] servers = None + @property + def l3_plugin(self): + return manager.NeutronManager.get_service_plugins().get( + pconst.L3_ROUTER_NAT) + def _get_all_data(self, get_ports=True, get_floating_ips=True, get_routers=True): admin_context = qcontext.get_admin_context() @@ -196,9 +198,9 @@ class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2, data = {'networks': networks} - if get_routers: + if get_routers and self.l3_plugin: routers = [] - all_routers = self.get_routers(admin_context) or [] + all_routers = self.l3_plugin.get_routers(admin_context) or [] for router in all_routers: interfaces = [] mapped_router = self._map_state_and_status(router) @@ -242,9 +244,10 @@ class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2, net_id = network['id'] net_filter = {'floating_network_id': [net_id]} - fl_ips = self.get_floatingips(context, - filters=net_filter) or [] - network['floatingips'] = fl_ips + if self.l3_plugin: + fl_ips = self.l3_plugin.get_floatingips(context, + filters=net_filter) or [] + network['floatingips'] = fl_ips return network @@ -454,8 +457,8 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base, agentschedulers_db.DhcpAgentSchedulerDbMixin, SecurityGroupServerRpcMixin): - _supported_extension_aliases = ["external-net", "router", "binding", - "router_rules", "extra_dhcp_opt", "quotas", + _supported_extension_aliases = ["external-net", "binding", + "extra_dhcp_opt", "quotas", "dhcp_agent_scheduler", "agent", "security-group", "allowed-address-pairs"] @@ -805,11 +808,12 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base, # if needed, check to see if this is a port owned by # and l3-router. If so, we should prevent deletion. - if l3_port_check: - self.prevent_l3_port_deletion(context, port_id) + if l3_port_check and self.l3_plugin: + self.l3_plugin.prevent_l3_port_deletion(context, port_id) with context.session.begin(subtransactions=True): - router_ids = self.disassociate_floatingips( - context, port_id, do_notify=False) + if self.l3_plugin: + router_ids = self.l3_plugin.disassociate_floatingips( + context, port_id, do_notify=False) self._delete_port_security_group_bindings(context, port_id) port = super(NeutronRestProxyV2, self).get_port(context, port_id) # Tenant ID must come from network in case the network is shared @@ -817,8 +821,9 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base, self._delete_port(context, port_id) self.servers.rest_delete_port(tenid, port['network_id'], port_id) - # now that we've left db transaction, we are safe to notify - self.notify_routers_updated(context, router_ids) + if self.l3_plugin: + # now that we've left db transaction, we are safe to notify + self.l3_plugin.notify_routers_updated(context, router_ids) @put_context_in_serverpool def create_subnet(self, context, subnet): @@ -869,264 +874,6 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base, # update network on network controller - exception will rollback self._send_update_network(orig_net, context) - def _get_tenant_default_router_rules(self, tenant): - rules = cfg.CONF.ROUTER.tenant_default_router_rule - defaultset = [] - tenantset = [] - for rule in rules: - items = rule.split(':') - if len(items) == 5: - (tenantid, source, destination, action, nexthops) = items - elif len(items) == 4: - (tenantid, source, destination, action) = items - nexthops = '' - else: - continue - parsedrule = {'source': source, - 'destination': destination, 'action': action, - 'nexthops': nexthops.split(',')} - if parsedrule['nexthops'][0] == '': - parsedrule['nexthops'] = [] - if tenantid == '*': - defaultset.append(parsedrule) - if tenantid == tenant: - tenantset.append(parsedrule) - if tenantset: - return tenantset - return defaultset - - @put_context_in_serverpool - def create_router(self, context, router): - LOG.debug(_("NeutronRestProxyV2: create_router() called")) - - self._warn_on_state_status(router['router']) - - tenant_id = self._get_tenant_id_for_create(context, router["router"]) - - # set default router rules - rules = self._get_tenant_default_router_rules(tenant_id) - router['router']['router_rules'] = rules - - with context.session.begin(subtransactions=True): - # create router in DB - new_router = super(NeutronRestProxyV2, self).create_router(context, - router) - mapped_router = self._map_state_and_status(new_router) - self.servers.rest_create_router(tenant_id, mapped_router) - - # return created router - return new_router - - @put_context_in_serverpool - def update_router(self, context, router_id, router): - - LOG.debug(_("NeutronRestProxyV2.update_router() called")) - - self._warn_on_state_status(router['router']) - - orig_router = super(NeutronRestProxyV2, self).get_router(context, - router_id) - tenant_id = orig_router["tenant_id"] - with context.session.begin(subtransactions=True): - new_router = super(NeutronRestProxyV2, - self).update_router(context, router_id, router) - router = self._map_state_and_status(new_router) - - # update router on network controller - self.servers.rest_update_router(tenant_id, router, router_id) - - # return updated router - return new_router - - # NOTE(kevinbenton): workaround for eventlet/mysql deadlock. - # delete_router ends up calling _delete_port instead of delete_port. - @utils.synchronized('bsn-port-barrier') - @put_context_in_serverpool - def delete_router(self, context, router_id): - LOG.debug(_("NeutronRestProxyV2: delete_router() called")) - - with context.session.begin(subtransactions=True): - orig_router = self._get_router(context, router_id) - tenant_id = orig_router["tenant_id"] - - # Ensure that the router is not used - router_filter = {'router_id': [router_id]} - fips = self.get_floatingips_count(context.elevated(), - filters=router_filter) - if fips: - raise l3.RouterInUse(router_id=router_id) - - device_owner = l3_db.DEVICE_OWNER_ROUTER_INTF - device_filter = {'device_id': [router_id], - 'device_owner': [device_owner]} - ports = self.get_ports_count(context.elevated(), - filters=device_filter) - if ports: - raise l3.RouterInUse(router_id=router_id) - ret_val = super(NeutronRestProxyV2, - self).delete_router(context, router_id) - - # delete from network ctrl - self.servers.rest_delete_router(tenant_id, router_id) - return ret_val - - @put_context_in_serverpool - def add_router_interface(self, context, router_id, interface_info): - - LOG.debug(_("NeutronRestProxyV2: add_router_interface() called")) - - # Validate args - router = self._get_router(context, router_id) - tenant_id = router['tenant_id'] - - with context.session.begin(subtransactions=True): - # create interface in DB - new_intf_info = super(NeutronRestProxyV2, - self).add_router_interface(context, - router_id, - interface_info) - port = self._get_port(context, new_intf_info['port_id']) - net_id = port['network_id'] - subnet_id = new_intf_info['subnet_id'] - # we will use the port's network id as interface's id - interface_id = net_id - intf_details = self._get_router_intf_details(context, - interface_id, - subnet_id) - - # create interface on the network controller - self.servers.rest_add_router_interface(tenant_id, router_id, - intf_details) - return new_intf_info - - @put_context_in_serverpool - def remove_router_interface(self, context, router_id, interface_info): - - LOG.debug(_("NeutronRestProxyV2: remove_router_interface() called")) - - # Validate args - router = self._get_router(context, router_id) - tenant_id = router['tenant_id'] - - # we will first get the interface identifier before deleting in the DB - if not interface_info: - msg = _("Either subnet_id or port_id must be specified") - raise exceptions.BadRequest(resource='router', msg=msg) - if 'port_id' in interface_info: - port = self._get_port(context, interface_info['port_id']) - interface_id = port['network_id'] - elif 'subnet_id' in interface_info: - subnet = self._get_subnet(context, interface_info['subnet_id']) - interface_id = subnet['network_id'] - else: - msg = _("Either subnet_id or port_id must be specified") - raise exceptions.BadRequest(resource='router', msg=msg) - - with context.session.begin(subtransactions=True): - # remove router in DB - del_ret = super(NeutronRestProxyV2, - self).remove_router_interface(context, - router_id, - interface_info) - - # create router on the network controller - self.servers.rest_remove_router_interface(tenant_id, router_id, - interface_id) - return del_ret - - @put_context_in_serverpool - def create_floatingip(self, context, floatingip): - LOG.debug(_("NeutronRestProxyV2: create_floatingip() called")) - - with context.session.begin(subtransactions=True): - # create floatingip in DB - new_fl_ip = super(NeutronRestProxyV2, - self).create_floatingip(context, floatingip) - - # create floatingip on the network controller - try: - if 'floatingip' in self.servers.get_capabilities(): - self.servers.rest_create_floatingip( - new_fl_ip['tenant_id'], new_fl_ip) - else: - self._send_floatingip_update(context) - except servermanager.RemoteRestError as e: - with excutils.save_and_reraise_exception(): - LOG.error( - _("NeutronRestProxyV2: Unable to create remote " - "floating IP: %s"), e) - # return created floating IP - return new_fl_ip - - @put_context_in_serverpool - def update_floatingip(self, context, id, floatingip): - LOG.debug(_("NeutronRestProxyV2: update_floatingip() called")) - - with context.session.begin(subtransactions=True): - # update floatingip in DB - new_fl_ip = super(NeutronRestProxyV2, - self).update_floatingip(context, id, floatingip) - - # update network on network controller - if 'floatingip' in self.servers.get_capabilities(): - self.servers.rest_update_floatingip(new_fl_ip['tenant_id'], - new_fl_ip, id) - else: - self._send_floatingip_update(context) - return new_fl_ip - - @put_context_in_serverpool - def delete_floatingip(self, context, id): - LOG.debug(_("NeutronRestProxyV2: delete_floatingip() called")) - - with context.session.begin(subtransactions=True): - # delete floating IP in DB - old_fip = super(NeutronRestProxyV2, self).get_floatingip(context, - id) - super(NeutronRestProxyV2, self).delete_floatingip(context, id) - - # update network on network controller - if 'floatingip' in self.servers.get_capabilities(): - self.servers.rest_delete_floatingip(old_fip['tenant_id'], id) - else: - self._send_floatingip_update(context) - - @put_context_in_serverpool - def disassociate_floatingips(self, context, port_id, do_notify=True): - LOG.debug(_("NeutronRestProxyV2: diassociate_floatingips() called")) - router_ids = super(NeutronRestProxyV2, self).disassociate_floatingips( - context, port_id, do_notify=do_notify) - self._send_floatingip_update(context) - return router_ids - - # overriding method from l3_db as original method calls - # self.delete_floatingip() which in turn calls self.delete_port() which - # is locked with 'bsn-port-barrier' - @put_context_in_serverpool - def delete_disassociated_floatingips(self, context, network_id): - query = self._model_query(context, l3_db.FloatingIP) - query = query.filter_by(floating_network_id=network_id, - fixed_port_id=None, - router_id=None) - for fip in query: - context.session.delete(fip) - self._delete_port(context.elevated(), fip['floating_port_id']) - - def _send_floatingip_update(self, context): - try: - ext_net_id = self.get_external_network_id(context) - if ext_net_id: - # Use the elevated state of the context for the ext_net query - admin_context = context.elevated() - ext_net = super(NeutronRestProxyV2, - self).get_network(admin_context, ext_net_id) - # update external network on network controller - self._send_update_network(ext_net, admin_context) - except exceptions.TooManyExternalNetworks: - # get_external_network can raise errors when multiple external - # networks are detected, which isn't supported by the Plugin - LOG.error(_("NeutronRestProxyV2: too many external networks")) - def _add_host_route(self, context, destination, port): subnet = {} for fixed_ip in port['fixed_ips']: diff --git a/neutron/plugins/bigswitch/servermanager.py b/neutron/plugins/bigswitch/servermanager.py index bc070c2e75..68d62e6cc7 100644 --- a/neutron/plugins/bigswitch/servermanager.py +++ b/neutron/plugins/bigswitch/servermanager.py @@ -228,6 +228,15 @@ class ServerProxy(object): class ServerPool(object): + _instance = None + + @classmethod + def get_instance(cls): + if cls._instance: + return cls._instance + cls._instance = cls() + return cls._instance + def __init__(self, timeout=False, base_uri=BASE_URI, name='NeutronRestProxy'): LOG.debug(_("ServerPool: initializing")) @@ -268,6 +277,7 @@ class ServerPool(object): ] eventlet.spawn(self._consistency_watchdog, cfg.CONF.RESTPROXY.consistency_interval) + ServerPool._instance = self LOG.debug(_("ServerPool: initialization done")) def set_context(self, context): diff --git a/neutron/tests/unit/bigswitch/etc/restproxy.ini.test b/neutron/tests/unit/bigswitch/etc/restproxy.ini.test index 8df78a6eb0..b6ac26e7e0 100644 --- a/neutron/tests/unit/bigswitch/etc/restproxy.ini.test +++ b/neutron/tests/unit/bigswitch/etc/restproxy.ini.test @@ -1,4 +1,6 @@ # Test config file for quantum-proxy-plugin. +[DEFAULT] +service_plugins = bigswitch_l3 [database] # This line MUST be changed to actually run the plugin. diff --git a/neutron/tests/unit/bigswitch/test_base.py b/neutron/tests/unit/bigswitch/test_base.py index e74024c7cc..e31760e4ff 100644 --- a/neutron/tests/unit/bigswitch/test_base.py +++ b/neutron/tests/unit/bigswitch/test_base.py @@ -25,6 +25,7 @@ from neutron.tests.unit.bigswitch import fake_server RESTPROXY_PKG_PATH = 'neutron.plugins.bigswitch.plugin' +L3_RESTPROXY_PKG_PATH = 'neutron.plugins.bigswitch.l3_router_plugin' NOTIFIER = 'neutron.plugins.bigswitch.plugin.AgentNotifierApi' CERTFETCH = 'neutron.plugins.bigswitch.servermanager.ServerPool._fetch_cert' SERVER_MANAGER = 'neutron.plugins.bigswitch.servermanager' @@ -36,6 +37,7 @@ CWATCH = SERVER_MANAGER + '.ServerPool._consistency_watchdog' class BigSwitchTestBase(object): _plugin_name = ('%s.NeutronRestProxyV2' % RESTPROXY_PKG_PATH) + _l3_plugin_name = ('%s.L3RestProxy' % L3_RESTPROXY_PKG_PATH) def setup_config_files(self): etc_path = os.path.join(os.path.dirname(__file__), 'etc') @@ -49,6 +51,7 @@ class BigSwitchTestBase(object): os.path.join(etc_path, 'ssl'), 'RESTPROXY') # The mock interferes with HTTP(S) connection caching cfg.CONF.set_override('cache_connections', False, 'RESTPROXY') + cfg.CONF.set_override('service_plugins', ['bigswitch_l3']) def setup_patches(self): self.plugin_notifier_p = mock.patch(NOTIFIER) diff --git a/neutron/tests/unit/bigswitch/test_restproxy_plugin.py b/neutron/tests/unit/bigswitch/test_restproxy_plugin.py index 81b3749618..7a5a12f082 100644 --- a/neutron/tests/unit/bigswitch/test_restproxy_plugin.py +++ b/neutron/tests/unit/bigswitch/test_restproxy_plugin.py @@ -45,8 +45,9 @@ class BigSwitchProxyPluginV2TestCase(test_base.BigSwitchTestBase, self.setup_patches() if plugin_name: self._plugin_name = plugin_name + service_plugins = {'L3_ROUTER_NAT': self._l3_plugin_name} super(BigSwitchProxyPluginV2TestCase, - self).setUp(self._plugin_name) + self).setUp(self._plugin_name, service_plugins=service_plugins) self.port_create_status = 'BUILD' self.startHttpPatch() @@ -310,6 +311,6 @@ class TestBigSwitchProxySync(BigSwitchProxyPluginV2TestCase): self.assertEqual(result[0], 200) -class TestBigSwitchAddressPairs(BigSwitchProxyPluginV2TestCase, - test_addr_pair.TestAllowedAddressPairs): +class TestBigSwitchAddressPairs(test_addr_pair.TestAllowedAddressPairs, + BigSwitchProxyPluginV2TestCase): pass diff --git a/neutron/tests/unit/bigswitch/test_router_db.py b/neutron/tests/unit/bigswitch/test_router_db.py index 9fbbb8347e..e206d4fdd5 100644 --- a/neutron/tests/unit/bigswitch/test_router_db.py +++ b/neutron/tests/unit/bigswitch/test_router_db.py @@ -70,14 +70,19 @@ class RouterDBTestBase(test_base.BigSwitchTestBase, test_l3_plugin.L3BaseForIntTests, test_l3_plugin.L3NatTestCaseMixin): + mock_rescheduling = False + def setUp(self): self.setup_patches() self.setup_config_files() ext_mgr = RouterRulesTestExtensionManager() + service_plugins = {'L3_ROUTER_NAT': self._l3_plugin_name} super(RouterDBTestBase, self).setUp(plugin=self._plugin_name, - ext_mgr=ext_mgr) + ext_mgr=ext_mgr, + service_plugins=service_plugins) cfg.CONF.set_default('allow_overlapping_ips', False) - self.plugin_obj = manager.NeutronManager.get_plugin() + self.plugin_obj = manager.NeutronManager.get_service_plugins().get( + 'L3_ROUTER_NAT') self.startHttpPatch() def tearDown(self): diff --git a/setup.cfg b/setup.cfg index 6e4f50f73f..056698ab45 100644 --- a/setup.cfg +++ b/setup.cfg @@ -147,6 +147,7 @@ neutron.core_plugins = neutron.service_plugins = dummy = neutron.tests.unit.dummy_plugin:DummyServicePlugin router = neutron.services.l3_router.l3_router_plugin:L3RouterPlugin + bigswitch_l3 = neutron.plugins.bigswitch.l3_router_plugin:L3RestProxy firewall = neutron.services.firewall.fwaas_plugin:FirewallPlugin lbaas = neutron.services.loadbalancer.plugin:LoadBalancerPlugin vpnaas = neutron.services.vpn.plugin:VPNDriverPlugin