Created
March 6, 2019 23:44
-
-
Save cidrblock/42a51803e90e93cfb848ed831c88d5a6 to your computer and use it in GitHub Desktop.
json schema to python object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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