From 75345fe49da09b084fc4cf8109287253110e52a6 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 23 Sep 2013 17:05:24 +0100 Subject: [PATCH] Documentation Additions - add CSV plugin output docs - add node about migrating from netdisco 1 - add authZ note to developer docs - add doc on X namespace and site_plugins INC dir - js and css plugin docs note - add port col plugin docs - suggest enable housekeeping in docs - document Observium plugin - add plugin config advice to docs --- Netdisco/lib/App/Netdisco.pm | 22 +-- .../lib/App/Netdisco/Manual/Developing.pod | 90 +++------ .../lib/App/Netdisco/Manual/ReleaseNotes.pod | 27 +++ .../App/Netdisco/Manual/WritingPlugins.pod | 174 +++++++++++++++++- .../lib/App/NetdiscoX/Web/Plugin/Observium.pm | 71 +++++++ Netdisco/share/config.yml | 2 +- 6 files changed, 303 insertions(+), 83 deletions(-) diff --git a/Netdisco/lib/App/Netdisco.pm b/Netdisco/lib/App/Netdisco.pm index 72fa6de7..e445934a 100644 --- a/Netdisco/lib/App/Netdisco.pm +++ b/Netdisco/lib/App/Netdisco.pm @@ -220,16 +220,21 @@ Run the following command to start the web-app server as a backgrounded daemon ~/bin/netdisco-web start If the Inventory is empty because this is a new installation, you probably -want to either run some polling jobs from the command-line, or give a web user -some admin rights (TODO: user rights management). +want to run some polling jobs. This can be done from from the web interface or +command-line (see L). Run the following command to start the job control daemon (port control, etc): ~/bin/netdisco-daemon start -You should take care not to run this Netdisco daemon and the legacy daemon at -the same time. Similarly, if you use the device discovery with Netdisco 2, -disable your system's cron jobs for the Netdisco 1 poller. +You should take care not to run this Netdisco daemon and the Netdisco 1.x +daemon at the same time. Similarly, if you use the device discovery with +Netdisco 2, disable your system's cron jobs for the Netdisco 1.x poller. + +At this point you can revisit the C<~/environments/deployment.yml> file to +uncomment more configuration. Check out the community string settings, and +C which enables the automatic periodic device discovery. See +L for further details. =head1 Upgrading @@ -297,13 +302,6 @@ within the L documentation. =head1 Caveats -Some sections are not yet implemented, e.g. the I tab. - -Some menu items on the main black navigation bar go nowhere. - -None of the Reports yet exist (e.g. searching for wireless devices, or duplex -mismatches). These will be implemented as a plugin bundle. - The Wireless, IP Phone and NetBIOS Node properies are not yet shown. =head1 AUTHOR diff --git a/Netdisco/lib/App/Netdisco/Manual/Developing.pod b/Netdisco/lib/App/Netdisco/Manual/Developing.pod index 6a31658d..e0166541 100644 --- a/Netdisco/lib/App/Netdisco/Manual/Developing.pod +++ b/Netdisco/lib/App/Netdisco/Manual/Developing.pod @@ -36,20 +36,20 @@ codebase, hopefully in enough detail that you can get hacking yourself :-) This is Netdisco major version 2. The minor version has six digits, which are split into two components of three digits each. It's unlikely that the major -version number (2) will increment. Each "feature" release to CPAN will -increment the first three digits of the minor version. Each "bug fix" release +version number (2) will increment. Each "significant" release to CPAN will +increment the first three digits of the minor version. Each "trivial" release will increment the second three digits of the minor version. -Stable releases will have an even "feature" number. Beta releases will have an -odd "feature" number and also a suffix with an underscore, to prevent CPAN +Beta releases will have a a suffix with an underscore, to prevent CPAN indexing the distribution. Some examples: - 2.002002 - "feature" release 2, "bug fix" release 2 - 2.002003 - another bug was found and fixed, hence "bug fix" release 3 - 2.003000_001 - first beta for the next "feature" release + 2.002002 - "significant" release 2, second "trivial" release + 2.002003 - a bug was found and fixed, hence "trivial" release 3 + 2.003000_001 - first beta for the next "significant" release 2.003000_002 - second beta - 2.004000 - the next "feature" release + 2.004000 - the next "significant" release +The words "significant" and "trivial" are entirely subjective, of course. =head1 Global Configuration @@ -98,7 +98,6 @@ need to do to access the Netdisco database, with no additional setup, is: schema('netdisco')->resultset(...)->search({...}); - =head1 DBIx::Class Layer DBIx::Class, or DBIC for short, is an Object-Relational Mapper. This means it @@ -174,15 +173,11 @@ using the C script which also ships with the distribution. =head2 Foreign Key Constraints -We have not yet deployed any FK constraints into the Netdisco schema. This is +We have not deployed any FK constraints into the Netdisco schema. This is partly because the current poller inserts and deletes entries from the database in an order which would violate such constraints, but also because some of the archiving features of Netdisco might not be compatible anyway. -Regardless, a lack of FK constraints doesn't upset DBIx::Class. The -constraints can easily be deployed in a future release of Netdisco. - - =head1 Web Application The Netdisco web app is a "classic" Dancer app, using most of the bundled @@ -235,31 +230,23 @@ server so you can fire-and-forget the Netdisco web app without much trouble at all. This script in turn calls C which is the real Dancer application, that runs in the foreground if called on its own. -All web app code lives below L, but there are also some -helper routines in L (for example sorting device -port names). - -If you're working on code in the web application, it's possible to have the -app restart itself each time you save a file in your editor. The following -command will watch the C and C folder trees for changes, and you -probably want to edit your C configuration to enable -additional logging (see L): - - DANCER_ENVIRONMENT=development DBIC_TRACE_PROFILE=console DBIC_TRACE=1 \ - ~/bin/localenv starman -R lib,share bin/netdisco-web-fg - =head2 Authentication -Dancer includes (of course) good session management using cookies and a memory -database. You should change this to a disk database if using a proper forking -web server installation so that sessions are available to all instances. - Session and authentication code lives in L. It is fully backwards compatible with the existing Netdisco user management, making use of the database users and their MD5 passwords. There is also support for unauthenticated access to the web app (for instance if you have some kind of external authentication, or simply trust everyone). +See L for further details. + +=head2 Authorization + +Every Dancer route handler must have proper role based access control enabled, +to prevent unauthorized access to Netdisco's data, or admin features. This is +done with the L module. It handles both the +authentication using Netdisco's database, and then protects each route +handler. See L for details. =head2 Templates @@ -336,22 +323,6 @@ they're loaded within the page body by the templates. These files contain a function C which is called each time AJAX delivers new content into a tab in the page (think of it like a callback, perhaps). -Also in the C folder are the other public -libraries loaded by the Netdisco application: - -The Toastr library is used for "Growl"-like notifications which appear in the -corner of the web browser and then fade away. These notify the user of -successful background job submission, and jos results. - -The d3 library is a graphics toolkit used to display the NetMap feature. This -works differently from the old Netdisco in that everything is generated -on-the-fly using SQL queries (C resultset) and this d3 library -for rendering. - -Finally Twitter Bootstrap also ships with a toolkit of helpful Javascript -driven features such as the tooltips and collapsers. - - =head1 Job Daemon The old Netdisco has a job control daemon which processes "port control" @@ -361,12 +332,9 @@ web application. However, it still makes use of the Dancer configuration and database connection management features mentioned above. The job daemon is backwards compatible with the old Netdisco database job -requests table, although it doesn't yet log results in the same way. Most -important, it cannot yet poll any devices for discovery or macsuck/arpnip, -although that's next on the list! - -All code for the job daemon lives under the L namespace -and like the rest of Netdisco is broken down into manageable chunks. +requests table. All code for the job daemon lives under the +L namespace and like the rest of Netdisco is broken +down into manageable chunks. =head2 Running the Job Daemon @@ -384,7 +352,7 @@ runs in the foreground if called on its own. The job daemon is based on the L library, which handles the forking and management of child processes doing the actual work. This actually runs in the foreground unless wrapped with Daemon::Control, as mentioned above. MCE -handles three flavours of "worker" for different tasks. +handles four flavours of "worker" for different tasks. One goal that we had designing the daemon was that sites should be able to run many instances on different servers, with different processing capacities. @@ -406,10 +374,8 @@ the "interactive" jobs of workers we have two types of worker. The Interactive worker picks jobs from the local job queue relating to device and port reconfiguration only. It submits results directly back to the central -Netdisco database. - -The Poller worker (is not yet written!) and similarly picks job from the local -queue, this time relating to device discovery and polling. +Netdisco database. The Poller worker similarly picks job from the local queue, +this time relating to device discovery and polling. There is support in the daemon for the workers to pick more than one job at a time from the local queue, in case we decide this is worth doing. However the @@ -419,6 +385,11 @@ daemons on other servers). The user is free to configure the number of Interactive and Poller workers in their C file (zero or more of each). +The fourth kind of worker is called the Scheduler and takes care of adding +discover, macsuck, and arpnip jobs to the queue (which are in turn handled by +the Poller worker). This worker is automatically started only if the user has +enabled the "C" section of their C site config. + =head2 SNMP::Info The daemon obviously needs to use L for device control. All the @@ -434,9 +405,6 @@ Configuration for SNMP::Info comes from the YAML files, of course. This means that our C and C settings are now in YAML format. In particular, the C list is a real list within the configuration. -Other libraries will be added to this namespace in due course, as we add more -functionality to the Job Daemon. - =head2 DBIx::Class Layer The local job queue for each Job Daemon is actually an SQLite database running diff --git a/Netdisco/lib/App/Netdisco/Manual/ReleaseNotes.pod b/Netdisco/lib/App/Netdisco/Manual/ReleaseNotes.pod index 47f69371..70ffc02f 100644 --- a/Netdisco/lib/App/Netdisco/Manual/ReleaseNotes.pod +++ b/Netdisco/lib/App/Netdisco/Manual/ReleaseNotes.pod @@ -8,6 +8,33 @@ This document will list only the most significant changes with each release of Netdisco. You are B recommended to read this document each time you install and upgrade. Also see the Changes file, for more information. +=head1 Migrating from Netdisco 1.x + +This distribution (App::Netdisco) is a complete rewrite of the Netdisco +application. Users often ask whether they can run both versions at the same +time, and whether the database must be copied. Here are the guidelines for +migrating from Netdisco 1.x: + +=over 4 + +=item * + +You can run both Netdisco 1.x and App::Netdisco web frontends at the same +time, using the same database. + +=item * + +Only enable the backend daemon and discovery jobs from I Netdisco 1.x +I App::Netdisco. + +=item * + +You can share a single database between Netdisco 1.x and App::Netdisco. The +deploy script for App::Netdisco will make some schema changes to the database, +but they are backwards compatible. + +=back + =head1 2.016000 =head2 General Notices diff --git a/Netdisco/lib/App/Netdisco/Manual/WritingPlugins.pod b/Netdisco/lib/App/Netdisco/Manual/WritingPlugins.pod index 67a18357..2d37fad7 100644 --- a/Netdisco/lib/App/Netdisco/Manual/WritingPlugins.pod +++ b/Netdisco/lib/App/Netdisco/Manual/WritingPlugins.pod @@ -14,7 +14,7 @@ See L for more general information about plugins. =head1 Developing Plugins A plugin is simply a Perl module which is loaded. Therefore it can do anything -you like, but most usefully for the App::Netdisco web application, the module +you like, but most usefully for the App::Netdisco web application the module will install a L route handler subroutine, and link this to a web user interface (UI) component. @@ -29,15 +29,15 @@ Here's the boilerplate code for our example plugin module: package App::Netdisco::Web::Plugin::MyNewFeature use Dancer ':syntax'; - use Dancer::Plugin::Ajax; use Dancer::Plugin::DBIC; + use Dancer::Plugin::Auth::Extensible; use App::Netdisco::Web::Plugin; # plugin registration code goes here, ** see below ** - # your Dancer route handler, for example: - get '/mynewfeature' => sub { + # your Dancer route handler + get '/mynewfeature' => require_login sub { # ...lorem ipsum... }; @@ -91,17 +91,16 @@ Therefore your plugin module should look like the following: package App::Netdisco::Web::Plugin::Search::MyNewFeature use Dancer ':syntax'; - use Dancer::Plugin::Ajax; use Dancer::Plugin::DBIC; + use Dancer::Plugin::Auth::Extensible; use App::Netdisco::Web::Plugin; register_search_tab({tag => 'newfeature', label => 'My New Feature'}); - ajax '/ajax/content/search/newfeature' => sub { + get '/ajax/content/search/newfeature' => require_login sub { # ...lorem ipsum... - content_type('text/html'); # return some HTML content here, probably using a template }; @@ -168,13 +167,39 @@ the following URL: /ajax/content/report/ -Therefore you should implement in your plugin an AJAX handler for this path. +Therefore you should implement in your plugin a route handler for this path. The handler must return the HTML content for the report. It can also process any query parameters which might customize the report search. See the L module for a simple example of how to implement the handler. +=head1 CSV Response + +Most pages in Netdisco are a table with data. It's possible to have the +application add a link to download a CSV version of the same data. To do this, +include the following option in your call to C, +C, or C: + + provides_csv => 1 + +The other thing you need to do is adjust your Dancer route handler to return +either HTML or CSV data. Here's the typical way to do it: + + get '/ajax/content/search/newfeature' => require_login sub { + # build some kind of dataset here (e.g. a DBIx::Class query) + + if (request->is_ajax) { + template 'mytemplate', { data => $mydataset }, { layout => undef }; + } + else { + header( 'Content-Type' => 'text/comma-separated-values' ); + template 'mytemplate_csv', { data => $mydataset }, { layout => undef }; + } + }; + +Note that the C call is part of the standard Dancer featureset. + =head1 Admin Tasks These components appear in the black navigation bar under an Admin menu, but only @@ -193,6 +218,64 @@ Note that this won't work for any target link - the path must be an App::Netdisco Dancer route handler. Please bug the App::Netdisco devs if you want arbitrary links supported. +=head1 Device Port Columns + +You can also add columns to the Device Ports page. The canonical example of +this is to add hyperlinks (or embedded images) of traffic graphs for each +port, however the plugin is a regular Template::Toolkit template so can be any +HTML output. + +The column plugin has a name (used internally to locate files on disk), label +(the heading for the column in the table or CSV output), position in the table +(three options: left, mid, right), and finally a flag for whether the column +is displayed by default. + +To register the column call the following helper routine: + + register_device_port_column({ + name => 'myportcolumnplugin', + label => 'My Port Column Heading', + position => 'left', # or "mid" or "right" + default => 'on', # or undef + }); + +App::Netdisco searches for one Template::Toolkit file in the regular template +include paths (see also C, below). The template must +be called "C" on disk and live in the directory: + + plugin/myportcolumnplugin/device_port_column.tt + +For a good example of this, see the L +distribution. + +=head1 User Authorization + +All Dancer route handlers must have proper authorization configured. This is +not difficult. Make sure that your module loads the +L module (as shown above). + +For each route handler you either simply require that a user be logged in, or +that the user is an administrator. + +To require a logged in user, include the C wrapper: + + get '/ajax/content/search/newfeature' => require_login sub { + # etc ..... + +To require an administrator, specify their role: + + get '/ajax/control/admin/newfeature' => require_role admin => sub { + # etc ..... + +Finally in case you need it, the other role a user can have is +C: + + ajax '/ajax/portcontrol' => require_role port_control => sub { + # etc ..... + +Take care over the subtle differences in syntax, especially the placement of +the fat comma ("C<< => >>"). + =head1 Templates All of Netdisco's web page templates are stashed away in its distribution, @@ -215,7 +298,7 @@ templates along with your plugin, as shown. Each path added using C is searched I any existing paths in the template config. -=head3 Template Variables +=head2 Template Variables Some useful variables are made available in your templates automatically by App::Netdisco: @@ -260,5 +343,78 @@ current page with some additional parameters, for example: =back +=head1 Javascript and Stylesheets + +A simple mechanism exists for loading additional Javascript and CSS documents. +This is done in the C<< >> section of the web page. + +Within a Template include path (see C, above) create a +directory called "C" and within that another directory named after +your plugin (e.g. "C"). The Javascript and/or CSS files must +then be named "C" and "C" respectively. +For example: + + plugin/mynewfeature/mynewfeature.js + plugin/mynewfeature/mynewfeature.css + +Tell App::Netdisco that you wish to load one or the other using the following +helper routines: + + register_javascript('mynewfeature'); + register_css('mynewfeature'); + +Note that this searches all template include paths, both those built into the +application and those configured in your plugin(s) with +C. + +=head1 Naming and File Location + +There are several options for how you name, distribute and install your +App::Netdisco plugin. + +=head2 Namespaces + +As mentioned in L, official Netdisco plugins live +in the C namespace. You can use this namespace +and submit the product to the Netdisco developer team for consideration for +inclusion in the official distribution. + +Alternatively you can release the plugin to CPAN under your own account. In +that case we request that you instead use the C +namespace (note the "X"). Users can load such modules by using the +abbreviated form "X::MyPluginName" which is then expanded to the full package. + +=head2 File Location + +If writing your own plugins, Netdisco supports a local include path which is +usually C<~/site_plugins> (or C<${NETDISCO_HOME}/site_plugins>). + +This means if your plugin is called +"App::NetdiscoX::Web::Plugin::MyPluginName" then it could live at: + + ~/site_plugins/App/NetdiscoX/Web/Plugin/MyPluginName.pm + +This feature should make development of new plugins or maintenance of local +plugins much more straighforward. + +=head1 Plugin Configuration + +You can support new configuration items which the user should add to their +C<~/environments/deployment.yml> file. Please use a single Hash-Ref option +named "C" (if your plugin's called C). For +example: + + plugin_observium: + webhost: "web-server.example.com" + open_in_new_window: true + +You can then refer to this configuration in your plugin module: + + my $webhost = setting('plugin_observium')->{'webhost'}; + +Or in templates via Dancer's C key: + + network management application. It +adds a column to the Device Ports table named "Traffic" with a link and +thumbnail graph for the port, taken from a local Observium installation. + +=head1 Configuration + +Create an entry in your C<~/environments/deployment.yml> file named +"C", containing the following settings: + +=head2 webhost + +Value: String, Required. + +Name of the server hosting your local Observium installation. + +=head2 open_in_new_window + +Value: Boolean. Default: false. + +If set to true, the hyperlink is configured to open the port's Observium page +in a new browser window or tab. + +=head1 AUTHOR + +Oliver Gorwits + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2013 by The Netdisco Developer Team. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Netdisco Project nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE NETDISCO DEVELOPER TEAM BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=cut + true; diff --git a/Netdisco/share/config.yml b/Netdisco/share/config.yml index 3b6058be..08702de9 100644 --- a/Netdisco/share/config.yml +++ b/Netdisco/share/config.yml @@ -51,7 +51,7 @@ web_plugins: - Device::Modules - Device::Neighbors - Device::Addresses -web_plugins_extra: [] +extra_web_plugins: [] # ------------- # NETDISCO CORE