TVD+BGP: adapt the nsx bgp plugin to be used in TVD
The BGP plugin and driver used for NSX-v should be used for TVD as well. This plugin suports only NSX-V under the TVD plugin. Change-Id: I95be40fe0f58f0ff2b06590400d708ee95294b82
This commit is contained in:
parent
fcac238cb0
commit
2c21c61709
@ -20,27 +20,46 @@ from neutron_lib.callbacks import events
|
|||||||
from neutron_lib.callbacks import registry
|
from neutron_lib.callbacks import registry
|
||||||
from neutron_lib.callbacks import resources
|
from neutron_lib.callbacks import resources
|
||||||
from neutron_lib import context as n_context
|
from neutron_lib import context as n_context
|
||||||
|
from neutron_lib import exceptions as n_exc
|
||||||
|
from neutron_lib.plugins import directory
|
||||||
from neutron_lib.services import base as service_base
|
from neutron_lib.services import base as service_base
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
from vmware_nsx.common import locking
|
from vmware_nsx.common import locking
|
||||||
from vmware_nsx.common import nsxv_constants
|
from vmware_nsx.common import nsxv_constants
|
||||||
|
from vmware_nsx.db import db as nsx_db
|
||||||
from vmware_nsx.db import nsxv_db
|
from vmware_nsx.db import nsxv_db
|
||||||
from vmware_nsx.extensions import edge_service_gateway_bgp_peer as ext_esg
|
from vmware_nsx.extensions import edge_service_gateway_bgp_peer as ext_esg
|
||||||
|
from vmware_nsx.extensions import projectpluginmap
|
||||||
from vmware_nsx.services.dynamic_routing.nsx_v import driver as nsxv_driver
|
from vmware_nsx.services.dynamic_routing.nsx_v import driver as nsxv_driver
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
PLUGIN_NAME = bgp_ext.BGP_EXT_ALIAS + '_nsx_svc_plugin'
|
PLUGIN_NAME = bgp_ext.BGP_EXT_ALIAS + '_nsx_svc_plugin'
|
||||||
|
|
||||||
|
|
||||||
class NSXvBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
class NSXBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
||||||
|
"""BGP service plugin for NSX-V as well as TVD plugins.
|
||||||
|
|
||||||
|
Currently only the nsx-v is supported. other plugins will be refused.
|
||||||
|
"""
|
||||||
|
|
||||||
supported_extension_aliases = [bgp_ext.BGP_EXT_ALIAS,
|
supported_extension_aliases = [bgp_ext.BGP_EXT_ALIAS,
|
||||||
ext_esg.ESG_BGP_PEER_EXT_ALIAS]
|
ext_esg.ESG_BGP_PEER_EXT_ALIAS]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(NSXvBgpPlugin, self).__init__()
|
super(NSXBgpPlugin, self).__init__()
|
||||||
self.nsxv_driver = nsxv_driver.NSXvBgpDriver(self)
|
self._core_plugin = directory.get_plugin()
|
||||||
|
|
||||||
|
# initialize the supported drivers (currently only NSX-v)
|
||||||
|
self.drivers = {}
|
||||||
|
try:
|
||||||
|
self.drivers[projectpluginmap.NsxPlugins.NSX_V] = (
|
||||||
|
nsxv_driver.NSXvBgpDriver(self))
|
||||||
|
except Exception:
|
||||||
|
# No driver found
|
||||||
|
LOG.warning("NSXBgpPlugin failed to initialize the NSX-V driver")
|
||||||
|
self.drivers[projectpluginmap.NsxPlugins.NSX_V] = None
|
||||||
|
|
||||||
self._register_callbacks()
|
self._register_callbacks()
|
||||||
|
|
||||||
def get_plugin_name(self):
|
def get_plugin_name(self):
|
||||||
@ -74,33 +93,78 @@ class NSXvBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
|||||||
nsxv_constants.SERVICE_EDGE,
|
nsxv_constants.SERVICE_EDGE,
|
||||||
events.BEFORE_DELETE)
|
events.BEFORE_DELETE)
|
||||||
|
|
||||||
|
def _get_driver_by_project(self, context, project):
|
||||||
|
# Check if the current project id has a matching driver
|
||||||
|
# Currently only NSX-V is supported
|
||||||
|
if self._core_plugin.is_tvd_plugin():
|
||||||
|
mapping = nsx_db.get_project_plugin_mapping(
|
||||||
|
context.session, project)
|
||||||
|
if mapping:
|
||||||
|
plugin_type = mapping['plugin']
|
||||||
|
else:
|
||||||
|
msg = (_("Couldn't find the plugin project %s is "
|
||||||
|
"using") % project)
|
||||||
|
raise n_exc.InvalidInput(error_message=msg)
|
||||||
|
|
||||||
|
# make sure the core plugin is supported
|
||||||
|
if not self._core_plugin.get_plugin_by_type(plugin_type):
|
||||||
|
msg = (_("Plugin %(plugin)s for project %(project)s is not "
|
||||||
|
"supported by the core plugin") % {
|
||||||
|
'project': project,
|
||||||
|
'plugin': plugin_type})
|
||||||
|
raise n_exc.InvalidInput(error_message=msg)
|
||||||
|
else:
|
||||||
|
plugin_type = self._core_plugin.plugin_type()
|
||||||
|
|
||||||
|
if not self.drivers.get(plugin_type):
|
||||||
|
msg = (_("Project %(project)s with plugin %(plugin)s has no "
|
||||||
|
"support for dynamic routing") % {
|
||||||
|
'project': project,
|
||||||
|
'plugin': plugin_type})
|
||||||
|
raise n_exc.InvalidInput(error_message=msg)
|
||||||
|
|
||||||
|
return self.drivers[plugin_type]
|
||||||
|
|
||||||
|
def _get_driver_by_speaker(self, context, bgp_speaker_id):
|
||||||
|
try:
|
||||||
|
speaker = self.get_bgp_speaker(context, bgp_speaker_id)
|
||||||
|
except Exception:
|
||||||
|
msg = _("BGP speaker %s could not be found") % bgp_speaker_id
|
||||||
|
raise n_exc.BadRequest(resource=bgp_ext.BGP_SPEAKER_RESOURCE_NAME,
|
||||||
|
msg=msg)
|
||||||
|
return self._get_driver_by_project(context, speaker['tenant_id'])
|
||||||
|
|
||||||
def create_bgp_speaker(self, context, bgp_speaker):
|
def create_bgp_speaker(self, context, bgp_speaker):
|
||||||
self.nsxv_driver.create_bgp_speaker(context, bgp_speaker)
|
driver = self._get_driver_by_project(
|
||||||
return super(NSXvBgpPlugin, self).create_bgp_speaker(context,
|
context, bgp_speaker['bgp_speaker']['tenant_id'])
|
||||||
|
driver.create_bgp_speaker(context, bgp_speaker)
|
||||||
|
return super(NSXBgpPlugin, self).create_bgp_speaker(context,
|
||||||
bgp_speaker)
|
bgp_speaker)
|
||||||
|
|
||||||
def update_bgp_speaker(self, context, bgp_speaker_id, bgp_speaker):
|
def update_bgp_speaker(self, context, bgp_speaker_id, bgp_speaker):
|
||||||
|
driver = self._get_driver_by_speaker(context, bgp_speaker_id)
|
||||||
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
||||||
self.nsxv_driver.update_bgp_speaker(context, bgp_speaker_id,
|
driver.update_bgp_speaker(context, bgp_speaker_id, bgp_speaker)
|
||||||
bgp_speaker)
|
|
||||||
# TBD(roeyc): rolling back changes on edges base class call failed.
|
# TBD(roeyc): rolling back changes on edges base class call failed.
|
||||||
return super(NSXvBgpPlugin, self).update_bgp_speaker(
|
return super(NSXBgpPlugin, self).update_bgp_speaker(
|
||||||
context, bgp_speaker_id, bgp_speaker)
|
context, bgp_speaker_id, bgp_speaker)
|
||||||
|
|
||||||
def delete_bgp_speaker(self, context, bgp_speaker_id):
|
def delete_bgp_speaker(self, context, bgp_speaker_id):
|
||||||
|
driver = self._get_driver_by_speaker(context, bgp_speaker_id)
|
||||||
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
||||||
self.nsxv_driver.delete_bgp_speaker(context, bgp_speaker_id)
|
driver.delete_bgp_speaker(context, bgp_speaker_id)
|
||||||
super(NSXvBgpPlugin, self).delete_bgp_speaker(context,
|
super(NSXBgpPlugin, self).delete_bgp_speaker(context,
|
||||||
bgp_speaker_id)
|
bgp_speaker_id)
|
||||||
|
|
||||||
def _add_esg_peer_info(self, context, peer):
|
def _add_esg_peer_info(self, context, peer):
|
||||||
|
# TODO(asarfaty): only if nsxv driver, or do it in the driver itself
|
||||||
binding = nsxv_db.get_nsxv_bgp_peer_edge_binding(context.session,
|
binding = nsxv_db.get_nsxv_bgp_peer_edge_binding(context.session,
|
||||||
peer['id'])
|
peer['id'])
|
||||||
if binding:
|
if binding:
|
||||||
peer['esg_id'] = binding['edge_id']
|
peer['esg_id'] = binding['edge_id']
|
||||||
|
|
||||||
def get_bgp_peer(self, context, bgp_peer_id, fields=None):
|
def get_bgp_peer(self, context, bgp_peer_id, fields=None):
|
||||||
peer = super(NSXvBgpPlugin, self).get_bgp_peer(context,
|
peer = super(NSXBgpPlugin, self).get_bgp_peer(context,
|
||||||
bgp_peer_id, fields)
|
bgp_peer_id, fields)
|
||||||
if not fields or 'esg_id' in fields:
|
if not fields or 'esg_id' in fields:
|
||||||
self._add_esg_peer_info(context, peer)
|
self._add_esg_peer_info(context, peer)
|
||||||
@ -108,16 +172,26 @@ class NSXvBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
|||||||
|
|
||||||
def get_bgp_peers_by_bgp_speaker(self, context,
|
def get_bgp_peers_by_bgp_speaker(self, context,
|
||||||
bgp_speaker_id, fields=None):
|
bgp_speaker_id, fields=None):
|
||||||
ret = super(NSXvBgpPlugin, self).get_bgp_peers_by_bgp_speaker(
|
ret = super(NSXBgpPlugin, self).get_bgp_peers_by_bgp_speaker(
|
||||||
context, bgp_speaker_id, fields=fields)
|
context, bgp_speaker_id, fields=fields)
|
||||||
if fields is None or 'esg_id' in fields:
|
if fields is None or 'esg_id' in fields:
|
||||||
for peer in ret:
|
for peer in ret:
|
||||||
self._add_esg_peer_info(context, peer)
|
self._add_esg_peer_info(context, peer)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def _get_driver_by_peer(self, context, bgp_peer_id):
|
||||||
|
try:
|
||||||
|
peer = self.get_bgp_peer(context, bgp_peer_id)
|
||||||
|
except Exception:
|
||||||
|
raise bgp_ext.BgpPeerNotFound(id=bgp_peer_id)
|
||||||
|
return self._get_driver_by_project(context, peer['tenant_id'])
|
||||||
|
|
||||||
def create_bgp_peer(self, context, bgp_peer):
|
def create_bgp_peer(self, context, bgp_peer):
|
||||||
self.nsxv_driver.create_bgp_peer(context, bgp_peer)
|
driver = self._get_driver_by_project(
|
||||||
peer = super(NSXvBgpPlugin, self).create_bgp_peer(context, bgp_peer)
|
context, bgp_peer['bgp_peer']['tenant_id'])
|
||||||
|
driver.create_bgp_peer(context, bgp_peer)
|
||||||
|
peer = super(NSXBgpPlugin, self).create_bgp_peer(context, bgp_peer)
|
||||||
|
# TODO(asarfaty): only if nsxv driver, or do it in the driver itself
|
||||||
esg_id = bgp_peer['bgp_peer'].get('esg_id')
|
esg_id = bgp_peer['bgp_peer'].get('esg_id')
|
||||||
if esg_id:
|
if esg_id:
|
||||||
nsxv_db.add_nsxv_bgp_peer_edge_binding(context.session, peer['id'],
|
nsxv_db.add_nsxv_bgp_peer_edge_binding(context.session, peer['id'],
|
||||||
@ -126,14 +200,16 @@ class NSXvBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
|||||||
return peer
|
return peer
|
||||||
|
|
||||||
def update_bgp_peer(self, context, bgp_peer_id, bgp_peer):
|
def update_bgp_peer(self, context, bgp_peer_id, bgp_peer):
|
||||||
super(NSXvBgpPlugin, self).update_bgp_peer(context,
|
driver = self._get_driver_by_peer(context, bgp_peer_id)
|
||||||
|
super(NSXBgpPlugin, self).update_bgp_peer(context,
|
||||||
bgp_peer_id, bgp_peer)
|
bgp_peer_id, bgp_peer)
|
||||||
self.nsxv_driver.update_bgp_peer(context, bgp_peer_id, bgp_peer)
|
driver.update_bgp_peer(context, bgp_peer_id, bgp_peer)
|
||||||
return self.get_bgp_peer(context, bgp_peer_id)
|
return self.get_bgp_peer(context, bgp_peer_id)
|
||||||
|
|
||||||
def delete_bgp_peer(self, context, bgp_peer_id):
|
def delete_bgp_peer(self, context, bgp_peer_id):
|
||||||
|
driver = self._get_driver_by_peer(context, bgp_peer_id)
|
||||||
bgp_peer_info = {'bgp_peer_id': bgp_peer_id}
|
bgp_peer_info = {'bgp_peer_id': bgp_peer_id}
|
||||||
bgp_speaker_ids = self.nsxv_driver._get_bgp_speakers_by_bgp_peer(
|
bgp_speaker_ids = driver._get_bgp_speakers_by_bgp_peer(
|
||||||
context, bgp_peer_id)
|
context, bgp_peer_id)
|
||||||
for speaker_id in bgp_speaker_ids:
|
for speaker_id in bgp_speaker_ids:
|
||||||
try:
|
try:
|
||||||
@ -141,42 +217,74 @@ class NSXvBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
|||||||
except bgp_ext.BgpSpeakerPeerNotAssociated:
|
except bgp_ext.BgpSpeakerPeerNotAssociated:
|
||||||
LOG.debug("Couldn't find bgp speaker %s peer binding while "
|
LOG.debug("Couldn't find bgp speaker %s peer binding while "
|
||||||
"deleting bgp peer %s", speaker_id, bgp_peer_id)
|
"deleting bgp peer %s", speaker_id, bgp_peer_id)
|
||||||
super(NSXvBgpPlugin, self).delete_bgp_peer(context, bgp_peer_id)
|
super(NSXBgpPlugin, self).delete_bgp_peer(context, bgp_peer_id)
|
||||||
|
|
||||||
def add_bgp_peer(self, context, bgp_speaker_id, bgp_peer_info):
|
def add_bgp_peer(self, context, bgp_speaker_id, bgp_peer_info):
|
||||||
|
# speaker & peer must belong to the same driver
|
||||||
|
if not bgp_peer_info.get('bgp_peer_id'):
|
||||||
|
msg = _("bgp_peer_id must be specified")
|
||||||
|
raise n_exc.BadRequest(resource='bgp-peer', msg=msg)
|
||||||
|
peer_driver = self._get_driver_by_peer(
|
||||||
|
context, bgp_peer_info['bgp_peer_id'])
|
||||||
|
speaker_driver = self._get_driver_by_speaker(context, bgp_speaker_id)
|
||||||
|
if peer_driver != speaker_driver:
|
||||||
|
msg = _("Peer and Speaker must belong to the same plugin")
|
||||||
|
raise n_exc.InvalidInput(error_message=msg)
|
||||||
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
||||||
self.nsxv_driver.add_bgp_peer(context,
|
speaker_driver.add_bgp_peer(context,
|
||||||
bgp_speaker_id, bgp_peer_info)
|
bgp_speaker_id, bgp_peer_info)
|
||||||
return super(NSXvBgpPlugin, self).add_bgp_peer(context,
|
return super(NSXBgpPlugin, self).add_bgp_peer(context,
|
||||||
bgp_speaker_id,
|
bgp_speaker_id,
|
||||||
bgp_peer_info)
|
bgp_peer_info)
|
||||||
|
|
||||||
def remove_bgp_peer(self, context, bgp_speaker_id, bgp_peer_info):
|
def remove_bgp_peer(self, context, bgp_speaker_id, bgp_peer_info):
|
||||||
|
driver = self._get_driver_by_speaker(context, bgp_speaker_id)
|
||||||
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
||||||
ret = super(NSXvBgpPlugin, self).remove_bgp_peer(
|
ret = super(NSXBgpPlugin, self).remove_bgp_peer(
|
||||||
context, bgp_speaker_id, bgp_peer_info)
|
context, bgp_speaker_id, bgp_peer_info)
|
||||||
self.nsxv_driver.remove_bgp_peer(context,
|
driver.remove_bgp_peer(context, bgp_speaker_id, bgp_peer_info)
|
||||||
bgp_speaker_id, bgp_peer_info)
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def _validate_network_plugin(
|
||||||
|
self, context, network_info,
|
||||||
|
plugin_type=projectpluginmap.NsxPlugins.NSX_V):
|
||||||
|
"""Make sure the network belongs to the NSX0-V plugin"""
|
||||||
|
if not network_info.get('network_id'):
|
||||||
|
msg = _("network_id must be specified")
|
||||||
|
raise n_exc.BadRequest(resource=bgp_ext.BGP_SPEAKER_RESOURCE_NAME,
|
||||||
|
msg=msg)
|
||||||
|
net_id = network_info['network_id']
|
||||||
|
p = self._core_plugin._get_plugin_from_net_id(context, net_id)
|
||||||
|
if p.plugin_type() != plugin_type:
|
||||||
|
msg = (_('Network should belong to the %s plugin as the bgp '
|
||||||
|
'speaker') % plugin_type)
|
||||||
|
raise n_exc.InvalidInput(error_message=msg)
|
||||||
|
|
||||||
def add_gateway_network(self, context, bgp_speaker_id, network_info):
|
def add_gateway_network(self, context, bgp_speaker_id, network_info):
|
||||||
|
driver = self._get_driver_by_speaker(context, bgp_speaker_id)
|
||||||
|
if self._core_plugin.is_tvd_plugin():
|
||||||
|
# The plugin of the network and speaker must be the same
|
||||||
|
self._validate_network_plugin(context, network_info)
|
||||||
|
|
||||||
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
||||||
self.nsxv_driver.add_gateway_network(context,
|
driver.add_gateway_network(context,
|
||||||
bgp_speaker_id,
|
bgp_speaker_id,
|
||||||
network_info)
|
network_info)
|
||||||
return super(NSXvBgpPlugin, self).add_gateway_network(
|
return super(NSXBgpPlugin, self).add_gateway_network(
|
||||||
context, bgp_speaker_id, network_info)
|
context, bgp_speaker_id, network_info)
|
||||||
|
|
||||||
def remove_gateway_network(self, context, bgp_speaker_id, network_info):
|
def remove_gateway_network(self, context, bgp_speaker_id, network_info):
|
||||||
|
driver = self._get_driver_by_speaker(context, bgp_speaker_id)
|
||||||
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
with locking.LockManager.get_lock(str(bgp_speaker_id)):
|
||||||
super(NSXvBgpPlugin, self).remove_gateway_network(
|
super(NSXBgpPlugin, self).remove_gateway_network(
|
||||||
context, bgp_speaker_id, network_info)
|
context, bgp_speaker_id, network_info)
|
||||||
self.nsxv_driver.remove_gateway_network(context,
|
driver.remove_gateway_network(context,
|
||||||
bgp_speaker_id,
|
bgp_speaker_id,
|
||||||
network_info)
|
network_info)
|
||||||
|
|
||||||
def get_advertised_routes(self, context, bgp_speaker_id):
|
def get_advertised_routes(self, context, bgp_speaker_id):
|
||||||
return self.nsxv_driver.get_advertised_routes(context, bgp_speaker_id)
|
driver = self._get_driver_by_speaker(context, bgp_speaker_id)
|
||||||
|
return driver.get_advertised_routes(context, bgp_speaker_id)
|
||||||
|
|
||||||
def router_interface_callback(self, resource, event, trigger, **kwargs):
|
def router_interface_callback(self, resource, event, trigger, **kwargs):
|
||||||
if not kwargs['network_id']:
|
if not kwargs['network_id']:
|
||||||
@ -195,14 +303,16 @@ class NSXvBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
|||||||
speaker_id = speaker.id
|
speaker_id = speaker.id
|
||||||
with locking.LockManager.get_lock(str(speaker_id)):
|
with locking.LockManager.get_lock(str(speaker_id)):
|
||||||
speaker = self.get_bgp_speaker(context, speaker_id)
|
speaker = self.get_bgp_speaker(context, speaker_id)
|
||||||
|
driver = self._get_driver_by_project(
|
||||||
|
context, speaker['tenant_id'])
|
||||||
if network_id not in speaker['networks']:
|
if network_id not in speaker['networks']:
|
||||||
continue
|
continue
|
||||||
if event == events.AFTER_CREATE:
|
if event == events.AFTER_CREATE:
|
||||||
self.nsxv_driver.advertise_subnet(context, speaker_id,
|
driver.advertise_subnet(context, speaker_id,
|
||||||
router_id, subnets[0])
|
router_id, subnets[0])
|
||||||
if event == events.AFTER_DELETE:
|
if event == events.AFTER_DELETE:
|
||||||
subnet_id = port['fixed_ips'][0]['subnet_id']
|
subnet_id = port['fixed_ips'][0]['subnet_id']
|
||||||
self.nsxv_driver.withdraw_subnet(context, speaker_id,
|
driver.withdraw_subnet(context, speaker_id,
|
||||||
router_id, subnet_id)
|
router_id, subnet_id)
|
||||||
|
|
||||||
def router_gateway_callback(self, resource, event, trigger, **kwargs):
|
def router_gateway_callback(self, resource, event, trigger, **kwargs):
|
||||||
@ -214,20 +324,22 @@ class NSXvBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
|||||||
|
|
||||||
for speaker in speakers:
|
for speaker in speakers:
|
||||||
speaker_id = speaker.id
|
speaker_id = speaker.id
|
||||||
|
driver = self._get_driver_by_project(
|
||||||
|
context, speaker['tenant_id'])
|
||||||
with locking.LockManager.get_lock(str(speaker_id)):
|
with locking.LockManager.get_lock(str(speaker_id)):
|
||||||
speaker = self.get_bgp_speaker(context, speaker_id)
|
speaker = self.get_bgp_speaker(context, speaker_id)
|
||||||
if network_id not in speaker['networks']:
|
if network_id not in speaker['networks']:
|
||||||
continue
|
continue
|
||||||
if event == events.AFTER_DELETE:
|
if event == events.AFTER_DELETE:
|
||||||
gw_ips = kwargs['gateway_ips']
|
gw_ips = kwargs['gateway_ips']
|
||||||
self.nsxv_driver.disable_bgp_on_router(context,
|
driver.disable_bgp_on_router(context,
|
||||||
speaker,
|
speaker,
|
||||||
router_id,
|
router_id,
|
||||||
gw_ips[0])
|
gw_ips[0])
|
||||||
if event == events.AFTER_UPDATE:
|
if event == events.AFTER_UPDATE:
|
||||||
updated_port = kwargs['updated_port']
|
updated_port = kwargs['updated_port']
|
||||||
router = kwargs['router']
|
router = kwargs['router']
|
||||||
self.nsxv_driver.process_router_gw_port_update(
|
driver.process_router_gw_port_update(
|
||||||
context, speaker, router, updated_port)
|
context, speaker, router, updated_port)
|
||||||
|
|
||||||
def _before_service_edge_delete_callback(self, resource, event,
|
def _before_service_edge_delete_callback(self, resource, event,
|
||||||
@ -239,11 +351,13 @@ class NSXvBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
|||||||
edge_id = kwargs.get('edge_id')
|
edge_id = kwargs.get('edge_id')
|
||||||
speakers = self._bgp_speakers_for_gateway_network(context, ext_net_id)
|
speakers = self._bgp_speakers_for_gateway_network(context, ext_net_id)
|
||||||
for speaker in speakers:
|
for speaker in speakers:
|
||||||
|
driver = self._get_driver_by_project(
|
||||||
|
context, speaker['tenant_id'])
|
||||||
with locking.LockManager.get_lock(speaker.id):
|
with locking.LockManager.get_lock(speaker.id):
|
||||||
speaker = self.get_bgp_speaker(context, speaker.id)
|
speaker = self.get_bgp_speaker(context, speaker.id)
|
||||||
if ext_net_id not in speaker['networks']:
|
if ext_net_id not in speaker['networks']:
|
||||||
continue
|
continue
|
||||||
self.nsxv_driver.disable_bgp_on_router(context, speaker,
|
driver.disable_bgp_on_router(context, speaker,
|
||||||
router['id'],
|
router['id'],
|
||||||
gw_ip, edge_id)
|
gw_ip, edge_id)
|
||||||
|
|
||||||
@ -254,9 +368,15 @@ class NSXvBgpPlugin(service_base.ServicePluginBase, bgp_db.BgpDbMixin):
|
|||||||
ext_net_id = router.gw_port and router.gw_port['network_id']
|
ext_net_id = router.gw_port and router.gw_port['network_id']
|
||||||
speakers = self._bgp_speakers_for_gateway_network(context, ext_net_id)
|
speakers = self._bgp_speakers_for_gateway_network(context, ext_net_id)
|
||||||
for speaker in speakers:
|
for speaker in speakers:
|
||||||
|
driver = self._get_driver_by_project(
|
||||||
|
context, speaker['tenant_id'])
|
||||||
with locking.LockManager.get_lock(speaker.id):
|
with locking.LockManager.get_lock(speaker.id):
|
||||||
speaker = self.get_bgp_speaker(context, speaker.id)
|
speaker = self.get_bgp_speaker(context, speaker.id)
|
||||||
if ext_net_id not in speaker['networks']:
|
if ext_net_id not in speaker['networks']:
|
||||||
continue
|
continue
|
||||||
self.nsxv_driver.enable_bgp_on_router(context, speaker,
|
driver.enable_bgp_on_router(context, speaker, router['id'])
|
||||||
router['id'])
|
|
||||||
|
|
||||||
|
class NSXvBgpPlugin(NSXBgpPlugin):
|
||||||
|
"""Defined for backwards compatibility only"""
|
||||||
|
pass
|
||||||
|
@ -31,6 +31,7 @@ from vmware_nsx.common import locking
|
|||||||
from vmware_nsx.common import nsxv_constants
|
from vmware_nsx.common import nsxv_constants
|
||||||
from vmware_nsx.db import nsxv_db
|
from vmware_nsx.db import nsxv_db
|
||||||
from vmware_nsx.extensions import edge_service_gateway_bgp_peer as ext_esg_peer
|
from vmware_nsx.extensions import edge_service_gateway_bgp_peer as ext_esg_peer
|
||||||
|
from vmware_nsx.extensions import projectpluginmap
|
||||||
from vmware_nsx.plugins.nsx_v.vshield.common import exceptions as vcns_exc
|
from vmware_nsx.plugins.nsx_v.vshield.common import exceptions as vcns_exc
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -87,6 +88,12 @@ class NSXvBgpDriver(object):
|
|||||||
super(NSXvBgpDriver, self).__init__()
|
super(NSXvBgpDriver, self).__init__()
|
||||||
self._plugin = plugin
|
self._plugin = plugin
|
||||||
self._core_plugin = directory.get_plugin()
|
self._core_plugin = directory.get_plugin()
|
||||||
|
if self._core_plugin.is_tvd_plugin():
|
||||||
|
self._core_plugin = self._core_plugin.get_plugin_by_type(
|
||||||
|
projectpluginmap.NsxPlugins.NSX_V)
|
||||||
|
if not self._core_plugin:
|
||||||
|
err_msg = _("NSXv BGP cannot work without the NSX-V core plugin")
|
||||||
|
raise n_exc.InvalidInput(error_message=err_msg)
|
||||||
self._nsxv = self._core_plugin.nsx_v
|
self._nsxv = self._core_plugin.nsx_v
|
||||||
self._edge_manager = self._core_plugin.edge_manager
|
self._edge_manager = self._core_plugin.edge_manager
|
||||||
|
|
||||||
@ -99,7 +106,7 @@ class NSXvBgpDriver(object):
|
|||||||
if not edge_binding:
|
if not edge_binding:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
# Idicates which routes should be advertised - connected or static.
|
# Indicates which routes should be advertised - connected or static.
|
||||||
advertise_static_routes = False
|
advertise_static_routes = False
|
||||||
if edge_binding['edge_type'] != nsxv_constants.SERVICE_EDGE:
|
if edge_binding['edge_type'] != nsxv_constants.SERVICE_EDGE:
|
||||||
# Distributed router
|
# Distributed router
|
||||||
|
@ -43,13 +43,15 @@ class TestNSXvBgpPlugin(test_plugin.NsxVPluginV2TestCase,
|
|||||||
service_plugins = {ext_bgp.BGP_EXT_ALIAS: BGP_PLUGIN}
|
service_plugins = {ext_bgp.BGP_EXT_ALIAS: BGP_PLUGIN}
|
||||||
super(TestNSXvBgpPlugin, self).setUp(service_plugins=service_plugins)
|
super(TestNSXvBgpPlugin, self).setUp(service_plugins=service_plugins)
|
||||||
self.bgp_plugin = bgp_plugin.NSXvBgpPlugin()
|
self.bgp_plugin = bgp_plugin.NSXvBgpPlugin()
|
||||||
self.bgp_plugin.nsxv_driver._validate_gateway_network = mock.Mock()
|
self.nsxv_driver = self.bgp_plugin.drivers['nsx-v']
|
||||||
self.bgp_plugin.nsxv_driver._validate_bgp_configuration_on_peer_esg = (
|
self.nsxv_driver._validate_gateway_network = mock.Mock()
|
||||||
|
self.nsxv_driver._validate_bgp_configuration_on_peer_esg = (
|
||||||
mock.Mock())
|
mock.Mock())
|
||||||
self.plugin = directory.get_plugin()
|
self.plugin = directory.get_plugin()
|
||||||
self.l3plugin = self.plugin
|
self.l3plugin = self.plugin
|
||||||
self.plugin.init_is_complete = True
|
self.plugin.init_is_complete = True
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
|
self.project_id = 'dummy_project'
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def gw_network(self, external=True, **kwargs):
|
def gw_network(self, external=True, **kwargs):
|
||||||
@ -85,18 +87,46 @@ class TestNSXvBgpPlugin(test_plugin.NsxVPluginV2TestCase,
|
|||||||
'esg_id': esg_id,
|
'esg_id': esg_id,
|
||||||
'auth_type': 'none',
|
'auth_type': 'none',
|
||||||
'password': '',
|
'password': '',
|
||||||
'tenant_id': ''}
|
'tenant_id': self.project_id}
|
||||||
bgp_peer = self.bgp_plugin.create_bgp_peer(self.context,
|
bgp_peer = self.bgp_plugin.create_bgp_peer(self.context,
|
||||||
{'bgp_peer': data})
|
{'bgp_peer': data})
|
||||||
yield bgp_peer
|
yield bgp_peer
|
||||||
self.bgp_plugin.delete_bgp_peer(self.context, bgp_peer['id'])
|
self.bgp_plugin.delete_bgp_peer(self.context, bgp_peer['id'])
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def bgp_speaker(self, ip_version, local_as, name='my-speaker',
|
||||||
|
advertise_fip_host_routes=True,
|
||||||
|
advertise_tenant_networks=True,
|
||||||
|
networks=None, peers=None):
|
||||||
|
data = {'ip_version': ip_version,
|
||||||
|
test_bgp_db.ADVERTISE_FIPS_KEY: advertise_fip_host_routes,
|
||||||
|
'advertise_tenant_networks': advertise_tenant_networks,
|
||||||
|
'local_as': local_as, 'name': name,
|
||||||
|
'tenant_id': self.project_id}
|
||||||
|
bgp_speaker = self.bgp_plugin.create_bgp_speaker(self.context,
|
||||||
|
{'bgp_speaker': data})
|
||||||
|
bgp_speaker_id = bgp_speaker['id']
|
||||||
|
|
||||||
|
if networks:
|
||||||
|
for network_id in networks:
|
||||||
|
self.bgp_plugin.add_gateway_network(
|
||||||
|
self.context,
|
||||||
|
bgp_speaker_id,
|
||||||
|
{'network_id': network_id})
|
||||||
|
if peers:
|
||||||
|
for peer_id in peers:
|
||||||
|
self.bgp_plugin.add_bgp_peer(self.context, bgp_speaker_id,
|
||||||
|
{'bgp_peer_id': peer_id})
|
||||||
|
|
||||||
|
yield self.bgp_plugin.get_bgp_speaker(self.context, bgp_speaker_id)
|
||||||
|
|
||||||
def test_create_v6_bgp_speaker(self):
|
def test_create_v6_bgp_speaker(self):
|
||||||
fake_bgp_speaker = {
|
fake_bgp_speaker = {
|
||||||
"bgp_speaker": {
|
"bgp_speaker": {
|
||||||
"ip_version": 6,
|
"ip_version": 6,
|
||||||
"local_as": "1000",
|
"local_as": "1000",
|
||||||
"name": "bgp-speaker"
|
"name": "bgp-speaker",
|
||||||
|
"tenant_id": self.project_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.assertRaises(n_exc.InvalidInput,
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
@ -109,7 +139,8 @@ class TestNSXvBgpPlugin(test_plugin.NsxVPluginV2TestCase,
|
|||||||
"auth_type": "none",
|
"auth_type": "none",
|
||||||
"remote_as": "1000",
|
"remote_as": "1000",
|
||||||
"name": "bgp-peer",
|
"name": "bgp-peer",
|
||||||
"peer_ip": "fc00::/7"
|
"peer_ip": "fc00::/7",
|
||||||
|
"tenant_id": self.project_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.assertRaises(n_exc.InvalidInput,
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
@ -128,13 +159,14 @@ class TestNSXvBgpPlugin(test_plugin.NsxVPluginV2TestCase,
|
|||||||
def test_create_bgp_peer_md5_auth_no_password(self):
|
def test_create_bgp_peer_md5_auth_no_password(self):
|
||||||
bgp_peer = {'bgp_peer':
|
bgp_peer = {'bgp_peer':
|
||||||
{'auth_type': 'md5', 'password': None,
|
{'auth_type': 'md5', 'password': None,
|
||||||
'peer_ip': '10.0.0.3'}}
|
'peer_ip': '10.0.0.3',
|
||||||
|
'tenant_id': self.project_id}}
|
||||||
self.assertRaises(ext_bgp.InvalidBgpPeerMd5Authentication,
|
self.assertRaises(ext_bgp.InvalidBgpPeerMd5Authentication,
|
||||||
self.bgp_plugin.create_bgp_peer,
|
self.bgp_plugin.create_bgp_peer,
|
||||||
self.context, bgp_peer)
|
self.context, bgp_peer)
|
||||||
|
|
||||||
def test_add_non_external_gateway_network(self):
|
def test_add_non_external_gateway_network(self):
|
||||||
self.bgp_plugin.nsxv_driver._validate_gateway_network = (
|
self.nsxv_driver._validate_gateway_network = (
|
||||||
bgp_driver.NSXvBgpDriver(
|
bgp_driver.NSXvBgpDriver(
|
||||||
self.bgp_plugin)._validate_gateway_network)
|
self.bgp_plugin)._validate_gateway_network)
|
||||||
with self.gw_network(external=False) as net,\
|
with self.gw_network(external=False) as net,\
|
||||||
@ -170,15 +202,14 @@ class TestNSXvBgpPlugin(test_plugin.NsxVPluginV2TestCase,
|
|||||||
with self.router(external_gateway_info=gw_info1) as rtr1,\
|
with self.router(external_gateway_info=gw_info1) as rtr1,\
|
||||||
self.router(external_gateway_info=gw_info2) as rtr2,\
|
self.router(external_gateway_info=gw_info2) as rtr2,\
|
||||||
mock.patch.object(
|
mock.patch.object(
|
||||||
self.bgp_plugin.nsxv_driver,
|
self.nsxv_driver, '_get_router_edge_info',
|
||||||
'_get_router_edge_info',
|
|
||||||
return_value=('edge-1', False)),\
|
return_value=('edge-1', False)),\
|
||||||
mock.patch.object(
|
mock.patch.object(
|
||||||
self.plugin.edge_manager,
|
self.plugin.edge_manager,
|
||||||
'get_routers_on_same_edge',
|
'get_routers_on_same_edge',
|
||||||
return_value=[rtr1['id'], rtr2['id']]),\
|
return_value=[rtr1['id'], rtr2['id']]),\
|
||||||
mock.patch.object(
|
mock.patch.object(
|
||||||
self.bgp_plugin.nsxv_driver,
|
self.nsxv_driver,
|
||||||
'_update_edge_bgp_identifier') as up_bgp:
|
'_update_edge_bgp_identifier') as up_bgp:
|
||||||
gw_clear = {u'router': {u'external_gateway_info': {}}}
|
gw_clear = {u'router': {u'external_gateway_info': {}}}
|
||||||
self.plugin.update_router(self.context,
|
self.plugin.update_router(self.context,
|
||||||
@ -246,3 +277,13 @@ class TestNSXvBgpPlugin(test_plugin.NsxVPluginV2TestCase,
|
|||||||
def test__get_routes_by_router_with_fip(self):
|
def test__get_routes_by_router_with_fip(self):
|
||||||
# base class tests uses no-snat router with floating ips
|
# base class tests uses no-snat router with floating ips
|
||||||
self.skipTest('No SNAT with floating ips not supported')
|
self.skipTest('No SNAT with floating ips not supported')
|
||||||
|
|
||||||
|
def test_add_bgp_peer_with_bad_id(self):
|
||||||
|
with self.subnetpool_with_address_scope(
|
||||||
|
4, prefixes=['8.0.0.0/8']) as sp:
|
||||||
|
with self.bgp_speaker(sp['ip_version'], 1234) as speaker:
|
||||||
|
self.assertRaises(ext_bgp.BgpPeerNotFound,
|
||||||
|
self.bgp_plugin.add_bgp_peer,
|
||||||
|
self.context,
|
||||||
|
speaker['id'],
|
||||||
|
{'bgp_peer_id': 'aaa'})
|
||||||
|
Loading…
Reference in New Issue
Block a user