devel:blueprints:ipdevpoll
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
devel:blueprints:ipdevpoll [2009/07/02 13:29] – Fixed list klette | devel:blueprints:ipdevpoll [2012/05/07 11:26] (current) – fix url morten | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== ipdevpoll design specification ====== | ====== ipdevpoll design specification ====== | ||
+ | |||
+ | **This page is currently being updated to match whats being developed. Dont trust this stuff just yet :-)** | ||
+ | |||
===== Introduction ===== | ===== Introduction ===== | ||
// | // | ||
Line 7: | Line 10: | ||
* Asynchronous SNMP polling, built with [[http:// | * Asynchronous SNMP polling, built with [[http:// | ||
* Plugin based architecture | * Plugin based architecture | ||
- | * Data persistence based on Twisted aDBI? (FIXME) | ||
==== Core application ==== | ==== Core application ==== | ||
- | The gDD core application has the following basic tasks: | + | The core application has the following basic tasks: |
* Schedule executing of jobs | * Schedule executing of jobs | ||
- | * Execute | + | * Execute |
- | * Handle rescheduling when a plugin signals that previous state has been invalidated | + | * Provide data persistence to plug-ins |
- | * Provide data persistence to plugins | + | |
- | Scheduling of jobs instead of individual plugins has been chosen to simplify the application due to the high level of dependency between some of the plugins. Each job defined in the the gDD configuration defines | + | Jobs are a group of plug-ins |
+ | NAV provide two jobs in the default configuration, | ||
+ | These provide a sane order for the plug-ins to run. The user may specify their own jobs and schedules | ||
+ | demanded by the python ConfigParser-module. | ||
+ | \\ | ||
+ | \\ | ||
+ | Example jobs.conf | ||
+ | <code ini> | ||
+ | [inventory] | ||
+ | interval: 60s | ||
+ | plugins: | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | </ | ||
- | The previous version | + | One advantage |
==== Data ==== | ==== Data ==== | ||
- | Data storage will to a certain degree be modeled around | + | Data is provided through |
- | to a class-level array of initiated | + | |
- | | + | Shadow-classes are created in '' |
- | - Retrieve current data in db. | + | \\ |
- | - Update if necessary. | + | Example shadowclass specification |
- | - Flush global | + | <code python> |
+ | class Interface(Shadow): | ||
+ | __shadowclass__ = manage.Interface | ||
+ | __lookups__ = [(' | ||
+ | </ | ||
+ | |||
+ | The Shadow-class has two important attributes. ''< | ||
+ | which django model to mimic. This will make any instances | ||
+ | answers | ||
+ | on the shadowclass, | ||
+ | determining wheter to update an object | ||
+ | existing objects in the database the storage system first tries the primary key | ||
+ | field on the object. If the PK is None, the ''< | ||
+ | for the checking. The ''< | ||
+ | Tuples specifies combined lookups, while strings specifies single field | ||
+ | lookups. The different lookups are tried in the order they are defined in the | ||
+ | list. If we look at the example above, it will first try to get an existing | ||
+ | object with only the '' | ||
+ | first object in the lookup-list, a combined search for objects matching both | ||
+ | the '' | ||
+ | unsuccessful it goes on to the next lookup field. | ||
+ | |||
+ | There are two major " | ||
+ | multiple rows are returned an exception is raised. The second is primary key | ||
+ | lookups where the primary key is not an AutoField; if no rows are found when | ||
+ | using non-AutoField primary keys, a new object is created. If the field is an | ||
+ | AutoField however, and no rows are returned, an exception is raised. | ||
+ | |||
+ | Deletion of objects in the database is done if the shadowobject has its | ||
+ | '' | ||
+ | |||
+ | Once the job is done the storage | ||
+ | the shadow objects contained in '' | ||
+ | an instance are saved before the object it self. | ||
==== Plugins ==== | ==== Plugins ==== | ||
Line 54: | Line 103: | ||
- arp.py | - arp.py | ||
- ... | - ... | ||
+ | |||
+ | ===== New plugin design proposal ===== | ||
+ | |||
+ | Plugins should be divided into their respective responsibilities. Each plugin should be its own python module | ||
+ | with a defined handler-class sub-classed from the nav.ipdevpoll.Plugin-class. The handler should only deal with | ||
+ | storing the information to the database and logic to determine if vendor-specific collections methods should be used. | ||
+ | Each plugin should supply its own test-suite in a folder called test withing the plugin module. Every plugin should | ||
+ | prefer to use the MIB-2 standard mibs for collecting information, | ||
+ | To maximize the amount of easily testable code, all parsing logic should be extracted into their own methods and not | ||
+ | be entangled into the collection process (methods that returns deferred objects). Remember to call the processing | ||
+ | methods asynchronously as well. | ||
+ | |||
+ | / | ||
+ | - /iftable | ||
+ | - iftable.py | ||
+ | - test_iftable.py | ||
+ | - collector.py | ||
+ | - /vendor | ||
+ | - cisco.py | ||
+ | - test_cisco.py | ||
+ | - alcatel.py | ||
+ | - test_alcatel.py | ||
+ | - .. | ||
+ | |||
+ | Example plugin: | ||
+ | <code python> | ||
+ | from nav.ipdevpoll import Plugin | ||
+ | from nav.ipdevpoll.plugins.vlan import collector | ||
+ | |||
+ | class Vlan(Plugin): | ||
+ | def __init__(self, | ||
+ | """ | ||
+ | Initialize the plugin | ||
+ | """ | ||
+ | Plugin.__init__(self, | ||
+ | self.deferred = defer.Deferred() | ||
+ | |||
+ | def handle(self): | ||
+ | """ | ||
+ | This is the entry point for the plugin. | ||
+ | """ | ||
+ | self.logger.debug(" | ||
+ | collector.collect(self.job_handler.agent) | ||
+ | return self.deferred | ||
+ | |||
+ | def process_result(self, | ||
+ | """ | ||
+ | Standard processing method for all plugins. | ||
+ | The collections methods should provide data | ||
+ | in the same format to this method. | ||
+ | """ | ||
+ | if not result: | ||
+ | self.logger.debug( | ||
+ | "No VLAN information found using MIB-2 MIBS.\ | ||
+ | | ||
+ | # Try vendor specific methods | ||
+ | else: | ||
+ | self.logger.debug(" | ||
+ | for ifIndex, vlan in result: | ||
+ | # Store the information to database or similar | ||
+ | pass | ||
+ | |||
+ | # Plugin-run finished. Exit. | ||
+ | self.deferred.callback(True) | ||
+ | return result | ||
+ | </ | ||
=== Suggested log plugins === | === Suggested log plugins === | ||
Line 75: | Line 190: | ||
* ModuleMon | * ModuleMon | ||
+ | |||
+ | === Implemented plugins === | ||
+ | |||
+ | Already implemented plugins can be found on [[devel: | ||
===== Database changes ===== | ===== Database changes ===== | ||
Line 92: | Line 211: | ||
The IF-MIB has no concept of an interface/ | The IF-MIB has no concept of an interface/ | ||
- | ===== Code ===== | + | ===== Status |
- | The mercurial repositories can be found at FIXME | + | The first NAV release to include ipdevpoll was version 3.6. |
===== References ===== | ===== References ===== |
devel/blueprints/ipdevpoll.1246541368.txt.gz · Last modified: by klette