Add port bindings to ports created in Midonet

Currently Midokura uses its own script (mm-ctl) to bind ports. However, support
for using this script is left out of the nova and neutron projects. This causes
confusion and makes deployments unnecessarily complicated for customers using
Havana. This fix is to change Neutron to properly set up port bindings to use
the "midonet" vif driver when creating a port. Corresponding changes will be
submitted to the devstack and Nova projects.

Change-Id: I91f2e4fe7135da0c22fb408081efdc63fff748df
Closes-Bug: 1235134
This commit is contained in:
Joe Mills 2013-10-04 01:55:18 +09:00
parent f0b48a61b9
commit 976de09b55
3 changed files with 38 additions and 5 deletions

View File

@ -44,10 +44,12 @@ VIF_TYPE_BRIDGE = 'bridge'
VIF_TYPE_802_QBG = '802.1qbg' VIF_TYPE_802_QBG = '802.1qbg'
VIF_TYPE_802_QBH = '802.1qbh' VIF_TYPE_802_QBH = '802.1qbh'
VIF_TYPE_HYPERV = 'hyperv' VIF_TYPE_HYPERV = 'hyperv'
VIF_TYPE_MIDONET = 'midonet'
VIF_TYPE_OTHER = 'other' VIF_TYPE_OTHER = 'other'
VIF_TYPES = [VIF_TYPE_UNBOUND, VIF_TYPE_BINDING_FAILED, VIF_TYPE_OVS, VIF_TYPES = [VIF_TYPE_UNBOUND, VIF_TYPE_BINDING_FAILED, VIF_TYPE_OVS,
VIF_TYPE_IVS, VIF_TYPE_BRIDGE, VIF_TYPE_802_QBG, VIF_TYPE_IVS, VIF_TYPE_BRIDGE, VIF_TYPE_802_QBG,
VIF_TYPE_802_QBH, VIF_TYPE_HYPERV, VIF_TYPE_OTHER] VIF_TYPE_802_QBH, VIF_TYPE_HYPERV, VIF_TYPE_MIDONET,
VIF_TYPE_OTHER]
EXTENDED_ATTRIBUTES_2_0 = { EXTENDED_ATTRIBUTES_2_0 = {

View File

@ -38,9 +38,11 @@ from neutron.db import dhcp_rpc_base
from neutron.db import external_net_db from neutron.db import external_net_db
from neutron.db import l3_db from neutron.db import l3_db
from neutron.db import models_v2 from neutron.db import models_v2
from neutron.db import portbindings_db
from neutron.db import securitygroups_db from neutron.db import securitygroups_db
from neutron.extensions import external_net as ext_net from neutron.extensions import external_net as ext_net
from neutron.extensions import l3 from neutron.extensions import l3
from neutron.extensions import portbindings
from neutron.extensions import securitygroup as ext_sg from neutron.extensions import securitygroup as ext_sg
from neutron.openstack.common import excutils from neutron.openstack.common import excutils
from neutron.openstack.common import log as logging from neutron.openstack.common import log as logging
@ -195,13 +197,14 @@ class MidonetPluginException(n_exc.NeutronException):
class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2, class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
portbindings_db.PortBindingMixin,
external_net_db.External_net_db_mixin, external_net_db.External_net_db_mixin,
l3_db.L3_NAT_db_mixin, l3_db.L3_NAT_db_mixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin, agentschedulers_db.DhcpAgentSchedulerDbMixin,
securitygroups_db.SecurityGroupDbMixin): securitygroups_db.SecurityGroupDbMixin):
supported_extension_aliases = ['external-net', 'router', 'security-group', supported_extension_aliases = ['external-net', 'router', 'security-group',
'agent' 'dhcp_agent_scheduler'] 'agent' 'dhcp_agent_scheduler', 'binding']
__native_bulk_support = False __native_bulk_support = False
def __init__(self): def __init__(self):
@ -229,6 +232,12 @@ class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
self.setup_rpc() self.setup_rpc()
db.configure_db() db.configure_db()
self.base_binding_dict = {
portbindings.VIF_TYPE: portbindings.VIF_TYPE_MIDONET,
portbindings.CAPABILITIES: {
portbindings.CAP_PORT_FILTER:
'security-group' in self.supported_extension_aliases}}
def _get_provider_router(self): def _get_provider_router(self):
if self.provider_router is None: if self.provider_router is None:
self.provider_router = self.client.get_router( self.provider_router = self.client.get_router(
@ -529,7 +538,7 @@ class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
if _is_vif_port(port_data): if _is_vif_port(port_data):
# Bind security groups to the port # Bind security groups to the port
sg_ids = self._get_security_groups_on_port(context, port) sg_ids = self._get_security_groups_on_port(context, port)
self._bind_port_to_sgs(context, port_data, sg_ids) self._bind_port_to_sgs(context, new_port, sg_ids)
# Create port chains # Create port chains
port_chains = {} port_chains = {}
@ -561,6 +570,8 @@ class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
self.client.add_dhcp_route_option(bridge, cidr, ip, self.client.add_dhcp_route_option(bridge, cidr, ip,
METADATA_DEFAULT_IP) METADATA_DEFAULT_IP)
self._process_portbindings_create_and_update(context,
port_data, new_port)
except Exception as ex: except Exception as ex:
# Try removing the MidoNet port before raising an exception. # Try removing the MidoNet port before raising an exception.
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
@ -569,8 +580,8 @@ class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
{"net_id": port_data["network_id"], "err": ex}) {"net_id": port_data["network_id"], "err": ex})
self.client.delete_port(bridge_port.get_id()) self.client.delete_port(bridge_port.get_id())
LOG.debug(_("MidonetPluginV2.create_port exiting: port=%r"), port_data) LOG.debug(_("MidonetPluginV2.create_port exiting: port=%r"), new_port)
return port_data return new_port
def get_port(self, context, id, fields=None): def get_port(self, context, id, fields=None):
"""Retrieve port.""" """Retrieve port."""
@ -677,6 +688,9 @@ class MidonetPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
sg_ids = self._get_security_groups_on_port(context, port) sg_ids = self._get_security_groups_on_port(context, port)
self._bind_port_to_sgs(context, p, sg_ids) self._bind_port_to_sgs(context, p, sg_ids)
self._process_portbindings_create_and_update(context,
port['port'],
p)
return p return p
def create_router(self, context, router): def create_router(self, context, router):

