From ffc2696bcb265fee5f762607203073c0e82e4cfa Mon Sep 17 00:00:00 2001 From: Antoine Millet Date: Tue, 1 Mar 2016 15:06:06 +0100 Subject: [PATCH] Fixed vlan tags to handle simultaneous tagged and untagged VLANs --- .../node/hypervisor/domains/__init__.py | 52 ++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/cloudcontrol/node/hypervisor/domains/__init__.py b/cloudcontrol/node/hypervisor/domains/__init__.py index 71598cb..a4ff0f0 100644 --- a/cloudcontrol/node/hypervisor/domains/__init__.py +++ b/cloudcontrol/node/hypervisor/domains/__init__.py @@ -21,7 +21,6 @@ import socket import weakref from StringIO import StringIO from xml.etree import cElementTree as et -from collections import namedtuple from itertools import izip, count from functools import partial @@ -42,7 +41,22 @@ REGEX_TAG_VALUE = '.+' REGEX_TAG_IN_DESCRIPTION = '^@(' + REGEX_TAG_NAME + ')[ ]*?=[ ]*?(' + REGEX_TAG_VALUE + ')$' REGEX_TAG_REPLACE = '^@%s[ ]*?=[ ]*?(' + REGEX_TAG_VALUE + ')$' -NetworkInterface = namedtuple('NetworkInterface', ('source', 'mac', 'model', 'vlans', 'mode')) + +class NetworkInterface(object): + + def __init__(self, source=None, mac=None, model=None, untagged_vlan=None, tagged_vlans=None): + self.source = source + self.mac = mac + self.model = model + self.untagged_vlan = untagged_vlan + self.tagged_vlans = set() if tagged_vlans is None else set(tagged_vlans) + + @property + def vlans(self): + if self.untagged_vlan is not None: + yield self.untagged_vlan + for vlan in self.tagged_vlans: + yield vlan class VirtualMachine(object): @@ -88,8 +102,9 @@ class VirtualMachine(object): Tag('nic%s_mac' % i, nic.mac), Tag('nic%s_source' % i, nic.source), Tag('nic%s_model' % i, nic.model), - Tag('nic%s_vlans' % i, ' '.join(nic.vlans)), - Tag('nic%s_mode' % i, nic.mode), + Tag('nic%s_untagged_vlan' % i, nic.untagged_vlan), + Tag('nic%s_tagged_vlans' % i, ' '.join(str(x) for x in nic.tagged_vlans)), + Tag('nic%s_vlans' % i, ' '.join(str(x) for x in nic.vlans)), ): self.tag_db.add_tag(t) @@ -316,26 +331,27 @@ class VirtualMachine(object): except AttributeError: source = None - vlans = set() - vlan_list = nic.find('vlan') - if vlan_list is not None: - for tag in vlan_list.findall('tag'): - tid = tag.get('id') - if tid is not None: - vlans.add(tid) - mode = {'yes': 'tagged', 'no': 'untagged'}[vlan_list.get('trunk', 'yes' if len(vlans) > 1 else 'no')] - elif source is not None: - mode = 'untagged' - vlans.add(source[2:]) + untagged_vlan = None + tagged_vlans = set() + vlan = nic.find('vlan') + if vlan is None: + untagged_vlan = source[2:] else: - mode = 'unknown' + tags = vlan.findall('tag') + trunk = vlan.get('trunk') == 'yes' or len(tags) > 1 + default_mode = 'tagged' if trunk else 'untagged' + for tag in tags: + if tag.get('nativeMode', default_mode) == 'untagged': + untagged_vlan = int(tag.get('id')) + else: + tagged_vlans.add(int(tag.get('id'))) yield NetworkInterface( mac=mac, source=source, model=model, - vlans=vlans, - mode=mode, + untagged_vlan=untagged_vlan, + tagged_vlans=tagged_vlans, ) def open_console(self): -- GitLab