diff options
-rw-r--r-- | nova/network/model.py | 25 | ||||
-rw-r--r-- | nova/tests/network/test_manager.py | 2 | ||||
-rw-r--r-- | nova/tests/test_libvirt_vif.py | 121 | ||||
-rw-r--r-- | nova/virt/libvirt/config.py | 3 | ||||
-rw-r--r-- | nova/virt/libvirt/designer.py | 32 | ||||
-rw-r--r-- | nova/virt/libvirt/vif.py | 57 |
6 files changed, 238 insertions, 2 deletions
diff --git a/nova/network/model.py b/nova/network/model.py index 9accb883e..bfd4639ee 100644 --- a/nova/network/model.py +++ b/nova/network/model.py @@ -204,10 +204,29 @@ class Network(Model): return network +class VIF8021QbgParams(Model): + """Represents the parameters for a 802.1qbg VIF.""" + + def __init__(self, managerid, typeid, typeidversion, instanceid): + self['managerid'] = managerid + self['typeid'] = typeid + self['typeidversion'] = typeidversion + self['instanceid'] = instanceid + + +class VIF8021QbhParams(Model): + """Represents the parameters for a 802.1qbh VIF.""" + + def __init__(self, profileid): + self['profileid'] = profileid + + class VIF(Model): """Represents a Virtual Interface in Nova.""" def __init__(self, id=None, address=None, network=None, type=None, - devname=None, ovs_interfaceid=None, **kwargs): + devname=None, ovs_interfaceid=None, + qbh_params=None, qbg_params=None, + **kwargs): super(VIF, self).__init__() self['id'] = id @@ -217,6 +236,8 @@ class VIF(Model): self['devname'] = devname self['ovs_interfaceid'] = ovs_interfaceid + self['qbh_params'] = qbh_params + self['qbg_params'] = qbg_params self._set_meta(kwargs) @@ -384,6 +405,8 @@ class NetworkInfo(list): 'vif_devname': vif.get('devname'), 'vif_uuid': vif['id'], 'ovs_interfaceid': vif.get('ovs_interfaceid'), + 'qbh_params': vif.get('qbh_params'), + 'qbg_params': vif.get('qbg_params'), 'rxtx_cap': vif.get_meta('rxtx_cap', 0), 'dns': [get_ip(ip) for ip in subnet_v4['dns']], 'ips': [fixed_ip_dict(ip, subnet) diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py index c0a434e6c..3728dd2e0 100644 --- a/nova/tests/network/test_manager.py +++ b/nova/tests/network/test_manager.py @@ -186,6 +186,8 @@ class FlatNetworkTestCase(test.TestCase): 'vif_uuid': '00000000-0000-0000-0000-00000000000000%02d' % nid, 'ovs_interfaceid': None, + 'qbh_params': None, + 'qbg_params': None, 'should_create_vlan': False, 'should_create_bridge': False} self.assertThat(info, matchers.DictMatches(check)) diff --git a/nova/tests/test_libvirt_vif.py b/nova/tests/test_libvirt_vif.py index c6937bde3..916b961da 100644 --- a/nova/tests/test_libvirt_vif.py +++ b/nova/tests/test_libvirt_vif.py @@ -111,6 +111,41 @@ class LibvirtVifTestCase(test.TestCase): 'vif_uuid': 'vif-xxx-yyy-zzz', } + net_8021 = { + 'cidr': '101.168.1.0/24', + 'cidr_v6': '101:1db9::/64', + 'gateway_v6': '101:1db9::1', + 'netmask_v6': '64', + 'netmask': '255.255.255.0', + 'interface': 'eth0', + 'vlan': 99, + 'gateway': '101.168.1.1', + 'broadcast': '101.168.1.255', + 'dns1': '8.8.8.8', + 'id': 'network-id-xxx-yyy-zzz' + } + + mapping_8021qbh = { + 'mac': 'ca:fe:de:ad:be:ef', + 'vif_uuid': 'vif-xxx-yyy-zzz', + 'vif_devname': 'tap-xxx-yyy-zzz', + 'vif_type': network_model.VIF_TYPE_802_QBH, + 'qbh_params': network_model.VIF8021QbhParams( + profileid="xxx-yyy-zzz"), + } + + mapping_8021qbg = { + 'mac': 'ca:fe:de:ad:be:ef', + 'vif_uuid': 'vif-xxx-yyy-zzz', + 'vif_devname': 'tap-xxx-yyy-zzz', + 'vif_type': network_model.VIF_TYPE_802_QBG, + 'qbg_params': network_model.VIF8021QbgParams( + managerid="xxx-yyy-zzz", + typeid="aaa-bbb-ccc", + typeidversion="1", + instanceid="ddd-eee-fff") + } + mapping_none = { 'mac': 'ca:fe:de:ad:be:ef', 'gateway_v6': net_bridge['gateway_v6'], @@ -457,3 +492,89 @@ class LibvirtVifTestCase(test.TestCase): self.net_ovs, self.mapping_ovs, br_want) + + def test_generic_8021qbh_driver(self): + def get_connection(): + return fakelibvirt.Connection("qemu:///session", + False) + d = vif.LibvirtGenericVIFDriver(get_connection) + xml = self._get_instance_xml(d, + self.net_8021, + self.mapping_8021qbh) + + doc = etree.fromstring(xml) + ret = doc.findall('./devices/interface') + self.assertEqual(len(ret), 1) + node = ret[0] + self.assertEqual(node.get("type"), "direct") + + br_name = node.find("source").get("dev") + self.assertEqual(br_name, "eth0") + mac = node.find("mac").get("address") + self.assertEqual(mac, self.mapping_8021qbh['mac']) + vp = node.find("virtualport") + self.assertEqual(vp.get("type"), "802.1Qbh") + profile_id_found = False + for p_elem in vp.findall("parameters"): + wantparams = self.mapping_8021qbh['qbh_params'] + profile_id = p_elem.get("profileid", None) + if profile_id: + self.assertEqual(profile_id, + wantparams['profileid']) + profile_id_found = True + + self.assertTrue(profile_id_found) + + def test_generic_8021qbg_driver(self): + def get_connection(): + return fakelibvirt.Connection("qemu:///session", + False) + d = vif.LibvirtGenericVIFDriver(get_connection) + xml = self._get_instance_xml(d, + self.net_8021, + self.mapping_8021qbg) + + doc = etree.fromstring(xml) + print xml + ret = doc.findall('./devices/interface') + self.assertEqual(len(ret), 1) + node = ret[0] + self.assertEqual(node.get("type"), "direct") + + br_name = node.find("source").get("dev") + self.assertEqual(br_name, "eth0") + mac = node.find("mac").get("address") + self.assertEqual(mac, self.mapping_8021qbg['mac']) + vp = node.find("virtualport") + self.assertEqual(vp.get("type"), "802.1Qbg") + manager_id_found = False + type_id_found = False + typeversion_id_found = False + instance_id_found = False + for p_elem in vp.findall("parameters"): + wantparams = self.mapping_8021qbg['qbg_params'] + manager_id = p_elem.get("managerid", None) + type_id = p_elem.get("typeid", None) + typeversion_id = p_elem.get("typeidversion", None) + instance_id = p_elem.get("instanceid", None) + if manager_id: + self.assertEqual(manager_id, + wantparams['managerid']) + manager_id_found = True + if type_id: + self.assertEqual(type_id, + wantparams['typeid']) + type_id_found = True + if typeversion_id: + self.assertEqual(typeversion_id, + wantparams['typeidversion']) + typeversion_id_found = True + if instance_id: + self.assertEqual(instance_id, + wantparams['instanceid']) + instance_id_found = True + + self.assertTrue(manager_id_found) + self.assertTrue(type_id_found) + self.assertTrue(typeversion_id_found) + self.assertTrue(instance_id_found) diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py index ed5b21c79..d6ef3fca9 100644 --- a/nova/virt/libvirt/config.py +++ b/nova/virt/libvirt/config.py @@ -549,6 +549,7 @@ class LibvirtConfigGuestInterface(LibvirtConfigGuestDevice): self.mac_addr = None self.script = None self.source_dev = None + self.source_mode = "private" self.vporttype = None self.vportparams = [] self.filtername = None @@ -571,7 +572,7 @@ class LibvirtConfigGuestInterface(LibvirtConfigGuestDevice): dev.append(etree.Element("script", path=self.script)) elif self.net_type == "direct": dev.append(etree.Element("source", dev=self.source_dev, - mode="private")) + mode=self.source_mode)) else: dev.append(etree.Element("source", bridge=self.source_dev)) diff --git a/nova/virt/libvirt/designer.py b/nova/virt/libvirt/designer.py index b832db4fa..176eeef4c 100644 --- a/nova/virt/libvirt/designer.py +++ b/nova/virt/libvirt/designer.py @@ -70,6 +70,38 @@ def set_vif_host_backend_ovs_config(conf, brname, interfaceid, tapname=None): conf.script = "" +def set_vif_host_backend_802qbg_config(conf, devname, managerid, + typeid, typeidversion, + instanceid, tapname=None): + """Populate a LibvirtConfigGuestInterface instance + with host backend details for an 802.1qbg device""" + + conf.net_type = "direct" + conf.source_dev = devname + conf.source_mode = "vepa" + conf.vporttype = "802.1Qbg" + conf.add_vport_param("managerid", managerid) + conf.add_vport_param("typeid", typeid) + conf.add_vport_param("typeidversion", typeidversion) + conf.add_vport_param("instanceid", instanceid) + if tapname: + conf.target_dev = tapname + + +def set_vif_host_backend_802qbh_config(conf, devname, profileid, + tapname=None): + """Populate a LibvirtConfigGuestInterface instance + with host backend details for an 802.1qbh device""" + + conf.net_type = "direct" + conf.source_dev = devname + conf.source_mode = "vepa" + conf.vporttype = "802.1Qbh" + conf.add_vport_param("profileid", profileid) + if tapname: + conf.target_dev = tapname + + def set_vif_host_backend_filter_config(conf, name, primary_addr, dhcp_server=None, diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index 4a56e3fb6..0990f29b1 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -196,6 +196,35 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): return self.get_config_ovs_ethernet(instance, network, mapping) + def get_config_802qbg(self, instance, network, mapping): + conf = super(LibvirtGenericVIFDriver, + self).get_config(instance, + network, + mapping) + + params = mapping["qbg_params"] + designer.set_vif_host_backend_802qbg_config( + conf, network["interface"], + params['managerid'], + params['typeid'], + params['typeidversion'], + params['instanceid']) + + return conf + + def get_config_802qbh(self, instance, network, mapping): + conf = super(LibvirtGenericVIFDriver, + self).get_config(instance, + network, + mapping) + + params = mapping["qbh_params"] + designer.set_vif_host_backend_802qbh_config( + conf, network["interface"], + params['profileid']) + + return conf + def get_config(self, instance, network, mapping): vif_type = mapping.get('vif_type') @@ -212,6 +241,10 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): return self.get_config_bridge(instance, network, mapping) elif vif_type == network_model.VIF_TYPE_OVS: return self.get_config_ovs(instance, network, mapping) + elif vif_type == network_model.VIF_TYPE_802_QBG: + return self.get_config_802qbg(instance, network, mapping) + elif vif_type == network_model.VIF_TYPE_802_QBH: + return self.get_config_802qbh(instance, network, mapping) else: raise exception.NovaException( _("Unexpected vif_type=%s") % vif_type) @@ -294,6 +327,14 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): else: self.plug_ovs_ethernet(instance, vif) + def plug_802qbg(self, instance, vif): + super(LibvirtGenericVIFDriver, + self).plug(instance, vif) + + def plug_802qbh(self, instance, vif): + super(LibvirtGenericVIFDriver, + self).plug(instance, vif) + def plug(self, instance, vif): network, mapping = vif vif_type = mapping.get('vif_type') @@ -311,6 +352,10 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): self.plug_bridge(instance, vif) elif vif_type == network_model.VIF_TYPE_OVS: self.plug_ovs(instance, vif) + elif vif_type == network_model.VIF_TYPE_802_QBG: + self.plug_802qbg(instance, vif) + elif vif_type == network_model.VIF_TYPE_802_QBH: + self.plug_802qbh(instance, vif) else: raise exception.NovaException( _("Unexpected vif_type=%s") % vif_type) @@ -369,6 +414,14 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): else: self.unplug_ovs_ethernet(instance, vif) + def unplug_802qbg(self, instance, vif): + super(LibvirtGenericVIFDriver, + self).unplug(instance, vif) + + def unplug_802qbh(self, instance, vif): + super(LibvirtGenericVIFDriver, + self).unplug(instance, vif) + def unplug(self, instance, vif): network, mapping = vif vif_type = mapping.get('vif_type') @@ -386,6 +439,10 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): self.unplug_bridge(instance, vif) elif vif_type == network_model.VIF_TYPE_OVS: self.unplug_ovs(instance, vif) + elif vif_type == network_model.VIF_TYPE_802_QBG: + self.unplug_802qbg(instance, vif) + elif vif_type == network_model.VIF_TYPE_802_QBH: + self.unplug_802qbh(instance, vif) else: raise exception.NovaException( _("Unexpected vif_type=%s") % vif_type) |