View File

@ -25,6 +25,8 @@ import os
import sys import sys
import neutron.common.test_lib as test_lib import neutron.common.test_lib as test_lib
from neutron.extensions import portbindings
from neutron.tests.unit import _test_extension_portbindings as test_bindings
import neutron.tests.unit.midonet.mock_lib as mock_lib import neutron.tests.unit.midonet.mock_lib as mock_lib
import neutron.tests.unit.test_db_plugin as test_plugin import neutron.tests.unit.test_db_plugin as test_plugin
import neutron.tests.unit.test_extension_security_group as sg import neutron.tests.unit.test_extension_security_group as sg
@ -138,3 +140,18 @@ class TestMidonetPortsV2(test_plugin.TestPortsV2,
def test_requested_subnet_id_v4_and_v6(self): def test_requested_subnet_id_v4_and_v6(self):
pass pass
def test_vif_port_binding(self):
with self.port(name='myname') as port:
self.assertEqual('midonet', port['port']['binding:vif_type'])
self.assertTrue(port['port']['admin_state_up'])
class TestMidonetPluginPortBinding(test_bindings.PortBindingsTestCase,
MidonetPluginV2TestCase):
VIF_TYPE = portbindings.VIF_TYPE_MIDONET
HAS_PORT_FILTER = True
def setUp(self):
super(TestMidonetPluginPortBinding, self).setUp()