VMware: Network fallback in case specified one not found

In the case that opqaue network does not match the bridge ID then
we will fall back on a predefined network (configurable by the admin
via 'integration_bridge' in the 'vmware' section).

Fixes bug 1225002

(cherry picked from commit a0546fd3f4)

Change-Id: I7508a13f116b539fef1f771fc5ab4c32ffa520bc
This commit is contained in:
Gary Kotton 2013-08-14 02:05:27 -07:00
parent 96d828fb69
commit a4e214ec81
2 changed files with 147 additions and 12 deletions

View File

@ -15,11 +15,20 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo.config import cfg
from nova import exception
from nova.network import model as network_model
from nova import test
from nova.tests import matchers
from nova.tests.virt.vmwareapi import test_vmwareapi_vm_util
from nova.virt.vmwareapi import fake
from nova.virt.vmwareapi import network_util
from nova.virt.vmwareapi import vif
from nova.virt.vmwareapi import vim_util
from nova.virt.vmwareapi import vm_util
CONF = cfg.CONF
class VMwareVifTestCase(test.NoDBTestCase):
@ -42,7 +51,7 @@ class VMwareVifTestCase(test.NoDBTestCase):
ovs_interfaceid=None,
rxtx_cap=3)
])[0]
self.session = "fake"
self.session = test_vmwareapi_vm_util.fake_session()
self.cluster = None
def tearDown(self):
@ -63,7 +72,7 @@ class VMwareVifTestCase(test.NoDBTestCase):
self.cluster).AndReturn(True)
network_util.create_port_group(self.session, 'fa0', 'vmnet0', 3,
self.cluster)
network_util.get_network_with_the_name('fake', 'fa0', None)
network_util.get_network_with_the_name(self.session, 'fa0', None)
self.mox.ReplayAll()
vif.ensure_vlan_bridge(self.session, self.vif, create_vlan=True)
@ -85,7 +94,7 @@ class VMwareVifTestCase(test.NoDBTestCase):
self.cluster).AndReturn(True)
network_util.create_port_group(self.session, 'fa0', 'vmnet0', 0,
self.cluster)
network_util.get_network_with_the_name('fake', 'fa0', None)
network_util.get_network_with_the_name(self.session, 'fa0', None)
self.mox.ReplayAll()
vif.ensure_vlan_bridge(self.session, self.vif, create_vlan=False)
@ -158,3 +167,110 @@ class VMwareVifTestCase(test.NoDBTestCase):
rxtx_cap=3)
])[0]
vif.get_network_ref(self.session, self.cluster, self.vif, False)
def test_get_network_ref_bridge(self):
opaque_networks = [{'opaqueNetworkId': 'bridge_id',
'opaqueNetworkName': 'name',
'opaqueNetworkType': 'OpaqueNetwork'}]
network_ref = vif._get_network_ref_from_opaque(opaque_networks,
'integration_bridge', 'bridge_id')
self.assertEqual('bridge_id', network_ref['network-id'])
def test_get_network_ref_bridges(self):
opaque_networks = [{'opaqueNetworkId': 'bridge_id1',
'opaqueNetworkName': 'name1',
'opaqueNetworkType': 'OpaqueNetwork'},
{'opaqueNetworkId': 'bridge_id2',
'opaqueNetworkName': 'name2',
'opaqueNetworkType': 'OpaqueNetwork'}]
network_ref = vif._get_network_ref_from_opaque(opaque_networks,
'integration_bridge', 'bridge_id2')
self.assertEqual('bridge_id2', network_ref['network-id'])
def test_get_network_ref_integration(self):
opaque_networks = [{'opaqueNetworkId': 'integration_bridge',
'opaqueNetworkName': 'name',
'opaqueNetworkType': 'OpaqueNetwork'}]
network_ref = vif._get_network_ref_from_opaque(opaque_networks,
'integration_bridge', 'bridge_id')
self.assertEqual('integration_bridge', network_ref['network-id'])
def test_get_network_ref_bridge_none(self):
opaque_networks = [{'opaqueNetworkId': 'bridge_id1',
'opaqueNetworkName': 'name1',
'opaqueNetworkType': 'OpaqueNetwork'},
{'opaqueNetworkId': 'bridge_id2',
'opaqueNetworkName': 'name2',
'opaqueNetworkType': 'OpaqueNetwork'}]
network_ref = vif._get_network_ref_from_opaque(opaque_networks,
'integration_bridge', 'bridge_id')
self.assertIsNone(network_ref)
def test_get_network_ref_integration_multiple(self):
opaque_networks = [{'opaqueNetworkId': 'bridge_id1',
'opaqueNetworkName': 'name1',
'opaqueNetworkType': 'OpaqueNetwork'},
{'opaqueNetworkId': 'integration_bridge',
'opaqueNetworkName': 'name2',
'opaqueNetworkType': 'OpaqueNetwork'}]
network_ref = vif._get_network_ref_from_opaque(opaque_networks,
'integration_bridge', 'bridge_id')
self.assertIsNone(network_ref)
def test_get_neutron_network(self):
self.mox.StubOutWithMock(vm_util, 'get_host_ref')
self.mox.StubOutWithMock(self.session, '_call_method')
self.mox.StubOutWithMock(vif, '_get_network_ref_from_opaque')
vm_util.get_host_ref(self.session,
self.cluster).AndReturn('fake-host')
opaque = fake.DataObject()
opaque.HostOpaqueNetworkInfo = ['fake-network-info']
self.session._call_method(vim_util, "get_dynamic_property",
'fake-host', 'HostSystem',
'config.network.opaqueNetwork').AndReturn(opaque)
vif._get_network_ref_from_opaque(opaque.HostOpaqueNetworkInfo,
CONF.vmware.integration_bridge,
self.vif['network']['id']).AndReturn('fake-network-ref')
self.mox.ReplayAll()
network_ref = vif.get_neutron_network(self.session,
self.vif['network']['id'],
self.cluster,
self.vif)
self.assertEqual(network_ref, 'fake-network-ref')
def test_get_neutron_network_opaque_network_not_found(self):
self.mox.StubOutWithMock(vm_util, 'get_host_ref')
self.mox.StubOutWithMock(self.session, '_call_method')
self.mox.StubOutWithMock(vif, '_get_network_ref_from_opaque')
vm_util.get_host_ref(self.session,
self.cluster).AndReturn('fake-host')
opaque = fake.DataObject()
opaque.HostOpaqueNetworkInfo = ['fake-network-info']
self.session._call_method(vim_util, "get_dynamic_property",
'fake-host', 'HostSystem',
'config.network.opaqueNetwork').AndReturn(opaque)
vif._get_network_ref_from_opaque(opaque.HostOpaqueNetworkInfo,
CONF.vmware.integration_bridge,
self.vif['network']['id']).AndReturn(None)
self.mox.ReplayAll()
self.assertRaises(exception.NetworkNotFoundForBridge,
vif.get_neutron_network, self.session,
self.vif['network']['id'], self.cluster, self.vif)
def test_get_neutron_network_bridge_network_not_found(self):
self.mox.StubOutWithMock(vm_util, 'get_host_ref')
self.mox.StubOutWithMock(self.session, '_call_method')
self.mox.StubOutWithMock(network_util, 'get_network_with_the_name')
vm_util.get_host_ref(self.session,
self.cluster).AndReturn('fake-host')
opaque = fake.DataObject()
opaque.HostOpaqueNetworkInfo = ['fake-network-info']
self.session._call_method(vim_util, "get_dynamic_property",
'fake-host', 'HostSystem',
'config.network.opaqueNetwork').AndReturn(None)
network_util.get_network_with_the_name(self.session, 0,
self.cluster).AndReturn(None)
self.mox.ReplayAll()
self.assertRaises(exception.NetworkNotFoundForBridge,
vif.get_neutron_network, self.session,
self.vif['network']['id'], self.cluster, self.vif)

