The unified diff between revisions [609f1fd1..] and [50ac7d23..] is displayed below. It can also be downloaded as a raw diff.

#
#
# add_file "snmp.py"
#  content [da39a3ee5e6b4b0d3255bfef95601890afd80709]
#
# patch "config.py"
#  from [f9ee8420c3a69c3b178bdd5b6ee387fadab4c7b7]
#    to [752487f2f3c5389f4303fa83efa808dc23a32841]
#
# patch "plugins/basic_snmp.py"
#  from [58d9b388f06033a3509ee35b93c6a163207442f9]
#    to [b31e67918315f0373741bd567fa881f5f137b086]
#
# patch "tables/ethernet_forwarding.csv"
#  from [a349e48f2b462ffef79d0993fe75a3d10fbf9a47]
#    to [91a6649f3ceeea0276a7d8a73639a28943af92d3]
#
# patch "yowie.py"
#  from [91da93a9f5f30fd3c5b3fba3332c51ea63169051]
#    to [bd82e0a47d455ab54b669b6e637b117fe11306d8]
#
============================================================
--- snmp.py	da39a3ee5e6b4b0d3255bfef95601890afd80709
+++ snmp.py	da39a3ee5e6b4b0d3255bfef95601890afd80709
============================================================
--- config.py	f9ee8420c3a69c3b178bdd5b6ee387fadab4c7b7
+++ config.py	752487f2f3c5389f4303fa83efa808dc23a32841
@@ -9,6 +9,10 @@ data_path = os.path.join(install_path, '
 install_path = '/Users/grahame/monotone/yowie/'
 plugin_path = os.path.join(install_path, 'plugins')
 data_path = os.path.join(install_path, 'data')
+db_path = os.path.join(install_path, 'db')
+mtn = '/opt/monotone/bin/mtn'
+mtn_database = os.path.join(db_path, 'data.db')
+mtn_branch = 'net.angrygoats.yowie.data'

 drivers = (
     'basic_snmp',
@@ -22,9 +26,13 @@ devices = {

 devices = {
     'gringo.net.uwa.edu.au' : {
-        'driver' : 'basic_snmp'
-    }
+        'driver' : 'basic_snmp',
+        'zone' : 'backbone',
+        'execute_on' : ('ssh', 'grahame@typhaon.ucs.uwa.edu.au'),
+    },
+#    'phlegethon.snap.uwa.edu.au' : {
+#        'driver' : 'basic_snmp',
+#        'zone' : 'snap',
+#        'execute_on' : ('ssh', 'phlegethon.snap.uwa.edu.au'),
+#    },
 }
-
-
-
============================================================
--- plugins/basic_snmp.py	58d9b388f06033a3509ee35b93c6a163207442f9
+++ plugins/basic_snmp.py	b31e67918315f0373741bd567fa881f5f137b086
@@ -1,4 +1,8 @@

+#
+# basic_snmp : stuff a generic managed switch should support
+#
+
 plugin_info = {
     'description' : '''\
 A basic module, which provides as many tables as possible without
@@ -8,7 +12,7 @@ def ethernet_forwarding(table_name, tabl
 }

 def ethernet_forwarding(table_name, table_io, device):
-    return None
+    yield device.config['zone'], 1, '00:11:24:c7:dd:41', 'en1', now()

 def ethernet_arp(table_name, table_io, device):
     return None
============================================================
--- tables/ethernet_forwarding.csv	a349e48f2b462ffef79d0993fe75a3d10fbf9a47
+++ tables/ethernet_forwarding.csv	91a6649f3ceeea0276a7d8a73639a28943af92d3
@@ -1 +1 @@
-"epoch_time","ethernet_address","interface"
+"zone","vlan","ethernet_address","interface","epoch_time"
============================================================
--- yowie.py	91da93a9f5f30fd3c5b3fba3332c51ea63169051
+++ yowie.py	bd82e0a47d455ab54b669b6e637b117fe11306d8
@@ -1,11 +1,20 @@
 #!/usr/bin/env python2.4

-import csv, os, sha, sys, time
 import config
+import pipes
+import time
+import csv
+import sha
+import sys
+import os

 class DeviceProxy:
-    def __init__(self, device_name, driver):
-        self.device_name, self.driver = device_name, driver
+    def __init__(self, device_name, device_config):
+        self.config = device_config
+        self.device_name = device_name
+        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))

 class Table:
     def __init__(self, table_name, column_file):
@@ -18,14 +27,19 @@ class TableIO:
 class TableIO:
     def __init__(self, implement, filename):
         self.implement, self.filename = implement, filename
-        self.values = {}
+
+    def read_last_values(self):
         if os.access(self.filename, os.R_OK):
             for row in csv.reader(open(self.filename)):
-                self.values[row[0]] = row[1:]
-    def write(self, rows):
+                yield row
+
+    def write(self, rows, rowlen):
         fd = open(self.filename, "w")
-        writer = cvs.writer(fd)
-        fd.writerows(rows)
+        writer = csv.writer(fd)
+        for row in rows:
+            if len(row) != rowlen:
+                raise Exception("Row has length %d (must be %d)" % (len(row), rowlen))
+            writer.writerow(row)

 export_funcs = {}
 def export_to_drivers(f):
@@ -33,6 +47,10 @@ def export_to_drivers(f):
     return f

 @export_to_drivers
+def now():
+    return int(time.time())
+
+@export_to_drivers
 def log(*args):
     if len(args) == 1:
         args = args[0]
@@ -50,6 +68,19 @@ def simple_get_table(supported):
         return supported[args[0]](*args, **kwargs)
     return __get_table

+def monotone_commit():
+    def s(*args, **kwargs):
+        return os.system(*args, **kwargs) >> 8
+    os.chdir(config.data_path)
+    pq = pipes.quote
+    if not os.access(config.mtn_database, os.R_OK):
+        rv = s(config.mtn + ' --db=%s db init' % pq(config.mtn_database))
+        if rv != 0:
+            raise Exception("Unable to initialise monotone database: %s" % config.mtn_database)
+    base_cmd = '%s --db=%s --branch=%s ' % (config.mtn,
+                                           pq(config.mtn_database),
+                                           pq(config.mtn_branch))
+
 if __name__ == '__main__':
     def init_drivers():
         rv = {}
@@ -71,10 +102,7 @@ if __name__ == '__main__':
     def init_devices():
         rv = {}
         for name in config.devices:
-            conf = config.devices[name]
-            if not conf.has_key('driver'):
-                raise Exception("all devices must have a driver: " + name)
-            p = DeviceProxy(name, conf['driver'])
+            p = DeviceProxy(name, config.devices[name])
             rv[name] = p
         return rv

@@ -97,7 +125,7 @@ if __name__ == '__main__':

     def update_device(device):
         log("updating: " + device)
-        export = drivers[devices[device].driver]
+        export = drivers[devices[device].config['driver']]
         has_table, get_table = export.get('has_table'), export.get('get_table')
         if not has_table or not get_table:
             log("device does not implement basic functionality: " + device)
@@ -108,14 +136,15 @@ if __name__ == '__main__':
                 continue
             log("updating table %s on: %s" % (table, device))
             tio = TableIO(tables[table], get_filename(device, table))
-            rows = get_table(table, tio, devices[device])
-            print rows
+            rowlen = len(tables[table].columns)
+            tio.write(get_table(table, tio, devices[device]), rowlen)

     drivers = init_drivers()
     devices = init_devices()
     tables = init_tables()
-
     map(update_device, devices)
+    # commit changes to the data repository
+    monotone_commit()
+
+
+
-
-
-