diff --git a/nova/tests/unit/virt/vmwareapi/test_network_util.py b/nova/tests/unit/virt/vmwareapi/test_network_util.py index 76680c22a0..9d6533ebfb 100644 --- a/nova/tests/unit/virt/vmwareapi/test_network_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_network_util.py @@ -208,3 +208,16 @@ class GetVlanIdAndVswitchForPortgroupTestCase(test.NoDBTestCase): response = fake.DataObject() response.HostPortGroup = [port_group] return response + + +class GetDVSNetworkNameTestCase(test.NoDBTestCase): + + def test__get_name_from_dvs_name(self): + vxw = 'vxw-dvs-22-virtualwire-89-sid-5008-' + uuid = '2425c130-fd39-45a6-91d8-bf7ebe66b77c' + cases = [('name', 'name'), + ('%sname' % vxw, 'name'), + ('%s%s' % (vxw, uuid), uuid)] + for (dvsname, expected) in cases: + self.assertEqual(expected, + network_util._get_name_from_dvs_name(dvsname)) diff --git a/nova/tests/unit/virt/vmwareapi/test_vif.py b/nova/tests/unit/virt/vmwareapi/test_vif.py index 901fef2a5d..5aaed61e84 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vif.py +++ b/nova/tests/unit/virt/vmwareapi/test_vif.py @@ -366,3 +366,22 @@ class VMwareVifTestCase(test.NoDBTestCase): version_arg_found = True break self.assertTrue(version_arg_found) + + @mock.patch.object(network_util, 'get_network_with_the_name') + def test_get_neutron_network_dvs_provider(self, mock_network_name): + fake_network_obj = {'type': 'DistributedVirtualPortgroup', + 'dvpg': 'fake-key', + 'dvsw': 'fake-props'} + mock_network_name.side_effect = [None, fake_network_obj] + vif_info = network_model.NetworkInfo([ + network_model.VIF(type=network_model.VIF_TYPE_DVS, + address='DE:AD:BE:EF:00:00', + network=self._network)] + )[0] + network_ref = vif._get_neutron_network('fake-session', + 'fake-cluster', + vif_info) + calls = [mock.call('fake-session', 'fa0', 'fake-cluster'), + mock.call('fake-session', 'fake', 'fake-cluster')] + mock_network_name.assert_has_calls(calls) + self.assertEqual(fake_network_obj, network_ref) diff --git a/nova/virt/vmwareapi/network_util.py b/nova/virt/vmwareapi/network_util.py index 3a00cd8c92..c3169a8b5e 100644 --- a/nova/virt/vmwareapi/network_util.py +++ b/nova/virt/vmwareapi/network_util.py @@ -17,6 +17,8 @@ """ Utility functions for ESX Networking. """ +import re + from oslo_log import log as logging from oslo_vmware import exceptions as vexc from oslo_vmware import vim_util as vutil @@ -28,6 +30,20 @@ from nova.virt.vmwareapi import vm_util LOG = logging.getLogger(__name__) +# a virtual wire will have the following format: +# vxw---- +# Examples: +# - vxw-dvs-22-virtualwire-89-sid-5008-NAME +# - vxw-dvs-22-virtualwire-89-sid-5008-UUID +VWIRE_REGEX = re.compile('vxw-dvs-(\d+)-virtualwire-(\d+)-sid-(\d+)-(.*)') + + +def _get_name_from_dvs_name(dvs_name): + vwire = VWIRE_REGEX.match(dvs_name) + if not vwire: + return dvs_name + return vwire.group(4) + def _get_network_obj(session, network_objects, network_name): """Gets the network object for the requested network. @@ -64,10 +80,8 @@ def _get_network_obj(session, network_objects, network_name): "config") # NOTE(asomya): This only works on ESXi if the port binding # is set to ephemeral - # For a VLAN the network name will be the UUID. For a VXLAN - # network this will have a VXLAN prefix and then the - # network name. - if network_name in props.name: + net_name = _get_name_from_dvs_name(props.name) + if network_name in net_name: network_obj['type'] = 'DistributedVirtualPortgroup' network_obj['dvpg'] = props.key dvs_props = session._call_method(vutil, diff --git a/nova/virt/vmwareapi/vif.py b/nova/virt/vmwareapi/vif.py index ebcf873de6..dce87bcb6e 100644 --- a/nova/virt/vmwareapi/vif.py +++ b/nova/virt/vmwareapi/vif.py @@ -138,6 +138,13 @@ def _get_neutron_network(session, cluster, vif): network_id = vif['network']['bridge'] network_ref = network_util.get_network_with_the_name( session, network_id, cluster) + if not network_ref: + # We may have a provider network for a portgroup. The portgroup + # will have the same name as the network 'label'. This is enforced + # when the provider network is created + network_id = vif['network']['label'] + network_ref = network_util.get_network_with_the_name( + session, network_id, cluster) if not network_ref: raise exception.NetworkNotFoundForBridge(bridge=network_id) if vif.get('details') and vif['details'].get('dvs_port_key'):