diff -r 7077379fb5a0 -r 9de553b50128 bin/pvl.hosts-lldp --- a/bin/pvl.hosts-lldp Tue Mar 18 13:59:22 2014 +0200 +++ b/bin/pvl.hosts-lldp Tue Mar 18 14:02:26 2014 +0200 @@ -8,7 +8,7 @@ import pvl.args import pvl.hosts from pvl.invoke import merge -from pvl.snmp import snmp, lldp, vlan +from pvl.snmp import snmp, lldp, vlan, bridge import logging; log = logging.getLogger('pvl.hosts-lldp') import optparse @@ -79,6 +79,27 @@ yield host, agent +def hosts_bridge (options, hosts) : + """ + Discover Bridge-supporting hosts. + + Yields Host, BridgeAgent + """ + + for host, host_snmp in hosts_snmp(options, hosts) : + agent = bridge.BridgeAgent.apply(options, host.fqdn(), community=host_snmp.get('community')) + + try : + agent.ping() + except snmp.SNMPError as ex : + log.warning("%s: %s", host, ex) + continue + + log.info("%s", host) + + yield host, agent + + def apply_hosts_lldp (options, hosts) : """ Query host LLDP info. @@ -111,6 +132,8 @@ def apply_hosts_vlan (options, hosts) : """ Query host VLAN ports. + + Yields host, { port: (untagged, [tagged]) } """ _hosts_vlan = list(hosts_vlan(options, hosts)) @@ -141,6 +164,22 @@ ) for port in set(vlan_untagged) | set(vlan_tagged) ) +def apply_hosts_bridge (options, hosts) : + """ + Query host bridge tables. + + Yields host, { port: (macs) } + """ + + for host, agent in hosts_bridge(options, hosts) : + ports = collections.defaultdict(list) + + for ether, port in agent.fdb() : + if port : + ports[port].append(ether) + + yield host, ports + COLOR_VLANS = { 1: 'grey', # pvl-lan 2: 'blue', # pvl-lan2 @@ -344,6 +383,9 @@ # discover node/port graph items = apply_hosts_lldp(options, hosts) + # discover edge nodes + leafs = apply_hosts_bridge(options, hosts) + # print if options.graph_dot : apply_graph(options, items, vlans) @@ -353,8 +395,10 @@ print "{host:30} {host.location:>30} {local[port]:>25} <-> {remote[port]:<25} {remote_host.location:>30} # {remote[chassis]} ({remote_host})".format(host=host, local=local, remote=remote, remote_host=remote_host) else : print "{host:30} {host.location:>30} {local[port]:>25} <-- {remote[port]:<25} {empty:30} # {remote[chassis]} ({remote[sys_name]})".format(host=host, local=local, remote=remote, empty='') - - + + for host, ports in leafs : + for port, ethers in ports.iteritems() : + print "{host:30} {host.location:>30} {port:25} <== # {ethers}".format(host=host, port=port, ethers=' '.join(ethers)) if __name__ == '__main__': pvl.args.main(main)