Big Switch: Separate L3 functions into L3 service

Separate the L3 functions from the core Big Switch
plugin into an L3 service plugin. This is will allow
the L3 functions to be used in ML2 deployments that
use the Big Switch ML2 driver.

DocImpact

Implements: blueprint bsn-l3-service-plugin
Change-Id: I889db0047fb9a85f02d1fb95b9c099e9243a5bb5
This commit is contained in:
Kevin Benton 2014-08-12 14:04:24 -07:00
parent f3305bbd7e
commit c9443e5662
8 changed files with 354 additions and 281 deletions

View File

@ -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

View File

@ -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 allowedaddresspairs as addr_pair
from neutron.extensions import external_net from neutron.extensions import external_net
from neutron.extensions import extra_dhcp_opt as edo_ext from neutron.extensions import extra_dhcp_opt as edo_ext
from neutron.extensions import l3
from neutron.extensions import portbindings from neutron.extensions import portbindings
from neutron import manager from neutron import manager
from neutron.openstack.common import excutils
from neutron.openstack.common import importutils from neutron.openstack.common import importutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
from neutron.plugins.bigswitch import config as pl_config from neutron.plugins.bigswitch import config as pl_config
from neutron.plugins.bigswitch.db import porttracker_db from neutron.plugins.bigswitch.db import porttracker_db
from neutron.plugins.bigswitch import extensions from neutron.plugins.bigswitch import extensions
from neutron.plugins.bigswitch import routerrule_db
from neutron.plugins.bigswitch import servermanager from neutron.plugins.bigswitch import servermanager
from neutron.plugins.bigswitch import version from neutron.plugins.bigswitch import version
from neutron.plugins.common import constants as pconst
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -154,12 +152,16 @@ class SecurityGroupServerRpcMixin(sg_db_rpc.SecurityGroupServerRpcMixin):
class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2, class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2,
external_net_db.External_net_db_mixin, external_net_db.External_net_db_mixin):
routerrule_db.RouterRule_db_mixin):
supported_extension_aliases = ["binding"] supported_extension_aliases = ["binding"]
servers = None 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, def _get_all_data(self, get_ports=True, get_floating_ips=True,
get_routers=True): get_routers=True):
admin_context = qcontext.get_admin_context() admin_context = qcontext.get_admin_context()
@ -196,9 +198,9 @@ class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2,
data = {'networks': networks} data = {'networks': networks}
if get_routers: if get_routers and self.l3_plugin:
routers = [] routers = []
all_routers = self.get_routers(admin_context) or [] all_routers = self.l3_plugin.get_routers(admin_context) or []
for router in all_routers: for router in all_routers:
interfaces = [] interfaces = []
mapped_router = self._map_state_and_status(router) mapped_router = self._map_state_and_status(router)
@ -242,9 +244,10 @@ class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2,
net_id = network['id'] net_id = network['id']
net_filter = {'floating_network_id': [net_id]} net_filter = {'floating_network_id': [net_id]}
fl_ips = self.get_floatingips(context, if self.l3_plugin:
filters=net_filter) or [] fl_ips = self.l3_plugin.get_floatingips(context,
network['floatingips'] = fl_ips filters=net_filter) or []
network['floatingips'] = fl_ips
return network return network
@ -454,8 +457,8 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base,
agentschedulers_db.DhcpAgentSchedulerDbMixin, agentschedulers_db.DhcpAgentSchedulerDbMixin,
SecurityGroupServerRpcMixin): SecurityGroupServerRpcMixin):
_supported_extension_aliases = ["external-net", "router", "binding", _supported_extension_aliases = ["external-net", "binding",
"router_rules", "extra_dhcp_opt", "quotas", "extra_dhcp_opt", "quotas",
"dhcp_agent_scheduler", "agent", "dhcp_agent_scheduler", "agent",
"security-group", "allowed-address-pairs"] "security-group", "allowed-address-pairs"]
@ -805,11 +808,12 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base,
# if needed, check to see if this is a port owned by # if needed, check to see if this is a port owned by
# and l3-router. If so, we should prevent deletion. # and l3-router. If so, we should prevent deletion.
if l3_port_check: if l3_port_check and self.l3_plugin:
self.prevent_l3_port_deletion(context, port_id) self.l3_plugin.prevent_l3_port_deletion(context, port_id)
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
router_ids = self.disassociate_floatingips( if self.l3_plugin:
context, port_id, do_notify=False) router_ids = self.l3_plugin.disassociate_floatingips(
context, port_id, do_notify=False)
self._delete_port_security_group_bindings(context, port_id) self._delete_port_security_group_bindings(context, port_id)
port = super(NeutronRestProxyV2, self).get_port(context, port_id) port = super(NeutronRestProxyV2, self).get_port(context, port_id)
# Tenant ID must come from network in case the network is shared # 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._delete_port(context, port_id)
self.servers.rest_delete_port(tenid, port['network_id'], 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 if self.l3_plugin:
self.notify_routers_updated(context, router_ids) # 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 @put_context_in_serverpool
def create_subnet(self, context, subnet): def create_subnet(self, context, subnet):
@ -869,264 +874,6 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base,
# update network on network controller - exception will rollback # update network on network controller - exception will rollback
self._send_update_network(orig_net, context) 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): def _add_host_route(self, context, destination, port):
subnet = {} subnet = {}
for fixed_ip in port['fixed_ips']: for fixed_ip in port['fixed_ips']:

