pvl.hosts-graph: support new syntax, with dict updates
authorTero Marttila <terom@paivola.fi>
Wed, 19 Mar 2014 01:08:56 +0200
changeset 404 78e3d83135ab
parent 403 9bae04e1780c
child 405 97b436f9363a
pvl.hosts-graph: support new syntax, with dict updates
bin/pvl.hosts-graph
--- a/bin/pvl.hosts-graph	Wed Mar 19 01:08:34 2014 +0200
+++ b/bin/pvl.hosts-graph	Wed Mar 19 01:08:56 2014 +0200
@@ -43,26 +43,19 @@
     else :
         return part
 
-def _parse_snmp_line (line) :
+def _parse_snmp_attr (line) :
     for part in line.split() :
         yield _parse_snmp_part(part)
 
-def _parse_snmp_attr (line) :
-    parts = line.split()
-
-    key = parts.pop(0)
+def _parse_snmp_value (line) :
+    if '\t' in line :
+        key, value = line.split('\t', 1)
 
-    if len(parts) == 0 :
-        return key, None
-
-    elif len(parts) == 1 :
-        value, = parts
-
-        return key, value
+        return { _parse_snmp_part(key): _parse_snmp_part(value) }
 
     else :
-        return key, parts
-
+        return set((_parse_snmp_part(line), ))
+    
 def _load_snmp_data (options, file) :
     """
         Load a data dict generated by pvl.hosts-snmp from a file.
@@ -73,7 +66,6 @@
     host = None
     attr = None
     value = None
-    values = None
     
     for idx, line in enumerate(file, 1) :
         indent = 0
@@ -82,48 +74,26 @@
             indent += 1
             line = line[1:]
 
-        line = line.strip()
-
-        if '\t' in line :
-            args = line.split('\t')
-
-            line = args.pop(0)
-            args = tuple(args)
-        else :
-            args = None
+        line = line.lstrip('\t').rstrip('\n')
 
         if indent == 0 :
             host = line
             attr = None
             value = None
-            values = None
 
         elif indent == 1 :
-            if attr and not value and not values :
-                raise ParseError(file, line, "[%s] %s: no value" % (host, attr))
-
-            attr = tuple(_parse_snmp_line(line))
+            attr = tuple(_parse_snmp_attr(line))
+            value = None
 
-            if args :
-                value = dict(_parse_snmp_attr(arg) for arg in args)
-            else :
-                value = None
-            
-            values = None
-
-            if value :
-                yield host, attr, value
+            yield host, attr, None
 
         elif indent == 2 :
             if not 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 = _parse_snmp_value(line)
 
-            values = _parse_snmp_part(line)
-
-            yield host, attr, set((values, ))
+            yield host, attr, value
 
 def load_snmp_data (options, file, hosts) :
     """
@@ -139,8 +109,11 @@
 
     for host_name, attr, value in _load_snmp_data(options, file) :
         host = hosts.get(host_name)
-
-        log.info("[%s] %s%s", host, ' '.join(str(a) for a in attr), (': ' + str(value)) if value else '')
+        
+        if value :
+            log.info("[%s] %s: %s", host, ' '.join(str(a) for a in attr), value)
+        else :
+            log.info("[%s] %s", host, ' '.join(str(a) for a in attr),)
 
         item = root.setdefault(host, { })
         
@@ -149,9 +122,15 @@
 
         a = attr[-1]
         
-        if isinstance(value, set) :
+        if value is None :
+            pass
+
+        elif isinstance(value, set) :
             item.setdefault(a, set()).update(value)
 
+        elif isinstance(value, dict) :
+            item.setdefault(a, dict()).update(value)
+
         else :
             item[a] = value
             
@@ -172,12 +151,13 @@
                 vlans_tagged[port].add(vlan)
             
             for port in snmp[host]['vlan'][vlan].get('untagged', ()) :
+                ports.add(port)
                 vlans_untagged[port] = vlan
         
         out = { }
         for port in ports :
             untag = vlans_untagged.get(port)
-            tagged = vlans_tagged.get(port)
+            tagged = vlans_tagged.get(port, ())
 
             log.info("%s: %s: untag=%s tag=%s", host, port, untag, tagged)