--- a/bin/pvl.hosts-graph Tue Mar 18 23:14:01 2014 +0200
+++ b/bin/pvl.hosts-graph Tue Mar 18 23:53:16 2014 +0200
@@ -36,6 +36,16 @@
def __str__ (self) :
return "{self.file}:{self.line}: {self.msg}".format(self=self)
+def _parse_snmp_part (part) :
+ if part.isdigit() :
+ return int(part)
+ else :
+ return part
+
+def _parse_snmp_line (line) :
+ for part in line.split() :
+ yield _parse_snmp_part(part)
+
def _load_snmp_data (options, file) :
"""
Load a data dict generated by pvl.hosts-snmp from a file.
@@ -46,30 +56,57 @@
host = None
attr = None
value = None
+ values = None
for idx, line in enumerate(file, 1) :
- indent = line.count('\t')
+ indent = 0
+
+ while line.startswith('\t') :
+ indent += 1
+ line = line[1:]
+
line = line.strip()
+ if '\t' in line :
+ args = line.split('\t', 1)
+
+ line = args.pop(0)
+ args = tuple(args)
+ else :
+ args = None
+
if indent == 0 :
host = line
attr = None
value = None
+ values = None
elif indent == 1 :
- if attr and not value :
- yield host, attr, None
+ if attr and not value and not values :
+ raise ParseError(file, line, "[%s] %s: no value" % (host, attr))
- attr = tuple((int(a) if a.isdigit() else a) for a in line.split())
- value = None
+ attr = tuple(_parse_snmp_line(line))
+
+ if args :
+ value = tuple(tuple(_parse_snmp_line(arg)) for arg in args)
+ else :
+ value = None
+
+ values = None
+
+ if value :
+ yield host, attr, value
elif indent == 2 :
if not attr :
- raise ParseError(file, line, "value outside of attr")
+ raise ParseError(file, line, "[%s] %s: value outside of attr" % (host, attr))
+
+ if value :
+ raise ParseError(file, line, "[%s] %s: values with value" % (host, attr))
- value = line
+ values = _parse_snmp_part(line)
- yield host, attr, value
+ yield host, attr, set((values, ))
def load_snmp_data (options, file, hosts) :
"""
@@ -89,23 +126,18 @@
log.info("[%s] %s%s", host, ' '.join(str(a) for a in attr), (': ' + str(value)) if value else '')
item = root.setdefault(host, { })
-
- if value :
- end = None
- else :
- end = attr[-1]
- attr = attr[:-1]
-
+
for a in attr[:-1] :
item = item.setdefault(a, {})
a = attr[-1]
+
+ if isinstance(value, set) :
+ item.setdefault(a, set()).update(value)
- if value is None :
- item[a] = end
else :
- item.setdefault(a, set()).add(value)
-
+ item[a] = dict(value)
+
return root
def apply_graph (options, items, vlans={}) :