View File

@ -228,6 +228,15 @@ class ServerProxy(object):
class ServerPool(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, def __init__(self, timeout=False,
base_uri=BASE_URI, name='NeutronRestProxy'): base_uri=BASE_URI, name='NeutronRestProxy'):
LOG.debug(_("ServerPool: initializing")) LOG.debug(_("ServerPool: initializing"))
@ -268,6 +277,7 @@ class ServerPool(object):
] ]
eventlet.spawn(self._consistency_watchdog, eventlet.spawn(self._consistency_watchdog,
cfg.CONF.RESTPROXY.consistency_interval) cfg.CONF.RESTPROXY.consistency_interval)
ServerPool._instance = self
LOG.debug(_("ServerPool: initialization done")) LOG.debug(_("ServerPool: initialization done"))
def set_context(self, context): def set_context(self, context):

View File

@ -1,4 +1,6 @@
# Test config file for quantum-proxy-plugin. # Test config file for quantum-proxy-plugin.
[DEFAULT]
service_plugins = bigswitch_l3
[database] [database]
# This line MUST be changed to actually run the plugin. # This line MUST be changed to actually run the plugin.

View File

@ -25,6 +25,7 @@ from neutron.tests.unit.bigswitch import fake_server
RESTPROXY_PKG_PATH = 'neutron.plugins.bigswitch.plugin' RESTPROXY_PKG_PATH = 'neutron.plugins.bigswitch.plugin'
L3_RESTPROXY_PKG_PATH = 'neutron.plugins.bigswitch.l3_router_plugin'
NOTIFIER = 'neutron.plugins.bigswitch.plugin.AgentNotifierApi' NOTIFIER = 'neutron.plugins.bigswitch.plugin.AgentNotifierApi'
CERTFETCH = 'neutron.plugins.bigswitch.servermanager.ServerPool._fetch_cert' CERTFETCH = 'neutron.plugins.bigswitch.servermanager.ServerPool._fetch_cert'
SERVER_MANAGER = 'neutron.plugins.bigswitch.servermanager' SERVER_MANAGER = 'neutron.plugins.bigswitch.servermanager'
@ -36,6 +37,7 @@ CWATCH = SERVER_MANAGER + '.ServerPool._consistency_watchdog'
class BigSwitchTestBase(object): class BigSwitchTestBase(object):
_plugin_name = ('%s.NeutronRestProxyV2' % RESTPROXY_PKG_PATH) _plugin_name = ('%s.NeutronRestProxyV2' % RESTPROXY_PKG_PATH)
_l3_plugin_name = ('%s.L3RestProxy' % L3_RESTPROXY_PKG_PATH)
def setup_config_files(self): def setup_config_files(self):
etc_path = os.path.join(os.path.dirname(__file__), 'etc') etc_path = os.path.join(os.path.dirname(__file__), 'etc')
@ -49,6 +51,7 @@ class BigSwitchTestBase(object):
os.path.join(etc_path, 'ssl'), 'RESTPROXY') os.path.join(etc_path, 'ssl'), 'RESTPROXY')
# The mock interferes with HTTP(S) connection caching # The mock interferes with HTTP(S) connection caching
cfg.CONF.set_override('cache_connections', False, 'RESTPROXY') cfg.CONF.set_override('cache_connections', False, 'RESTPROXY')
cfg.CONF.set_override('service_plugins', ['bigswitch_l3'])
def setup_patches(self): def setup_patches(self):
self.plugin_notifier_p = mock.patch(NOTIFIER) self.plugin_notifier_p = mock.patch(NOTIFIER)

