--- 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)