From dca4b4fc030f851d55eb5ec52efbc62e593a3eed Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Wed, 26 Jul 2017 11:50:10 +0100 Subject: [PATCH] add backend driver documentation --- lib/App/Netdisco/Core/Plugin.pm | 4 +- .../Netdisco/Manual/WritingBackendDrivers.pod | 171 ++++++++++++++++++ lib/App/Netdisco/Manual/WritingWebPlugins.pod | 2 +- share/config.yml | 2 +- 4 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 lib/App/Netdisco/Manual/WritingBackendDrivers.pod diff --git a/lib/App/Netdisco/Core/Plugin.pm b/lib/App/Netdisco/Core/Plugin.pm index e7a19eed..94f5333d 100644 --- a/lib/App/Netdisco/Core/Plugin.pm +++ b/lib/App/Netdisco/Core/Plugin.pm @@ -98,8 +98,8 @@ add to or remove from the default set, then create a version of C instead. Netdisco prepends "C" to any entry in the list. -For example, "C" will load the -C package. +For example, "C" will load the +C package. If an entry in the list starts with a "C<+>" (plus) sign then Netdisco attemps to load the module as-is, without prepending anything to the name. This allows diff --git a/lib/App/Netdisco/Manual/WritingBackendDrivers.pod b/lib/App/Netdisco/Manual/WritingBackendDrivers.pod new file mode 100644 index 00000000..0f2e27e2 --- /dev/null +++ b/lib/App/Netdisco/Manual/WritingBackendDrivers.pod @@ -0,0 +1,171 @@ +=head1 NAME + +App::Netdisco::Manual::WritingCorePlugins - Documentation on Backend Driver +Plugins for Developers + +=head1 Introduction + +L's plugin system allows users to create backend I +which use different I to gather information from network devices +and store in the database. + +For example, transports might be SNMP, SSH, or HTTPS. Drivers might be +combining those transports with application protocols such as SNMP, NETCONF +(OpenConfig with XML), RESTCONF (OpenConfig with JSON), eAPI, or even CLI +scraping. + +Drivers can be restricted to certain vendor platforms using familiar ACL +syntax. They are also attached to specific phases in Netdisco's backend +operation. + +See L for more information about core 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 application the module +will make a connection to a device, gather some data, and store it in +Netdisco's database. + +App::Netdisco plugins should load the L module. +This exports a set of helper subroutines to register the driver. Here's the +boilerplate code for our example plugin module: + + package App::Netdisco::Core::Plugin::Discover::Wireless::UniFi; + + use Dancer ':syntax'; + use Dancer::Plugin::DBIC; + use App::Netdisco::Core::Plugin; + + # driver registration code goes here, ** see below ** + + true; + +=head1 Registering a Driver + +Use the C helper from L to +register a driver: + + register_core_driver( \%driverconf, $coderef ); + +For example: + + register_core_driver({ + driver => 'unifiapi', + phase => 'discover_wireless', + }, sub { "driver code here" }); + +An explanation of the C<$driverconf> options is below. The C<$coderef> is the +main body of your driver. Your driver is run in a L statement to +catch errors, and passed the following arguments: + + $coderef->($device, $driverconf, $userconf); + +The C<$device> is an instance of L; that +is, a representation of a row in the database. Note that for early discover +phases this row may not yet exist in the database. + +The C<$driverconf> hashref is the set of configuration parameters you used to +declare the driver (documented below). The C<$userconf> hashref is the +settings from C that the end-user configured for authentication; +these are typically specific to the driver and transport in use. + +=head2 Required Parameters + +You must register drivers with a C and C parameter. + +The C is a label associated with a group of drivers and typically +refers to the combination of transport and application protocol. Examples +include C, C, C, C, and C. The convention +is for driver names to be lowercase. Users use the driver name to associate +authentication configuration settings with the correct drivers. + +The C corresponds to the action run by Netdisco's backend, with the +addition of wrapping phases for additional windows of execution. The list of +so-called I
phases is below (and you can see the actions these map to): + + core_phases: + - discover_properties + - discover_interfaces + - discover_vlans + - discover_wireless + - discover_entities + - macsuck_nodes + - arpnip_nodes + - arpnip_subnets + - netbios_stat + +Each main phase also has C and C phases. For example the +C phase will have C and +C phases available when you register a driver. Note the +significance of the Return Code, and execution order, of drivers in these +phases, explained below. + +=head2 Optional Parameters + +Drivers may have C and C parameters configured which use the +standard ACL syntax described in +L. The C +directive is especially useful as it can restrict a driver to a given device +platform or operating system (for example Cisco IOS XR, for RESTCONF). + +=head2 Driver Execution and Return Code + +Drivers are configured as an ordered list (in C or +C). For the C and C phases of any +action, drivers are run in the order loaded. For the main phase of any action +they are run in REVERSE order. This has the effect that driver plugins loaded +through C will be run I core drivers. + +The return code of the driver is ignored for C and C phases, +but is significant for the main phase of the action. During this phase if any +driver returns a true value then the main phase is deemed to have been +satisfied and Netdsico will move on to any C driver plugins. + +Remember that a driver is only run if it matches the hardware platform of the +target device and the user's configuration, and is not also excluded by the +user's configuration. + +=head1 Database Connections + +The Netdisco database is available via the C schema key, as below. +You can also use the C configuration item to set up +connections to other databases. + + # plugin code + use Dancer::Plugin::DBIC; + schema('netdisco')->resultset('Devices')->search({vendor => 'cisco'}); + +=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 that are not for redistribution or packaging on +CPAN, Netdisco can enable a local include path (C<@INC>). Configuring the +C setting to be "true" enables: + + $ENV{NETDISCO_HOME}/nd-site-local/lib + +As an example, if your plugin is called +"App::NetdiscoX::Core::Plugin::MyPluginName" then it could live at: + + ~netdisco/nd-site-local/lib/App/NetdiscoX/Core/Plugin/MyPluginName.pm + +=cut + diff --git a/lib/App/Netdisco/Manual/WritingWebPlugins.pod b/lib/App/Netdisco/Manual/WritingWebPlugins.pod index bba4a20c..fd89cb44 100644 --- a/lib/App/Netdisco/Manual/WritingWebPlugins.pod +++ b/lib/App/Netdisco/Manual/WritingWebPlugins.pod @@ -26,7 +26,7 @@ App::Netdisco plugins should load the L module. This exports a set of helper subroutines to register the new UI components. Here's the boilerplate code for our example plugin module: - package App::Netdisco::Web::Plugin::MyNewFeature + package App::Netdisco::Web::Plugin::MyNewFeature; use Dancer ':syntax'; use Dancer::Plugin::DBIC; diff --git a/share/config.yml b/share/config.yml index dff044a4..4b695c80 100644 --- a/share/config.yml +++ b/share/config.yml @@ -270,7 +270,7 @@ collector_plugins: - Discover::BGPNeighbors::RFC - Discover::OSPFNeighbors::RFC - Discover::VLANs::RFC - - Discover::WirelessServices::RFC + - Discover::Wireless::RFC - Discover::Entities::RFC - Macsuck::Nodes::RFC # {platform: any} - Macsuck::WirelessNodes::RFC