netbox-agent/netbox_agent/lldp.py
illes a59fb446f3
Fix KeyError: 'pvid' in lldp.py
```
lldp.eth0.vlan.vlan-id=300
lldp.eth0.vlan.pvid=yes
lldp.eth0.vlan=VLAN300
```
```
Version: lldpd 1.0.11
```

```
{'300': {'pvid': True}, 'VLAN300': {}}
Traceback (most recent call last):
  File "/root/.local/bin/netbox_agent", line 8, in <module>
    sys.exit(main())
  File "/root/.local/lib/python3.10/site-packages/netbox_agent/cli.py", line 44, in main
    return run(config)
  File "/root/.local/lib/python3.10/site-packages/netbox_agent/cli.py", line 39, in run
    server.netbox_create_or_update(config)
  File "/root/.local/lib/python3.10/site-packages/netbox_agent/server.py", line 292, in netbox_create_or_update
    self.network.create_or_update_netbox_network_cards()
  File "/root/.local/lib/python3.10/site-packages/netbox_agent/network.py", line 417, in create_or_update_netbox_network_cards
    ret, interface = self.reset_vlan_on_interface(nic, interface)
  File "/root/.local/lib/python3.10/site-packages/netbox_agent/network.py", line 234, in reset_vlan_on_interface
    pvid_vlan = [key for (key, value) in lldp_vlan.items() if value['pvid']]
  File "/root/.local/lib/python3.10/site-packages/netbox_agent/network.py", line 234, in <listcomp>
    pvid_vlan = [key for (key, value) in lldp_vlan.items() if value['pvid']]
KeyError: 'pvid'
```
2022-04-26 12:25:28 +02:00

70 lines
2.6 KiB
Python

import logging
import subprocess
from netbox_agent.misc import is_tool
class LLDP():
def __init__(self, output=None):
if not is_tool('lldpctl'):
logging.debug('lldpd package seems to be missing or daemon not running.')
if output:
self.output = output
else:
self.output = subprocess.getoutput('lldpctl -f keyvalue')
self.data = self.parse()
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)
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]
if 'vlan-id' in path:
vid = value
vlans[interface][value] = vlans[interface].get(vid, {})
elif path.endswith('vlan'):
vid = value.replace('vlan-', '').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
if not output_dict:
logging.debug('No LLDP output, please check your network config.')
return output_dict
def get_switch_ip(self, interface):
# lldp.eth0.chassis.mgmt-ip=100.66.7.222
if self.data['lldp'].get(interface) is None:
return None
return self.data['lldp'][interface]['chassis']['mgmt-ip']
def get_switch_port(self, interface):
# lldp.eth0.port.descr=GigabitEthernet1/0/1
if self.data['lldp'].get(interface) is None:
return None
if self.data['lldp'][interface]['port'].get('ifname'):
return self.data['lldp'][interface]['port']['ifname']
return self.data['lldp'][interface]['port']['descr']
def get_switch_vlan(self, interface):
# lldp.eth0.vlan.vlan-id=296
if self.data['lldp'].get(interface) is None:
return None
return self.data['lldp'][interface]['vlan']