Add basic network representation and comparison.

Very PoC quality code, but will do for now.
old_stateparser
LEdoian 2 years ago
parent 9edd3dea02
commit dcf8b0184e

@ -0,0 +1,85 @@
from birdvisu.ospffile import load
import re
class Topology:
"""Basically a graph"""
def __init__(self):
self.routers = [] # Tuples like in ospffile for router section
self.networks = [] # Ditto, but the key is the address, not the ad-hoc string from bird
self.network_addrs = {} # Keeps mapping from network to address
self.links = [] # Tuples (router, network_addr, cost)
# FIXME: we are ugly, so everything are strings and I don't care as of now.
def add_area(self, dirtuple):
# FIXME: Do not use BIRD's strings, create an abstraction above them.
_area, topo = dirtuple # Ignoring the area
for obj in topo:
directive, details = obj
if directive.startswith('router'):
self.routers.append(obj)
elif directive.startswith('network'):
net_addr = None
for d, _ in details:
if d.startswith('address'):
net_addr = d
break
assert net_addr is not None
fixed_network = (net_addr, details + [directive])
self.networks.append(fixed_network)
self.network_addrs[directive] = net_addr
# Fix the topology: find other networks (stubnets, external, ...) and links:
for r, rd in self.routers:
for n, nd in rd:
if n.startswith(('network', 'stubnet', 'external')):
net_id = re.match(r'((network|stubnet|external) [^ ]+)', n).group(1)
if n.startswith(('stubnet', 'external')):
self.networks.append((net_id, []))
# Add dummy mapping
self.network_addrs[net_id] = net_id
metric = int(re.search(r'metric ([0-9]+)', n).group(1))
net_addr = self.network_addrs[net_id]
self.links.append((r, net_addr, metric))
@classmethod
def from_ospffile(cls, f):
# FIXME: We should create own classes from the OSPF file as soon as
# possible to avoid changing whole codebase when BIRD's format changes.
result = cls()
parsed = load(f)
for directive, details in parsed:
if directive.startswith('area'):
result.add_area((directive, details))
return result
class TopologyDifference:
def __init__(self, actual, reference):
self.actual = actual
self.reference = reference
def compare(self):
# FIXME: This also relies on BIRD's current format.
just_ident = lambda x: x[0]
act_routers = set(map(just_ident, self.actual.routers))
ref_routers = set(map(just_ident, self.reference.routers))
act_networks = set(map(just_ident, self.actual.networks))
ref_networks = set(map(just_ident, self.reference.networks))
act_links = set(self.actual.links)
ref_links = set(self.reference.links)
# *_missing: in reference, not in actual network.
# *_extra: in actual network, not in reference.
# *_discrepancies: different settings (currently only metrics)
self.routers_missing = ref_routers - act_routers
self.routers_extra = act_routers - ref_routers
self.networks_missing = ref_networks - act_networks
self.networks_extra = act_networks - ref_networks
# FIXME: be more clever. Discrepancy is not missing and extra…
self.links_missing = ref_links - act_links
self.links_extra = act_links - ref_links
self.links_discrepancies = act_links ^ ref_links
Loading…
Cancel
Save