use Scope::Guard to reduce device_auth
This commit is contained in:
1
Build.PL
1
Build.PL
@@ -55,6 +55,7 @@ Module::Build->new(
|
|||||||
'Plack::Middleware::ReverseProxy' => '0.15',
|
'Plack::Middleware::ReverseProxy' => '0.15',
|
||||||
'Pod::Usage' => 0,
|
'Pod::Usage' => 0,
|
||||||
'Role::Tiny' => '1.002005',
|
'Role::Tiny' => '1.002005',
|
||||||
|
'Scope::Guard' => 0,
|
||||||
'Sereal' => '0',
|
'Sereal' => '0',
|
||||||
'Socket6' => '0.23',
|
'Socket6' => '0.23',
|
||||||
'Starman' => '0.4008',
|
'Starman' => '0.4008',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use Dancer::Plugin;
|
|||||||
use Dancer::Factory::Hook;
|
use Dancer::Factory::Hook;
|
||||||
|
|
||||||
use App::Netdisco::Util::Permission qw/check_acl_no check_acl_only/;
|
use App::Netdisco::Util::Permission qw/check_acl_no check_acl_only/;
|
||||||
|
use Scope::Guard;
|
||||||
use Try::Tiny;
|
use Try::Tiny;
|
||||||
|
|
||||||
Dancer::Factory::Hook->instance->install_hooks(
|
Dancer::Factory::Hook->instance->install_hooks(
|
||||||
@@ -19,32 +20,38 @@ register 'register_core_driver' => sub {
|
|||||||
and exists $driverconf->{phase} and exists $driverconf->{driver}
|
and exists $driverconf->{phase} and exists $driverconf->{driver}
|
||||||
and Dancer::Factory::Hook->instance->hook_is_registered($driverconf->{phase}));
|
and Dancer::Factory::Hook->instance->hook_is_registered($driverconf->{phase}));
|
||||||
|
|
||||||
my $no = (exists $driverconf->{no} ? $driverconf->{no} : undef);
|
# needs to be here for caller() context
|
||||||
my $only = (exists $driverconf->{only} ? $driverconf->{only} : undef);
|
|
||||||
$driverconf->{plugin} = (caller)[0];
|
$driverconf->{plugin} = (caller)[0];
|
||||||
|
|
||||||
my $hook = sub {
|
my $hook = sub {
|
||||||
my ($device, $userconf) = @_;
|
my $device = shift or return false;
|
||||||
return false unless (ref $device and (ref {} eq ref $userconf));
|
|
||||||
|
|
||||||
# first check internal (driverconf) exclusion/inclusion criteria
|
my $no = (exists $driverconf->{no} ? $driverconf->{no} : undef);
|
||||||
return false if ($only and not check_acl_only($device, $only));
|
my $only = (exists $driverconf->{only} ? $driverconf->{only} : undef);
|
||||||
return false if ($no and (not exists $userconf->{driver})
|
|
||||||
and check_acl_no($device, $only));
|
|
||||||
|
|
||||||
# then check external (userconf) exclusion/inclusion criteria
|
my @newuserconf = ();
|
||||||
return false if exists $userconf->{phase}
|
my @userconf = @{ setting('device_auth') || [] };
|
||||||
and (($userconf->{phase} || '') ne $driverconf->{phase});
|
|
||||||
|
|
||||||
return false if exists $userconf->{driver}
|
# reduce device_auth by driver, plugin, driver's only/no
|
||||||
and (($userconf->{driver} || '') ne $driverconf->{driver});
|
foreach my $stanza (@userconf) {
|
||||||
|
next if $no and check_acl_no($device, $no);
|
||||||
|
next if $only and not check_acl_only($device, $only);
|
||||||
|
next if exists $stanza->{driver}
|
||||||
|
and (($stanza->{driver} || '') ne $driverconf->{driver});
|
||||||
|
next if exists $stanza->{plugin}
|
||||||
|
and (($stanza->{plugin} || '') ne $driverconf->{plugin});
|
||||||
|
push @newuserconf, $stanza;
|
||||||
|
}
|
||||||
|
|
||||||
return false if exists $userconf->{plugin}
|
# back up and restore device_auth
|
||||||
and (($userconf->{plugin} || '') ne $driverconf->{plugin});
|
return false unless scalar @newuserconf;
|
||||||
|
my $guard = guard { set(device_auth => \@userconf) };
|
||||||
|
set(device_auth => \@newuserconf);
|
||||||
|
|
||||||
|
# run driver
|
||||||
my $happy = false;
|
my $happy = false;
|
||||||
try {
|
try {
|
||||||
$code->($device, $driverconf, $userconf);
|
$code->($device, $driverconf);
|
||||||
$happy = true;
|
$happy = true;
|
||||||
}
|
}
|
||||||
catch { debug $_ };
|
catch { debug $_ };
|
||||||
@@ -109,11 +116,14 @@ Plugin modules can either ship with the App::Netdisco distribution itself, or
|
|||||||
be installed separately. Perl uses the standard C<@INC> path searching
|
be installed separately. Perl uses the standard C<@INC> path searching
|
||||||
mechanism to load the plugin modules. See the C<include_paths> and
|
mechanism to load the plugin modules. See the C<include_paths> and
|
||||||
C<site_local_files> settings in order to modify C<@INC> for loading local
|
C<site_local_files> settings in order to modify C<@INC> for loading local
|
||||||
plugins.
|
plugins. As an example, if your plugin is called
|
||||||
|
"App::NetdiscoX::Core::Plugin::MyPluginName" then it could live at:
|
||||||
|
|
||||||
The order of the entries is significant. Drivers are executed in REVERSE
|
~netdisco/nd-site-local/lib/App/NetdiscoX/Core/Plugin/MyPluginName.pm
|
||||||
order that they appear in the C<extra_collector_plugins> and
|
|
||||||
C<collector_plugins> settings.
|
The order of the entries is significant, drivers being executed in the order
|
||||||
|
which they appear in C<collector_plugins> and C<extra_collector_plugins>
|
||||||
|
(although see L<App::Netdisco::Manual::WritingBackendDrivers> for caveats).
|
||||||
|
|
||||||
Finally, you can also prepend module names with "C<X::>", to support the
|
Finally, you can also prepend module names with "C<X::>", to support the
|
||||||
"Netdisco extension" namespace. For example,
|
"Netdisco extension" namespace. For example,
|
||||||
|
|||||||
@@ -22,12 +22,11 @@ See L<App::Netdisco::Core::Plugin> for more information about core plugins.
|
|||||||
|
|
||||||
=head1 Developing Plugins
|
=head1 Developing Plugins
|
||||||
|
|
||||||
A plugin is simply a Perl module which is loaded. Therefore it can do anything
|
A plugin is a Perl module which is loaded. Therefore it can do anything you
|
||||||
you like, but most usefully for the App::Netdisco application the module
|
like, but the module will make a connection to a device, gather some data, and
|
||||||
will make a connection to a device, gather some data, and store it in
|
store it in Netdisco's database.
|
||||||
Netdisco's database.
|
|
||||||
|
|
||||||
App::Netdisco plugins should load the L<App::Netdisco::Core::Plugin> module.
|
App::Netdisco plugins must load the L<App::Netdisco::Core::Plugin> module.
|
||||||
This exports a set of helper subroutines to register the driver. Here's the
|
This exports a set of helper subroutines to register the driver. Here's the
|
||||||
boilerplate code for our example plugin module:
|
boilerplate code for our example plugin module:
|
||||||
|
|
||||||
@@ -55,24 +54,21 @@ For example:
|
|||||||
phase => 'discover_wireless',
|
phase => 'discover_wireless',
|
||||||
}, sub { "driver code here" });
|
}, sub { "driver code here" });
|
||||||
|
|
||||||
An explanation of the C<$driverconf> options is below. The C<$coderef> is the
|
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<Try::Tiny> statement to
|
main body of your driver. Your driver is run in a L<Try::Tiny> statement to
|
||||||
catch errors, and passed the following arguments:
|
catch errors, and passed the following arguments:
|
||||||
|
|
||||||
$coderef->($device, $driverconf, $userconf);
|
$coderef->($device, $driverconf);
|
||||||
|
|
||||||
The C<$device> is an instance of L<App::Netdisco::DB::Result::Device>; that
|
The C<$device> is an instance of L<App::Netdisco::DB::Result::Device>; that
|
||||||
is, a representation of a row in the database. Note that for early discover
|
is, a representation of a row in the database. Note that for early discover
|
||||||
phases this row may not yet exist in the database.
|
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
|
||||||
The C<$driverconf> hashref is the set of configuration parameters you used to
|
(documented below).
|
||||||
declare the driver (documented below). The C<$userconf> hashref is the
|
|
||||||
settings from C<device_auth> that the end-user configured for authentication;
|
|
||||||
these are typically specific to the driver and transport in use.
|
|
||||||
|
|
||||||
=head2 Required Parameters
|
=head2 Required Parameters
|
||||||
|
|
||||||
You must register drivers with a C<driver> and C<phase> parameter.
|
You must register drivers with a C<driver> and a C<phase> parameter.
|
||||||
|
|
||||||
The C<driver> is a label associated with a group of drivers and typically
|
The C<driver> is a label associated with a group of drivers and typically
|
||||||
refers to the combination of transport and application protocol. Examples
|
refers to the combination of transport and application protocol. Examples
|
||||||
@@ -161,36 +157,5 @@ connections to other databases.
|
|||||||
use Dancer::Plugin::DBIC;
|
use Dancer::Plugin::DBIC;
|
||||||
schema('netdisco')->resultset('Devices')->search({vendor => 'cisco'});
|
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<App::Netdisco::Core::Plugin>, official Netdisco plugins live
|
|
||||||
in the C<App::Netdisco::Core::Plugin::> 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<App::NetdiscoX::Core::Plugin::> 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<site_local_files> 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
|
=cut
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user