View File

@ -20,11 +20,14 @@
from oslo.config import cfg
from nova import exception
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log as logging
from nova.virt.vmwareapi import error_util
from nova.virt.vmwareapi import network_util
from nova.virt.vmwareapi import vim_util
from nova.virt.vmwareapi import vm_util
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
vmwareapi_vif_opts = [
@ -96,6 +99,28 @@ def ensure_vlan_bridge(session, vif, cluster=None, create_vlan=True):
return network_ref
def _is_valid_opaque_network_id(opaque_id, bridge_id, integration_bridge,
num_networks):
return (opaque_id == bridge_id or
(num_networks == 1 and
opaque_id == integration_bridge))
def _get_network_ref_from_opaque(opaque_networks, integration_bridge, bridge):
num_networks = len(opaque_networks)
for network in opaque_networks:
if _is_valid_opaque_network_id(network['opaqueNetworkId'], bridge,
integration_bridge, num_networks):
return {'type': 'OpaqueNetwork',
'network-id': network['opaqueNetworkId'],
'network-name': network['opaqueNetworkName'],
'network-type': network['opaqueNetworkType']}
LOG.warning(_("No valid network found in %(opaque)s, from %(bridge)s "
"or %(integration_bridge)s"),
{'opaque': opaque_networks, 'bridge': bridge,
'integration_bridge': integration_bridge})
def get_neutron_network(session, network_name, cluster, vif):
host = vm_util.get_host_ref(session, cluster)
try:
@ -104,22 +129,16 @@ def get_neutron_network(session, network_name, cluster, vif):
"config.network.opaqueNetwork")
except error_util.VimFaultException:
opaque = None
network_ref = None
if opaque:
bridge = vif['network']['id']
opaque_networks = opaque.HostOpaqueNetworkInfo
for network in opaque_networks:
if network['opaqueNetworkId'] == bridge:
network_ref = {'type': 'OpaqueNetwork',
'network-id': network['opaqueNetworkId'],
'network-name': network['opaqueNetworkName'],
'network-type': network['opaqueNetworkType']}
break
network_ref = _get_network_ref_from_opaque(opaque_networks,
CONF.vmware.integration_bridge, bridge)
else:
bridge = network_name
network_ref = network_util.get_network_with_the_name(
session, network_name, cluster)
if network_ref is None:
if not network_ref:
raise exception.NetworkNotFoundForBridge(bridge=bridge)
return network_ref