From 250e067316d2789c02b253e24d670d2d8f85302d Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 15 May 2016 23:26:10 +0200 Subject: inspectors : refactor done --- haircontrol/inspectors.py | 114 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 108 insertions(+), 6 deletions(-) (limited to 'haircontrol/inspectors.py') diff --git a/haircontrol/inspectors.py b/haircontrol/inspectors.py index 9b797fe..33bf360 100644 --- a/haircontrol/inspectors.py +++ b/haircontrol/inspectors.py @@ -1,21 +1,123 @@ import re +import xml.etree.ElementTree class Inspector(): cmds = {} - fd = None - def parse(self): - return None #XXX Implement + def __init__(self): + #XXX in a mockup class ? + self.testDataPath = '../test-data/input' + self.e = None + + def connect(self, e): + self.e = e + + def disconnect(self): + self.e = None + + def command(self, cmdname): + cmddef = self.cmds.get(cmdname) + if not cmddef: + return None + fd = self._exec(cmdname, cmddef['cmd']) + result = [] + re = cmddef.get('re') + func = cmddef.get('func') + if re: + for line in fd: + matches = re.match(line) + if matches: + result.append(matches.groups()) + elif func: + result = func(self, fd) + fd.close() + return result + + def _exec(self, cmdname, cmd): + #XXX in a mockup class ? + mockfile = self.testDataPath + '/' + self.e.name + '-' + cmdname + '.out' + return open(mockfile) + + class LinuxInspector(Inspector): + + def parse_lldpctl_xml(self, fd): + result = [] + root = xml.etree.ElementTree.parse(fd).getroot() + for iface in root.iter('interface'): + local_ifname = iface.get('name') + local_mac = self.e.ifaces[local_ifname].mac + chassis = iface.find('chassis') + remote_name = chassis.find('name').text + remote_ipmgmt = chassis.find('mgmt-ip').text + ports = [] + for port in iface.findall('port'): + remote_ifname = port.find('id').text + ports.append(remote_ifname) + result.append( (local_ifname, local_mac, remote_name, remote_ipmgmt, ports) ) + return result + cmds = { 'ip-neigh': { 'cmd': 'ip neigh', + 're': re.compile("(?P[a-f0-9:.]+) dev (?P.*) lladdr (?P[a-f0-9:]*)") # fe80::8300 dev eth1 lladdr 10:fe:ed:f1:e1:f3 router STALE # 172.16.20.210 dev eth1 lladdr c0:4a:00:fe:1f:87 REACHABLE + }, + 'ip-link': { + 'cmd': 'ip -o link', 'kind': 'text', - 'fields': ['ip','ifname','mac'], - 're': re.compile("(?P[a-f0-9:.]+) dev (?P.*) lladdr (?P[a-f0-9:]*)") - } + 're': re.compile("(?P\d+):\s+(?P[^:]*):.+\s+(?:link/ether\s+(?P[a-f0-9:]*)\s+brd|link/none)") + # 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default \ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + # 2: eth0: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000\ link/ether 8c:89:a5:c7:be:88 brd ff:ff:ff:ff:ff:ff + }, + 'lldpctl': { + 'cmd': 'lldpctl -f xml', + 'func': parse_lldpctl_xml + # + # + # + # + # Robert_VILO + # Robert_VILO + # LM5 running on + #XM.v5.5.10 + # 172.16.10.26 + # 169.254.227.212 + # + # + # + # br0 + # br0 + # + # + # + # ... + # + # + }, } + + +class UbntInspector(Inspector): + + def parse_status_json(self, fd): + return 'parse_status_json' + + def parse_brmacs_json(self, fd): + return 'parse_brmacs_json' + + cmds = { + 'status.cgi': { + 'cmd':'..', + 'kind': 'cgi-json', + 'func': parse_status_json + }, + 'brmacs.cgi': { + 'cmd':'..', + 'kind': 'cgi-json', + 'func': parse_brmacs_json + } + } -- cgit v1.1