From 70c659059b8fbef811ce79700aecb01c60242ebd Mon Sep 17 00:00:00 2001 From: Amir Sadoughi Date: Thu, 7 Feb 2013 04:28:34 +0000 Subject: VMWare driver to use current nova.network.model * Updated tests to use classes from nova.network.model instead of legacy "network,mapping" tuple. * Modified vmwareapi/{driver,vif,vmops}.py to use classes from nova.network.model instead of legacy "network,mapping" tuple. Fixes: bug 1112655 Change-Id: I7f4b39cd5add7d3cf7dcf485eb9855d0354f332c --- nova/tests/test_vmwareapi.py | 21 +--------- nova/tests/test_vmwareapi_vmops.py | 62 +++++++++++++++++++++++++++ nova/tests/utils.py | 85 ++++++++++++++++++++++++++++---------- nova/virt/vmwareapi/driver.py | 2 +- nova/virt/vmwareapi/vif.py | 6 +-- nova/virt/vmwareapi/vmops.py | 70 ++++++++++++++++--------------- 6 files changed, 169 insertions(+), 77 deletions(-) create mode 100644 nova/tests/test_vmwareapi_vmops.py diff --git a/nova/tests/test_vmwareapi.py b/nova/tests/test_vmwareapi.py index 74c786a86..e20a5a7b7 100644 --- a/nova/tests/test_vmwareapi.py +++ b/nova/tests/test_vmwareapi.py @@ -28,6 +28,7 @@ from nova import exception from nova import test import nova.tests.image.fake from nova.tests import matchers +from nova.tests import utils from nova.tests.vmwareapi import db_fakes from nova.tests.vmwareapi import stubs from nova.virt.vmwareapi import driver @@ -54,25 +55,7 @@ class VMwareAPIVMTestCase(test.TestCase): self.conn = driver.VMwareESXDriver(None, False) # NOTE(vish): none of the network plugging code is actually # being tested - self.network_info = [({'bridge': 'fa0', - 'id': 0, - 'vlan': None, - 'bridge_interface': None, - 'injected': True}, - {'broadcast': '192.168.0.255', - 'id': 'foo', - 'dns': ['192.168.0.1'], - 'gateway': '192.168.0.1', - 'gateway_v6': 'dead:beef::1', - 'ip6s': [{'enabled': '1', - 'ip': 'dead:beef::dcad:beff:feef:0', - 'netmask': '64'}], - 'ips': [{'enabled': '1', - 'ip': '192.168.0.100', - 'netmask': '255.255.255.0'}], - 'label': 'fake', - 'mac': 'DE:AD:BE:EF:00:00', - 'rxtx_cap': 3})] + self.network_info = utils.get_test_network_info(legacy_model=False) self.image = { 'id': 'c1c8ce3d-c2e0-4247-890c-ccf5cc1c004c', diff --git a/nova/tests/test_vmwareapi_vmops.py b/nova/tests/test_vmwareapi_vmops.py new file mode 100644 index 000000000..ad83cd21d --- /dev/null +++ b/nova/tests/test_vmwareapi_vmops.py @@ -0,0 +1,62 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2013 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.network import model as network_model +from nova import test +from nova.virt.vmwareapi import vmops + + +class VMwareVMOpsTestCase(test.TestCase): + def setUp(self): + super(VMwareVMOpsTestCase, self).setUp() + subnet_4 = network_model.Subnet(cidr='192.168.0.1/24', + dns=[network_model.IP('192.168.0.1')], + gateway= + network_model.IP('192.168.0.1'), + ips=[ + network_model.IP('192.168.0.100')], + routes=None) + subnet_6 = network_model.Subnet(cidr='dead:beef::1/64', + dns=None, + gateway= + network_model.IP('dead:beef::1'), + ips=[network_model.IP( + 'dead:beef::dcad:beff:feef:0')], + routes=None) + network = network_model.Network(id=0, + bridge='fa0', + label='fake', + subnets=[subnet_4, subnet_6], + vlan=None, + bridge_interface=None, + injected=True) + self.network_info = network_model.NetworkInfo([ + network_model.VIF(id=None, + address='DE:AD:BE:EF:00:00', + network=network, + type=None, + devname=None, + ovs_interfaceid=None, + rxtx_cap=3) + ]) + + def test_get_machine_id_str(self): + result = vmops.VMwareVMOps._get_machine_id_str(self.network_info) + print result + self.assertEqual(result, + 'DE:AD:BE:EF:00:00;192.168.0.100;255.255.255.0;' + '192.168.0.1;192.168.0.255;192.168.0.1#') diff --git a/nova/tests/utils.py b/nova/tests/utils.py index a5d4b4712..56be3ab71 100644 --- a/nova/tests/utils.py +++ b/nova/tests/utils.py @@ -89,7 +89,7 @@ def get_test_instance(context=None, instance_type=None): return instance_ref -def get_test_network_info(count=1): +def get_test_network_info(count=1, legacy_model=True): ipv6 = CONF.use_ipv6 fake = 'fake' fake_ip = '0.0.0.0/0' @@ -98,26 +98,69 @@ def get_test_network_info(count=1): fake_netmask = '255.255.255.255' fake_vlan = 100 fake_bridge_interface = 'eth0' - network = {'bridge': fake, - 'cidr': fake_ip, - 'cidr_v6': fake_ip, - 'vlan': fake_vlan, - 'bridge_interface': fake_bridge_interface, - 'injected': False} - mapping = {'mac': fake, - 'vif_type': network_model.VIF_TYPE_BRIDGE, - 'vif_uuid': 'vif-xxx-yyy-zzz', - 'dhcp_server': fake, - 'dns': ['fake1', 'fake2'], - 'gateway': fake, - 'gateway_v6': fake, - 'ips': [{'ip': fake_ip, 'netmask': fake_netmask}, - {'ip': fake_ip, 'netmask': fake_netmask}]} - if ipv6: - mapping['ip6s'] = [{'ip': fake_ip, 'netmask': fake_netmask}, - {'ip': fake_ip_2}, - {'ip': fake_ip_3}] - return [(network, mapping) for x in xrange(0, count)] + + def legacy(): + network = {'bridge': fake, + 'cidr': fake_ip, + 'cidr_v6': fake_ip, + 'vlan': fake_vlan, + 'bridge_interface': fake_bridge_interface, + 'injected': False} + mapping = {'mac': fake, + 'vif_type': network_model.VIF_TYPE_BRIDGE, + 'vif_uuid': 'vif-xxx-yyy-zzz', + 'dhcp_server': fake, + 'dns': ['fake1', 'fake2'], + 'gateway': fake, + 'gateway_v6': fake, + 'ips': [{'ip': fake_ip, 'netmask': fake_netmask}, + {'ip': fake_ip, 'netmask': fake_netmask}]} + if ipv6: + mapping['ip6s'] = [{'ip': fake_ip, 'netmask': fake_netmask}, + {'ip': fake_ip_2}, + {'ip': fake_ip_3}] + return network, mapping + + def current(): + fake_ip = '0.0.0.0' + subnet_4 = network_model.Subnet(cidr=fake_ip, + dns=[network_model.IP(fake_ip), + network_model.IP(fake_ip)], + gateway=network_model.IP(fake_ip), + ips=[network_model.IP(fake_ip), + network_model.IP(fake_ip)], + routes=None, + dhcp_server=network_model.IP(fake_ip)) + subnet_6 = network_model.Subnet(cidr=fake_ip, + gateway=network_model.IP(fake_ip), + ips=[network_model.IP(fake_ip), + network_model.IP(fake_ip), + network_model.IP(fake_ip)], + routes=None, + version=6) + subnets = [subnet_4] + if ipv6: + subnets.append(subnet_6) + network = network_model.Network(id=None, + bridge=fake, + label=None, + subnets=subnets, + vlan=fake_vlan, + bridge_interface=fake_bridge_interface, + injected=False) + vif = network_model.VIF(id='vif-xxx-yyy-zzz', + address=fake, + network=network, + type=network_model.VIF_TYPE_BRIDGE, + devname=None, + ovs_interfaceid=None) + + return vif + + if legacy_model: + return [legacy() for x in xrange(0, count)] + else: + return network_model.NetworkInfo([current() for x in xrange(0, count)]) def is_osx(): diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index 19f984c7d..63d9e3c57 100755 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -164,7 +164,7 @@ class VMwareESXDriver(driver.ComputeDriver): pass def legacy_nwinfo(self): - return True + return False def list_instances(self): """List VM instances.""" diff --git a/nova/virt/vmwareapi/vif.py b/nova/virt/vmwareapi/vif.py index 137045508..e2dfa0427 100644 --- a/nova/virt/vmwareapi/vif.py +++ b/nova/virt/vmwareapi/vif.py @@ -36,10 +36,10 @@ vmwareapi_vif_opts = [ CONF.register_opts(vmwareapi_vif_opts) -def ensure_vlan_bridge(self, session, network, cluster=None): +def ensure_vlan_bridge(self, session, vif, cluster=None): """Create a vlan and bridge unless they already exist.""" - vlan_num = network['vlan'] - bridge = network['bridge'] + vlan_num = vif['network'].get_meta('vlan') + bridge = vif['network']['bridge'] vlan_interface = CONF.vmwareapi_vlan_interface # Check if the vlan_interface physical network adapter exists on the diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 4b8f926e3..0aeb58ea3 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -176,20 +176,20 @@ class VMwareVMOps(object): vif_infos = [] if network_info is None: return vif_infos - for (network, mapping) in network_info: - mac_address = mapping['mac'] - network_name = network['bridge'] or \ + for vif in network_info: + mac_address = vif['address'] + network_name = vif['network']['bridge'] or \ CONF.vmware.integration_bridge - if mapping.get('should_create_vlan'): + if vif['network'].get_meta('should_create_vlan', False): network_ref = vmwarevif.ensure_vlan_bridge( - self._session, network, + self._session, vif, self._cluster) else: network_ref = _check_if_network_bridge_exists(network_name) vif_infos.append({'network_name': network_name, 'mac_address': mac_address, 'network_ref': network_ref, - 'iface_id': mapping.get('id'), + 'iface_id': vif.get_meta('iface_id'), }) return vif_infos @@ -1127,6 +1127,33 @@ class VMwareVMOps(object): return port + @staticmethod + def _get_machine_id_str(network_info): + machine_id_str = '' + for vif in network_info: + # TODO(vish): add support for dns2 + # TODO(sateesh): add support for injection of ipv6 configuration + network = vif['network'] + ip_v4 = netmask_v4 = gateway_v4 = broadcast_v4 = dns = None + subnets_v4 = [s for s in network['subnets'] if s['version'] == 4] + if len(subnets_v4[0]['ips']) > 0: + ip_v4 = subnets_v4[0]['ips'][0] + if len(subnets_v4[0]['dns']) > 0: + dns = subnets_v4[0]['dns'][0]['address'] + + netmask_v4 = str(subnets_v4[0].as_netaddr().netmask) + gateway_v4 = subnets_v4[0]['gateway']['address'] + broadcast_v4 = str(subnets_v4[0].as_netaddr().broadcast) + + interface_str = ";".join([vif['address'], + ip_v4 and ip_v4['address'] or '', + netmask_v4 or '', + gateway_v4 or '', + broadcast_v4 or '', + dns or '']) + machine_id_str = machine_id_str + interface_str + '#' + return machine_id_str + def _set_machine_id(self, client_factory, instance, network_info): """ Set the machine id of the VM for guest tools to pick up and reconfigure @@ -1136,40 +1163,17 @@ class VMwareVMOps(object): if vm_ref is None: raise exception.InstanceNotFound(instance_id=instance['uuid']) - machine_id_str = '' - for (network, info) in network_info: - # TODO(vish): add support for dns2 - # TODO(sateesh): add support for injection of ipv6 configuration - ip_v4 = ip_v6 = None - if 'ips' in info and len(info['ips']) > 0: - ip_v4 = info['ips'][0] - if 'ip6s' in info and len(info['ip6s']) > 0: - ip_v6 = info['ip6s'][0] - if len(info['dns']) > 0: - dns = info['dns'][0] - else: - dns = '' - - interface_str = ";".join([info['mac'], - ip_v4 and ip_v4['ip'] or '', - ip_v4 and ip_v4['netmask'] or '', - info['gateway'], - info['broadcast'], - dns]) - machine_id_str = machine_id_str + interface_str + '#' - machine_id_change_spec = vm_util.get_machine_id_change_spec( - client_factory, machine_id_str) + client_factory, + self._get_machine_id_str(network_info)) - LOG.debug(_("Reconfiguring VM instance to set the machine id " - "with ip - %(ip_addr)s") % {'ip_addr': ip_v4['ip']}, + LOG.debug(_("Reconfiguring VM instance to set the machine id"), instance=instance) reconfig_task = self._session._call_method(self._session._get_vim(), "ReconfigVM_Task", vm_ref, spec=machine_id_change_spec) self._session._wait_for_task(instance['uuid'], reconfig_task) - LOG.debug(_("Reconfigured VM instance to set the machine id " - "with ip - %(ip_addr)s") % {'ip_addr': ip_v4['ip']}, + LOG.debug(_("Reconfigured VM instance to set the machine id"), instance=instance) def _set_vnc_config(self, client_factory, instance, port, password): -- cgit