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 [2008/12/11 09:09] – Add list of suggested plugins thomaska | 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 |
- | FIXME data persistence/containers | + | ==== Data ==== |
+ | |||
+ | Data is provided through the use of shadow-classes of django-models. Plugins never write django-objects directly. This is handled by the job the plugin runs in at the end of each job. | ||
+ | |||
+ | Shadow-classes are created in '' | ||
+ | \\ | ||
+ | Example shadowclass specification | ||
+ | <code python> | ||
+ | class Interface(Shadow): | ||
+ | __shadowclass__ = manage.Interface | ||
+ | __lookups__ = [(' | ||
+ | </code> | ||
+ | |||
+ | The Shadow-class has two important attributes. ''< | ||
+ | which django model to mimic. This will make any instances of the shadowclass | ||
+ | answers to the same attributes as the django model. When a property is changed | ||
+ | on the shadowclass, | ||
+ | determining wheter to update an object or not at the end of a run. To lookup | ||
+ | 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, | ||
+ | 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 routine is called. The storage system then parses all | ||
+ | the shadow objects contained in '' | ||
+ | an instance are saved before the object it self. | ||
==== Plugins ==== | ==== Plugins ==== | ||
Line 30: | Line 87: | ||
Installed plugins should be specified as a simple list of module names to import in string form (much like django' | Installed plugins should be specified as a simple list of module names to import in string form (much like django' | ||
- | Each plugin will be called in order and must itself determine if the netbox in question is of instrest (ie. dues it support the mibs that the plugin knows about, does the netbox vendor match those supported by the plugin...). Once this is decided the plugin can either pass or start collecting more SNMP data and populate the data persistence store and/or modify the allready | + | Each plugin will be called in order and must itself determine if the netbox in question is of instrest (ie. dues it support the mibs that the plugin knows about, does the netbox vendor match those supported by the plugin...). Once this is decided the plugin can either pass or start collecting more SNMP data and populate the data persistence store and/or modify the already |
To keep the plugin directory somewhat organized the following organization has been proposed: | To keep the plugin directory somewhat organized the following organization has been proposed: | ||
Line 46: | 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 === | ||
- | | + | |
- | | + | |
- | | + | |
- | - ModuleMon replacement | + | |
=== Suggested inventory plugins === | === Suggested inventory plugins === | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
+ | === Suggested status monitoring plugins === | ||
+ | |||
+ | * ModuleMon | ||
+ | |||
+ | === Implemented plugins === | ||
+ | |||
+ | Already implemented plugins can be found on [[devel: | ||
===== Database changes ===== | ===== Database changes ===== | ||
- | The following database changes have been suggested | + | The following database changes have been suggested. |
+ | |||
+ | ==== Merge swport/ | ||
+ | |||
+ | A long standing issue has been merging the artificially separated '' | ||
+ | |||
+ | Most NAV code that deals with interfaces will have duplicate code to take care of '' | ||
+ | |||
+ | ==== No module requirement for interfaces ==== | ||
+ | |||
+ | The current NAV data model mandates that all gwports/ | ||
+ | |||
+ | 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.1228986550.txt.gz · Last modified: by thomaska