diff --git a/lib/App/Netdisco/Backend/Worker/Poller/Nbtstat.pm b/lib/App/Netdisco/Backend/Worker/Poller/Nbtstat.pm deleted file mode 100644 index 72c7c9ef..00000000 --- a/lib/App/Netdisco/Backend/Worker/Poller/Nbtstat.pm +++ /dev/null @@ -1,73 +0,0 @@ -package App::Netdisco::Backend::Worker::Poller::Nbtstat; - -use Dancer qw/:moose :syntax :script/; -use Dancer::Plugin::DBIC 'schema'; - -use App::Netdisco::Core::Nbtstat qw/nbtstat_resolve_async store_nbt/; -use App::Netdisco::Util::Node 'is_nbtstatable'; -use App::Netdisco::Util::Device qw/get_device is_macsuckable/; -use App::Netdisco::Backend::Util ':all'; - -use NetAddr::IP::Lite ':lower'; -use Time::HiRes 'gettimeofday'; - -use Role::Tiny; -use namespace::clean; - -with 'App::Netdisco::Backend::Worker::Poller::Common'; - -sub nbtstat_action { \&do_nbtstat } -sub nbtstat_filter { \&is_nbtstatable } -sub nbtstat_layer { 2 } - -sub nbtwalk { (shift)->_walk_body('nbtstat', @_) } - -sub nbtstat { - my ($self, $job) = @_; - - my $device = get_device($job->device) - or job_error("nbtstat failed: unable to interpret device parameter"); - my $host = $device->ip; - - unless (is_macsuckable($device)) { - return job_defer("nbtstat deferred: $host is not macsuckable"); - } - - # get list of nodes on device - my $interval = (setting('nbtstat_max_age') || 7) . ' day'; - my $rs = schema('netdisco')->resultset('NodeIp')->search({ - -bool => 'me.active', - -bool => 'nodes.active', - 'nodes.switch' => $device->ip, - 'me.time_last' => \[ '>= now() - ?::interval', $interval ], - },{ - join => 'nodes', - columns => 'ip', - distinct => 1, - })->ip_version(4); - - my @nodes = $rs->get_column('ip')->all; - - # Unless we have IP's don't bother - if (scalar @nodes) { - # filter exclusions from config - @nodes = grep { is_nbtstatable( $_ ) } @nodes; - - # setup the hash nbtstat_resolve_async expects - my @ips = map {+{'ip' => $_}} @nodes; - my $now = 'to_timestamp('. (join '.', gettimeofday) .')'; - - my $resolved_nodes = nbtstat_resolve_async(\@ips); - - # update node_nbt with status entries - foreach my $result (@$resolved_nodes) { - if (defined $result->{'nbname'}) { - store_nbt($result, $now); - } - } - } - - return job_done("Ended nbtstat for $host"); -} - -1; diff --git a/lib/App/Netdisco/Core/Nbtstat.pm b/lib/App/Netdisco/Util/Nbtstat.pm similarity index 91% rename from lib/App/Netdisco/Core/Nbtstat.pm rename to lib/App/Netdisco/Util/Nbtstat.pm index 4c66b1cf..c12efc56 100644 --- a/lib/App/Netdisco/Core/Nbtstat.pm +++ b/lib/App/Netdisco/Util/Nbtstat.pm @@ -1,10 +1,9 @@ -package App::Netdisco::Core::Nbtstat; +package App::Netdisco::Util::Nbtstat; use Dancer qw/:syntax :script/; use Dancer::Plugin::DBIC 'schema'; use App::Netdisco::Util::Node 'check_mac'; -use NetAddr::IP::Lite ':lower'; use App::Netdisco::AnyEvent::Nbtstat; use Encode; @@ -15,7 +14,7 @@ our %EXPORT_TAGS = (all => \@EXPORT_OK); =head1 NAME -App::Netdisco::Core::Nbtstat +App::Netdisco::Util::Nbtstat =head1 DESCRIPTION @@ -130,12 +129,12 @@ sub _filter_nbname { $mac = $node_ip->mac; } - $hash_ref->{'ip'} = $ip; - $hash_ref->{'mac'} = $mac; - $hash_ref->{'nbname'} = Encode::decode('UTF-8', $nbname); - $hash_ref->{'domain'} = Encode::decode('UTF-8', $domain); - $hash_ref->{'server'} = $server; - $hash_ref->{'nbuser'} = Encode::decode('UTF-8', $nbuser); + $hash_ref->{'ip'} = $ip; + $hash_ref->{'mac'} = $mac; + $hash_ref->{'nbname'} = Encode::decode('UTF-8', $nbname); + $hash_ref->{'domain'} = Encode::decode('UTF-8', $domain); + $hash_ref->{'server'} = $server; + $hash_ref->{'nbuser'} = Encode::decode('UTF-8', $nbuser); return; } diff --git a/lib/App/Netdisco/Worker/Plugin/Nbtstat.pm b/lib/App/Netdisco/Worker/Plugin/Nbtstat.pm new file mode 100644 index 00000000..3bb79a5b --- /dev/null +++ b/lib/App/Netdisco/Worker/Plugin/Nbtstat.pm @@ -0,0 +1,21 @@ +package App::Netdisco::Worker::Plugin::Nbtstat; + +use Dancer ':syntax'; +use App::Netdisco::Worker::Plugin; +use aliased 'App::Netdisco::Worker::Status'; + +use App::Netdisco::Util::Device 'is_macsuckable'; + +register_worker({ primary => true }, sub { + my ($job, $workerconf) = @_; + + return Status->error('nbtstat failed: unable to interpret device param') + if !defined $job->device; + + return Status->defer(sprintf 'nbtstat deferred: %s is not macsuckable', $job->device->ip) + unless is_macsuckable($job->device); + + return Status->done('Nbtstat is able to run.'); +}); + +true; diff --git a/lib/App/Netdisco/Worker/Plugin/Nbtstat/Core.pm b/lib/App/Netdisco/Worker/Plugin/Nbtstat/Core.pm new file mode 100644 index 00000000..e47ef8da --- /dev/null +++ b/lib/App/Netdisco/Worker/Plugin/Nbtstat/Core.pm @@ -0,0 +1,50 @@ +package App::Netdisco::Worker::Plugin::Nbtstat::Core; + +use Dancer ':syntax'; +use App::Netdisco::Worker::Plugin; +use aliased 'App::Netdisco::Worker::Status'; + +use App::Netdisco::Util::Nbtstat qw/nbtstat_resolve_async store_nbt/; +use App::Netdisco::Util::Node 'is_nbtstatable'; +use Dancer::Plugin::DBIC 'schema'; +use Time::HiRes 'gettimeofday'; + +register_worker({ primary => true }, sub { + my ($job, $workerconf) = @_; + my $host = $job->device->ip; + + # get list of nodes on device + my $interval = (setting('nbtstat_max_age') || 7) . ' day'; + my $rs = schema('netdisco')->resultset('NodeIp')->search({ + -bool => 'me.active', + -bool => 'nodes.active', + 'nodes.switch' => $host, + 'me.time_last' => \[ '>= now() - ?::interval', $interval ], + },{ + join => 'nodes', + columns => 'ip', + distinct => 1, + })->ip_version(4); + + my @ips = map {+{'ip' => $_}} + grep { is_nbtstatable( $_ ) } + $rs->get_column('ip')->all; + + # Unless we have IPs don't bother + if (scalar @ips) { + my $now = 'to_timestamp('. (join '.', gettimeofday) .')'; + my $resolved_nodes = nbtstat_resolve_async(\@ips); + + # update node_nbt with status entries + foreach my $result (@$resolved_nodes) { + if (defined $result->{'nbname'}) { + store_nbt($result, $now); + } + } + } + + return Status->done("Ended nbtstat for $host"); +}); + +true; + diff --git a/lib/App/Netdisco/Worker/Plugin/Nbtwalk.pm b/lib/App/Netdisco/Worker/Plugin/Nbtwalk.pm new file mode 100644 index 00000000..60463363 --- /dev/null +++ b/lib/App/Netdisco/Worker/Plugin/Nbtwalk.pm @@ -0,0 +1,31 @@ +package App::Netdisco::Worker::Plugin::Nbtwalk; + +use Dancer ':syntax'; +use App::Netdisco::Worker::Plugin; +use aliased 'App::Netdisco::Worker::Status'; + +use App::Netdisco::JobQueue qw/jq_queued jq_insert/; +use Dancer::Plugin::DBIC 'schema'; + +register_worker({ primary => true }, sub { + my ($job, $workerconf) = @_; + + my %queued = map {$_ => 1} jq_queued('nbtstat'); + my @devices = schema('netdisco')->resultset('Device')->search({ + -or => [ 'vendor' => undef, 'vendor' => { '!=' => 'netdisco' }], + })->has_layer('2')->get_column('ip')->all; + my @filtered_devices = grep {!exists $queued{$_}} @devices; + + jq_insert([ + map {{ + device => $_, + action => 'nbtstat', + username => $job->username, + userip => $job->userip, + }} (@filtered_devices) + ]); + + return Status->done('Queued nbtstat job for all devices'); +}); + +true; diff --git a/lib/App/Netdisco/Worker/Plugin/Test.pm b/lib/App/Netdisco/Worker/Plugin/Test.pm new file mode 100644 index 00000000..8b9c0ba5 --- /dev/null +++ b/lib/App/Netdisco/Worker/Plugin/Test.pm @@ -0,0 +1,19 @@ +package App::Netdisco::Worker::Plugin::Test; + +use Dancer ':syntax'; +use App::Netdisco::Worker::Plugin; +use aliased 'App::Netdisco::Worker::Status'; + +register_worker({ primary => true }, sub { + my ($job, $workerconf) = @_; + debug 'Test (primary) ran successfully.'; + return Status->done('Test (primary) ran successfully.'); +}); + +register_worker({ primary => false }, sub { + my ($job, $workerconf) = @_; + debug 'Test ran successfully.'; + return Status->done('Test ran successfully.'); +}); + +true; diff --git a/share/config.yml b/share/config.yml index 30f259f2..0892751c 100644 --- a/share/config.yml +++ b/share/config.yml @@ -278,7 +278,9 @@ worker_plugins: - Arpnip::Nodes::CLI - Arpnip::Nodes::RFC - Arpnip::Subnets::RFC - - NetBIOS::Nbtstat::RFC + - Nbtwalk + - Nbtstat + - Nbtstat::Core - Graph - Stats - Monitor @@ -286,6 +288,7 @@ worker_plugins: - Show - Psql - Renumber + - Test # --------------- # GraphViz Export