pvl.hosts-graph: update for new hostname format, map non-snmp lldp hosts by Host.ethernet
authorTero Marttila <terom@paivola.fi>
Mon, 31 Mar 2014 14:47:53 +0300
changeset 408 32b7a0f2e7dc
parent 407 3197d049f345
child 409 b2b1bc488195
pvl.hosts-graph: update for new hostname format, map non-snmp lldp hosts by Host.ethernet
bin/pvl.hosts-graph
--- a/bin/pvl.hosts-graph	Mon Mar 31 14:47:32 2014 +0300
+++ b/bin/pvl.hosts-graph	Mon Mar 31 14:47:53 2014 +0300
@@ -106,9 +106,15 @@
         file = sys.stdin
 
     root = { }
+    
+    hosts_by_namedomain = dict(
+        (
+            '{host}@{domain}'.format(host=host, domain=host.domain), host
+        ) for host in hosts
+    )
 
-    for host_name, attr, value in _load_snmp_data(options, file) :
-        host = hosts.get(host_name)
+    for host_domain, attr, value in _load_snmp_data(options, file) :
+        host = hosts_by_namedomain.get(host_domain)
         
         if value :
             log.debug("[%s] %s: %s", host, ' '.join(str(a) for a in attr), value)
@@ -172,7 +178,8 @@
     nodes = { } # host: label
     links = { }
 
-    hosts_by_lldp = { }
+    hosts_by_lldp = { } # chassis: host
+    hosts_by_ethernet = { } # ethernet: host
     
     # first scan: lldp hosts
     for host, host_attrs in snmp.iteritems() :
@@ -182,9 +189,14 @@
             lldp_local = lldp['local']
             local = lldp_local['chassis']
             
-            nodes[host] = host.location
+            nodes[host] = host.location or str(host)
             hosts_by_lldp[local] = host
     
+    # second scan: nodes by ethernet
+    for host in hosts :
+        for ethernet in host.ethernet.itervalues() :
+            hosts_by_ethernet[ethernet] = host
+
     # second scan: lldp remotes
     for host, host_attrs in snmp.iteritems() :
         lldp = host_attrs.get('lldp')
@@ -204,15 +216,31 @@
             local_port = port_attrs['local']['port']
 
             for remote, remote_attrs in port_attrs['remote'].iteritems() :
+                # determine remote node
+                remote_label = remote_attrs['sys_name']
+
                 if remote in hosts_by_lldp :
-                    remote_node = hosts_by_lldp[remote]
+                    remote_node = remote_host = hosts_by_lldp[remote]
+
+                elif remote in hosts_by_ethernet :
+                    remote_node = remote_host = hosts_by_ethernet[remote]
+
+                    if remote_host.location :
+                        remote_label = remote_host.location
+
+                    log.info("%s:%s: guessing lldp host %s -> %s (%s)", host, port, remote, remote_host, remote_label)
+
                 else :
                     remote_node = remote
+                    remote_host = None
 
-                    # non-snmp lldp host
-                    nodes[remote_node] = remote_attrs['sys_name']
+                    log.warning("%s:%s: unknown remote %s (%s)", host, port, remote, remote_label)
+                
+                # ensure remote node
+                if remote_node not in nodes :
+                    log.info("%s:%s: lazy-add remote %s (%s)", host, port, remote_node, remote_label)
 
-                remote_port = remote_attrs['port']
+                    nodes[remote_node] = remote_label
                 
                 # local vlans
                 if vlans :
@@ -224,6 +252,8 @@
                     local_untag, local_tagged = port_vlans
                 
                 # bidirectional mappings
+                remote_port = remote_attrs['port']
+
                 forward = (local_node, local_port, remote_port, remote_node)
                 reverse = (remote_node, remote_port, local_port, local_node)
 
@@ -399,8 +429,8 @@
     options, args = parser.parse_args(argv[1:])
     pvl.args.apply(options)
     
-    # load hosts for correlation
-    hosts = dict((str(host), host) for host in pvl.hosts.apply(options, args))
+    # load hosts
+    hosts = list(pvl.hosts.apply(options, args))
 
     # load raw snmp data
     snmp = load_snmp_data(options, options.snmp_data, hosts)