mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-31 21:13:00 +02:00
103 lines
3.7 KiB
Python
103 lines
3.7 KiB
Python
from .host import HOST
|
|
from collections import defaultdict
|
|
|
|
def operational():
|
|
"""Retrieve LLDP neighbor information and store in remote-systems-data under the correct port."""
|
|
|
|
# https://www.ieee802.org/1/files/public/YANGs/ieee802-types.yang
|
|
# <chassis-component> and <port-component> subtypes are not supported in
|
|
# https://github.com/lldpd/lldpd until v1.0.19
|
|
chassis_id_subtype_mapping = {
|
|
#"unhandled": "chassis-component",
|
|
"ifalias": "interface-alias",
|
|
#"unhandled": "port-component",
|
|
"mac": "mac-address",
|
|
"ip": "network-address",
|
|
"ifname": "interface-name",
|
|
"local": "local"
|
|
}
|
|
|
|
# https://www.ieee802.org/1/files/public/YANGs/ieee802-types.yang
|
|
# <port-component> and <agent-circuit-id> subtypes are not supported in
|
|
# https://github.com/lldpd/lldpd until v1.0.19
|
|
port_id_subtype_mapping = {
|
|
"ifalias": "interface-alias",
|
|
#"unhandled": "port-component",
|
|
"mac": "mac-address",
|
|
"ip": "network-address",
|
|
"ifname": "interface-name",
|
|
#"unhandled": "agent-circuit-id"
|
|
"local": "local"
|
|
}
|
|
|
|
LLDP_MULTICAST_MAC = "01:80:C2:00:00:0E"
|
|
|
|
port_data = defaultdict(lambda: {"remote-systems-data": [], "dest-mac-address": LLDP_MULTICAST_MAC})
|
|
|
|
data = HOST.run_json(["lldpcli", "show", "neighbors", "-f", "json"])
|
|
|
|
interfaces = data.get("lldp", {}).get("interface", [])
|
|
|
|
if isinstance(interfaces, dict):
|
|
interfaces = [interfaces]
|
|
|
|
for iface_entry in interfaces:
|
|
for iface_name, iface_data in iface_entry.items():
|
|
remote_index = int(iface_data.get("rid", 0))
|
|
time_mark = parse_time(iface_data.get("age"))
|
|
|
|
chassis = iface_data.get("chassis", {})
|
|
chassis_id_type, chassis_id_value = extract_chassis_id(chassis, chassis_id_subtype_mapping)
|
|
|
|
port_info = iface_data.get("port", {})
|
|
port_id_type = port_id_subtype_mapping.get(port_info.get("id", {}).get("type"), "unknown")
|
|
port_id_value = port_info.get("id", {}).get("value", "")
|
|
|
|
remote_entry = {
|
|
"time-mark": time_mark,
|
|
"remote-index": remote_index,
|
|
"chassis-id-subtype": chassis_id_type,
|
|
"chassis-id": chassis_id_value,
|
|
"port-id-subtype": port_id_type,
|
|
"port-id": port_id_value
|
|
}
|
|
|
|
port_data[iface_name]["remote-systems-data"].append(remote_entry)
|
|
|
|
formatted_output = {
|
|
"ieee802-dot1ab-lldp:lldp": {
|
|
"port": [
|
|
{
|
|
"name": port_name,
|
|
"dest-mac-address": port_info["dest-mac-address"],
|
|
"remote-systems-data": port_info["remote-systems-data"]
|
|
}
|
|
for port_name, port_info in port_data.items() if port_info["remote-systems-data"]
|
|
]
|
|
}
|
|
}
|
|
|
|
return formatted_output
|
|
|
|
def extract_chassis_id(chassis_block, subtype_mapping):
|
|
if "id" in chassis_block:
|
|
id_info = chassis_block["id"]
|
|
return subtype_mapping.get(id_info.get("type"), "unknown"), id_info.get("value", "")
|
|
|
|
for _, value in chassis_block.items():
|
|
if isinstance(value, dict) and "id" in value:
|
|
id_info = value["id"]
|
|
return subtype_mapping.get(id_info.get("type"), "unknown"), id_info.get("value", "")
|
|
|
|
return "unknown", ""
|
|
|
|
def parse_time(time_str):
|
|
"""Convert LLDP time format to seconds"""
|
|
import re
|
|
if time_str:
|
|
match = re.search(r"(\d+)\s*day[s]*,\s*(\d+):(\d+):(\d+)", time_str)
|
|
if match:
|
|
days, hours, minutes, seconds = map(int, match.groups())
|
|
return days * 86400 + hours * 3600 + minutes * 60 + seconds
|
|
return 0
|