bin/pvl.hosts-graph
changeset 408 32b7a0f2e7dc
parent 406 92a4de88b86f
child 409 b2b1bc488195
equal deleted inserted replaced
407:3197d049f345 408:32b7a0f2e7dc
   104         file = open(file)
   104         file = open(file)
   105     else :
   105     else :
   106         file = sys.stdin
   106         file = sys.stdin
   107 
   107 
   108     root = { }
   108     root = { }
   109 
   109     
   110     for host_name, attr, value in _load_snmp_data(options, file) :
   110     hosts_by_namedomain = dict(
   111         host = hosts.get(host_name)
   111         (
       
   112             '{host}@{domain}'.format(host=host, domain=host.domain), host
       
   113         ) for host in hosts
       
   114     )
       
   115 
       
   116     for host_domain, attr, value in _load_snmp_data(options, file) :
       
   117         host = hosts_by_namedomain.get(host_domain)
   112         
   118         
   113         if value :
   119         if value :
   114             log.debug("[%s] %s: %s", host, ' '.join(str(a) for a in attr), value)
   120             log.debug("[%s] %s: %s", host, ' '.join(str(a) for a in attr), value)
   115         else :
   121         else :
   116             log.debug("[%s] %s", host, ' '.join(str(a) for a in attr),)
   122             log.debug("[%s] %s", host, ' '.join(str(a) for a in attr),)
   170     """
   176     """
   171 
   177 
   172     nodes = { } # host: label
   178     nodes = { } # host: label
   173     links = { }
   179     links = { }
   174 
   180 
   175     hosts_by_lldp = { }
   181     hosts_by_lldp = { } # chassis: host
       
   182     hosts_by_ethernet = { } # ethernet: host
   176     
   183     
   177     # first scan: lldp hosts
   184     # first scan: lldp hosts
   178     for host, host_attrs in snmp.iteritems() :
   185     for host, host_attrs in snmp.iteritems() :
   179         lldp = host_attrs.get('lldp')
   186         lldp = host_attrs.get('lldp')
   180 
   187 
   181         if lldp :
   188         if lldp :
   182             lldp_local = lldp['local']
   189             lldp_local = lldp['local']
   183             local = lldp_local['chassis']
   190             local = lldp_local['chassis']
   184             
   191             
   185             nodes[host] = host.location
   192             nodes[host] = host.location or str(host)
   186             hosts_by_lldp[local] = host
   193             hosts_by_lldp[local] = host
   187     
   194     
       
   195     # second scan: nodes by ethernet
       
   196     for host in hosts :
       
   197         for ethernet in host.ethernet.itervalues() :
       
   198             hosts_by_ethernet[ethernet] = host
       
   199 
   188     # second scan: lldp remotes
   200     # second scan: lldp remotes
   189     for host, host_attrs in snmp.iteritems() :
   201     for host, host_attrs in snmp.iteritems() :
   190         lldp = host_attrs.get('lldp')
   202         lldp = host_attrs.get('lldp')
   191 
   203 
   192         if not lldp :
   204         if not lldp :
   202         
   214         
   203         for port, port_attrs in lldp.get('port', { }).iteritems() :
   215         for port, port_attrs in lldp.get('port', { }).iteritems() :
   204             local_port = port_attrs['local']['port']
   216             local_port = port_attrs['local']['port']
   205 
   217 
   206             for remote, remote_attrs in port_attrs['remote'].iteritems() :
   218             for remote, remote_attrs in port_attrs['remote'].iteritems() :
       
   219                 # determine remote node
       
   220                 remote_label = remote_attrs['sys_name']
       
   221 
   207                 if remote in hosts_by_lldp :
   222                 if remote in hosts_by_lldp :
   208                     remote_node = hosts_by_lldp[remote]
   223                     remote_node = remote_host = hosts_by_lldp[remote]
       
   224 
       
   225                 elif remote in hosts_by_ethernet :
       
   226                     remote_node = remote_host = hosts_by_ethernet[remote]
       
   227 
       
   228                     if remote_host.location :
       
   229                         remote_label = remote_host.location
       
   230 
       
   231                     log.info("%s:%s: guessing lldp host %s -> %s (%s)", host, port, remote, remote_host, remote_label)
       
   232 
   209                 else :
   233                 else :
   210                     remote_node = remote
   234                     remote_node = remote
   211 
   235                     remote_host = None
   212                     # non-snmp lldp host
   236 
   213                     nodes[remote_node] = remote_attrs['sys_name']
   237                     log.warning("%s:%s: unknown remote %s (%s)", host, port, remote, remote_label)
   214 
   238                 
   215                 remote_port = remote_attrs['port']
   239                 # ensure remote node
       
   240                 if remote_node not in nodes :
       
   241                     log.info("%s:%s: lazy-add remote %s (%s)", host, port, remote_node, remote_label)
       
   242 
       
   243                     nodes[remote_node] = remote_label
   216                 
   244                 
   217                 # local vlans
   245                 # local vlans
   218                 if vlans :
   246                 if vlans :
   219                     port_vlans = vlans.get(port)
   247                     port_vlans = vlans.get(port)
   220                 else :
   248                 else :
   222 
   250 
   223                 if port_vlans :
   251                 if port_vlans :
   224                     local_untag, local_tagged = port_vlans
   252                     local_untag, local_tagged = port_vlans
   225                 
   253                 
   226                 # bidirectional mappings
   254                 # bidirectional mappings
       
   255                 remote_port = remote_attrs['port']
       
   256 
   227                 forward = (local_node, local_port, remote_port, remote_node)
   257                 forward = (local_node, local_port, remote_port, remote_node)
   228                 reverse = (remote_node, remote_port, local_port, local_node)
   258                 reverse = (remote_node, remote_port, local_port, local_node)
   229 
   259 
   230                 if reverse not in links :
   260                 if reverse not in links :
   231                     links[forward] = (local_untag, local_tagged, None)
   261                     links[forward] = (local_untag, local_tagged, None)
   397 
   427 
   398     # input
   428     # input
   399     options, args = parser.parse_args(argv[1:])
   429     options, args = parser.parse_args(argv[1:])
   400     pvl.args.apply(options)
   430     pvl.args.apply(options)
   401     
   431     
   402     # load hosts for correlation
   432     # load hosts
   403     hosts = dict((str(host), host) for host in pvl.hosts.apply(options, args))
   433     hosts = list(pvl.hosts.apply(options, args))
   404 
   434 
   405     # load raw snmp data
   435     # load raw snmp data
   406     snmp = load_snmp_data(options, options.snmp_data, hosts)
   436     snmp = load_snmp_data(options, options.snmp_data, hosts)
   407 
   437 
   408     # process data into graph
   438     # process data into graph