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