Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
james-scripts/vlan-id-reuse.py
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
executable file
129 lines (96 sloc)
3.62 KB
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
#!/usr/bin/env python3 | |
import glob | |
import re | |
import xml.etree.ElementTree as et | |
import json | |
from datetime import datetime | |
from collections import namedtuple | |
from collections import defaultdict | |
def main(): | |
# Load up config from each router | |
for config_file in glob.glob("../internet2-configs/rtsw/xml/*.xml"): | |
print("parsing file {}".format(config_file)) | |
try: | |
ifaces = parse_router_config(config_file) | |
for i in ifaces: | |
print(i) | |
except et.ParseError: | |
pass | |
# Done | |
class InterfaceInfo: | |
_repr_fields = ("router", "name", "description", | |
"vlan_outer", "vlan_inner") | |
router = None | |
name = None | |
description = None | |
vlan_outer = None | |
vlan_inner = None | |
def __str__(self): | |
return "InterfaceInfo({})".format(", ".join([ | |
"{}={!r}".format(attr, getattr(self, attr)) | |
for attr | |
in self._repr_fields | |
])) | |
def parse_router_config(rtr_xml_file): | |
"""Parse a router config. | |
Returns a list of InterfaceInfo objects. | |
""" | |
config_root = et.parse(rtr_xml_file) | |
# Get Hostname | |
rtr_name = extract_hostname(config_root) | |
# Get interfaces | |
ifaces = extract_interfaces(config_root, rtr_name) | |
return ifaces | |
RE_HOSTNAME_CLEANUP = re.compile(r'-re\d', re.IGNORECASE) | |
def extract_hostname(config_root): | |
"""Return the sanitized router hostname""" | |
rtr_name = config_root.findtext('.//system/host-name') | |
rtr_name = RE_HOSTNAME_CLEANUP.sub('', rtr_name) | |
return rtr_name | |
SKIP_IF_NAMES = set(["all", "fxp0.0", "dsc", "dsc.0"]) | |
def extract_interfaces(config_root, rtr_name): | |
# Key is interface_name (w/ unit) | |
# Value is InterfaceInfo (which we build up more info on) | |
rv = defaultdict(InterfaceInfo) | |
# Loop through interfaces | |
for iface in config_root.findall('.//interface'): | |
if_name = iface.findtext('./name') | |
if_descr = iface.findtext('./description') | |
if_vlan_id = iface.findtext('./vlan-id') | |
if_vlan_outer = iface.findtext('./vlan-tags/outer') | |
if_vlan_inner = iface.findtext('./vlan-tags/inner') | |
if if_name is None or "*" in if_name or if_name in SKIP_IF_NAMES: | |
continue | |
# Stash main unit | |
rv[if_name].name = if_name | |
rv[if_name].router = rtr_name | |
rv[if_name].description = if_descr | |
if if_vlan_id is not None: | |
rv[if_name].vlan_outer = int(if_vlan_id) | |
elif if_vlan_outer is not None: | |
rv[if_name].vlan_outer = int(if_vlan_outer) | |
rv[if_name].vlan_inner = int(if_vlan_inner) | |
extract_units(rtr_name, iface, if_name, rv) | |
return sorted(rv.values(), key=lambda i: i.name) | |
def extract_units(rtr_name, iface, if_name, rv): | |
for if_unit in iface.findall("./unit"): | |
unit_name = if_unit.findtext('./name') | |
unit_descr = if_unit.findtext('./description') | |
unit_vlan_id = if_unit.findtext('./vlan-id') | |
unit_vlan_outer = if_unit.findtext('./vlan-tags/outer') | |
unit_vlan_inner = if_unit.findtext('./vlan-tags/inner') | |
if unit_name is None or "*" in unit_name: | |
continue | |
# Stash | |
full_name = if_name + "." + unit_name | |
rv[full_name].name = full_name | |
rv[full_name].router = rtr_name | |
rv[full_name].description = unit_descr | |
if unit_vlan_id is not None: | |
rv[full_name].vlan_outer = int(unit_vlan_id) | |
elif unit_vlan_outer is not None: | |
rv[full_name].vlan_outer = int(unit_vlan_outer) | |
rv[full_name].vlan_inner = int(unit_vlan_inner) | |
# Main program | |
if __name__ == "__main__": | |
main() |