from neutron.plugins.ml2 import driver_api as api
+EXTERNAL_PORT_OWNER = 'neutron:external_port'
LOG = log.getLogger(__name__)
# time in seconds to maintain existence of vswitch response
return prepped_port
def bind_port(self, context):
- if not self.does_vswitch_exist(context.host):
- # this is not an IVS host
- return
-
- # currently only vlan segments are supported
- for segment in context.network.network_segments:
- if segment[api.NETWORK_TYPE] == pconst.TYPE_VLAN:
- context.set_binding(segment[api.ID], portbindings.VIF_TYPE_IVS,
- {portbindings.CAP_PORT_FILTER: True,
- portbindings.OVS_HYBRID_PLUG: False})
+ """Marks ports as bound.
+
+ Binds external ports and IVS ports.
+ Fabric configuration will occur on the subsequent port update.
+ Currently only vlan segments are supported.
+ """
+ if context.current['device_owner'] == EXTERNAL_PORT_OWNER:
+ # TODO(kevinbenton): check controller to see if the port exists
+ # so this driver can be run in parallel with others that add
+ # support for external port bindings
+ for segment in context.network.network_segments:
+ if segment[api.NETWORK_TYPE] == pconst.TYPE_VLAN:
+ context.set_binding(
+ segment[api.ID], portbindings.VIF_TYPE_BRIDGE,
+ {portbindings.CAP_PORT_FILTER: False,
+ portbindings.OVS_HYBRID_PLUG: False})
+ return
+
+ # IVS hosts will have a vswitch with the same name as the hostname
+ if self.does_vswitch_exist(context.host):
+ for segment in context.network.network_segments:
+ if segment[api.NETWORK_TYPE] == pconst.TYPE_VLAN:
+ context.set_binding(
+ segment[api.ID], portbindings.VIF_TYPE_IVS,
+ {portbindings.CAP_PORT_FILTER: True,
+ portbindings.OVS_HYBRID_PLUG: False})
def does_vswitch_exist(self, host):
"""Check if Indigo vswitch exists with the given hostname.
from neutron import context as neutron_context
from neutron.extensions import portbindings
from neutron import manager
+from neutron.openstack.common import jsonutils
from neutron.plugins.bigswitch import servermanager
from neutron.plugins.ml2 import config as ml2_config
+from neutron.plugins.ml2.drivers.mech_bigswitch import driver as bsn_driver
from neutron.plugins.ml2.drivers import type_vlan as vlan_config
import neutron.tests.unit.bigswitch.test_restproxy_plugin as trp
from neutron.tests.unit.ml2 import test_ml2_plugin
self.assertEqual('host', pb['binding:host_id'])
self.assertIn('bound_segment', pb)
self.assertIn('network', pb)
+
+ def test_bind_external_port(self):
+ ext_id = jsonutils.dumps({'type': 'vlan', 'chassis_id': 'FF',
+ 'port_id': '1'})
+ port_kwargs = {
+ portbindings.HOST_ID: ext_id,
+ 'device_owner': bsn_driver.EXTERNAL_PORT_OWNER
+ }
+ with contextlib.nested(
+ mock.patch(SERVER_POOL + '.rest_create_port'),
+ self.port(arg_list=(portbindings.HOST_ID,), **port_kwargs)
+ ) as (rmock, port):
+ create_body = rmock.mock_calls[-1][1][2]
+ self.assertIsNotNone(create_body['bound_segment'])
+ self.assertEqual(create_body[portbindings.HOST_ID], ext_id)