replace unicode nonbreaking space with ascii space (#794)
This commit is contained in:
4
Changes
4
Changes
@@ -679,7 +679,7 @@
|
|||||||
|
|
||||||
[NEW FEATURES]
|
[NEW FEATURES]
|
||||||
|
|
||||||
* #401 Autodiscovery via EIGRP peers
|
* #401 Autodiscovery via EIGRP peers
|
||||||
|
|
||||||
[BUG FIXES]
|
[BUG FIXES]
|
||||||
|
|
||||||
@@ -746,7 +746,7 @@
|
|||||||
|
|
||||||
[NEW FEATURES]
|
[NEW FEATURES]
|
||||||
|
|
||||||
* #48 Node Monitor supports matching on OUI
|
* #48 Node Monitor supports matching on OUI
|
||||||
* #31 configurable Free Time in Port Utilization Report
|
* #31 configurable Free Time in Port Utilization Report
|
||||||
* improvements to network map, location filtering and auto saving
|
* improvements to network map, location filtering and auto saving
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ my $result = GetOptions(
|
|||||||
use App::Netdisco::Environment;
|
use App::Netdisco::Environment;
|
||||||
my $config = ($ENV{PLACK_ENV} || $ENV{DANCER_ENVIRONMENT}) .'.yml';
|
my $config = ($ENV{PLACK_ENV} || $ENV{DANCER_ENVIRONMENT}) .'.yml';
|
||||||
|
|
||||||
# make sure there is a config file in place
|
# make sure there is a config file in place
|
||||||
my $template_config = file($ENV{DANCER_CONFDIR}, 'environments', $config);
|
my $template_config = file($ENV{DANCER_CONFDIR}, 'environments', $config);
|
||||||
my $app_config = file($ENV{DANCER_ENVDIR}, $config);
|
my $app_config = file($ENV{DANCER_ENVDIR}, $config);
|
||||||
if (! -e $app_config and -e $template_config) {
|
if (! -e $app_config and -e $template_config) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ BEGIN {
|
|||||||
setting('workers')->{'BACKEND'} ||= (hostfqdn || 'fqdn-undefined');
|
setting('workers')->{'BACKEND'} ||= (hostfqdn || 'fqdn-undefined');
|
||||||
}
|
}
|
||||||
|
|
||||||
use App::Netdisco::Util::MCE; # set $0 and parse maxworkers
|
use App::Netdisco::Util::MCE; # set $0 and parse maxworkers
|
||||||
use NetAddr::IP::Lite ':lower'; # to quench AF_INET6 symbol errors
|
use NetAddr::IP::Lite ':lower'; # to quench AF_INET6 symbol errors
|
||||||
use Role::Tiny::With;
|
use Role::Tiny::With;
|
||||||
|
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ sub shorten {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub deploy_mibs {
|
sub deploy_mibs {
|
||||||
my $mibhome = dir(shift); # /path/to/netdisco-mibs
|
my $mibhome = dir(shift); # /path/to/netdisco-mibs
|
||||||
my $fail = 0;
|
my $fail = 0;
|
||||||
|
|
||||||
my $latest = 'https://github.com/netdisco/netdisco-mibs/releases/latest';
|
my $latest = 'https://github.com/netdisco/netdisco-mibs/releases/latest';
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ my $result = GetOptions(
|
|||||||
use App::Netdisco::Environment;
|
use App::Netdisco::Environment;
|
||||||
my $config = ($ENV{PLACK_ENV} || $ENV{DANCER_ENVIRONMENT}) .'.yml';
|
my $config = ($ENV{PLACK_ENV} || $ENV{DANCER_ENVIRONMENT}) .'.yml';
|
||||||
|
|
||||||
# make sure there is a config file in place
|
# make sure there is a config file in place
|
||||||
my $template_config = file($ENV{DANCER_CONFDIR}, 'environments', $config);
|
my $template_config = file($ENV{DANCER_CONFDIR}, 'environments', $config);
|
||||||
my $app_config = file($ENV{DANCER_ENVDIR}, $config);
|
my $app_config = file($ENV{DANCER_ENVDIR}, $config);
|
||||||
if (! -e $app_config and -e $template_config) {
|
if (! -e $app_config and -e $template_config) {
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ sub finalise_status {
|
|||||||
my $job = shift;
|
my $job = shift;
|
||||||
# use DDP; p $job->_statuslist;
|
# use DDP; p $job->_statuslist;
|
||||||
|
|
||||||
# fallback
|
# fallback
|
||||||
$job->status('error');
|
$job->status('error');
|
||||||
$job->log('failed to report from any worker!');
|
$job->log('failed to report from any worker!');
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ sub finalise_status {
|
|||||||
next if $status->phase
|
next if $status->phase
|
||||||
and $status->phase !~ m/^(?:check|early|main|store|late)$/;
|
and $status->phase !~ m/^(?:check|early|main|store|late)$/;
|
||||||
|
|
||||||
# done() from check phase should not be the action's done()
|
# done() from check phase should not be the action's done()
|
||||||
next if $status->phase eq 'check' and $status->is_ok;
|
next if $status->phase eq 'check' and $status->is_ok;
|
||||||
|
|
||||||
if ($status->level >= $max_level) {
|
if ($status->level >= $max_level) {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ sub worker_body {
|
|||||||
|
|
||||||
$self->close_job($job);
|
$self->close_job($job);
|
||||||
sleep( setting('workers')->{'min_runtime'} || 0 );
|
sleep( setting('workers')->{'min_runtime'} || 0 );
|
||||||
$self->exit(0); # recycle worker
|
$self->exit(0); # recycle worker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ BEGIN {
|
|||||||
|
|
||||||
# set up database schema config from simple config vars
|
# set up database schema config from simple config vars
|
||||||
if (ref {} eq ref setting('database')) {
|
if (ref {} eq ref setting('database')) {
|
||||||
# override from env for docker
|
# override from env for docker
|
||||||
|
|
||||||
setting('database')->{name} =
|
setting('database')->{name} =
|
||||||
($ENV{NETDISCO_DB_NAME} || $ENV{NETDISCO_DBNAME} || setting('database')->{name});
|
($ENV{NETDISCO_DB_NAME} || $ENV{NETDISCO_DBNAME} || setting('database')->{name});
|
||||||
@@ -73,19 +73,19 @@ if (ref {} eq ref setting('database')) {
|
|||||||
# always set this
|
# always set this
|
||||||
$ENV{DBIC_TRACE_PROFILE} = 'console';
|
$ENV{DBIC_TRACE_PROFILE} = 'console';
|
||||||
|
|
||||||
# override from env for docker
|
# override from env for docker
|
||||||
config->{'community'} = ($ENV{NETDISCO_RO_COMMUNITY} ?
|
config->{'community'} = ($ENV{NETDISCO_RO_COMMUNITY} ?
|
||||||
[split ',', $ENV{NETDISCO_RO_COMMUNITY}] : config->{'community'});
|
[split ',', $ENV{NETDISCO_RO_COMMUNITY}] : config->{'community'});
|
||||||
config->{'community_rw'} = ($ENV{NETDISCO_RW_COMMUNITY} ?
|
config->{'community_rw'} = ($ENV{NETDISCO_RW_COMMUNITY} ?
|
||||||
[split ',', $ENV{NETDISCO_RW_COMMUNITY}] : config->{'community_rw'});
|
[split ',', $ENV{NETDISCO_RW_COMMUNITY}] : config->{'community_rw'});
|
||||||
|
|
||||||
# if snmp_auth and device_auth not set, add defaults to community{_rw}
|
# if snmp_auth and device_auth not set, add defaults to community{_rw}
|
||||||
if ((setting('snmp_auth') and 0 == scalar @{ setting('snmp_auth') })
|
if ((setting('snmp_auth') and 0 == scalar @{ setting('snmp_auth') })
|
||||||
and (setting('device_auth') and 0 == scalar @{ setting('device_auth') })) {
|
and (setting('device_auth') and 0 == scalar @{ setting('device_auth') })) {
|
||||||
config->{'community'} = [ @{setting('community')}, 'public' ];
|
config->{'community'} = [ @{setting('community')}, 'public' ];
|
||||||
config->{'community_rw'} = [ @{setting('community_rw')}, 'private' ];
|
config->{'community_rw'} = [ @{setting('community_rw')}, 'private' ];
|
||||||
}
|
}
|
||||||
# fix up device_auth (or create it from old snmp_auth and community settings)
|
# fix up device_auth (or create it from old snmp_auth and community settings)
|
||||||
# also imports legacy sshcollector config
|
# also imports legacy sshcollector config
|
||||||
config->{'device_auth'}
|
config->{'device_auth'}
|
||||||
= [ App::Netdisco::Util::DeviceAuth::fixup_device_auth() ];
|
= [ App::Netdisco::Util::DeviceAuth::fixup_device_auth() ];
|
||||||
@@ -122,7 +122,7 @@ setting('dns')->{'ETCHOSTS'} = {};
|
|||||||
for keys %AnyEvent::DNS::EtcHosts::HOSTS;
|
for keys %AnyEvent::DNS::EtcHosts::HOSTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
# override from env for docker
|
# override from env for docker
|
||||||
if ($ENV{NETDISCO_DOMAIN}) {
|
if ($ENV{NETDISCO_DOMAIN}) {
|
||||||
if ($ENV{NETDISCO_DOMAIN} eq 'discover') {
|
if ($ENV{NETDISCO_DOMAIN} eq 'discover') {
|
||||||
delete $ENV{NETDISCO_DOMAIN};
|
delete $ENV{NETDISCO_DOMAIN};
|
||||||
@@ -187,7 +187,7 @@ elsif (ref [] eq ref setting('tacacs')) {
|
|||||||
config->{'tacacs'} = [ @newservers ];
|
config->{'tacacs'} = [ @newservers ];
|
||||||
}
|
}
|
||||||
|
|
||||||
# support unordered dictionary as if it were a single item list
|
# support unordered dictionary as if it were a single item list
|
||||||
if (ref {} eq ref setting('device_identity')) {
|
if (ref {} eq ref setting('device_identity')) {
|
||||||
config->{'device_identity'} = [ setting('device_identity') ];
|
config->{'device_identity'} = [ setting('device_identity') ];
|
||||||
}
|
}
|
||||||
@@ -236,8 +236,8 @@ setting('workers')->{'timeout'} = setting('timeout')
|
|||||||
if defined setting('timeout')
|
if defined setting('timeout')
|
||||||
and !defined setting('workers')->{'timeout'};
|
and !defined setting('workers')->{'timeout'};
|
||||||
|
|
||||||
# 0 for workers max_deferrals and retry_after is like disabling
|
# 0 for workers max_deferrals and retry_after is like disabling
|
||||||
# but we need to fake it with special values
|
# but we need to fake it with special values
|
||||||
setting('workers')->{'max_deferrals'} ||= (2**30);
|
setting('workers')->{'max_deferrals'} ||= (2**30);
|
||||||
setting('workers')->{'retry_after'} ||= '100 years';
|
setting('workers')->{'retry_after'} ||= '100 years';
|
||||||
|
|
||||||
@@ -254,15 +254,15 @@ if (setting('reports') and ref {} eq ref setting('reports')) {
|
|||||||
}} keys %{ setting('reports') } ];
|
}} keys %{ setting('reports') } ];
|
||||||
}
|
}
|
||||||
|
|
||||||
# add system_reports onto reports
|
# add system_reports onto reports
|
||||||
config->{'reports'} = [ @{setting('system_reports')}, @{setting('reports')} ];
|
config->{'reports'} = [ @{setting('system_reports')}, @{setting('reports')} ];
|
||||||
|
|
||||||
# set swagger ui location
|
# set swagger ui location
|
||||||
#config->{plugins}->{Swagger}->{ui_dir} =
|
#config->{plugins}->{Swagger}->{ui_dir} =
|
||||||
#dir(dist_dir('App-Netdisco'), 'share', 'public', 'swagger-ui')->absolute;
|
#dir(dist_dir('App-Netdisco'), 'share', 'public', 'swagger-ui')->absolute;
|
||||||
|
|
||||||
# setup helpers for when request->uri_for() isn't available
|
# setup helpers for when request->uri_for() isn't available
|
||||||
# (for example when inside swagger_path())
|
# (for example when inside swagger_path())
|
||||||
config->{url_base}
|
config->{url_base}
|
||||||
= URI::Based->new((config->{path} eq '/') ? '' : config->{path});
|
= URI::Based->new((config->{path} eq '/') ? '' : config->{path});
|
||||||
config->{api_base}
|
config->{api_base}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ use base 'DBIx::Class::Core';
|
|||||||
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||||
|
|
||||||
# note to future devs:
|
# note to future devs:
|
||||||
# this query does not use the slave_of field in device_port table to group
|
# this query does not use the slave_of field in device_port table to group
|
||||||
# ports because what we actually want is total b/w between devices on all
|
# ports because what we actually want is total b/w between devices on all
|
||||||
# links, regardless of whether those links are in an aggregate.
|
# links, regardless of whether those links are in an aggregate.
|
||||||
|
|
||||||
__PACKAGE__->table('device_links');
|
__PACKAGE__->table('device_links');
|
||||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ C<retry_after> when devices will be retried once (disabled if 0/undef passed).
|
|||||||
sub skipped {
|
sub skipped {
|
||||||
my ($rs, $backend, $max_deferrals, $retry) = @_;
|
my ($rs, $backend, $max_deferrals, $retry) = @_;
|
||||||
$backend ||= 'fqdn-undefined';
|
$backend ||= 'fqdn-undefined';
|
||||||
$max_deferrals ||= (2**30); # not really 'disabled'
|
$max_deferrals ||= (2**30); # not really 'disabled'
|
||||||
$retry ||= '100 years'; # not really 'disabled'
|
$retry ||= '100 years'; # not really 'disabled'
|
||||||
|
|
||||||
return $rs->correlate('device_skips')->search(undef,{
|
return $rs->correlate('device_skips')->search(undef,{
|
||||||
# NOTE: bind param list order is significant
|
# NOTE: bind param list order is significant
|
||||||
bind => [[deferrals => $max_deferrals], [last_defer => $retry], [backend => $backend]],
|
bind => [[deferrals => $max_deferrals], [last_defer => $retry], [backend => $backend]],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ sub device_ips_with_address_or_name {
|
|||||||
$q ||= '255.255.255.255/32';
|
$q ||= '255.255.255.255/32';
|
||||||
|
|
||||||
return $rs->search(undef,{
|
return $rs->search(undef,{
|
||||||
# NOTE: bind param list order is significant
|
# NOTE: bind param list order is significant
|
||||||
join => ['device_ips_by_address_or_name'],
|
join => ['device_ips_by_address_or_name'],
|
||||||
bind => [$q, $ipbind, $q],
|
bind => [$q, $ipbind, $q],
|
||||||
});
|
});
|
||||||
@@ -44,7 +44,7 @@ sub ports_with_mac {
|
|||||||
$mac ||= '00:00:00:00:00:00';
|
$mac ||= '00:00:00:00:00:00';
|
||||||
|
|
||||||
return $rs->search(undef,{
|
return $rs->search(undef,{
|
||||||
# NOTE: bind param list order is significant
|
# NOTE: bind param list order is significant
|
||||||
join => ['ports_by_mac'],
|
join => ['ports_by_mac'],
|
||||||
bind => [$mac],
|
bind => [$mac],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ sub _set_operation {
|
|||||||
unless $self->_compare_arrays($as, $attrs->{as});
|
unless $self->_compare_arrays($as, $attrs->{as});
|
||||||
|
|
||||||
my ($sql, @bind) = @{${$_->as_query}};
|
my ($sql, @bind) = @{${$_->as_query}};
|
||||||
# $sql =~ s/^\s*\((.*)\)\s*$/$1/;
|
# $sql =~ s/^\s*\((.*)\)\s*$/$1/;
|
||||||
$sql = q<(> . $sql . q<)>;
|
$sql = q<(> . $sql . q<)>;
|
||||||
|
|
||||||
push @sql, $sql;
|
push @sql, $sql;
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ our @EXPORT_OK = qw/
|
|||||||
/;
|
/;
|
||||||
our %EXPORT_TAGS = ( all => \@EXPORT_OK );
|
our %EXPORT_TAGS = ( all => \@EXPORT_OK );
|
||||||
|
|
||||||
# given a device, tests if any of the primary acls applies
|
# given a device, tests if any of the primary acls applies
|
||||||
# returns a list of job actions to be denied/skipped on this host.
|
# returns a list of job actions to be denied/skipped on this host.
|
||||||
sub _get_denied_actions {
|
sub _get_denied_actions {
|
||||||
my $device = shift;
|
my $device = shift;
|
||||||
my @badactions = ();
|
my @badactions = ();
|
||||||
@@ -110,10 +110,10 @@ sub jq_getsome {
|
|||||||
|
|
||||||
while (my $job = $tasty->next) {
|
while (my $job = $tasty->next) {
|
||||||
if ($job->device) {
|
if ($job->device) {
|
||||||
# need to handle device discovered since backend daemon started
|
# need to handle device discovered since backend daemon started
|
||||||
# and the skiplist was primed. these should be checked against
|
# and the skiplist was primed. these should be checked against
|
||||||
# the various acls and have device_skip entry added if needed,
|
# the various acls and have device_skip entry added if needed,
|
||||||
# and return false if it should have been skipped.
|
# and return false if it should have been skipped.
|
||||||
my @badactions = _get_denied_actions($job->device);
|
my @badactions = _get_denied_actions($job->device);
|
||||||
if (scalar @badactions) {
|
if (scalar @badactions) {
|
||||||
schema('netdisco')->resultset('DeviceSkip')->find_or_create({
|
schema('netdisco')->resultset('DeviceSkip')->find_or_create({
|
||||||
@@ -128,10 +128,10 @@ sub jq_getsome {
|
|||||||
# remove any duplicate jobs, incuding possibly this job if there
|
# remove any duplicate jobs, incuding possibly this job if there
|
||||||
# is already an equivalent job running
|
# is already an equivalent job running
|
||||||
|
|
||||||
# note that the self-removal of a job has an unhelpful log: it is
|
# note that the self-removal of a job has an unhelpful log: it is
|
||||||
# reported as a duplicate of itself! however what's happening is that
|
# reported as a duplicate of itself! however what's happening is that
|
||||||
# netdisco has seen another running job with same params (but the query
|
# netdisco has seen another running job with same params (but the query
|
||||||
# cannot see that ID to use it in the message).
|
# cannot see that ID to use it in the message).
|
||||||
|
|
||||||
my %job_properties = (
|
my %job_properties = (
|
||||||
action => $job->action,
|
action => $job->action,
|
||||||
@@ -217,12 +217,12 @@ sub jq_defer {
|
|||||||
my $job = shift;
|
my $job = shift;
|
||||||
my $happy = false;
|
my $happy = false;
|
||||||
|
|
||||||
# note this taints all actions on the device. for example if both
|
# note this taints all actions on the device. for example if both
|
||||||
# macsuck and arpnip are allowed, but macsuck fails 10 times, then
|
# macsuck and arpnip are allowed, but macsuck fails 10 times, then
|
||||||
# arpnip (and every other action) will be prevented on the device.
|
# arpnip (and every other action) will be prevented on the device.
|
||||||
|
|
||||||
# seeing as defer is only triggered by an SNMP connect failure, this
|
# seeing as defer is only triggered by an SNMP connect failure, this
|
||||||
# behaviour seems reasonable, to me (or desirable, perhaps).
|
# behaviour seems reasonable, to me (or desirable, perhaps).
|
||||||
|
|
||||||
try {
|
try {
|
||||||
schema('netdisco')->txn_do(sub {
|
schema('netdisco')->txn_do(sub {
|
||||||
@@ -252,9 +252,9 @@ sub jq_complete {
|
|||||||
|
|
||||||
# lock db row and update to show job is done/error
|
# lock db row and update to show job is done/error
|
||||||
|
|
||||||
# now that SNMP connect failures are deferrals and not errors, any complete
|
# now that SNMP connect failures are deferrals and not errors, any complete
|
||||||
# status, whether success or failure, indicates an SNMP connect. reset the
|
# status, whether success or failure, indicates an SNMP connect. reset the
|
||||||
# connection failures counter to forget about occasional connect glitches.
|
# connection failures counter to forget about occasional connect glitches.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
schema('netdisco')->txn_do(sub {
|
schema('netdisco')->txn_do(sub {
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ Returns C<undef> if the connection fails.
|
|||||||
sub test_connection {
|
sub test_connection {
|
||||||
my ($class, $ip) = @_;
|
my ($class, $ip) = @_;
|
||||||
my $addr = NetAddr::IP::Lite->new($ip) or return undef;
|
my $addr = NetAddr::IP::Lite->new($ip) or return undef;
|
||||||
# avoid renumbering to localhost loopbacks
|
# avoid renumbering to localhost loopbacks
|
||||||
return undef if $addr->addr eq '0.0.0.0'
|
return undef if $addr->addr eq '0.0.0.0'
|
||||||
or check_acl_no($addr->addr, 'group:__LOCAL_ADDRESSES__');
|
or check_acl_no($addr->addr, 'group:__LOCAL_ADDRESSES__');
|
||||||
my $device = schema('netdisco')->resultset('Device')
|
my $device = schema('netdisco')->resultset('Device')
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ sub fixup_device_auth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# legacy config
|
# legacy config
|
||||||
# note: read strings tried before write
|
# note: read strings tried before write
|
||||||
# note: read-write is no longer used for read operations
|
# note: read-write is no longer used for read operations
|
||||||
|
|
||||||
push @new_stanzas, map {{
|
push @new_stanzas, map {{
|
||||||
read => 1, write => 0,
|
read => 1, write => 0,
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ sub hostnames_resolve_async {
|
|||||||
$done->recv;
|
$done->recv;
|
||||||
|
|
||||||
# Remove reference to resolver so that we close sockets
|
# Remove reference to resolver so that we close sockets
|
||||||
# and allow return to any instance defaults we have changed
|
# and allow return to any instance defaults we have changed
|
||||||
undef $AnyEvent::DNS::RESOLVER if $AnyEvent::DNS::RESOLVER;
|
undef $AnyEvent::DNS::RESOLVER if $AnyEvent::DNS::RESOLVER;
|
||||||
|
|
||||||
return $ips;
|
return $ips;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ for details of what C<$acl> may contain.
|
|||||||
sub check_acl_only {
|
sub check_acl_only {
|
||||||
my ($thing, $setting_name) = @_;
|
my ($thing, $setting_name) = @_;
|
||||||
return 0 unless $thing and $setting_name;
|
return 0 unless $thing and $setting_name;
|
||||||
# logic to make an empty config be equivalent to 'any' (i.e. a match)
|
# logic to make an empty config be equivalent to 'any' (i.e. a match)
|
||||||
my $config = (exists config->{"$setting_name"} ? setting($setting_name)
|
my $config = (exists config->{"$setting_name"} ? setting($setting_name)
|
||||||
: $setting_name);
|
: $setting_name);
|
||||||
return 1 if not $config # undef or empty string
|
return 1 if not $config # undef or empty string
|
||||||
@@ -99,7 +99,7 @@ sub check_acl {
|
|||||||
$thing->can('addr') ? $thing->addr : $thing )));
|
$thing->can('addr') ? $thing->addr : $thing )));
|
||||||
}
|
}
|
||||||
return 0 if !defined $real_ip
|
return 0 if !defined $real_ip
|
||||||
or blessed $real_ip; # class we do not understand
|
or blessed $real_ip; # class we do not understand
|
||||||
|
|
||||||
$config = [$config] if ref '' eq ref $config;
|
$config = [$config] if ref '' eq ref $config;
|
||||||
if (ref [] ne ref $config) {
|
if (ref [] ne ref $config) {
|
||||||
@@ -113,12 +113,12 @@ sub check_acl {
|
|||||||
return 1 if $find and not $all;
|
return 1 if $find and not $all;
|
||||||
|
|
||||||
my $addr = NetAddr::IP::Lite->new($real_ip) or return 0;
|
my $addr = NetAddr::IP::Lite->new($real_ip) or return 0;
|
||||||
my $name = undef; # only look up once, and only if qr// is used
|
my $name = undef; # only look up once, and only if qr// is used
|
||||||
my $ropt = { retry => 1, retrans => 1, udp_timeout => 1, tcp_timeout => 2 };
|
my $ropt = { retry => 1, retrans => 1, udp_timeout => 1, tcp_timeout => 2 };
|
||||||
my $qref = ref qr//;
|
my $qref = ref qr//;
|
||||||
|
|
||||||
INLIST: foreach (@$config) {
|
INLIST: foreach (@$config) {
|
||||||
my $item = $_; # must copy so that we can modify safely
|
my $item = $_; # must copy so that we can modify safely
|
||||||
next INLIST if !defined $item or $item eq 'op:and';
|
next INLIST if !defined $item or $item eq 'op:and';
|
||||||
|
|
||||||
if ($qref eq ref $item) {
|
if ($qref eq ref $item) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package App::Netdisco::Util::Statistics;
|
|||||||
use Dancer qw/:syntax :script/;
|
use Dancer qw/:syntax :script/;
|
||||||
use Dancer::Plugin::DBIC 'schema';
|
use Dancer::Plugin::DBIC 'schema';
|
||||||
|
|
||||||
use Time::Piece; # for OO localtime
|
use Time::Piece; # for OO localtime
|
||||||
|
|
||||||
use base 'Exporter';
|
use base 'Exporter';
|
||||||
our @EXPORT = ();
|
our @EXPORT = ();
|
||||||
@@ -36,7 +36,7 @@ sub update_stats {
|
|||||||
my $snmpinfo_ver = ($@ ? 'n/a' : $SNMP::Info::VERSION);
|
my $snmpinfo_ver = ($@ ? 'n/a' : $SNMP::Info::VERSION);
|
||||||
my $postgres_ver = pretty_version($schema->storage->dbh->{pg_server_version}, 2);
|
my $postgres_ver = pretty_version($schema->storage->dbh->{pg_server_version}, 2);
|
||||||
|
|
||||||
# TODO: (when we have the capabilities table?)
|
# TODO: (when we have the capabilities table?)
|
||||||
# $stats{waps} = sql_scalar('device',['COUNT(*)'], {"model"=>"AIR%"});
|
# $stats{waps} = sql_scalar('device',['COUNT(*)'], {"model"=>"AIR%"});
|
||||||
|
|
||||||
$schema->txn_do(sub {
|
$schema->txn_do(sub {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ sub queue_hook {
|
|||||||
my $extra = { action_conf => dclone ($conf->{'with'} || {}),
|
my $extra = { action_conf => dclone ($conf->{'with'} || {}),
|
||||||
event_data => dclone (vars->{'hook_data'} || {}) };
|
event_data => dclone (vars->{'hook_data'} || {}) };
|
||||||
|
|
||||||
# remove scalar references which to_json cannot handle
|
# remove scalar references which to_json cannot handle
|
||||||
visit( $extra->{'event_data'}, sub {
|
visit( $extra->{'event_data'}, sub {
|
||||||
my ($key, $valueref) = @_;
|
my ($key, $valueref) = @_;
|
||||||
$$valueref = '' if ref $$valueref eq 'SCALAR';
|
$$valueref = '' if ref $$valueref eq 'SCALAR';
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ if (setting('extra_web_plugins') and ref [] eq ref setting('extra_web_plugins'))
|
|||||||
push @{ config->{engines}->{netdisco_template_toolkit}->{INCLUDE_PATH} },
|
push @{ config->{engines}->{netdisco_template_toolkit}->{INCLUDE_PATH} },
|
||||||
setting('views');
|
setting('views');
|
||||||
|
|
||||||
# any template paths in deployment.yml (should override plugins)
|
# any template paths in deployment.yml (should override plugins)
|
||||||
if (setting('template_paths') and ref [] eq ref setting('template_paths')) {
|
if (setting('template_paths') and ref [] eq ref setting('template_paths')) {
|
||||||
if (setting('site_local_files')) {
|
if (setting('site_local_files')) {
|
||||||
push @{setting('template_paths')},
|
push @{setting('template_paths')},
|
||||||
@@ -135,7 +135,7 @@ hook after_error_render => sub { setting('layout' => 'main') };
|
|||||||
|
|
||||||
set('port_columns' => \@port_columns);
|
set('port_columns' => \@port_columns);
|
||||||
|
|
||||||
# update sidebar_defaults so hooks scanning params see new plugin cols
|
# update sidebar_defaults so hooks scanning params see new plugin cols
|
||||||
setting('sidebar_defaults')->{'device_ports'}->{ $_->{name} } = $_
|
setting('sidebar_defaults')->{'device_ports'}->{ $_->{name} } = $_
|
||||||
for @port_columns;
|
for @port_columns;
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ hook 'before' => sub {
|
|||||||
# trim whitespace
|
# trim whitespace
|
||||||
params->{'q'} =~ s/^\s+|\s+$//g if param('q');
|
params->{'q'} =~ s/^\s+|\s+$//g if param('q');
|
||||||
|
|
||||||
# copy sidebar defaults into vars so we can mess about with it
|
# copy sidebar defaults into vars so we can mess about with it
|
||||||
foreach my $sidebar (keys %{setting('sidebar_defaults')}) {
|
foreach my $sidebar (keys %{setting('sidebar_defaults')}) {
|
||||||
vars->{'sidebar_defaults'}->{$sidebar} = { map {
|
vars->{'sidebar_defaults'}->{$sidebar} = { map {
|
||||||
($_ => setting('sidebar_defaults')->{$sidebar}->{$_}->{'default'})
|
($_ => setting('sidebar_defaults')->{$sidebar}->{$_}->{'default'})
|
||||||
@@ -160,19 +160,19 @@ hook 'before' => sub {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# swagger submits "false" params whereas web UI does not - remove them
|
# swagger submits "false" params whereas web UI does not - remove them
|
||||||
# so that code testing for param existence as truth still works.
|
# so that code testing for param existence as truth still works.
|
||||||
hook 'before' => sub {
|
hook 'before' => sub {
|
||||||
return unless request_is_api_report or request_is_api_search;
|
return unless request_is_api_report or request_is_api_search;
|
||||||
map {delete params->{$_} if params->{$_} eq 'false'} keys %{params()};
|
map {delete params->{$_} if params->{$_} eq 'false'} keys %{params()};
|
||||||
};
|
};
|
||||||
|
|
||||||
hook 'before_template' => sub {
|
hook 'before_template' => sub {
|
||||||
# search or report from navbar, or reset of sidebar, can ignore params
|
# search or report from navbar, or reset of sidebar, can ignore params
|
||||||
return if param('firstsearch')
|
return if param('firstsearch')
|
||||||
or var('sidebar_key') !~ m/^\w+_\w+$/;
|
or var('sidebar_key') !~ m/^\w+_\w+$/;
|
||||||
|
|
||||||
# update defaults to contain the passed url params
|
# update defaults to contain the passed url params
|
||||||
# (this follows initial copy from config.yml, then cookie restore)
|
# (this follows initial copy from config.yml, then cookie restore)
|
||||||
var('sidebar_defaults')->{var('sidebar_key')}->{$_} = param($_)
|
var('sidebar_defaults')->{var('sidebar_key')}->{$_} = param($_)
|
||||||
for keys %{ var('sidebar_defaults')->{var('sidebar_key')} || {} };
|
for keys %{ var('sidebar_defaults')->{var('sidebar_key')} || {} };
|
||||||
};
|
};
|
||||||
@@ -187,7 +187,7 @@ hook 'before_template' => sub {
|
|||||||
# allow portable dynamic content
|
# allow portable dynamic content
|
||||||
$tokens->{uri_for} = sub { uri_for(@_)->path_query };
|
$tokens->{uri_for} = sub { uri_for(@_)->path_query };
|
||||||
|
|
||||||
# current query string to all resubmit from within ajax template
|
# current query string to all resubmit from within ajax template
|
||||||
my $queryuri = URI->new();
|
my $queryuri = URI->new();
|
||||||
$queryuri->query_param($_ => param($_))
|
$queryuri->query_param($_ => param($_))
|
||||||
for grep {$_ ne 'return_url'} keys %{params()};
|
for grep {$_ ne 'return_url'} keys %{params()};
|
||||||
@@ -222,7 +222,7 @@ hook 'before_template' => sub {
|
|||||||
$tokens->{$sidebar_key} = $tokens->{$sidebar_key}->path_query;
|
$tokens->{$sidebar_key} = $tokens->{$sidebar_key}->path_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
# helper from NetAddr::MAC for the MAC formatting
|
# helper from NetAddr::MAC for the MAC formatting
|
||||||
$tokens->{mac_format_call} = 'as_'. lc(param('mac_format'))
|
$tokens->{mac_format_call} = 'as_'. lc(param('mac_format'))
|
||||||
if param('mac_format');
|
if param('mac_format');
|
||||||
|
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ sub match_with_radius {
|
|||||||
my $conf = setting('radius');
|
my $conf = setting('radius');
|
||||||
my $radius = Authen::Radius->new(@$conf);
|
my $radius = Authen::Radius->new(@$conf);
|
||||||
# my $dict_dir = Path::Class::Dir->new( dist_dir('App-Netdisco') )
|
# my $dict_dir = Path::Class::Dir->new( dist_dir('App-Netdisco') )
|
||||||
# ->subdir('radius_dictionaries')->stringify;
|
# ->subdir('radius_dictionaries')->stringify;
|
||||||
Authen::Radius->load_dictionary(); # put $dict_dir in here once it's useful
|
Authen::Radius->load_dictionary(); # put $dict_dir in here once it's useful
|
||||||
|
|
||||||
$radius->add_attributes(
|
$radius->add_attributes(
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ post '/login' => sub {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# ugh, *puke*, but D::P::Swagger has no way to set this with swagger_path
|
# ugh, *puke*, but D::P::Swagger has no way to set this with swagger_path
|
||||||
# must be after the path is declared, above.
|
# must be after the path is declared, above.
|
||||||
Dancer::Plugin::Swagger->instance->doc
|
Dancer::Plugin::Swagger->instance->doc
|
||||||
->{paths}->{ setting('url_base')->with('/login')->path }
|
->{paths}->{ setting('url_base')->with('/login')->path }
|
||||||
->{post}->{security}->[0]->{BasicAuth} = [];
|
->{post}->{security}->[0]->{BasicAuth} = [];
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ hook 'before_template' => sub {
|
|||||||
or return;
|
or return;
|
||||||
|
|
||||||
# override ports form defaults with cookie settings
|
# override ports form defaults with cookie settings
|
||||||
# always do this so that embedded links to device ports page have user prefs
|
# always do this so that embedded links to device ports page have user prefs
|
||||||
if (param('reset')) {
|
if (param('reset')) {
|
||||||
cookie('nd_ports-form' => '', expires => '-1 day');
|
cookie('nd_ports-form' => '', expires => '-1 day');
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ hook 'before_template' => sub {
|
|||||||
return if param('reset')
|
return if param('reset')
|
||||||
or not var('sidebar_key') or (var('sidebar_key') ne 'device_ports');
|
or not var('sidebar_key') or (var('sidebar_key') ne 'device_ports');
|
||||||
|
|
||||||
# update cookie from params we just recieved in form submit
|
# update cookie from params we just recieved in form submit
|
||||||
my $uri = URI->new();
|
my $uri = URI->new();
|
||||||
foreach my $key (keys %{ $defaults }) {
|
foreach my $key (keys %{ $defaults }) {
|
||||||
$uri->query_param($key => param($key));
|
$uri->query_param($key => param($key));
|
||||||
|
|||||||
@@ -32,15 +32,15 @@ ajax '/ajax/data/device/netmappositions' => require_login sub {
|
|||||||
my $mapshow = param('mapshow');
|
my $mapshow = param('mapshow');
|
||||||
return if !defined $mapshow or $mapshow !~ m/^(?:all|neighbors)$/;
|
return if !defined $mapshow or $mapshow !~ m/^(?:all|neighbors)$/;
|
||||||
|
|
||||||
# list of groups selected by user and passed in param
|
# list of groups selected by user and passed in param
|
||||||
my $hgroup = (ref [] eq ref param('hgroup') ? param('hgroup') : [param('hgroup')]);
|
my $hgroup = (ref [] eq ref param('hgroup') ? param('hgroup') : [param('hgroup')]);
|
||||||
# list of groups validated as real host groups and named host groups
|
# list of groups validated as real host groups and named host groups
|
||||||
my @hgrplist = List::MoreUtils::uniq
|
my @hgrplist = List::MoreUtils::uniq
|
||||||
grep { exists setting('host_group_displaynames')->{$_} }
|
grep { exists setting('host_group_displaynames')->{$_} }
|
||||||
grep { exists setting('host_groups')->{$_} }
|
grep { exists setting('host_groups')->{$_} }
|
||||||
grep { defined } @{ $hgroup };
|
grep { defined } @{ $hgroup };
|
||||||
|
|
||||||
# list of locations selected by user and passed in param
|
# list of locations selected by user and passed in param
|
||||||
my $lgroup = (ref [] eq ref param('lgroup') ? param('lgroup') : [param('lgroup')]);
|
my $lgroup = (ref [] eq ref param('lgroup') ? param('lgroup') : [param('lgroup')]);
|
||||||
my @lgrplist = List::MoreUtils::uniq grep { defined } @{ $lgroup };
|
my @lgrplist = List::MoreUtils::uniq grep { defined } @{ $lgroup };
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ ajax '/ajax/data/device/netmappositions' => require_login sub {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
# copied from SNMP::Info to avoid introducing dependency to web frontend
|
# copied from SNMP::Info to avoid introducing dependency to web frontend
|
||||||
sub munge_highspeed {
|
sub munge_highspeed {
|
||||||
my $speed = shift;
|
my $speed = shift;
|
||||||
my $fmt = "%d Mbps";
|
my $fmt = "%d Mbps";
|
||||||
@@ -147,15 +147,15 @@ ajax '/ajax/data/device/netmap' => require_login sub {
|
|||||||
$mapshow = 'neighbors' if $mapshow !~ m/^(?:all|neighbors)$/;
|
$mapshow = 'neighbors' if $mapshow !~ m/^(?:all|neighbors)$/;
|
||||||
$mapshow = 'all' unless $qdev->in_storage;
|
$mapshow = 'all' unless $qdev->in_storage;
|
||||||
|
|
||||||
# list of groups selected by user and passed in param
|
# list of groups selected by user and passed in param
|
||||||
my $hgroup = (ref [] eq ref param('hgroup') ? param('hgroup') : [param('hgroup')]);
|
my $hgroup = (ref [] eq ref param('hgroup') ? param('hgroup') : [param('hgroup')]);
|
||||||
# list of groups validated as real host groups and named host groups
|
# list of groups validated as real host groups and named host groups
|
||||||
my @hgrplist = List::MoreUtils::uniq
|
my @hgrplist = List::MoreUtils::uniq
|
||||||
grep { exists setting('host_group_displaynames')->{$_} }
|
grep { exists setting('host_group_displaynames')->{$_} }
|
||||||
grep { exists setting('host_groups')->{$_} }
|
grep { exists setting('host_groups')->{$_} }
|
||||||
grep { defined } @{ $hgroup };
|
grep { defined } @{ $hgroup };
|
||||||
|
|
||||||
# list of locations selected by user and passed in param
|
# list of locations selected by user and passed in param
|
||||||
my $lgroup = (ref [] eq ref param('lgroup') ? param('lgroup') : [param('lgroup')]);
|
my $lgroup = (ref [] eq ref param('lgroup') ? param('lgroup') : [param('lgroup')]);
|
||||||
my @lgrplist = List::MoreUtils::uniq grep { defined } @{ $lgroup };
|
my @lgrplist = List::MoreUtils::uniq grep { defined } @{ $lgroup };
|
||||||
|
|
||||||
@@ -217,21 +217,21 @@ ajax '/ajax/data/device/netmap' => require_login sub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEVICE: while (my $device = $devices->next) {
|
DEVICE: while (my $device = $devices->next) {
|
||||||
# if in neighbors mode then use %ok_dev to filter
|
# if in neighbors mode then use %ok_dev to filter
|
||||||
next DEVICE if ($device->ip ne $qdev->ip)
|
next DEVICE if ($device->ip ne $qdev->ip)
|
||||||
and ($mapshow eq 'neighbors')
|
and ($mapshow eq 'neighbors')
|
||||||
and (not $ok_dev{$device->ip}); # showing only neighbors but no link
|
and (not $ok_dev{$device->ip}); # showing only neighbors but no link
|
||||||
|
|
||||||
# if location picked then filter
|
# if location picked then filter
|
||||||
next DEVICE if ((scalar @lgrplist) and ((!defined $device->location)
|
next DEVICE if ((scalar @lgrplist) and ((!defined $device->location)
|
||||||
or (0 == scalar grep {$_ eq $device->location} @lgrplist)));
|
or (0 == scalar grep {$_ eq $device->location} @lgrplist)));
|
||||||
|
|
||||||
# if host groups picked then use ACLs to filter
|
# if host groups picked then use ACLs to filter
|
||||||
my $first_hgrp =
|
my $first_hgrp =
|
||||||
first { check_acl_only($device, setting('host_groups')->{$_}) } @hgrplist;
|
first { check_acl_only($device, setting('host_groups')->{$_}) } @hgrplist;
|
||||||
next DEVICE if ((scalar @hgrplist) and (not $first_hgrp));
|
next DEVICE if ((scalar @hgrplist) and (not $first_hgrp));
|
||||||
|
|
||||||
# now reset first_hgroup to be the group matching the device, if any
|
# now reset first_hgroup to be the group matching the device, if any
|
||||||
$first_hgrp = first { check_acl_only($device, setting('host_groups')->{$_}) }
|
$first_hgrp = first { check_acl_only($device, setting('host_groups')->{$_}) }
|
||||||
keys %{ setting('host_group_displaynames') || {} };
|
keys %{ setting('host_group_displaynames') || {} };
|
||||||
|
|
||||||
@@ -273,7 +273,7 @@ ajax '/ajax/data/device/netmap' => require_login sub {
|
|||||||
if $qdev and $qdev->in_storage and $device->ip eq $qdev->ip;
|
if $qdev and $qdev->in_storage and $device->ip eq $qdev->ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
# to help get a sensible range of node sizes
|
# to help get a sensible range of node sizes
|
||||||
$metadata{'numsizes'} = scalar keys %logvals;
|
$metadata{'numsizes'} = scalar keys %logvals;
|
||||||
|
|
||||||
content_type('application/json');
|
content_type('application/json');
|
||||||
|
|||||||
@@ -99,11 +99,11 @@ get '/ajax/content/device/ports' => require_login sub {
|
|||||||
$set = $set->search({-or => \@combi});
|
$set = $set->search({-or => \@combi});
|
||||||
}
|
}
|
||||||
|
|
||||||
# so far only the basic device_port data
|
# so far only the basic device_port data
|
||||||
# now begin to join tables depending on the selected columns/options
|
# now begin to join tables depending on the selected columns/options
|
||||||
|
|
||||||
# get vlans on the port
|
# get vlans on the port
|
||||||
# leave this query dormant (lazy) unless c_vmember is set or vlan filtering
|
# leave this query dormant (lazy) unless c_vmember is set or vlan filtering
|
||||||
my $vlans = $set->search({}, {
|
my $vlans = $set->search({}, {
|
||||||
select => [
|
select => [
|
||||||
'port',
|
'port',
|
||||||
@@ -117,7 +117,7 @@ get '/ajax/content/device/ports' => require_login sub {
|
|||||||
if (param('c_vmember') or ($prefer eq 'vlan') or (not $prefer and $f =~ m/^\d+$/)) {
|
if (param('c_vmember') or ($prefer eq 'vlan') or (not $prefer and $f =~ m/^\d+$/)) {
|
||||||
$vlans = { map {(
|
$vlans = { map {(
|
||||||
$_->port => {
|
$_->port => {
|
||||||
# DBIC smart enough to work out this should be an arrayref :)
|
# DBIC smart enough to work out this should be an arrayref :)
|
||||||
vlan_set => $_->get_column('vlan_set'),
|
vlan_set => $_->get_column('vlan_set'),
|
||||||
vlan_count => $_->get_column('vlan_count'),
|
vlan_count => $_->get_column('vlan_count'),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ sub load_workers {
|
|||||||
my @core_plugins = @{ setting('worker_plugins') || [] };
|
my @core_plugins = @{ setting('worker_plugins') || [] };
|
||||||
my @user_plugins = @{ setting('extra_worker_plugins') || [] };
|
my @user_plugins = @{ setting('extra_worker_plugins') || [] };
|
||||||
|
|
||||||
# load worker plugins for our action
|
# load worker plugins for our action
|
||||||
foreach my $plugin (@user_plugins, @core_plugins) {
|
foreach my $plugin (@user_plugins, @core_plugins) {
|
||||||
$plugin =~ s/^X::/+App::NetdiscoX::Worker::Plugin::/;
|
$plugin =~ s/^X::/+App::NetdiscoX::Worker::Plugin::/;
|
||||||
$plugin = 'App::Netdisco::Worker::Plugin::'. $plugin
|
$plugin = 'App::Netdisco::Worker::Plugin::'. $plugin
|
||||||
@@ -35,7 +35,7 @@ sub load_workers {
|
|||||||
Module::Load::load $plugin;
|
Module::Load::load $plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
# now vars->{workers} is populated, we set the dispatch order
|
# now vars->{workers} is populated, we set the dispatch order
|
||||||
my $workers = vars->{'workers'}->{$action} || {};
|
my $workers = vars->{'workers'}->{$action} || {};
|
||||||
#use DDP; p vars->{'workers'};
|
#use DDP; p vars->{'workers'};
|
||||||
|
|
||||||
|
|||||||
@@ -31,15 +31,15 @@ register 'register_worker' => sub {
|
|||||||
|
|
||||||
my $worker = sub {
|
my $worker = sub {
|
||||||
my $job = shift or die 'missing job param';
|
my $job = shift or die 'missing job param';
|
||||||
# use DDP; p $workerconf;
|
# use DDP; p $workerconf;
|
||||||
|
|
||||||
debug sprintf '-> run worker %s/%s/%s',
|
debug sprintf '-> run worker %s/%s/%s',
|
||||||
@$workerconf{qw/phase namespace priority/};
|
@$workerconf{qw/phase namespace priority/};
|
||||||
|
|
||||||
return if $job->is_cancelled;
|
return if $job->is_cancelled;
|
||||||
|
|
||||||
# check to see if this namespace has already passed at higher priority
|
# check to see if this namespace has already passed at higher priority
|
||||||
# and also update job's record of namespace and priority
|
# and also update job's record of namespace and priority
|
||||||
return $job->add_status( Status->info('skip: namespace passed at higher priority') )
|
return $job->add_status( Status->info('skip: namespace passed at higher priority') )
|
||||||
if $job->namespace_passed($workerconf);
|
if $job->namespace_passed($workerconf);
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ register 'register_worker' => sub {
|
|||||||
my @newuserconf = ();
|
my @newuserconf = ();
|
||||||
my @userconf = @{ dclone (setting('device_auth') || []) };
|
my @userconf = @{ dclone (setting('device_auth') || []) };
|
||||||
|
|
||||||
# worker might be vendor/platform specific
|
# worker might be vendor/platform specific
|
||||||
if (ref $job->device) {
|
if (ref $job->device) {
|
||||||
my $no = (exists $workerconf->{no} ? $workerconf->{no} : undef);
|
my $no = (exists $workerconf->{no} ? $workerconf->{no} : undef);
|
||||||
my $only = (exists $workerconf->{only} ? $workerconf->{only} : undef);
|
my $only = (exists $workerconf->{only} ? $workerconf->{only} : undef);
|
||||||
@@ -62,33 +62,33 @@ register 'register_worker' => sub {
|
|||||||
if ($no and check_acl_no($job->device, $no))
|
if ($no and check_acl_no($job->device, $no))
|
||||||
or ($only and not check_acl_only($job->device, $only));
|
or ($only and not check_acl_only($job->device, $only));
|
||||||
|
|
||||||
# reduce device_auth by driver and action filters
|
# reduce device_auth by driver and action filters
|
||||||
foreach my $stanza (@userconf) {
|
foreach my $stanza (@userconf) {
|
||||||
next if exists $stanza->{driver} and exists $workerconf->{driver}
|
next if exists $stanza->{driver} and exists $workerconf->{driver}
|
||||||
and (($stanza->{driver} || '') ne ($workerconf->{driver} || ''));
|
and (($stanza->{driver} || '') ne ($workerconf->{driver} || ''));
|
||||||
|
|
||||||
# filter here rather than in Runner as runner does not know namespace
|
# filter here rather than in Runner as runner does not know namespace
|
||||||
next if exists $stanza->{action}
|
next if exists $stanza->{action}
|
||||||
and not _find_matchaction($workerconf, lc($stanza->{action}));
|
and not _find_matchaction($workerconf, lc($stanza->{action}));
|
||||||
|
|
||||||
push @newuserconf, dclone $stanza;
|
push @newuserconf, dclone $stanza;
|
||||||
}
|
}
|
||||||
|
|
||||||
# per-device action but no device creds available
|
# per-device action but no device creds available
|
||||||
return $job->add_status( Status->info('skip: driver or action not applicable') )
|
return $job->add_status( Status->info('skip: driver or action not applicable') )
|
||||||
if 0 == scalar @newuserconf && $job->action ne "delete";
|
if 0 == scalar @newuserconf && $job->action ne "delete";
|
||||||
}
|
}
|
||||||
|
|
||||||
# back up and restore device_auth
|
# back up and restore device_auth
|
||||||
my $guard = guard { set(device_auth => \@userconf) };
|
my $guard = guard { set(device_auth => \@userconf) };
|
||||||
set(device_auth => \@newuserconf);
|
set(device_auth => \@newuserconf);
|
||||||
# use DDP; p @newuserconf;
|
# use DDP; p @newuserconf;
|
||||||
|
|
||||||
# run worker
|
# run worker
|
||||||
$code->($job, $workerconf);
|
$code->($job, $workerconf);
|
||||||
};
|
};
|
||||||
|
|
||||||
# store the built worker as Worker.pm will build the dispatch order later on
|
# store the built worker as Worker.pm will build the dispatch order later on
|
||||||
push @{ vars->{'workers'}->{$workerconf->{action}}
|
push @{ vars->{'workers'}->{$workerconf->{action}}
|
||||||
->{$workerconf->{phase}}
|
->{$workerconf->{phase}}
|
||||||
->{$workerconf->{namespace}}
|
->{$workerconf->{namespace}}
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ register_worker({ phase => 'check' }, sub {
|
|||||||
return Status->info("arpnip skipped: $device is not arpnipable")
|
return Status->info("arpnip skipped: $device is not arpnipable")
|
||||||
unless is_arpnipable_now($device);
|
unless is_arpnipable_now($device);
|
||||||
|
|
||||||
# support for Hooks
|
# support for Hooks
|
||||||
vars->{'hook_data'} = { $device->get_columns };
|
vars->{'hook_data'} = { $device->get_columns };
|
||||||
delete vars->{'hook_data'}->{'snmp_comm'}; # for privacy
|
delete vars->{'hook_data'}->{'snmp_comm'}; # for privacy
|
||||||
|
|
||||||
return Status->done('arpnip is able to run');
|
return Status->done('arpnip is able to run');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ sub gather_subnets {
|
|||||||
my @subnets = ();
|
my @subnets = ();
|
||||||
|
|
||||||
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
|
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
|
||||||
or return (); # already checked!
|
or return (); # already checked!
|
||||||
|
|
||||||
my $ip_netmask = $snmp->ip_netmask;
|
my $ip_netmask = $snmp->ip_netmask;
|
||||||
foreach my $entry (keys %$ip_netmask) {
|
foreach my $entry (keys %$ip_netmask) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ register_worker({ phase => 'check' }, sub {
|
|||||||
return Status->error("discover failed: no device param (need -d ?)")
|
return Status->error("discover failed: no device param (need -d ?)")
|
||||||
if $device->ip eq '0.0.0.0';
|
if $device->ip eq '0.0.0.0';
|
||||||
|
|
||||||
# runner has already called get_device to promote $job->device
|
# runner has already called get_device to promote $job->device
|
||||||
return $job->cancel("fresh discover cancelled: $device already known")
|
return $job->cancel("fresh discover cancelled: $device already known")
|
||||||
if $device->in_storage
|
if $device->in_storage
|
||||||
and ($job->subaction eq 'with-nodes' and not $job->username);
|
and ($job->subaction eq 'with-nodes' and not $job->username);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
|||||||
next unless ref {} eq ref $map;
|
next unless ref {} eq ref $map;
|
||||||
|
|
||||||
foreach my $key (sort keys %$map) {
|
foreach my $key (sort keys %$map) {
|
||||||
# lhs matches device, rhs matches device_ip
|
# lhs matches device, rhs matches device_ip
|
||||||
if (check_acl_only($device, $key)
|
if (check_acl_only($device, $key)
|
||||||
and check_acl_only($alias, $map->{$key})) {
|
and check_acl_only($alias, $map->{$key})) {
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} # ALIAS
|
} # ALIAS
|
||||||
}
|
}
|
||||||
|
|
||||||
return if $new_ip eq $old_ip;
|
return if $new_ip eq $old_ip;
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ sub store_neighbors {
|
|||||||
my @to_discover = ();
|
my @to_discover = ();
|
||||||
|
|
||||||
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
|
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
|
||||||
or return (); # already checked!
|
or return (); # already checked!
|
||||||
|
|
||||||
# first allow any manually configured topology to be set
|
# first allow any manually configured topology to be set
|
||||||
# and do this before we cache the rows in vars->{'device_ports'}
|
# and do this before we cache the rows in vars->{'device_ports'}
|
||||||
@@ -127,14 +127,14 @@ sub store_neighbors {
|
|||||||
{ map {($_->port => $_)} $device->ports->reset->all };
|
{ map {($_->port => $_)} $device->ports->reset->all };
|
||||||
my $device_ports = vars->{'device_ports'};
|
my $device_ports = vars->{'device_ports'};
|
||||||
|
|
||||||
# v4 and v6 neighbor tables
|
# v4 and v6 neighbor tables
|
||||||
my $c_ip = ($snmp->c_ip || {});
|
my $c_ip = ($snmp->c_ip || {});
|
||||||
my %c_ipv6 = %{ ($snmp->can('hasLLDP') and $snmp->hasLLDP)
|
my %c_ipv6 = %{ ($snmp->can('hasLLDP') and $snmp->hasLLDP)
|
||||||
? ($snmp->lldp_ipv6 || {}) : {} };
|
? ($snmp->lldp_ipv6 || {}) : {} };
|
||||||
|
|
||||||
# remove keys with undef values, as c_ip does
|
# remove keys with undef values, as c_ip does
|
||||||
delete @c_ipv6{ grep { not defined $c_ipv6{$_} } keys %c_ipv6 };
|
delete @c_ipv6{ grep { not defined $c_ipv6{$_} } keys %c_ipv6 };
|
||||||
# now combine them, v6 wins
|
# now combine them, v6 wins
|
||||||
$c_ip = { %$c_ip, %c_ipv6 };
|
$c_ip = { %$c_ip, %c_ipv6 };
|
||||||
|
|
||||||
foreach my $entry (sort (List::MoreUtils::uniq( keys %$c_ip ))) {
|
foreach my $entry (sort (List::MoreUtils::uniq( keys %$c_ip ))) {
|
||||||
|
|||||||
@@ -71,11 +71,11 @@ register_worker({ phase => 'early', driver => 'snmp' }, sub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# support for Hooks
|
# support for Hooks
|
||||||
vars->{'hook_data'} = { $device->get_columns };
|
vars->{'hook_data'} = { $device->get_columns };
|
||||||
delete vars->{'hook_data'}->{'snmp_comm'}; # for privacy
|
delete vars->{'hook_data'}->{'snmp_comm'}; # for privacy
|
||||||
|
|
||||||
# support for new_device Hook
|
# support for new_device Hook
|
||||||
vars->{'new_device'} = 1 if not $device->in_storage;
|
vars->{'new_device'} = 1 if not $device->in_storage;
|
||||||
|
|
||||||
schema('netdisco')->txn_do(sub {
|
schema('netdisco')->txn_do(sub {
|
||||||
@@ -156,7 +156,7 @@ register_worker({ phase => 'early', driver => 'snmp' }, sub {
|
|||||||
push @$resolved_aliases, { alias => $device->ip, dns => $device->dns }
|
push @$resolved_aliases, { alias => $device->ip, dns => $device->dns }
|
||||||
if 0 == scalar grep {$_->{alias} eq $device->ip} @aliases;
|
if 0 == scalar grep {$_->{alias} eq $device->ip} @aliases;
|
||||||
|
|
||||||
# support for Hooks
|
# support for Hooks
|
||||||
vars->{'hook_data'}->{'device_ips'} = $resolved_aliases;
|
vars->{'hook_data'}->{'device_ips'} = $resolved_aliases;
|
||||||
|
|
||||||
schema('netdisco')->txn_do(sub {
|
schema('netdisco')->txn_do(sub {
|
||||||
@@ -308,7 +308,7 @@ register_worker({ phase => 'early', driver => 'snmp' }, sub {
|
|||||||
$interfaces{$master}->{is_master} = 'true';
|
$interfaces{$master}->{is_master} = 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
# support for Hooks
|
# support for Hooks
|
||||||
vars->{'hook_data'}->{'ports'} = [values %interfaces];
|
vars->{'hook_data'}->{'ports'} = [values %interfaces];
|
||||||
|
|
||||||
schema('netdisco')->resultset('DevicePort')->txn_do_locked(sub {
|
schema('netdisco')->resultset('DevicePort')->txn_do_locked(sub {
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
# support for Hooks
|
# support for Hooks
|
||||||
vars->{'hook_data'}->{'vlans'} = \@devicevlans;
|
vars->{'hook_data'}->{'vlans'} = \@devicevlans;
|
||||||
|
|
||||||
schema('netdisco')->txn_do(sub {
|
schema('netdisco')->txn_do(sub {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ register_worker({ phase => 'main' }, sub {
|
|||||||
my $device = $job->device;
|
my $device = $job->device;
|
||||||
|
|
||||||
# if requested, and the device has not yet been
|
# if requested, and the device has not yet been
|
||||||
# arpniped/macsucked, queue those jobs now
|
# arpniped/macsucked, queue those jobs now
|
||||||
return unless $device->in_storage and $job->subaction eq 'with-nodes';
|
return unless $device->in_storage and $job->subaction eq 'with-nodes';
|
||||||
|
|
||||||
if (!defined $device->last_macsuck and $device->has_layer(2)) {
|
if (!defined $device->last_macsuck and $device->has_layer(2)) {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ register_worker({ phase => 'main' }, sub {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
# also have to clean up node_ip that have no correspoding node
|
# also have to clean up node_ip that have no correspoding node
|
||||||
schema('netdisco')->resultset('NodeIp')->search({
|
schema('netdisco')->resultset('NodeIp')->search({
|
||||||
mac => { -in => schema('netdisco')->resultset('NodeIp')->search(
|
mac => { -in => schema('netdisco')->resultset('NodeIp')->search(
|
||||||
{ port => undef },
|
{ port => undef },
|
||||||
@@ -82,7 +82,7 @@ register_worker({ phase => 'main' }, sub {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
# now update stats
|
# now update stats
|
||||||
update_stats();
|
update_stats();
|
||||||
|
|
||||||
return Status->done('Checked expiry and updated stats');
|
return Status->done('Checked expiry and updated stats');
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ register_worker({ phase => 'check' }, sub {
|
|||||||
return Status->info("macsuck skipped: $device is not macsuckable")
|
return Status->info("macsuck skipped: $device is not macsuckable")
|
||||||
unless is_macsuckable_now($device);
|
unless is_macsuckable_now($device);
|
||||||
|
|
||||||
# support for Hooks
|
# support for Hooks
|
||||||
vars->{'hook_data'} = { $device->get_columns };
|
vars->{'hook_data'} = { $device->get_columns };
|
||||||
delete vars->{'hook_data'}->{'snmp_comm'}; # for privacy
|
delete vars->{'hook_data'}->{'snmp_comm'}; # for privacy
|
||||||
|
|
||||||
return Status->done('Macsuck is able to run.');
|
return Status->done('Macsuck is able to run.');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ sub get_vlan_list {
|
|||||||
my $device = shift;
|
my $device = shift;
|
||||||
|
|
||||||
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
|
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
|
||||||
or return (); # already checked!
|
or return (); # already checked!
|
||||||
|
|
||||||
return () unless $snmp->cisco_comm_indexing;
|
return () unless $snmp->cisco_comm_indexing;
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ sub walk_fwtable {
|
|||||||
my $cache = {};
|
my $cache = {};
|
||||||
|
|
||||||
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
|
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
|
||||||
or return $cache; # already checked!
|
or return $cache; # already checked!
|
||||||
|
|
||||||
my $fw_mac = $snmp->fw_mac || {};
|
my $fw_mac = $snmp->fw_mac || {};
|
||||||
my $fw_port = $snmp->fw_port || {};
|
my $fw_port = $snmp->fw_port || {};
|
||||||
|
|||||||
@@ -156,8 +156,8 @@ C<rancid>. All keys are optional:
|
|||||||
rancid:
|
rancid:
|
||||||
rancid_cvsroot: '$ENV{NETDISCO_HOME}/rancid' # default
|
rancid_cvsroot: '$ENV{NETDISCO_HOME}/rancid' # default
|
||||||
rancid_conf: '/etc/rancid' # default
|
rancid_conf: '/etc/rancid' # default
|
||||||
down_age: '1 day' # default
|
down_age: '1 day' # default
|
||||||
delimiter: ';' # default
|
delimiter: ';' # default
|
||||||
default_group: 'default' # default
|
default_group: 'default' # default
|
||||||
groups:
|
groups:
|
||||||
groupname1: 'host_group1_acl'
|
groupname1: 'host_group1_acl'
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use namespace::clean;
|
|||||||
with 'App::Netdisco::Worker::Loader';
|
with 'App::Netdisco::Worker::Loader';
|
||||||
has 'job' => ( is => 'rw' );
|
has 'job' => ( is => 'rw' );
|
||||||
|
|
||||||
# mixin code to run workers loaded via plugins
|
# mixin code to run workers loaded via plugins
|
||||||
sub run {
|
sub run {
|
||||||
my ($self, $job) = @_;
|
my ($self, $job) = @_;
|
||||||
|
|
||||||
@@ -31,13 +31,13 @@ sub run {
|
|||||||
$job->device( get_device($job->device) );
|
$job->device( get_device($job->device) );
|
||||||
$self->load_workers();
|
$self->load_workers();
|
||||||
|
|
||||||
# finalise job status when we exit
|
# finalise job status when we exit
|
||||||
my $statusguard = guard { $job->finalise_status };
|
my $statusguard = guard { $job->finalise_status };
|
||||||
|
|
||||||
my @newuserconf = ();
|
my @newuserconf = ();
|
||||||
my @userconf = @{ dclone (setting('device_auth') || []) };
|
my @userconf = @{ dclone (setting('device_auth') || []) };
|
||||||
|
|
||||||
# reduce device_auth by only/no
|
# reduce device_auth by only/no
|
||||||
if (ref $job->device) {
|
if (ref $job->device) {
|
||||||
foreach my $stanza (@userconf) {
|
foreach my $stanza (@userconf) {
|
||||||
my $no = (exists $stanza->{no} ? $stanza->{no} : undef);
|
my $no = (exists $stanza->{no} ? $stanza->{no} : undef);
|
||||||
@@ -49,25 +49,25 @@ sub run {
|
|||||||
push @newuserconf, dclone $stanza;
|
push @newuserconf, dclone $stanza;
|
||||||
}
|
}
|
||||||
|
|
||||||
# per-device action but no device creds available
|
# per-device action but no device creds available
|
||||||
return $job->add_status( Status->defer('deferred job with no device creds') )
|
return $job->add_status( Status->defer('deferred job with no device creds') )
|
||||||
if 0 == scalar @newuserconf && $job->action ne "delete";
|
if 0 == scalar @newuserconf && $job->action ne "delete";
|
||||||
}
|
}
|
||||||
|
|
||||||
# back up and restore device_auth
|
# back up and restore device_auth
|
||||||
my $configguard = guard { set(device_auth => \@userconf) };
|
my $configguard = guard { set(device_auth => \@userconf) };
|
||||||
set(device_auth => \@newuserconf);
|
set(device_auth => \@newuserconf);
|
||||||
|
|
||||||
my $runner = sub {
|
my $runner = sub {
|
||||||
my ($self, $job) = @_;
|
my ($self, $job) = @_;
|
||||||
# roll everything back if we're testing
|
# roll everything back if we're testing
|
||||||
my $txn_guard = $ENV{ND2_DB_ROLLBACK}
|
my $txn_guard = $ENV{ND2_DB_ROLLBACK}
|
||||||
? schema('netdisco')->storage->txn_scope_guard : undef;
|
? schema('netdisco')->storage->txn_scope_guard : undef;
|
||||||
|
|
||||||
# run check phase and if there are workers then one MUST be successful
|
# run check phase and if there are workers then one MUST be successful
|
||||||
$self->run_workers('workers_check');
|
$self->run_workers('workers_check');
|
||||||
|
|
||||||
# run other phases
|
# run other phases
|
||||||
if ($job->check_passed) {
|
if ($job->check_passed) {
|
||||||
$self->run_workers("workers_${_}") for qw/early main user store late/;
|
$self->run_workers("workers_${_}") for qw/early main user store late/;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ workers:
|
|||||||
retry_after: '7 days'
|
retry_after: '7 days'
|
||||||
queue: PostgreSQL
|
queue: PostgreSQL
|
||||||
|
|
||||||
# 50 minutes
|
# 50 minutes
|
||||||
jobs_stale_after: 3000
|
jobs_stale_after: 3000
|
||||||
jobs_qdepth: 50
|
jobs_qdepth: 50
|
||||||
|
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ device_auth:
|
|||||||
#discover_phones: false
|
#discover_phones: false
|
||||||
|
|
||||||
# this is the schedule for automatically keeping netdisco up-to-date;
|
# this is the schedule for automatically keeping netdisco up-to-date;
|
||||||
# these are good defaults, so only uncomment if needing to change.
|
# these are good defaults, so only uncomment if needing to change.
|
||||||
# (or set "schedule: null" if you wish to disable the scheduler)
|
# (or set "schedule: null" if you wish to disable the scheduler)
|
||||||
# ````````````````````````````````````````````````````````````````````
|
# ````````````````````````````````````````````````````````````````````
|
||||||
#schedule:
|
#schedule:
|
||||||
# discoverall:
|
# discoverall:
|
||||||
|
|||||||
@@ -15,101 +15,101 @@ BEGIN {
|
|||||||
use Dancer qw/:script !pass/;
|
use Dancer qw/:script !pass/;
|
||||||
|
|
||||||
my @conf = (
|
my @conf = (
|
||||||
# +ve match -ve match
|
# +ve match -ve match
|
||||||
'localhost', '!www.example.com', # 0, 1
|
'localhost', '!www.example.com', # 0, 1
|
||||||
'127.0.0.1', '!192.0.2.1', # 2, 3
|
'127.0.0.1', '!192.0.2.1', # 2, 3
|
||||||
'::1', '!2001:db8::1', # 4, 5
|
'::1', '!2001:db8::1', # 4, 5
|
||||||
'127.0.0.0/29', '!192.0.2.0/24', # 6, 7
|
'127.0.0.0/29', '!192.0.2.0/24', # 6, 7
|
||||||
'::1/128', '!2001:db8::/32', # 8, 9
|
'::1/128', '!2001:db8::/32', # 8, 9
|
||||||
|
|
||||||
'127.0.0.1-10', '!192.0.2.1-10', # 10,11
|
'127.0.0.1-10', '!192.0.2.1-10', # 10,11
|
||||||
'::1-10', '!2001:db8::1-10', # 12,13
|
'::1-10', '!2001:db8::1-10', # 12,13
|
||||||
|
|
||||||
qr/^localhost$/, qr/^www.example.com$/, # 14,15
|
qr/^localhost$/, qr/^www.example.com$/, # 14,15
|
||||||
qr/(?!:www.example.com)/, '!127.0.0.0/29', # 16,17
|
qr/(?!:www.example.com)/, '!127.0.0.0/29', # 16,17
|
||||||
'!127.0.0.1-10', qr/(?!:localhost)/, # 18,19
|
'!127.0.0.1-10', qr/(?!:localhost)/, # 18,19
|
||||||
|
|
||||||
'op:and', # 20
|
'op:and', # 20
|
||||||
'group:groupreftest', # 21
|
'group:groupreftest', # 21
|
||||||
'!group:groupreftest', # 22
|
'!group:groupreftest', # 22
|
||||||
);
|
);
|
||||||
|
|
||||||
# name, ipv4, ipv6, v4 prefix, v6 prefix
|
# name, ipv4, ipv6, v4 prefix, v6 prefix
|
||||||
ok(check_acl('localhost',[$conf[0]]), 'same name');
|
ok(check_acl('localhost',[$conf[0]]), 'same name');
|
||||||
ok(check_acl('127.0.0.1',[$conf[2]]), 'same ipv4');
|
ok(check_acl('127.0.0.1',[$conf[2]]), 'same ipv4');
|
||||||
ok(check_acl('::1',[$conf[4]]), 'same ipv6');
|
ok(check_acl('::1',[$conf[4]]), 'same ipv6');
|
||||||
ok(check_acl('127.0.0.0/29',[$conf[6]]), 'same v4 prefix');
|
ok(check_acl('127.0.0.0/29',[$conf[6]]), 'same v4 prefix');
|
||||||
ok(check_acl('::1/128',[$conf[8]]), 'same v6 prefix');
|
ok(check_acl('::1/128',[$conf[8]]), 'same v6 prefix');
|
||||||
|
|
||||||
# failed name, ipv4, ipv6, v4 prefix, v6 prefix
|
# failed name, ipv4, ipv6, v4 prefix, v6 prefix
|
||||||
is(check_acl('www.microsoft.com',[$conf[0]]), 0, 'failed name');
|
is(check_acl('www.microsoft.com',[$conf[0]]), 0, 'failed name');
|
||||||
is(check_acl('172.20.0.1',[$conf[2]]), 0, 'failed ipv4');
|
is(check_acl('172.20.0.1',[$conf[2]]), 0, 'failed ipv4');
|
||||||
is(check_acl('2001:db8::5',[$conf[4]]), 0, 'failed ipv6');
|
is(check_acl('2001:db8::5',[$conf[4]]), 0, 'failed ipv6');
|
||||||
is(check_acl('172.16.1.3/29',[$conf[6]]), 0, 'failed v4 prefix');
|
is(check_acl('172.16.1.3/29',[$conf[6]]), 0, 'failed v4 prefix');
|
||||||
is(check_acl('2001:db8:f00d::/64',[$conf[8]]), 0, 'failed v6 prefix');
|
is(check_acl('2001:db8:f00d::/64',[$conf[8]]), 0, 'failed v6 prefix');
|
||||||
|
|
||||||
# negated name, ipv4, ipv6, v4 prefix, v6 prefix
|
# negated name, ipv4, ipv6, v4 prefix, v6 prefix
|
||||||
ok(check_acl('localhost',[$conf[1]]), 'not same name');
|
ok(check_acl('localhost',[$conf[1]]), 'not same name');
|
||||||
ok(check_acl('127.0.0.1',[$conf[3]]), 'not same ipv4');
|
ok(check_acl('127.0.0.1',[$conf[3]]), 'not same ipv4');
|
||||||
ok(check_acl('::1',[$conf[5]]), 'not same ipv6');
|
ok(check_acl('::1',[$conf[5]]), 'not same ipv6');
|
||||||
ok(check_acl('127.0.0.0/29',[$conf[7]]), 'not same v4 prefix');
|
ok(check_acl('127.0.0.0/29',[$conf[7]]), 'not same v4 prefix');
|
||||||
ok(check_acl('::1/128',[$conf[9]]), 'not same v6 prefix');
|
ok(check_acl('::1/128',[$conf[9]]), 'not same v6 prefix');
|
||||||
|
|
||||||
# v4 range, v6 range
|
# v4 range, v6 range
|
||||||
ok(check_acl('127.0.0.1',[$conf[10]]), 'in v4 range');
|
ok(check_acl('127.0.0.1',[$conf[10]]), 'in v4 range');
|
||||||
ok(check_acl('::1',[$conf[12]]), 'in v6 range');
|
ok(check_acl('::1',[$conf[12]]), 'in v6 range');
|
||||||
|
|
||||||
# failed v4 range, v6 range
|
# failed v4 range, v6 range
|
||||||
is(check_acl('172.20.0.1',[$conf[10]]), 0, 'failed v4 range');
|
is(check_acl('172.20.0.1',[$conf[10]]), 0, 'failed v4 range');
|
||||||
is(check_acl('2001:db8::5',[$conf[12]]), 0, 'failed v6 range');
|
is(check_acl('2001:db8::5',[$conf[12]]), 0, 'failed v6 range');
|
||||||
|
|
||||||
# negated v4 range, v6 range
|
# negated v4 range, v6 range
|
||||||
ok(check_acl('127.0.0.1',[$conf[11]]), 'not in v4 range');
|
ok(check_acl('127.0.0.1',[$conf[11]]), 'not in v4 range');
|
||||||
ok(check_acl('::1',[$conf[13]]), 'not in v6 range');
|
ok(check_acl('::1',[$conf[13]]), 'not in v6 range');
|
||||||
|
|
||||||
# hostname regexp
|
# hostname regexp
|
||||||
# FIXME ok(check_acl('localhost',[$conf[14]]), 'name regexp');
|
# FIXME ok(check_acl('localhost',[$conf[14]]), 'name regexp');
|
||||||
# FIXME ok(check_acl('127.0.0.1',[$conf[14]]), 'IP regexp');
|
# FIXME ok(check_acl('127.0.0.1',[$conf[14]]), 'IP regexp');
|
||||||
is(check_acl('www.google.com',[$conf[14]]), 0, 'failed regexp');
|
is(check_acl('www.google.com',[$conf[14]]), 0, 'failed regexp');
|
||||||
|
|
||||||
# OR of prefix, range, regexp, property (2 of, 3 of, 4 of)
|
# OR of prefix, range, regexp, property (2 of, 3 of, 4 of)
|
||||||
ok(check_acl('127.0.0.1',[@conf[8,0]]), 'OR: prefix, name');
|
ok(check_acl('127.0.0.1',[@conf[8,0]]), 'OR: prefix, name');
|
||||||
ok(check_acl('127.0.0.1',[@conf[8,12,0]]), 'OR: prefix, range, name');
|
ok(check_acl('127.0.0.1',[@conf[8,12,0]]), 'OR: prefix, range, name');
|
||||||
ok(check_acl('127.0.0.1',[@conf[8,12,15,0]]), 'OR: prefix, range, regexp, name');
|
ok(check_acl('127.0.0.1',[@conf[8,12,15,0]]), 'OR: prefix, range, regexp, name');
|
||||||
|
|
||||||
# OR of negated prefix, range, regexp, property (2 of, 3 of, 4 of)
|
# OR of negated prefix, range, regexp, property (2 of, 3 of, 4 of)
|
||||||
ok(check_acl('127.0.0.1',[@conf[17,0]]), 'OR: !prefix, name');
|
ok(check_acl('127.0.0.1',[@conf[17,0]]), 'OR: !prefix, name');
|
||||||
ok(check_acl('127.0.0.1',[@conf[17,18,0]]), 'OR: !prefix, !range, name');
|
ok(check_acl('127.0.0.1',[@conf[17,18,0]]), 'OR: !prefix, !range, name');
|
||||||
ok(check_acl('127.0.0.1',[@conf[17,18,19,0]]), 'OR: !prefix, !range, !regexp, name');
|
ok(check_acl('127.0.0.1',[@conf[17,18,19,0]]), 'OR: !prefix, !range, !regexp, name');
|
||||||
|
|
||||||
# AND of prefix, range, regexp, property (2 of, 3 of, 4 of)
|
# AND of prefix, range, regexp, property (2 of, 3 of, 4 of)
|
||||||
ok(check_acl('127.0.0.1',[@conf[6,0,20]]), 'AND: prefix, name');
|
ok(check_acl('127.0.0.1',[@conf[6,0,20]]), 'AND: prefix, name');
|
||||||
ok(check_acl('127.0.0.1',[@conf[6,10,0,20]]), 'AND: prefix, range, name');
|
ok(check_acl('127.0.0.1',[@conf[6,10,0,20]]), 'AND: prefix, range, name');
|
||||||
# FIXME ok(check_acl('127.0.0.1',[@conf[6,10,14,0,20]]), 'AND: prefix, range, regexp, name');
|
# FIXME ok(check_acl('127.0.0.1',[@conf[6,10,14,0,20]]), 'AND: prefix, range, regexp, name');
|
||||||
|
|
||||||
# failed AND on prefix, range, regexp
|
# failed AND on prefix, range, regexp
|
||||||
is(check_acl('127.0.0.1',[@conf[8,10,14,0,20]]), 0, 'failed AND: prefix!, range, regexp, name');
|
is(check_acl('127.0.0.1',[@conf[8,10,14,0,20]]), 0, 'failed AND: prefix!, range, regexp, name');
|
||||||
is(check_acl('127.0.0.1',[@conf[6,12,14,0,20]]), 0, 'failed AND: prefix, range!, regexp, name');
|
is(check_acl('127.0.0.1',[@conf[6,12,14,0,20]]), 0, 'failed AND: prefix, range!, regexp, name');
|
||||||
is(check_acl('127.0.0.1',[@conf[6,10,15,0,20]]), 0, 'failed AND: prefix, range, regexp!, name');
|
is(check_acl('127.0.0.1',[@conf[6,10,15,0,20]]), 0, 'failed AND: prefix, range, regexp!, name');
|
||||||
|
|
||||||
# AND of negated prefix, range, regexp, property (2 of, 3 of, 4 of)
|
# AND of negated prefix, range, regexp, property (2 of, 3 of, 4 of)
|
||||||
ok(check_acl('127.0.0.1',[@conf[9,0,20]]), 'AND: !prefix, name');
|
ok(check_acl('127.0.0.1',[@conf[9,0,20]]), 'AND: !prefix, name');
|
||||||
ok(check_acl('127.0.0.1',[@conf[7,11,0,20]]), 'AND: !prefix, !range, name');
|
ok(check_acl('127.0.0.1',[@conf[7,11,0,20]]), 'AND: !prefix, !range, name');
|
||||||
ok(check_acl('127.0.0.1',[@conf[9,13,16,0,20]]), 'AND: !prefix, !range, !regexp, name');
|
ok(check_acl('127.0.0.1',[@conf[9,13,16,0,20]]), 'AND: !prefix, !range, !regexp, name');
|
||||||
|
|
||||||
# group ref
|
# group ref
|
||||||
is(check_acl('192.0.2.1',[$conf[22]]), 1, '!missing group ref');
|
is(check_acl('192.0.2.1',[$conf[22]]), 1, '!missing group ref');
|
||||||
is(check_acl('192.0.2.1',[$conf[21]]), 0, 'failed missing group ref');
|
is(check_acl('192.0.2.1',[$conf[21]]), 0, 'failed missing group ref');
|
||||||
setting('host_groups')->{'groupreftest'} = ['192.0.2.1'];
|
setting('host_groups')->{'groupreftest'} = ['192.0.2.1'];
|
||||||
is(check_acl('192.0.2.1',[$conf[21]]), 1, 'group ref');
|
is(check_acl('192.0.2.1',[$conf[21]]), 1, 'group ref');
|
||||||
is(check_acl('192.0.2.1',[$conf[22]]), 0, 'failed !missing group ref');
|
is(check_acl('192.0.2.1',[$conf[22]]), 0, 'failed !missing group ref');
|
||||||
|
|
||||||
# scalar promoted to list
|
# scalar promoted to list
|
||||||
ok(check_acl('localhost',$conf[0]), 'scalar promoted');
|
ok(check_acl('localhost',$conf[0]), 'scalar promoted');
|
||||||
ok(check_acl('localhost',$conf[1]), 'not scalar promoted');
|
ok(check_acl('localhost',$conf[1]), 'not scalar promoted');
|
||||||
is(check_acl('www.microsoft.com',$conf[0]), 0, 'failed scalar promoted');
|
is(check_acl('www.microsoft.com',$conf[0]), 0, 'failed scalar promoted');
|
||||||
|
|
||||||
# device property
|
# device property
|
||||||
# negated device property
|
# negated device property
|
||||||
|
|
||||||
done_testing;
|
done_testing;
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ Dancer::Logger->init('console', $CONFIG);
|
|||||||
with 'App::Netdisco::Worker::Runner';
|
with 'App::Netdisco::Worker::Runner';
|
||||||
}
|
}
|
||||||
|
|
||||||
# clear user device_auth and set our own
|
# clear user device_auth and set our own
|
||||||
config->{'device_auth'} = [{driver => 'snmp'}, {driver => 'cli'}];
|
config->{'device_auth'} = [{driver => 'snmp'}, {driver => 'cli'}];
|
||||||
|
|
||||||
# TESTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# TESTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
my $j1 = do_job('TestOne');
|
my $j1 = do_job('TestOne');
|
||||||
is($j1->status, 'done', 'status is done');
|
is($j1->status, 'done', 'status is done');
|
||||||
@@ -95,12 +95,12 @@ is($j8->log, 'OK: SNMP driver is successful.',
|
|||||||
|
|
||||||
done_testing;
|
done_testing;
|
||||||
|
|
||||||
# TESTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# TESTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
sub do_job {
|
sub do_job {
|
||||||
my $pkg = shift;
|
my $pkg = shift;
|
||||||
|
|
||||||
# include local plugins
|
# include local plugins
|
||||||
config->{'extra_worker_plugins'} = ["X::${pkg}"];
|
config->{'extra_worker_plugins'} = ["X::${pkg}"];
|
||||||
|
|
||||||
my $job = App::Netdisco::Backend::Job->new({
|
my $job = App::Netdisco::Backend::Job->new({
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use Dancer ':syntax';
|
|||||||
use App::Netdisco::Worker::Plugin;
|
use App::Netdisco::Worker::Plugin;
|
||||||
use aliased 'App::Netdisco::Worker::Status';
|
use aliased 'App::Netdisco::Worker::Status';
|
||||||
|
|
||||||
# info 'test: add to an action';
|
# info 'test: add to an action';
|
||||||
|
|
||||||
register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
||||||
return Status->error('NOT OK: additional worker at SNMP level.');
|
return Status->error('NOT OK: additional worker at SNMP level.');
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use Dancer ':syntax';
|
|||||||
use App::Netdisco::Worker::Plugin;
|
use App::Netdisco::Worker::Plugin;
|
||||||
use aliased 'App::Netdisco::Worker::Status';
|
use aliased 'App::Netdisco::Worker::Status';
|
||||||
|
|
||||||
# info 'test: override an action';
|
# info 'test: override an action';
|
||||||
|
|
||||||
register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
||||||
return Status->done('NOT OK: SNMP driver should NOT be run.');
|
return Status->done('NOT OK: SNMP driver should NOT be run.');
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use Dancer ':syntax';
|
|||||||
use App::Netdisco::Worker::Plugin;
|
use App::Netdisco::Worker::Plugin;
|
||||||
use aliased 'App::Netdisco::Worker::Status';
|
use aliased 'App::Netdisco::Worker::Status';
|
||||||
|
|
||||||
# info 'test: workers are run in decreasing priority until done';
|
# info 'test: workers are run in decreasing priority until done';
|
||||||
|
|
||||||
register_worker({ phase => 'main', driver => 'cli' }, sub {
|
register_worker({ phase => 'main', driver => 'cli' }, sub {
|
||||||
return Status->noop('NOT OK: CLI driver is not the winner here.');
|
return Status->noop('NOT OK: CLI driver is not the winner here.');
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use Dancer ':syntax';
|
|||||||
use App::Netdisco::Worker::Plugin;
|
use App::Netdisco::Worker::Plugin;
|
||||||
use aliased 'App::Netdisco::Worker::Status';
|
use aliased 'App::Netdisco::Worker::Status';
|
||||||
|
|
||||||
# info 'test: respect user config filtering the driver, action and namespace';
|
# info 'test: respect user config filtering the driver, action and namespace';
|
||||||
|
|
||||||
register_worker({ phase => 'main', driver => 'cli' }, sub {
|
register_worker({ phase => 'main', driver => 'cli' }, sub {
|
||||||
return Status->done('NOT OK: CLI driver should NOT be run.');
|
return Status->done('NOT OK: CLI driver should NOT be run.');
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use Dancer ':syntax';
|
|||||||
use App::Netdisco::Worker::Plugin;
|
use App::Netdisco::Worker::Plugin;
|
||||||
use aliased 'App::Netdisco::Worker::Status';
|
use aliased 'App::Netdisco::Worker::Status';
|
||||||
|
|
||||||
# info 'test: lower priority driver not run if higher is successful';
|
# info 'test: lower priority driver not run if higher is successful';
|
||||||
|
|
||||||
register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
||||||
return Status->done('NOT OK: SNMP driver should NOT be run.');
|
return Status->done('NOT OK: SNMP driver should NOT be run.');
|
||||||
|
|||||||
Reference in New Issue
Block a user