222 lines
7.8 KiB
Plaintext
222 lines
7.8 KiB
Plaintext
=head1 NAME
|
|
|
|
App::Netdisco::Manual::WritingCoreWorkers - Developer Documentation on Core Plugins
|
|
|
|
=head1 Introduction
|
|
|
|
L<App::Netdisco>'s plugin system allows users to write I<workers> to gather
|
|
information from network devices using different I<transports> and store
|
|
results in the database.
|
|
|
|
For example, transports might be SNMP, SSH, or HTTPS. Workers might be
|
|
combining those transports with application protocols such as SNMP, NETCONF
|
|
(OpenConfig with XML), RESTCONF (OpenConfig with JSON), eAPI, or even CLI
|
|
scraping. The combination of transport and protocol is known as a I<driver>.
|
|
|
|
Workers can be restricted to certain vendor platforms using familiar ACL
|
|
syntax. They are also attached to specific actions in Netdisco's backend
|
|
operation (discover, macsuck, etc).
|
|
|
|
See L<App::Netdisco::Core::Plugin> for more information about core plugins.
|
|
|
|
=head1 Developing Workers
|
|
|
|
A worker is Perl code which is run. Therefore it can do anything you like, but
|
|
typically it will make a connection to a device, gather some data, and store
|
|
it in Netdisco's database.
|
|
|
|
App::Netdisco plugins must load the L<App::Netdisco::Core::Plugin> module.
|
|
This exports a helper subroutine to register the worker. Here's the
|
|
boilerplate code for our example plugin module:
|
|
|
|
package App::Netdisco::Core::Plugin::Discover::Wireless::UniFi;
|
|
|
|
use Dancer ':syntax';
|
|
use App::Netdisco::Core::Plugin;
|
|
|
|
# worker registration code goes here, ** see below **
|
|
|
|
true;
|
|
|
|
=head1 Registering a Worker
|
|
|
|
Use the C<register_core_worker> helper from L<App::Netdisco::Core::Plugin> to
|
|
register a worker:
|
|
|
|
register_core_worker( \%workerconf, $coderef );
|
|
|
|
For example:
|
|
|
|
register_core_worker({
|
|
driver => 'unifiapi',
|
|
}, sub { "worker code here" });
|
|
|
|
An explanation of the C<%workerconf> options is below. The C<$coderef> is the
|
|
main body of your worker. Your worker is run in a L<Try::Tiny> statement to
|
|
catch errors, and passed the following arguments:
|
|
|
|
$coderef->($job, $workerconf);
|
|
|
|
The C<$job> is an instance of L<App::Netdisco::Backend::Job>. Note that this
|
|
class has a C<device> slot which may be filled, depending on the action, and
|
|
if the device is not yet discovered then the row will not yet be in storage.
|
|
The C<$workerconf> hashref is the set of configuration parameters you used
|
|
to declare the worker (documented below).
|
|
|
|
=head2 Package Naming Convention
|
|
|
|
The package name used where the worker is declared is significant. Let's look
|
|
at the boilerplate example again:
|
|
|
|
package App::Netdisco::Core::Plugin::Discover::Wireless::UniFi;
|
|
|
|
Workers registered in this package will be run during the I<discover> backend
|
|
action (that is, during a C<discover> job). You can replace C<Discover> with
|
|
other actions such as C<Macsuck>, C<Arpnip>, C<Expire>, and C<Nbtstat>.
|
|
|
|
The component after the action is known as the I<phase> (C<Wireless> in this
|
|
example), and is the way to override a Netdisco built-in worker, by using the
|
|
same name (plus an entry in C<$workerconf>, see below). Otherwise you can use
|
|
any valid Perl bareword for the phase.
|
|
|
|
=head2 Required Parameters
|
|
|
|
You must register workers with a C<driver> parameter.
|
|
|
|
The C<driver> is a label associated with a group of workers and typically
|
|
refers to the combination of transport and application protocol. Examples
|
|
include C<snmp>, C<netconf>, C<restconf>, C<eapi>, and C<cli>. The convention
|
|
is for driver names to be lowercase. Use the driver name to associate
|
|
authentication configuration settings with the correct workers.
|
|
|
|
A pseudo-driver of C<netdisco> can be used if you won't be connecting to a
|
|
device (such as within the C<Expire> action).
|
|
|
|
=head2 Optional Parameters
|
|
|
|
Workers may have C<only> and C<no> parameters configured which use the
|
|
standard ACL syntax described in L<the settings
|
|
guide|App::Netdisco::Manual::Configuration>. The C<only> directive is
|
|
especially useful as it can restrict a worker to a given device platform or
|
|
operating system (for example Cisco IOS XR for the C<restconf> driver).
|
|
|
|
The C<hook> parameter tells Netdisco the role that your worker plays in the
|
|
backend action. It can have one of three values:
|
|
|
|
=over 4
|
|
|
|
=item before
|
|
|
|
A worker that is essential to the action and run before any other workers
|
|
within the same action. For example at the start of C<discover> we need to
|
|
gather basic parameters and create a C<device> row in the database. The first
|
|
C<before> worker which succeeds will short-circuit any others (see Return
|
|
Code, below).
|
|
|
|
=item on
|
|
|
|
This worker is run alongside others with the same phase, and also
|
|
short-curcuits any other workers in the same phase (see Return Code, below).
|
|
|
|
=item after
|
|
|
|
This worker is run alongside others with the same phase. All workers are run,
|
|
regardless of their return code.
|
|
|
|
=back
|
|
|
|
=head2 Worker Execution and Return Code
|
|
|
|
Workers are configured as an ordered list. They are grouped by C<action> and
|
|
C<phase> (as in Package Naming Convention, above).
|
|
|
|
Workers defined in C<extra_core_plugins> are run before those in
|
|
C<core_plugins> so you have an opportunity to override core workers by
|
|
adding them to C<extra_core_plugins> and setting C<hook> to C<on> in the
|
|
worker configuration.
|
|
|
|
The return code of the worker is significant for the C<before> and C<on>
|
|
hooks: when the worker returns true, no other hooks are run for that phase.
|
|
The return code is ignored for C<after> hooks, meaning they all run regardless
|
|
of success.
|
|
|
|
Remember that a worker 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.
|
|
|
|
=head2 Accessing Transports
|
|
|
|
From your worker you will want to connect to a device to gather data. This is
|
|
done using a transport protocol session (SNMP, SSH, etc). Transports are
|
|
singleton objects instantiated on demand, so they can be shared among a set of
|
|
workers that are accessing the same device.
|
|
|
|
See the documentation for each transport to find out how to access it:
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
L<App::Netdisco::Core::Transport::SNMP>
|
|
|
|
=back
|
|
|
|
=head2 Review of Terminology
|
|
|
|
In summary, Worker code is defined in a package namespace specifying the
|
|
Action and Phase, and registered as a plugin with configuration specifying the
|
|
Hook and Driver. Some rules and Access Control Lists determine which Workers
|
|
are permitted to run, and when. Here are more complete definitions:
|
|
|
|
=over 4
|
|
|
|
=item C<action>
|
|
|
|
The highest level grouping of workers, corresponding to a Netdisco command
|
|
such as C<discover> or C<macsuck>. Hooks can be registered at this level to do
|
|
really early bootstrapping work.
|
|
|
|
=item C<phase>
|
|
|
|
The next level down from C<action> for grouping workers. Phases have arbitrary
|
|
names and are visited in the order defined in the C<extra_core_plugins>
|
|
setting list, followed by the C<core_plugins> setting list. Hooks are usually
|
|
registered at this level.
|
|
|
|
=item C<hook> (defaults to C<after>)
|
|
|
|
The next level down from C<phase> for grouping workers. C<before> hooks
|
|
are run first (for the action and then all its phases). C<on> and C<after>
|
|
hooks run next. The return code of workers may be significant, depending on
|
|
the hook they are registered to.
|
|
|
|
=item C<worker>
|
|
|
|
A lump of code you write which does a single clearly defined task. The package
|
|
namespace of the worker identifies the action and optionally the phase. The
|
|
code within is bound to a given hook when registered as a plugin.
|
|
|
|
=item C<driver>
|
|
|
|
A label associated with a group of workers which refers to a combination of
|
|
transport and application protocol used to connect to and communicate with the
|
|
target device. Users may attach authentication configuration to specific
|
|
drivers.
|
|
|
|
=back
|
|
|
|
=head2 Database Connections
|
|
|
|
The Netdisco database is available via the C<netdisco> schema key, as below.
|
|
You can also use the C<external_databases> configuration item to set up
|
|
connections to other databases.
|
|
|
|
# plugin package
|
|
use Dancer::Plugin::DBIC;
|
|
my $set =
|
|
schema('netdisco')->resultset('Devices')
|
|
->search({vendor => 'cisco'});
|
|
|
|
=cut
|
|
|