handle multiple vlans in lldp (#66)

This commit is contained in:
Solvik 2019-09-09 15:32:14 +02:00 committed by GitHub
parent fb68907efd
commit f68fed18b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 27 deletions

View file

@ -8,18 +8,35 @@ class LLDP():
def parse(self):
output_dict = {}
vlans = {}
vid = None
for entry in self.output.splitlines():
if '=' not in entry:
continue
path, value = entry.strip().split("=", 1)
path = path.split(".")
path_components, final = path[:-1], path[-1]
split_path = path.split(".")
interface = split_path[1]
path_components, final = split_path[:-1], split_path[-1]
current_dict = output_dict
if vlans.get(interface) is None:
vlans[interface] = {}
for path_component in path_components:
current_dict[path_component] = current_dict.get(path_component, {})
current_dict = current_dict[path_component]
current_dict[final] = value
if 'vlan-id' in path:
vid = value
vlans[interface][value] = vlans[interface].get(vid, {})
elif path.endswith('vlan'):
vid = value.replace('vlan-', '')
vlans[interface][vid] = vlans[interface].get(vid, {})
elif 'pvid' in path:
vlans[interface][vid]['pvid'] = True
if 'vlan' not in path:
current_dict[final] = value
for interface, vlan in vlans.items():
output_dict['lldp'][interface]['vlan'] = vlan
return output_dict
def get_switch_ip(self, interface):
@ -38,11 +55,4 @@ class LLDP():
# lldp.eth0.vlan.vlan-id=296
if self.data['lldp'].get(interface) is None:
return None
lldp = self.data['lldp'][interface]
if lldp.get('vlan'):
if type(lldp['vlan']) is str:
return int(lldp['vlan'].replace('vlan-', ''))
elif lldp['vlan'].get('vlan-id'):
return int(lldp['vlan'].get('vlan-id'))
return None
return self.data['lldp'][interface]['vlan']

View file

@ -224,17 +224,20 @@ class Network():
interface.mode = 200
interface.tagged_vlans = [nb_vlan] if nb_vlan else []
interface.untagged_vlan = None
# if lldp reports a vlan-id
elif lldp_vlan and (
interface.mode is None or interface.mode.value != 100 or
interface.untagged_vlan is None or
interface.untagged_vlan.vid != lldp_vlan):
logging.info('Resetting access VLAN on interface {interface}'.format(
interface=interface))
update = True
nb_vlan = self.get_or_create_vlan(lldp_vlan)
interface.mode = 100
interface.untagged_vlan = nb_vlan.id
# if lldp reports a vlan-id with pvid
elif lldp_vlan:
pvid_vlan = [key for (key, value) in lldp_vlan.items() if value['pvid']]
if len(pvid_vlan) > 0 and (
interface.mode is None or
interface.mode.value != 100 or
interface.untagged_vlan is None or
interface.untagged_vlan.vid != int(pvid_vlan[0])):
logging.info('Resetting access VLAN on interface {interface}'.format(
interface=interface))
update = True
nb_vlan = self.get_or_create_vlan(pvid_vlan[0])
interface.mode = 100
interface.untagged_vlan = nb_vlan.id
return update, interface
def create_or_update_ipmi(self):
@ -295,10 +298,14 @@ class Network():
interface.save()
elif config.network.lldp and self.lldp.get_switch_vlan(nic['name']) is not None:
# if lldp reports a vlan on an interface, tag the interface in access and set the vlan
vlan_id = self.lldp.get_switch_vlan(nic['name'])
nb_vlan = self.get_or_create_vlan(vlan_id)
interface.mode = 100
interface.untagged_vlan = nb_vlan.id
# report only the interface which has `pvid=yes` (ie: lldp.eth3.vlan.pvid=yes)
# if pvid is not present, it'll be processed as a vlan tagged interface
vlans = self.lldp.get_switch_vlan(nic['name'])
for vid, vlan_infos in vlans.items():
nb_vlan = self.get_or_create_vlan(vid)
if vlan_infos.get('vid'):
interface.mode = 100
interface.untagged_vlan = nb_vlan.id
interface.save()
# cable the interface