Skip to content

Instantly share code, notes, and snippets.

@cidrblock
Created March 6, 2019 23:44
Show Gist options
  • Save cidrblock/42a51803e90e93cfb848ed831c88d5a6 to your computer and use it in GitHub Desktop.
Save cidrblock/42a51803e90e93cfb848ed831c88d5a6 to your computer and use it in GitHub Desktop.
json schema to python object
import re
import python_jsonschema_objects as pjs
model = {
"title": "lldp",
"type": "object",
"properties": {
"neighbors": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "object",
}
},
"default": {}
}
},
"definitions": {
"neighbor": {
"type": "object",
"required": [ "name", "description"],
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"interfaces": {
"type": "array",
"items": {
"type": "object",
"properties": {
"local": {"type": "string"},
"neighbor": {"type": "string"}
}
}
}
}
}
}
}
data = """
Interface Ethernet1 detected 7 LLDP neighbors:
Neighbor 5254.0046.d315/"Ethernet1", age 27 seconds
Discovered 1 day, 3:14:51 ago; Last changed 1 day, 3:14:51 ago
- Chassis ID type: MAC address (4)
Chassis ID : 5254.0046.d315
- Port ID type: Interface name (5)
Port ID : "Ethernet1"
- Time To Live: 120 seconds
- System Name: "eos103"
- System Description: "Arista Networks EOS version 4.21.1.1F running on an Arista Networks vEOS"
- System Capabilities : Bridge, Router
Enabled Capabilities: Bridge
- Management Address Subtype: IPv4
Management Address : 192.168.101.12
Interface Number Subtype : ifIndex (2)
Interface Number : 999001
OID String :
- IEEE802.1 Port VLAN ID: 1
- IEEE802.1/IEEE802.3 Link Aggregation
Link Aggregation Status: Capable, Disabled (0x01)
Port ID : 0
- IEEE802.3 Maximum Frame Size: 9236 bytes
Neighbor 5254.008f.5171/"Ethernet1/1", age 4 seconds
Discovered 1 day, 20:26:15 ago; Last changed 1 day, 20:26:15 ago
- Chassis ID type: MAC address (4)
Chassis ID : 5254.008f.5171
- Port ID type: Interface name (5)
Port ID : "Ethernet1/1"
- Time To Live: 120 seconds
- Port Description: "Ethernet1/1"
- System Name: "nxos102"
- System Description: "Cisco Nexus Operating System (NX-OS) Software 9.2(2)
TAC support: http://www.cisco.com/tac
Copyright (c) 2002-2018, Cisco Systems, Inc. All rights reserved."
- System Capabilities : Bridge, Router
Enabled Capabilities: Bridge, Router
- Management Address Subtype: IPv4
Management Address : 192.168.101.15
Interface Number Subtype : ifIndex (2)
Interface Number : 83886080
OID String :
- Management Address Subtype: Ethernet
Management Address : 5254.008f.5171
Interface Number Subtype : ifIndex (2)
Interface Number : 83886080
OID String :
- IEEE802.1 Port VLAN ID: 1
- Unknown organizationally-defined TLV (OUI 00-01-42, subtype 1):
01
Interface Management1 detected 7 LLDP neighbors:
Neighbor 5254.0046.d315/"Management1", age 27 seconds
Discovered 1 day, 3:14:51 ago; Last changed 1 day, 3:14:51 ago
- Chassis ID type: MAC address (4)
Chassis ID : 5254.0046.d315
- Port ID type: Interface name (5)
Port ID : "Management1"
- Time To Live: 120 seconds
- System Name: "eos103"
- System Description: "Arista Networks EOS version 4.21.1.1F running on an Arista Networks vEOS"
- System Capabilities : Bridge, Router
Enabled Capabilities: Bridge
- Management Address Subtype: IPv4
Management Address : 192.168.101.12
Interface Number Subtype : ifIndex (2)
Interface Number : 999001
OID String :
- IEEE802.1 Port VLAN ID: 0
- IEEE802.1/IEEE802.3 Link Aggregation
Link Aggregation Status: Not Capable (0x00)
Port ID : 0
- IEEE802.3 Maximum Frame Size: 1518 bytes
"""
def section_split(regex, lines):
sections = []
section = ()
capturing = False
for line in lines:
if re.match(regex, line):
if not capturing:
capturing = True
else:
if section:
sections.append(section)
section = (line,[])
elif capturing:
section[1].append(line)
sections.append(section)
return sections
def parse_name(neighbor):
match = re.match(r'.*System Name: "(?P<name>\S+)"\n', neighbor, re.S)
if match:
return match.group('name')
def parse_description(neighbor):
match = re.match(r'.*System Description: "(?P<description>.*)"', neighbor, re.S)
if match:
return match.group('description')
def parse_neighbor_int(neighbor):
match = re.match(r'.*Port ID\s+: "(?P<neighbor_int>.*?)"\n', neighbor, re.S)
if match:
return match.group('neighbor_int')
def main():
ns = pjs.ObjectBuilder(model).build_classes()
lldp = ns.Lldp()
li_re = r'^Interface (?P<local_interface>\S+)'
local_interfaces = section_split(li_re, data.splitlines())
neighbors = {}
for local_interface in local_interfaces:
int_name = re.match(li_re, local_interface[0]).group('local_interface')
neighbors_text = section_split(r'^ Neighbor', local_interface[1])
for neighbor_text in neighbors_text:
neighbor_string = '\n'.join(neighbor_text[1])
name = parse_name(neighbor_string)
description = parse_description(neighbor_string)
neighbor_int = parse_neighbor_int(neighbor_string)
if name not in neighbors:
neighbors[name] = { "name": name,
"description": description,
"interfaces": [
{ "local": int_name,
"neighbor": neighbor_int }
]}
else:
neighbors[name]['interfaces'].append({ "local": int_name,
"neighbor": neighbor_int })
lldp.neighbors = neighbors
print(lldp.serialize())
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment