Commit ffc2696b authored by Antoine Millet's avatar Antoine Millet
Browse files

Fixed vlan tags to handle simultaneous tagged and untagged VLANs

parent 5335f5f4
Loading
Loading
Loading
Loading
+34 −18
Original line number Original line Diff line number Diff line
@@ -21,7 +21,6 @@ import socket
import weakref
import weakref
from StringIO import StringIO
from StringIO import StringIO
from xml.etree import cElementTree as et
from xml.etree import cElementTree as et
from collections import namedtuple
from itertools import izip, count
from itertools import izip, count
from functools import partial
from functools import partial


@@ -42,7 +41,22 @@ REGEX_TAG_VALUE = '.+'
REGEX_TAG_IN_DESCRIPTION = '^@(' + REGEX_TAG_NAME + ')[ ]*?=[ ]*?(' + REGEX_TAG_VALUE + ')$'
REGEX_TAG_IN_DESCRIPTION = '^@(' + REGEX_TAG_NAME + ')[ ]*?=[ ]*?(' + REGEX_TAG_VALUE + ')$'
REGEX_TAG_REPLACE = '^@%s[ ]*?=[ ]*?(' + 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):
class VirtualMachine(object):
@@ -88,8 +102,9 @@ class VirtualMachine(object):
                Tag('nic%s_mac' % i, nic.mac),
                Tag('nic%s_mac' % i, nic.mac),
                Tag('nic%s_source' % i, nic.source),
                Tag('nic%s_source' % i, nic.source),
                Tag('nic%s_model' % i, nic.model),
                Tag('nic%s_model' % i, nic.model),
                Tag('nic%s_vlans' % i, ' '.join(nic.vlans)),
                Tag('nic%s_untagged_vlan' % i, nic.untagged_vlan),
                Tag('nic%s_mode' % i, nic.mode),
                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)
                self.tag_db.add_tag(t)


@@ -316,26 +331,27 @@ class VirtualMachine(object):
                except AttributeError:
                except AttributeError:
                    source = None
                    source = None


                vlans = set()
                untagged_vlan = None
                vlan_list = nic.find('vlan')
                tagged_vlans = set()
                if vlan_list is not None:
                vlan = nic.find('vlan')
                    for tag in vlan_list.findall('tag'):
                if vlan is None:
                        tid = tag.get('id')
                    untagged_vlan = source[2:]
                        if tid is not None:
                else:
                            vlans.add(tid)
                    tags = vlan.findall('tag')
                    mode = {'yes': 'tagged', 'no': 'untagged'}[vlan_list.get('trunk', 'yes' if len(vlans) > 1 else 'no')]
                    trunk = vlan.get('trunk') == 'yes' or len(tags) > 1
                elif source is not None:
                    default_mode = 'tagged' if trunk else 'untagged'
                    mode = 'untagged'
                    for tag in tags:
                    vlans.add(source[2:])
                        if tag.get('nativeMode', default_mode) == 'untagged':
                            untagged_vlan = int(tag.get('id'))
                        else:
                        else:
                    mode = 'unknown'
                            tagged_vlans.add(int(tag.get('id')))


                yield NetworkInterface(
                yield NetworkInterface(
                    mac=mac,
                    mac=mac,
                    source=source,
                    source=source,
                    model=model,
                    model=model,
                    vlans=vlans,
                    untagged_vlan=untagged_vlan,
                    mode=mode,
                    tagged_vlans=tagged_vlans,
                )
                )


    def open_console(self):
    def open_console(self):