From: Kevin Benton Date: Mon, 30 Mar 2015 18:29:44 +0000 (-0700) Subject: Fix _device_to_port_id for non-tap devices X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=3e4e932a4d9dbfac908cf03c221b350e645d8b17;p=openstack-build%2Fneutron-build.git Fix _device_to_port_id for non-tap devices This adjusts the _device_to_port_id function in ML2 to recognize other interfaces that belong to Neutron under different name prefixes. Adds unit tests to achieve full converage of _device_to_port_id method. Closes-Bug: #1443710 Change-Id: I80284ee67e5876cf5689e49e1592ca1351ae5fa1 --- diff --git a/neutron/agent/l3/dvr_snat_ns.py b/neutron/agent/l3/dvr_snat_ns.py index 63478cbb8..2e360cca3 100644 --- a/neutron/agent/l3/dvr_snat_ns.py +++ b/neutron/agent/l3/dvr_snat_ns.py @@ -14,10 +14,11 @@ from oslo_log import log as logging from neutron.agent.l3 import namespaces from neutron.agent.linux import ip_lib +from neutron.common import constants LOG = logging.getLogger(__name__) SNAT_NS_PREFIX = 'snat-' -SNAT_INT_DEV_PREFIX = 'sg-' +SNAT_INT_DEV_PREFIX = constants.SNAT_INT_DEV_PREFIX class SnatNamespace(namespaces.Namespace): diff --git a/neutron/common/constants.py b/neutron/common/constants.py index 1bb489118..1539ed61a 100644 --- a/neutron/common/constants.py +++ b/neutron/common/constants.py @@ -141,6 +141,16 @@ DEVICE_NAME_MAX_LEN = 15 # Device names start with "tap" TAP_DEVICE_PREFIX = 'tap' +# The vswitch side of a veth pair for a nova iptables filter setup +VETH_DEVICE_PREFIX = 'qvo' +# prefix for SNAT interface in DVR +SNAT_INT_DEV_PREFIX = 'sg-' + +# Possible prefixes to partial port IDs in interface names used by the OVS, +# Linux Bridge, and IVS VIF drivers in Nova and the neutron agents. See the +# 'get_ovs_interfaceid' method in Nova (nova/virt/libvirt/vif.py) for details. +INTERFACE_PREFIXES = (TAP_DEVICE_PREFIX, VETH_DEVICE_PREFIX, + SNAT_INT_DEV_PREFIX) ATTRIBUTES_TO_UPDATE = 'attributes_to_update' diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index c668454ac..2f209db77 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -1464,17 +1464,18 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, return ports - def _device_to_port_id(self, device): + @staticmethod + def _device_to_port_id(device): # REVISIT(rkukura): Consider calling into MechanismDrivers to # process device names, or having MechanismDrivers supply list # of device prefixes to strip. - if device.startswith(const.TAP_DEVICE_PREFIX): - return device[len(const.TAP_DEVICE_PREFIX):] - else: - # REVISIT(irenab): Consider calling into bound MD to - # handle the get_device_details RPC, then remove the 'else' clause - if not uuidutils.is_uuid_like(device): - port = db.get_port_from_device_mac(device) - if port: - return port.id + for prefix in const.INTERFACE_PREFIXES: + if device.startswith(prefix): + return device[len(prefix):] + # REVISIT(irenab): Consider calling into bound MD to + # handle the get_device_details RPC + if not uuidutils.is_uuid_like(device): + port = db.get_port_from_device_mac(device) + if port: + return port.id return device diff --git a/neutron/tests/unit/plugins/ml2/test_plugin.py b/neutron/tests/unit/plugins/ml2/test_plugin.py index cc51029fd..21b90976a 100644 --- a/neutron/tests/unit/plugins/ml2/test_plugin.py +++ b/neutron/tests/unit/plugins/ml2/test_plugin.py @@ -38,6 +38,7 @@ from neutron.extensions import multiprovidernet as mpnet from neutron.extensions import portbindings from neutron.extensions import providernet as pnet from neutron import manager +from neutron.openstack.common import uuidutils from neutron.plugins.common import constants as p_const from neutron.plugins.ml2.common import exceptions as ml2_exc from neutron.plugins.ml2 import config @@ -607,6 +608,30 @@ class TestMl2PluginOnly(Ml2PluginV2TestCase): with testtools.ExpectedException(exc.PortBound): self._test_check_mac_update_allowed(portbindings.VIF_TYPE_OVS) + def test__device_to_port_id_prefix_names(self): + input_output = [('sg-abcdefg', 'abcdefg'), + ('tap123456', '123456'), + ('qvo567890', '567890')] + for device, expected in input_output: + self.assertEqual(expected, + ml2_plugin.Ml2Plugin._device_to_port_id(device)) + + def test__device_to_port_id_mac_address(self): + with self.port() as p: + mac = p['port']['mac_address'] + port_id = p['port']['id'] + self.assertEqual(port_id, + ml2_plugin.Ml2Plugin._device_to_port_id(mac)) + + def test__device_to_port_id_not_uuid_not_mac(self): + dev = '1234567' + self.assertEqual(dev, ml2_plugin.Ml2Plugin._device_to_port_id(dev)) + + def test__device_to_port_id_UUID(self): + port_id = uuidutils.generate_uuid() + self.assertEqual(port_id, + ml2_plugin.Ml2Plugin._device_to_port_id(port_id)) + class TestMl2DvrPortsV2(TestMl2PortsV2): def setUp(self):