diff --git a/Netdisco/Changes b/Netdisco/Changes index 18fa7bf8..03a6a517 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -4,6 +4,7 @@ * Display port descriptions in topology editing form * Support store_modules config (default true) + * Support for discover_min_age 2.013001 - 2013-08-23 diff --git a/Netdisco/Makefile.PL b/Netdisco/Makefile.PL index e38097da..3e84d52e 100644 --- a/Netdisco/Makefile.PL +++ b/Netdisco/Makefile.PL @@ -23,6 +23,7 @@ requires 'List::MoreUtils' => 0.33; requires 'MIME::Base64' => 3.13; requires 'Moo' => 1.001000; requires 'MCE' => 1.408; +requires 'Net::Domain' => 1.23; requires 'Net::DNS' => 0.72; requires 'Net::MAC' => 2.103622; requires 'NetAddr::IP' => 4.068; diff --git a/Netdisco/lib/App/Netdisco/DB/Result/Device.pm b/Netdisco/lib/App/Netdisco/DB/Result/Device.pm index 1ae4b7b0..1d83f3d8 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/Device.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/Device.pm @@ -250,4 +250,28 @@ between the date stamp and time stamp. That is: sub last_arpnip_stamp { return (shift)->get_column('last_arpnip_stamp') } +=head2 since_last_discover + +Number of seconds which have elapsed since the value of C. + +=cut + +sub since_last_discover { return (shift)->get_column('since_last_discover') } + +=head2 since_last_macsuck + +Number of seconds which have elapsed since the value of C. + +=cut + +sub since_last_macsuck { return (shift)->get_column('since_last_macsuck') } + +=head2 since_last_arpnip + +Number of seconds which have elapsed since the value of C. + +=cut + +sub since_last_arpnip { return (shift)->get_column('since_last_arpnip') } + 1; diff --git a/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm b/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm index 2f8066e3..7be1cc07 100644 --- a/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm +++ b/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm @@ -37,8 +37,11 @@ sub with_times { uptime_age => \("replace(age(timestamp 'epoch' + uptime / 100 * interval '1 second', " ."timestamp '1970-01-01 00:00:00-00')::text, 'mon', 'month')"), last_discover_stamp => \"to_char(last_discover, 'YYYY-MM-DD HH24:MI')", - last_macsuck_stamp => \"to_char(last_macsuck, 'YYYY-MM-DD HH24:MI')", - last_arpnip_stamp => \"to_char(last_arpnip, 'YYYY-MM-DD HH24:MI')", + last_macsuck_stamp => \"to_char(last_macsuck, 'YYYY-MM-DD HH24:MI')", + last_arpnip_stamp => \"to_char(last_arpnip, 'YYYY-MM-DD HH24:MI')", + since_last_discover => \"extract(epoch from (age(now(), last_discover)))", + since_last_macsuck => \"extract(epoch from (age(now(), last_macsuck)))", + since_last_arpnip => \"extract(epoch from (age(now(), last_arpnip)))", }, }); } diff --git a/Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm b/Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm index 139611b9..047196f2 100644 --- a/Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm +++ b/Netdisco/lib/App/Netdisco/Daemon/Worker/Manager.pm @@ -3,7 +3,6 @@ package App::Netdisco::Daemon::Worker::Manager; use Dancer qw/:moose :syntax :script/; use Dancer::Plugin::DBIC 'schema'; -use App::Netdisco::Util::Device 'is_discoverable'; use Net::Domain 'hostfqdn'; use Try::Tiny; @@ -57,10 +56,6 @@ sub worker_body { while (my $job = $rs->next) { my $jid = $job->job; - # filter for discover_* - next unless is_discoverable($job->device); - debug sprintf "mgr (%s): job %s is discoverable", $wid, $jid; - # check for available local capacity next unless $self->do('capacity_for', $job->action); debug sprintf "mgr (%s): processing node has capacity for job %s (%s)", diff --git a/Netdisco/lib/App/Netdisco/Daemon/Worker/Poller/Device.pm b/Netdisco/lib/App/Netdisco/Daemon/Worker/Poller/Device.pm index bfd96ee3..999b24d4 100644 --- a/Netdisco/lib/App/Netdisco/Daemon/Worker/Poller/Device.pm +++ b/Netdisco/lib/App/Netdisco/Daemon/Worker/Poller/Device.pm @@ -4,7 +4,7 @@ use Dancer qw/:moose :syntax :script/; use Dancer::Plugin::DBIC 'schema'; use App::Netdisco::Util::SNMP 'snmp_connect'; -use App::Netdisco::Util::Device 'get_device'; +use App::Netdisco::Util::Device qw/get_device is_discoverable/; use App::Netdisco::Core::Discover ':all'; use App::Netdisco::Daemon::Util ':all'; @@ -59,7 +59,11 @@ sub discover { if ($device->in_storage and $device->vendor and $device->vendor eq 'netdisco') { - return job_done("Skipped discover for pseudo-device $host"); + return job_done("discover skipped: $host is pseudo-device"); + } + + unless (is_discoverable($device->ip)) { + return job_defer("discover deferred: $host is not discoverable"); } my $snmp = snmp_connect($device); diff --git a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod index 58a52b56..9b0b1c61 100644 --- a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod +++ b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod @@ -305,6 +305,13 @@ but don't talk SNMP. For example: - 'cisco\s+AIR-LAP' - '(?i)Cisco\s+IP\s+Phone' +=head3 C + +Value: Number. Default: 0. + +Sets the minimum amount of time in seconds which must elapse between any two +discover jobs for a device. + =head3 C Value: Boolean. Default: C. @@ -590,10 +597,6 @@ C =item * -C - -=item * - C =item * diff --git a/Netdisco/lib/App/Netdisco/Util/Device.pm b/Netdisco/lib/App/Netdisco/Util/Device.pm index cc30d221..52b3630b 100644 --- a/Netdisco/lib/App/Netdisco/Util/Device.pm +++ b/Netdisco/lib/App/Netdisco/Util/Device.pm @@ -52,7 +52,7 @@ sub get_device { ->search({alias => $ip})->first; $ip = $alias->ip if defined $alias; - return schema('netdisco')->resultset('Device') + return schema('netdisco')->resultset('Device')->with_times ->find_or_new({ip => $ip}); } @@ -71,13 +71,15 @@ Returns false if the host is not permitted to discover the target device. =cut +sub _bail_msg { debug $_[0]; return 0; } + sub is_discoverable { my ($ip, $remote_type) = @_; my $device = get_device($ip) or return 0; if ($remote_type) { - return 0 if - scalar grep {$remote_type =~ m/$_/} + return _bail_msg("is_discoverable: device matched discover_no_type") + if scalar grep {$remote_type =~ m/$_/} @{setting('discover_no_type') || []}; } @@ -88,7 +90,8 @@ sub is_discoverable { if (scalar @$discover_no) { foreach my $item (@$discover_no) { my $ip = NetAddr::IP::Lite->new($item) or return 0; - return 0 if $ip->contains($addr); + return _bail_msg("is_discoverable: device matched discover_no") + if $ip->contains($addr); } } @@ -98,7 +101,16 @@ sub is_discoverable { my $ip = NetAddr::IP::Lite->new($item) or return 0; ++$okay if $ip->contains($addr); } - return 0 if not $okay; + return _bail_msg("is_discoverable: device failed to match discover_only") + if not $okay; + } + + my $discover_since = setting('discover_min_age') || 0; + + if ($device->since_last_discover + and $device->since_last_discover < $discover_since) { + + return _bail_msg("is_discoverable: last discovered less than discover_min_age"); } return 1;