bump version for release

This commit is contained in:
Oliver Gorwits
2013-03-07 21:49:58 +00:00
parent ae307f30b3
commit 02c46e2275
7 changed files with 21 additions and 635 deletions

View File

@@ -1,431 +0,0 @@
DEVELOPER NOTES
This document aims to help developers understand the intent and design
of the code within Netdisco. Patches and feedback are always welcome :-)
Introduction
This release of Netdisco is built as a Dancer application, and uses many
modern technologies and techniques. Hopefully this will make the code
easier to manage and maintain in the long term.
Although Dancer is a web application framework, it provides very useful
tools for command line applications as well, namely configuration file
management and database connection management. We make use of these
features in the daemon and deployment scripts.
Overall the application tries to be as self-contained as possible
without also needing an excessive number of CPAN modules to be
installed. However, Modern Perl techniques have made dependency
management almost a non-issue, and Netdisco can be installed by and run
completely within an unprivileged user's account, apart from the
PostgreSQL database setup.
Finally the other core component of Netdisco is now a DBIx::Class layer
for database access. This means there is no SQL anywhere in the code,
but more important, we can re-use the same complex queries in different
parts of Netdisco.
The rest of this document discusses each "interesting" area of the
Netdisco codebase, hopefully in enough detail that you can get hacking
yourself :-)
Versioning
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 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 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.003000_002 - second beta
2.004001 - the next "feature" release
Global Configuration
Dancer uses YAML as its standard configuration file format, which is
flexible enough for our needs, yet still simple to edit for the user. We
no longer need a parser as in the old version of Netdisco.
At the top of scripts you'll usually see something like:
use App::Netdisco;
use Dancer ':script';
First, this uses "App::Netdisco", which is almost nothing more than a
placeholder module (contains no actual application code). What it does
is set several environment variables in order to locate the
configuration files.
Then, when we call ""use Dancer"" these environment variables are used
to load two YAML files: "config.yml" and "<environment>.yml" where
"<environment>" is typically either "production" or "development".
The concept of "environments" allows us to have some shared "master"
config between all instances of the application ("config.yml"), and then
settings for specific circumstances. Typically this might be logging
levels, for example. The default file which "App::Netdisco" loads is
"development.yml" but you can override it by setting the
""DANCER_ENVIRONMENT"" environment variable.
Dancer loads the config using YAML, merging data from the two files.
Config is made available via Dancer's "setting('foo')" subroutine, which
is exported. So now the "foo" setting in either config file is easily
accessed.
Another line commonly seen in scripts is this:
use Dancer::Plugin::DBIC 'schema';
This plugin saves a lot of effort by taking some database connection
parameters from the configuration file, and instantiating DBIx::Class
database connections with them. The connections are managed
transparently so all we need to do to access the Netdisco database, with
no additional setup, is:
schema('netdisco')->resultset(...)->search({...});
DBIx::Class Layer
DBIx::Class, or DBIC for short, is an Object-Relational Mapper. This
means it abstracts away the SQL of database calls, presenting a Perl
object for each table, set of results from a query, table row, etc. The
advantage is that it can generate really smart SQL queries, and these
queries can be re-used throughout the application.
The DBIC layer for Netdisco is based at App::Netdisco::DB. This is the
global schema class and below that, under App::Netdisco::DB::Result is a
class for each table in the database. These contain metadata on the
columns but also several handy "helper" queries which can be called.
There are also "ResultSet" classes which provide additional "pre-canned"
queries.
Netdisco's DBIx::Class layer has excellent documentation which you are
encouraged to read, particularly if you find it difficult to sleep.
Results and ResultSets
In DBIC a "Result" is a table and a "ResultSet" is a set of rows
retrieved from the table as a result of a query (which might be all the
rows, of course). This is why we have two types of DBIC class. Items in
the "Result" generally relate to the single table directly, and simply.
In the "ResultSet" class are more complex search modifiers which might
synthesize new "columns" of data (e.g. formatting a timestamp) or
subroutines which accept parameters to customize the query.
However, regardless of the actual class name, you access them in the
same way. For example the "device" table has an
App::Netdisco::DB::Result::Device class and also an
App::Netdisco::DB::ResultSet::Device class. DBIC merges the two:
schema('netdisco')->resultset('Device')->get_models;
Virtual Tables (VIEWs)
Where we want to simplify our application code even further we can
either install a VIEW in PostgreSQL, or use DBIx::Class to synthesize
the view on-the-fly. Put simply, it uses the VIEW definition as the
basis of an SQL query, yet in the application we treat it as a real
table like any other.
Some good examples are a fake table of only the active Nodes (as opposed
to all nodes), or the more complex list of all ports which are connected
together ("DeviceLink").
All these tables live under the App::Netdisco::DB::Result::Virtual
namespace, and so you access them like so (for the "ActiveNode"
example):
schema('netdisco')->resultset('Virtual::ActiveNode')->count;
Versioning and Deployment
To manage the Netdisco schema in PostgreSQL we use DBIx::Class's
deployment feature. This attaches a version to the schema and provides
all the code to check the current version and do whatever is necessary
to upgrade. The schema version is stored in a new table called
"dbix_class_schema_versions", although you should never touch it.
The "netdisco-db-deploy" script included in the distribution performs
the following services:
* Installs the dbix_class_schema_versions table
* Upgrades the schema to the current distribtion's version
This works both on an empty, new database, and a legacy database from
the existing Netdisco release, in a non-destructive way. For further
information see DBIx::Class::Schema::Versioned and the
"netdisco-db-deploy" script.
The files used for the upgrades are shipped with this distribution and
stored in the ".../App/Netdisco/DB/schema_versions" directory. They are
generated using the "nd-dbic-versions" script which also ships with the
distribution.
Foreign Key Constraints
We have not yet 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.
Web Application
The Netdisco web app is a "classic" Dancer app, using most of the
bundled features which make development really easy. Dancer is based on
Ruby's Sinatra framework. Its style is for many "helper" subroutines to
be exported into the application namespace, to do things such as access
request parameters, navigate around the "handler" subroutines, manage
response headers, and so on.
Pretty much anything you want to do in a web application has been
wrapped up by Dancer into a neat helper routine that does the heavy
lifting. This includes configuration and database connection management,
as was discussed above. Also, templates can be executed and Netdisco
uses the venerable Template::Toolkit engine for this.
Like most web frameworks Dancer has a concept of "handlers" which are
subroutines to which a specific web request is routed. For example if
the user asks for ""/device"" with some parameters, the request ends up
at the App::Netdisco::Web::Device package's ""get '/device'"" handler.
All this is done automatically by Dancer according to some simple rules.
There are also "wrapper" subroutines which we use to do tasks such as
setting up data lookup tables, and handling authentication.
Dancer also supports AJAX very well, and it is used to retrieve most of
the data in the Netdisco web application in a dynamic way, to respond to
search queries and avoid lengthy page reloads. You will see the handlers
for AJAX look similar to those for GET requests but do not use
Template::Toolkit templates.
Compared to the current Netdisco, the handler routines are very small.
This is because (a) they don't include any HTML - this is delegated to a
template, and (b) they don't include an SQL - this is delegated to
DBIx::Class. Small routines are more manageable, and easier to maintain.
You'll also notice use of modules such as Net::MAC and NetAddr::IP::Lite
to simplify and make more robust the handling of data.
Running the Web App
Dancer apps conform to the "PSGI" standard interface for web
applications, which makes for easy deployment under many stacks such as
Apache, FCGI, etc. See Dancer::Deployment for more detail.
At a minimum Netdisco can run from within its own user area as an
unprivileged user, and ships with a simple web server engine (see the
user docs for instructions). The "netdisco-web" script uses
Daemon::Control to daemonize this simple web server so you can
fire-and-forget the Netdisco web app without much trouble at all. This
script in turn calls "netdisco-web-fg" which is the real Dancer
application, that runs in the foreground if called on its own.
All web app code lives below App::Netdisco::Web, but there are also some
helper routines in App::Netdisco::Util::Web (for example sorting device
port names).
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 App::Netdisco::Web::AuthN. 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).
Templates
In the "share/views" folder of this distribution you'll find all the
Template::Toolkit template files, with ".tt" extensions. Dancer first
loads "share/views/layouts/main.tt" which is the main page wrapper, that
has the HTML header and so on. It then loads other templates for
sections of the page body. This is a typical Template::Toolkit "wrapper"
configuration, as noted by the "[% content %]" call within "main.tt"
that loads the template you actually specified in your Dancer handler.
All templates (and Javascript and Stylesheets) are shipped in the
App::Netdisco distribution and located automatically by the application
(using the environment variables which App::Netdisco set up). The user
doesn't have to copy or install any files.
There's a template for the homepage called "index.tt", then separate
templates for searching, displaying device details, and showing
inventory. These are, pretty much, all that Netdisco ever does.
Each of these pages is designed in a deliberately similar way, with
re-used features. They each can have a "sidebar" with a search form (or
additional search parameters). They also can have a tabbed interface for
sub-topics.
Here's where it gets interesting. Up till now the page content has been
your typical synchronous page load (a single page comprised of many
templates) in response to a GET request. However the content of the tabs
is not within this. Each tab has its content dynamically retrieved via
an AJAX request back to the web application. Javscript triggers this
automatically on page load.
This feature allows the user to search and search again, each time
refreshing the data they see in the tab but without reloading the
complete page with all its static furniture. AJAX can, of course, return
any MIME type, not only JSON but also HTML content as in this case. The
templates for the tabs are organised below "share/views/ajax/..." in the
distribution.
Stylesheets
The main style for Netdisco uses Twitter Bootstrap, which is a modern
library of CSS and javascript used on many websites. It does a lot of
heavy lifting, providing simple CSS classes for all of the standard web
page furniture (forms, tables, etc). Check out the documetation at the
Twitter Bootstrap web site for more information.
These stylesheets are of course customised with our own "netdisco.css".
We try to name all CSS classes with a prefix ""nd_"" so as to be
distinct from Twitter Bootstrap and any other active styles.
All stylesheets are located in the "share/public/css" folder of the
distribution and, like the templates, are automatically located and
served by the Netdisco application. You can also choose to serve this
content statically via Apache/etc for high traffic sites.
Although Twitter Bootstrap ships with its own set of icons, we use an
alternative library called Fontawesome. This plugs in easily to
Bootstrap and provides a wider range of scaleable vectored icons which
are easy to use.
Javascript
Of course many parts of the Netdisco site use Javascript, beginning with
retrieving the page tab content itself. The standard library in use is
jQuery, and the latest version is shipped with this distribution.
Many parts of the Netdisco site have small Javscript routines. The code
for these, using jQuery as mentioned, lives in two places. The main
"netdisco.js" file is loaded once in the page HTML header, and lives in
"share/public/javascripts/netdisco.js". There's also a
"netdisco_portcontrol.js" which is included only if the current user has
Port Control rights.
Netdisco also has Javascript routines specific to the device search or
device details pages, and these files are located in
"share/views/js/..." because they're loaded within the page body by the
templates. These files contain a function "inner_view_processing" 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 "share/public/javascripts/..." 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 ("DeviceLinks" 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.
Job Daemon
The old Netdisco has a job control daemon which processes "port control"
actions and also manual requests for device polling. The new Netdisco
also has a daemon, although it is a true separate process and set of
libraries from the 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 App::Netdisco::Daemon
namespace and like the rest of Netdisco is broken down into manageable
chunks.
Running the Job Daemon
Like the web application, the job daemon is fully self contained and
runs via two simple scripts shipped with the distribution - one for
foreground and one for background execution (see the user docs for
instructions).
The "netdisco-daemon" script uses Daemon::Control to daemonize so you
can fire-and-forget the Netdisco job daemon without much trouble at all.
This script in turn calls "netdisco-daemon-fg" which is the real
application, that runs in the foreground if called on its own.
Daemon Engineering
The job daemon is based on the MCE 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.
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. This is both to take advantage of more processor capability,
but also to deal with security zones where you might only be able to
manage a subset of devices from certain locations. Netdisco has always
coped well with this via its "discover_*" and similar configuration, and
the separate poller process.
So, the single Manager "worker" in the daemon is responsible for
contacting the central Netdisco database and booking out jobs which it's
able to service according to the local configuration settings. Jobs are
"locked" in the central queue and then copied to a local job queue
within the daemon.
Along with the Manager we start zero or more of two other types of
worker. Some jobs such as port control are "interactive" and the user
typically wants quick feedback on the results. Others such as polling
are background tasks which can take more time and are less schedule
sensitive. So as not to starve 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.
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 Manager won't ever book out more jobs from the central
Netdisco job queue than it has workers available (so as not to hog jobs
for itself against other daemons on other servers). The user is free to
configure the number of Interactive and Poller workers in their
"config.yml" file (zero or more of each).
SNMP::Info
The daemon obviously needs to use SNMP::Info for device control. All the
code for this has been factored out into the App::Netdisco::Util
namespace.
The App::Netdisco::Util::Connect package provides for the creation of
SNMP::Info objects along with connection tests. So far, SNMPv3 is not
supported. To enable trace logging of the SNMP::Info object simply set
the "INFO_TRACE" environment variable to a true value. The Connect
library also provides routines to map interface and PoE IDs.
Configuration for SNMP::Info comes from the YAML files, of course. This
means that our "mibhome" and "mibdirs" settings are now in YAML format.
In particular, the "mibdirs" 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.
DBIx::Class Layer
The local job queue for each Job Daemon is actually an SQLite database
running in memory. This makes the queue management code a little more
elegant. The schema for this is of course DBIx::Class using Dancer
connection management, and lives in App::Netdisco::Daemon::DB.
There is currently only one table, the port control job queue, in
App::Netdisco::Daemon::DB::Result::Admin. It's likely this name will
change in the future.

View File

@@ -1,3 +1,9 @@
2.006000 - 2013-03-07
[ENHANCEMENTS]
* Documentation fixups
2.005000_004 - 2013-03-05 2.005000_004 - 2013-03-05
[ENHANCEMENTS] [ENHANCEMENTS]

View File

@@ -7,7 +7,7 @@ use 5.010_000;
use File::ShareDir 'dist_dir'; use File::ShareDir 'dist_dir';
use Path::Class; use Path::Class;
our $VERSION = '2.005000_004'; our $VERSION = '2.006000';
BEGIN { BEGIN {
if (not length ($ENV{DANCER_APPDIR} || '') if (not length ($ENV{DANCER_APPDIR} || '')
@@ -155,12 +155,21 @@ the same time.
=head1 Upgrading =head1 Upgrading
Simply install this module again, then upgrade the database schema: Before upgrading please review the latest L<Release
Notes|App::Netdisco::Manual::ReleaseNotes>. Then, the process is as follows:
# upgrade Netdisco
~/bin/localenv cpanm --notest App::Netdisco ~/bin/localenv cpanm --notest App::Netdisco
# apply database schema updates (optionally, get latest OIDs/MIBs)
~/bin/netdisco-deploy ~/bin/netdisco-deploy
# restart web service
~/bin/netdisco-web restart ~/bin/netdisco-web restart
# optionally, restart job daemon if you use it
~/bin/netdisco-daemon restart
=head1 Tips and Tricks =head1 Tips and Tricks
=head2 Searching =head2 Searching

View File

@@ -49,7 +49,7 @@ referenced in the configuration like so (and use C<--path> option):
For SQL debugging try the following commands: For SQL debugging try the following commands:
DBIC_TRACE_PROFILE=console DBIC_TRACE=1 ~/bin/localenv ~/bin/netdisco-web-fg DBIC_TRACE_PROFILE=console DBIC_TRACE=1 ~/bin/localenv starman --workers=1 ~/bin/netdisco-web-fg
DBIC_TRACE_PROFILE=console DBIC_TRACE=1 ~/bin/localenv ~/bin/netdisco-daemon-fg DBIC_TRACE_PROFILE=console DBIC_TRACE=1 ~/bin/localenv ~/bin/netdisco-daemon-fg
=head1 Further Reading... =head1 Further Reading...

View File

@@ -245,7 +245,8 @@ command will watch the C<lib> and C<share> folder trees for changes, and you
probably want to switch to the C<development.yml> dancer configuration for probably want to switch to the C<development.yml> dancer configuration for
additional logging: additional logging:
DANCER_ENVIRONMENT=development ~/bin/localenv plackup -R lib,share bin/netdisco-web-fg DANCER_ENVIRONMENT=development DBIC_TRACE_PROFILE=console DBIC_TRACE=1 \
~/bin/localenv starman -R lib,share bin/netdisco-web-fg
=head2 Authentication =head2 Authentication

View File

@@ -8,7 +8,7 @@ This document will list only the most important changes with each release of
Netdisco. You are B<STRONGLY> recommended to read this document each time you Netdisco. You are B<STRONGLY> recommended to read this document each time you
install and upgrade. install and upgrade.
=head1 2.005000_003 =head1 2.006000
=head2 Incompatible Changes =head2 Incompatible Changes

View File

@@ -1,199 +0,0 @@
NAME
App::Netdisco - An open source web-based network management tool.
Introduction
The content of this distribution is the next major version of the
Netdisco network management tool. Pieces are still missing however, so
if you're a new user please see <http://netdisco.org/> for further
information on the project and how to download the current official
release.
* See the demo at: <http://demo-ollyg.dotcloud.com/netdisco/>
App::Netdisco provides a web frontend and a backend daemon to handle
interactive requests such as changing port or device properties. There
is not yet a device poller, so please still use the old Netdisco's
discovery, arpnip, and macsuck.
If you have any trouble getting the frontend running, speak to someone
in the "#netdisco" IRC channel (on freenode).
Dependencies
Netdisco has several Perl library dependencies which will be
automatically installed. However it's *strongly* recommended that you
first install DBD::Pg and SNMP using your operating system packages. The
following commands will test for the existence of them on your system:
perl -MDBD::Pg\ 999
perl -MSNMP\ 999
With those two installed, we can proceed...
Create a user on your system called "netdisco" if one does not already
exist. We'll install Netdisco and its dependencies into this user's home
area, which will take about 250MB including MIB files.
root:~# useradd -m -p x -s /bin/bash netdisco
Netdisco uses the PostgreSQL database server. Install PostgreSQL and
then change to the PostgreSQL superuser (usually "postgres"). Create a
new database and PostgreSQL user for the Netdisco application:
root:~# su - postgres
postgres:~$ createuser -DRSP netdisco
Enter password for new role:
Enter it again:
postgres:~$ createdb -O netdisco netdisco
Installation
To avoid muddying your system, use the following script to download and
install Netdisco and its dependencies into the "netdisco" user's home
area ("~netdisco/perl5").
su - netdisco
curl -L http://cpanmin.us/ | perl - --notest --quiet \
--local-lib ~/perl5 \
App::cpanminus App::local::lib::helper App::Netdisco
Link some of the newly installed apps into the "netdisco" user's $PATH,
e.g. "~netdisco/bin":
mkdir ~/bin
ln -s ~/perl5/bin/{localenv,netdisco-*} ~/bin/
Test the installation by running the following command, which should
only produce a status message (and throw up no errors):
~/bin/netdisco-daemon status
Configuration
Make a directory for your local configuration and copy the configuration
template from this distribution:
mkdir ~/environments
cp ~/perl5/lib/perl5/auto/share/dist/App-Netdisco/environments/development.yml ~/environments
chmod +w ~/environments/development.yml
Edit the file and change the database connection parameters to match
those for your local system (that is, the "dsn", "user" and "pass").
Optionally, in the same file uncomment and edit the "domain_suffix"
setting to be appropriate for your local site.
Bootstrap
The database either needs configuring if new, or updating from the
current release of Netdisco (1.x). You also need vendor MAC address
prefixes (OUI data) and some MIBs if you want to run the daemon. The
following script will take care of all this for you:
DANCER_ENVDIR=~/environments ~/bin/localenv netdisco-deploy
If you don't want that level of automation, check out the database
schema diff from the current release of Netdisco, and apply it yourself:
~/perl5/lib/perl5/App/Netdisco/DB/schema_versions/App-Netdisco-DB-2-3-PostgreSQL.sql
Startup
Run the following command to start the web-app server as a daemon (port
5000):
DANCER_ENVDIR=~/environments ~/bin/netdisco-web start
Run the following command to start the job control daemon (port control,
etc):
DANCER_ENVDIR=~/environments ~/bin/netdisco-daemon start
You should (of course) avoid running this Netdisco daemon and the legacy
daemon at the same time.
Upgrading
Simply install this module again, then upgrade the database schema:
~/bin/localenv cpanm --quiet --notest App::Netdisco
DANCER_ENVDIR=~/environments ~/bin/localenv netdisco-deploy
Tips and Tricks
Searching
The main black navigation bar has a search box which is smart enough to
work out what you're looking for in most cases. For example device
names, node IP or MAC addreses, VLAN numbers, and so on.
SQL and HTTP Trace
For SQL debugging try the following commands:
DBIC_TRACE_PROFILE=console DBIC_TRACE=1 \
DANCER_ENVDIR=~/environments ~/bin/localenv plackup ~/bin/netdisco-web-fg
DBIC_TRACE_PROFILE=console DBIC_TRACE=1 \
DANCER_ENVDIR=~/environments ~/bin/localenv netdisco-daemon-fg
Deployment
Other ways to run and host the web application can be found in the
Dancer::Deployment page. See also the plackup documentation.
User Rights
With the default configuration user authentication is disabled and the
default "guest" user has no special privilege. To grant port and device
control rights to this user, create a row in the "users" table of the
Netdisco database with a username of "guest" and the "port_control" flag
set to true:
netdisco=> insert into users (username, port_control) values ('guest', true);
Database API
Bundled with this distribution is a DBIx::Class layer for the Netdisco
database. This abstracts away all the SQL into an elegant, re-usable OO
interface. See the App::Netdisco::Developing documentation for further
information.
Plugins
App::Netdisco includes a Plugin subsystem for building the web user
interface. Items in the navigation bar and the tabs on pages are loaded
as Plugins, and you have control over their appearance and ordering. See
App::Netdisco::Web::Plugin for further information.
Developing
Lots of information about the architecture of this application is
contained within the App::Netdisco::Developing documentation.
Caveats
Some sections are not yet implemented, e.g. the *Device Module* 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.
AUTHOR
Oliver Gorwits <oliver@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2012 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.