Merge "Bagpipe driver: use Neutron registry not an ML2 MD"
This commit is contained in:
5 changed files with 53 additions and 99 deletions
@@ -17,10 +17,6 @@ In devstack :
[service_providers]
service_provider=BGPVPN:BaGPipe:networking_bgpvpn.neutron.services.service_drivers.bagpipe.bagpipe.BaGPipeBGPVPNDriver:default
* add ``bgpvpn_notify`` to ``Q_ML2_PLUGIN_MECHANISM_DRIVERS``
* (this mech_driver does not implement the setup of L2 networks; it is used only to notify the ``bagpipe`` driver for the BGPVPN plugin of L2 ports coming and going on compute nodes)
* on a control node, if you want to run the Fake Route-Reflector there::
enable_plugin bagpipe-bgp https://github.com/Orange-OpenSource/bagpipe-bgp.git
@@ -53,12 +53,6 @@ class BGPVPNConnectionMissingRouteTarget(q_exc.BadRequest):
" route_targets, import_targets or export_targets attribute")
class BGPVPNNetworkInUse(q_exc.NetworkInUse):
message = _("Unable to complete operation on network %(network_id)s. "
"There are one or more BGP VPN connections associated"
" to the network.")
class BGPVPNPluginDb(common_db_mixin.CommonDbMixin):
"""BGP VPN service plugin database class using SQLAlchemy models."""
@@ -16,11 +16,16 @@
from sqlalchemy.orm import exc
from sqlalchemy import sql
from neutron import context as n_context
from neutron import manager
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.common import constants as const
from neutron.db import models_v2
from oslo_log import log as logging
from networking_bgpvpn.neutron.db import bgpvpn_db
from networking_bgpvpn.neutron.services import service_drivers
from networking_bagpipe_l2.agent.bgpvpn import rpc_client
@@ -74,6 +79,12 @@ class BaGPipeBGPVPNDriver(service_drivers.BGPVPNDriverDB):
self.agent_rpc = rpc_client.BGPVPNAgentNotifyApi()
registry.subscribe(self.registry_port_updated, resources.PORT,
events.AFTER_UPDATE)
registry.subscribe(self.registry_port_deleted, resources.PORT,
events.AFTER_DELETE)
@property
def service_type(self):
return BAGPIPE_BGPVPN
@@ -146,8 +157,7 @@ class BaGPipeBGPVPNDriver(service_drivers.BGPVPNDriverDB):
return bgpvpn_rts
def _retrieve_bgpvpn_network_info_for_port(self, context, port_id,
network_id):
def _retrieve_bgpvpn_network_info_for_port(self, context, port):
"""Retrieve BGP VPN network informations for a specific port
{
@@ -161,6 +171,9 @@ class BaGPipeBGPVPNDriver(service_drivers.BGPVPNDriverDB):
}
}
"""
port_id = port['id']
network_id = port['network_id']
bgpvpn_network_info = {}
# Check if port is connected on a BGP VPN network
@@ -297,17 +310,34 @@ class BaGPipeBGPVPNDriver(service_drivers.BGPVPNDriverDB):
self._format_bgpvpn_connection(bgpvpn_connection)
)
def _get_port_host(self, port_id):
# the port dict, as provided by the registry callback
# has no binding:host_id information, it seems the reason is
# because the context is not admin
# let's switch to an admin context and retrieve full port info
_core_plugin = manager.NeutronManager.get_plugin()
full_port = _core_plugin.get_port(n_context.get_admin_context(),
port_id)
if 'binding:host_id' not in full_port:
raise Exception("cannot determine host_id for port %s, "
"aborting BGPVPN update", port_id)
return full_port.get('binding:host_id')
def notify_port_updated(self, context, port):
port_bgpvpn_info = {'id': port['id'],
'network_id': port['network_id']}
agent_host = port['binding:host_id']
if port['device_owner'] == 'network:dhcp':
LOG.info("Owner of port %s is network:dhcp, ignoring")
agent_host = self._get_port_host(port['id'])
if port['status'] == const.PORT_STATUS_ACTIVE:
bgpvpn_network_info = (
self._retrieve_bgpvpn_network_info_for_port(
context,
port['id'],
port['network_id']))
self._retrieve_bgpvpn_network_info_for_port(context, port)
)
if bgpvpn_network_info:
port_bgpvpn_info.update(bgpvpn_network_info)
@@ -319,28 +349,28 @@ class BaGPipeBGPVPNDriver(service_drivers.BGPVPNDriverDB):
self.agent_rpc.detach_port_from_bgpvpn_network(context,
port_bgpvpn_info,
agent_host)
else:
LOG.debug("no action since new port status is %", port['status'])
def remove_port_from_bgpvpn_agent(self, context, port):
port_bgpvpn_info = {'id': port['id'],
'network_id': port['network_id']}
agent_host = port['binding:host_id']
if port['device_owner'] == 'network:dhcp':
LOG.info("Owner of port %s is network:dhcp, ignoring")
agent_host = self._get_port_host(port['id'])
self.agent_rpc.detach_port_from_bgpvpn_network(context,
port_bgpvpn_info,
agent_host)
def prevent_bgpvpn_network_deletion(self, context, network_id):
'''Method called by the mech_driver at delete_network_precommit time
def registry_port_updated(self, resource, event, trigger, **kwargs):
context = kwargs.get('context')
port_dict = kwargs.get('port')
self.notify_port_updated(context, port_dict)
Used to prevent deletion of a network referred to by a BGPVPN
connection.
'''
LOG.debug('Prevent BGP VPN network deletion')
# Note(ethuleau): can we use DB directly instead of the service
# provider to get that list?
if (self.service_plugin.get_bgpvpn_connections(
context,
filters={'network_id': [network_id]})):
raise bgpvpn_db.BGPVPNNetworkInUse(network_id=network_id)
else:
LOG.debug('Network %(network_id)s can be deleted')
def registry_port_deleted(self, resource, event, trigger, **kwargs):
context = kwargs.get('context')
port_dict = kwargs.get('port')
self.remove_port_from_bgpvpn_agent(context, port_dict)
@@ -1,64 +0,0 @@
# Copyright (c) 2015 Orange.
# 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.
from oslo_log import log
from neutron import context as n_context
from neutron import manager
from networking_bgpvpn.neutron.services.common import constants
from neutron.plugins.ml2 import driver_api as api
LOG = log.getLogger(__name__)
class ML2BGPVPNMechanismDriver(api.MechanismDriver):
"""This driver notifies the BGPVPNPlugin driver of port events.
It allows to notify BGP VPN plugin service drivers that need to be aware
of ports coming and going.
"""
def initialize(self):
self.db_context = n_context.get_admin_context()
def delete_network_precommit(self, context):
network = context.current
bgpvpnplugin = manager.NeutronManager.get_service_plugins().get(
constants.BGPVPN)
if bgpvpnplugin:
bgpvpnplugin.driver.prevent_bgpvpn_network_deletion(
self.db_context, network['id'])
def update_port_postcommit(self, context):
port = context.current
bgpvpnplugin = manager.NeutronManager.get_service_plugins().get(
constants.BGPVPN)
if bgpvpnplugin:
bgpvpnplugin.driver.notify_port_updated(self.db_context, port)
def delete_port_postcommit(self, context):
port = context.current
bgpvpnplugin = manager.NeutronManager.get_service_plugins().get(
constants.BGPVPN)
if bgpvpnplugin:
bgpvpnplugin.driver.remove_port_from_bgpvpn_agent(self.db_context,
port)
@@ -35,8 +35,6 @@ console_scripts=
neutron-bagpipe-openvswitch-agent = networking_bgpvpn.neutron.services.service_drivers.bagpipe.ovs_agent.ovs_bagpipe_neutron_agent:main
neutronclient.extension=
bgpvpn_connection = networking_bgpvpn.neutronclient.neutron.v2_0.bgpvpn.bgpvpn_connection
neutron.ml2.mechanism_drivers =
bgpvpn_notify = networking_bgpvpn.neutron.services.service_drivers.bagpipe.ml2_mech_driver:ML2BGPVPNMechanismDriver
[build_sphinx]
source-dir = doc/source
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.