summaryrefslogtreecommitdiff
path: root/haircontrol/inspectors.py
diff options
context:
space:
mode:
Diffstat (limited to 'haircontrol/inspectors.py')
-rw-r--r--haircontrol/inspectors.py114
1 files changed, 108 insertions, 6 deletions
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<ip>[a-f0-9:.]+) dev (?P<ifname>.*) lladdr (?P<mac>[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<ip>[a-f0-9:.]+) dev (?P<ifname>.*) lladdr (?P<mac>[a-f0-9:]*)")
- }
+ 're': re.compile("(?P<id>\d+):\s+(?P<ifname>[^:]*):.+\s+(?:link/ether\s+(?P<mac>[a-f0-9:]*)\s+brd|link/none)")
+ # 1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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
+ #<?xml version="1.0" encoding="UTF-8"?>
+ #<lldp label="LLDP neighbors">
+ # <interface label="Interface" name="eth0" via="CDPv1" rid="2" age="0 day, 21:41:18">
+ # <chassis label="Chassis">
+ # <id label="ChassisID" type="local">Robert_VILO</id>
+ # <name label="SysName">Robert_VILO</name>
+ # <descr label="SysDescr">LM5 running on
+ #XM.v5.5.10</descr>
+ # <mgmt-ip label="MgmtIP">172.16.10.26</mgmt-ip>
+ # <mgmt-ip label="MgmtIP">169.254.227.212</mgmt-ip>
+ # <capability label="Capability" type="Bridge" enabled="on"/>
+ # </chassis>
+ # <port label="Port">
+ # <id label="PortID" type="ifname">br0</id>
+ # <descr label="PortDescr">br0</descr>
+ # </port>
+ # </interface>
+ # <interface label="Interface" name="eth0" via="CDPv1" rid="4" age="0 day, 21:41:18">
+ # ...
+ # </interface>
+ #</lldp>
+ },
}
+
+
+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
+ }
+ }