View File

@ -45,8 +45,9 @@ class BigSwitchProxyPluginV2TestCase(test_base.BigSwitchTestBase,
self.setup_patches() self.setup_patches()
if plugin_name: if plugin_name:
self._plugin_name = plugin_name self._plugin_name = plugin_name
service_plugins = {'L3_ROUTER_NAT': self._l3_plugin_name}
super(BigSwitchProxyPluginV2TestCase, super(BigSwitchProxyPluginV2TestCase,
self).setUp(self._plugin_name) self).setUp(self._plugin_name, service_plugins=service_plugins)
self.port_create_status = 'BUILD' self.port_create_status = 'BUILD'
self.startHttpPatch() self.startHttpPatch()
@ -310,6 +311,6 @@ class TestBigSwitchProxySync(BigSwitchProxyPluginV2TestCase):
self.assertEqual(result[0], 200) self.assertEqual(result[0], 200)
class TestBigSwitchAddressPairs(BigSwitchProxyPluginV2TestCase, class TestBigSwitchAddressPairs(test_addr_pair.TestAllowedAddressPairs,
test_addr_pair.TestAllowedAddressPairs): BigSwitchProxyPluginV2TestCase):
pass pass

View File

@ -70,14 +70,19 @@ class RouterDBTestBase(test_base.BigSwitchTestBase,
test_l3_plugin.L3BaseForIntTests, test_l3_plugin.L3BaseForIntTests,
test_l3_plugin.L3NatTestCaseMixin): test_l3_plugin.L3NatTestCaseMixin):
mock_rescheduling = False
def setUp(self): def setUp(self):
self.setup_patches() self.setup_patches()
self.setup_config_files() self.setup_config_files()
ext_mgr = RouterRulesTestExtensionManager() ext_mgr = RouterRulesTestExtensionManager()
service_plugins = {'L3_ROUTER_NAT': self._l3_plugin_name}
super(RouterDBTestBase, self).setUp(plugin=self._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) 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() self.startHttpPatch()
def tearDown(self): def tearDown(self):

View File

@ -148,6 +148,7 @@ neutron.core_plugins =
neutron.service_plugins = neutron.service_plugins =
dummy = neutron.tests.unit.dummy_plugin:DummyServicePlugin dummy = neutron.tests.unit.dummy_plugin:DummyServicePlugin
router = neutron.services.l3_router.l3_router_plugin:L3RouterPlugin 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 firewall = neutron.services.firewall.fwaas_plugin:FirewallPlugin
lbaas = neutron.services.loadbalancer.plugin:LoadBalancerPlugin lbaas = neutron.services.loadbalancer.plugin:LoadBalancerPlugin
vpnaas = neutron.services.vpn.plugin:VPNDriverPlugin vpnaas = neutron.services.vpn.plugin:VPNDriverPlugin