The unified diff between revisions [705545af..] and [eb1440d9..] is displayed below. It can also be downloaded as a raw diff.

#
#
# patch "plugins/cisco_ios.py"
#  from [f0a099f779cf16686de93526376228a6e4df7592]
#    to [0b3dc43befd7a56156d092305ac3cc62968f9327]
#
# patch "yowie.py"
#  from [8303d0a3d2730d9b7caf3d9dab5260c25705787d]
#    to [7b6a0cb3235f0229a909686791a0fb28738e5685]
#
============================================================
--- plugins/cisco_ios.py	f0a099f779cf16686de93526376228a6e4df7592
+++ plugins/cisco_ios.py	0b3dc43befd7a56156d092305ac3cc62968f9327
@@ -1,6 +1,8 @@ import basic_snmp

 from goatpy.snmpwrapper import snmpwalk
 import basic_snmp
+import csv
+import os
 import re

 # http://tools.cisco.com/Support/SNMP/do/BrowseMIB.do?local=en&step=2&mibName=CISCO-TC-V1SMI
@@ -18,11 +20,11 @@ def adjacency(table_name, table_io, devi
         asdigits = [int(t, 16) for t in s.split(' ')]
         asdigits = filter(lambda x: x >= 32 and x <= 122, asdigits)
         return ''.join([chr(t) for t in asdigits])
-    row_to_field =  {   1 : ('INTEGER', 'cdpCacheIfIndex'),
-                        3 : ('INTEGER', 'cdpCacheAddressType'),
-                        4 : ('Hex-STRING', 'cdpCacheAddress'),
-                        6 : ('STRING', 'cdpCacheDeviceId'),
-                        7 : ('STRING', 'cdpCacheDevicePort')  }
+    row_to_field =  { 1 : ('INTEGER', 'cdpCacheIfIndex'),
+                      3 : ('INTEGER', 'cdpCacheAddressType'),
+                      4 : ('Hex-STRING', 'cdpCacheAddress'),
+                      6 : ('STRING', 'cdpCacheDeviceId'),
+                      7 : ('STRING', 'cdpCacheDevicePort')  }
     table = {}
     for oid, type, value in snmpwalk(device.device_name, device.config['community'], "2c", "SNMPv2-SMI::enterprises.9.9.23.1.2.1.1", ssh_dest=device.config.get('ssh')):
         id, row = tuple(oid[-2:]), int(oid[-3])
@@ -33,7 +35,6 @@ def adjacency(table_name, table_io, devi

     for row in table:
         vals = table[row]
-        print vals
         yield (device.config['zone'],
                vals.get('cdpCacheDeviceId', '')[1:-1],
                vals.get('cdpCacheIfIndex', ''),
@@ -43,8 +44,47 @@ def ethernet_forwarding(table_name, tabl

 # see: http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a0080094a9b.shtml
 def ethernet_forwarding(table_name, table_io, device):
-    yield device.config['zone'], 1, '00:11:24:c7:dd:41', 'en1'
+    vlans_file = device.get_filename('ethernet_vlans')
+    vlans = []
+    if os.access(vlans_file, os.R_OK):
+        rows = csv.reader(open(vlans_file))
+        header = rows.next()
+        vlan_column = header.index('vlan')
+        for row in rows:
+            vlans.append(row[vlan_column])
+	# build the bridgeport -> ifindex table
+	bridgeport_to_ifindex = {}
+	for oid, type, value in snmpwalk(device.device_name, device.config['community'], "2c", "1.3.6.1.2.1.2.2.1.1", ssh_dest=device.config.get('ssh')): # dot1dBasePortIfIndex
+		bridgeport = int(oid[-1])
+		ifindex = int(value)
+		bridgeport_to_ifindex[bridgeport] = ifindex

+    def get_uid_to_mac(vlan):
+    	rv = {}
+    	for oid, type, value in  snmpwalk(device.device_name, device.config['community'] + '@' + vlan, "2c", ".1.3.6.1.2.1.17.4.3.1.1", ssh_dest=device.config.get('ssh')): # dot1dTpFdbAddress
+    		uid = tuple(oid[-6:])
+    		mac = value
+    		rv[uid] = mac
+    	return rv
+
+    def get_uid_to_bridgeport(vlan):
+    	rv = {}
+    	for oid, type, value in  snmpwalk(device.device_name, device.config['community'] + '@' + vlan, "2c", ".1.3.6.1.2.1.17.4.3.1.2", ssh_dest=device.config.get('ssh')): # dot1dTpFdbAddress
+    		uid = tuple(oid[-6:])
+    		bridgeport = int(value)
+    		rv[uid] = bridgeport
+    	return rv
+
+    for vlan in vlans:
+        log("retrieving vlan forwarding table for : %s" % (vlan))
+        uid_to_mac = get_uid_to_mac(vlan)
+        uid_to_bridgeport = get_uid_to_bridgeport(vlan)
+        for uid in uid_to_mac:
+            mac, bridgeport = uid_to_mac.get(uid), uid_to_bridgeport.get(uid)
+            if bridgeport and mac:
+                ifindex = bridgeport_to_ifindex.get(bridgeport)
+                yield device.config['zone'], vlan, mac, ifindex
+
 def ethernet_vlans(table_name, table_io, device):
     # walk vtpVlanName
     for oid, type, value in snmpwalk(device.device_name, device.config['community'], "2c", ".1.3.6.1.4.1.9.9.46.1.3.1.1.4", ssh_dest=device.config.get('ssh')):
============================================================
--- yowie.py	8303d0a3d2730d9b7caf3d9dab5260c25705787d
+++ yowie.py	7b6a0cb3235f0229a909686791a0fb28738e5685
@@ -18,6 +18,8 @@ class DeviceProxy:
         for required in ('driver', 'zone'):
             if not self.config.has_key(required):
                 raise Exception('Cannot initialize device %s: required config item %s unspecified.' % (device_name, required))
+    def get_filename(self, table):
+        return os.path.join(config.data_path, self.device_name, table) + '.csv'

 class Table:
     def __init__(self, table_name, column_file):
@@ -36,7 +38,8 @@ class TableIO:
             for row in csv.reader(open(self.filename)):
                 yield row

-    def write(self, header, rows):
+    def write(self, rows):
+        header = self.implement.columns
         # use a temporary file; this avoids annoying problems where an update fails half-way
         # through and we potentially commit a half-complete version of the file.
         tmp_fdno, tmp_filename = tempfile.mkstemp(suffix='.csv', prefix='yowie')
@@ -174,9 +177,6 @@ if __name__ == '__main__':
             os.mkdir(datadir)
         return datadir

-    def get_filename(device, table):
-        return os.path.join(config.data_path, device, table) + '.csv'
-
     def update_device(device):
         log("updating: " + device)
         export = drivers[devices[device].config['driver']]
@@ -189,9 +189,8 @@ if __name__ == '__main__':
             if not has_table(table):
                 continue
             log("updating table %s on: %s" % (table, device))
-            tio = TableIO(tables[table], get_filename(device, table))
-            header = tables[table].columns
-            tio.write(header, get_table(table, tio, devices[device]))
+            tio = TableIO(tables[table], devices[device].get_filename(table))
+            tio.write(get_table(table, tio, devices[device]))

     monotone_setup()
     drivers = init_drivers()