refactor nbtstat to group probes by device
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
* Run daemons as target binary's owning user (supports run control)
|
* Run daemons as target binary's owning user (supports run control)
|
||||||
* Clean up library path fiddling across all scripts
|
* Clean up library path fiddling across all scripts
|
||||||
* Rename housekeeping expiry task to be expire
|
* Rename housekeeping expiry task to be expire
|
||||||
|
* Refactor nbtstat to group probes by device where node was arped
|
||||||
|
|
||||||
[BUG FIXES]
|
[BUG FIXES]
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ use Dancer::Plugin::DBIC 'schema';
|
|||||||
|
|
||||||
use App::Netdisco::Util::Node 'check_mac';
|
use App::Netdisco::Util::Node 'check_mac';
|
||||||
use NetAddr::IP::Lite ':lower';
|
use NetAddr::IP::Lite ':lower';
|
||||||
use Time::HiRes 'gettimeofday';
|
|
||||||
use Net::NBName;
|
use Net::NBName;
|
||||||
|
|
||||||
use base 'Exporter';
|
use base 'Exporter';
|
||||||
@@ -36,8 +35,7 @@ Returns whether a node is answering netbios calls or not.
|
|||||||
=cut
|
=cut
|
||||||
|
|
||||||
sub do_nbtstat {
|
sub do_nbtstat {
|
||||||
my $host = shift;
|
my ($host, $now) = @_;
|
||||||
|
|
||||||
my $ip = NetAddr::IP::Lite->new($host) or return;
|
my $ip = NetAddr::IP::Lite->new($host) or return;
|
||||||
|
|
||||||
unless ( $ip->version() == 4 ) {
|
unless ( $ip->version() == 4 ) {
|
||||||
@@ -46,7 +44,6 @@ sub do_nbtstat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $nb = Net::NBName->new;
|
my $nb = Net::NBName->new;
|
||||||
|
|
||||||
my $ns = $nb->node_status( $ip->addr );
|
my $ns = $nb->node_status( $ip->addr );
|
||||||
|
|
||||||
# Check for NetBIOS Info
|
# Check for NetBIOS Info
|
||||||
@@ -55,7 +52,7 @@ sub do_nbtstat {
|
|||||||
my $nbname = _filter_nbname( $ip->addr, $ns );
|
my $nbname = _filter_nbname( $ip->addr, $ns );
|
||||||
|
|
||||||
if ($nbname) {
|
if ($nbname) {
|
||||||
store_nbt($nbname);
|
store_nbt($nbname, $now);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ sub ip_version {
|
|||||||
die "ip_version input must be either 4 or 6\n"
|
die "ip_version input must be either 4 or 6\n"
|
||||||
unless $version && ( $version == 4 || $version == 6 );
|
unless $version && ( $version == 4 || $version == 6 );
|
||||||
|
|
||||||
return $rs->search_rs( \[ 'family(ip) = ?', $version ] );
|
return $rs->search_rs( \[ 'family(me.ip) = ?', $version ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -88,80 +88,23 @@ sub _single_body {
|
|||||||
return job_done("Ended $job_type for ". $host->addr);
|
return job_done("Ended $job_type for ". $host->addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
# _walk_nodes_body
|
|
||||||
# Queue a job for all active nodes that have been seen in the last
|
|
||||||
# configured days.
|
|
||||||
#
|
|
||||||
sub _walk_nodes_body {
|
|
||||||
my ($self, $job_type) = @_;
|
|
||||||
|
|
||||||
my $action_method = $job_type .'_action';
|
|
||||||
my $job_action = $self->$action_method;
|
|
||||||
|
|
||||||
my $jobqueue = schema('netdisco')->resultset('Admin');
|
|
||||||
my $rs = schema('netdisco')->resultset('NodeIp')
|
|
||||||
->search({ip => { -not_in =>
|
|
||||||
$jobqueue->search({
|
|
||||||
device => { '!=' => undef},
|
|
||||||
action => $job_type,
|
|
||||||
status => { -like => 'queued%' },
|
|
||||||
})->get_column('device')->as_query
|
|
||||||
}, -bool => 'active'});
|
|
||||||
|
|
||||||
my $ip_version = $job_type .'_ip_version';
|
|
||||||
my $job_ip_ver = $self->$ip_version;
|
|
||||||
|
|
||||||
if ($job_ip_ver) {
|
|
||||||
$rs = $rs->ip_version($job_ip_ver)
|
|
||||||
}
|
|
||||||
|
|
||||||
my $config_max_age = $job_type . '_max_age';
|
|
||||||
my $max_age = setting($config_max_age);
|
|
||||||
|
|
||||||
if ($max_age) {
|
|
||||||
my $interval = "$max_age day";
|
|
||||||
$rs = $rs->search(
|
|
||||||
{ time_last => \[ '>= now() - ?::interval', $interval ] } );
|
|
||||||
}
|
|
||||||
|
|
||||||
my @nodes = $rs->get_column('ip')->all;
|
|
||||||
|
|
||||||
my $filter_method = $job_type .'_filter';
|
|
||||||
my $job_filter = $self->$filter_method;
|
|
||||||
|
|
||||||
my @filtered_nodes = grep {$job_filter->($_)} @nodes;
|
|
||||||
|
|
||||||
schema('netdisco')->resultset('Admin')->txn_do_locked(sub {
|
|
||||||
$jobqueue->populate([
|
|
||||||
map {{
|
|
||||||
device => $_,
|
|
||||||
action => $job_type,
|
|
||||||
status => 'queued',
|
|
||||||
}} (@filtered_nodes)
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
return job_done("Queued $job_type job for all nodes");
|
|
||||||
}
|
|
||||||
|
|
||||||
sub _single_node_body {
|
sub _single_node_body {
|
||||||
my ($self, $job_type, $job) = @_;
|
my ($self, $job_type, $node, $now) = @_;
|
||||||
|
|
||||||
my $action_method = $job_type .'_action';
|
my $action_method = $job_type .'_action';
|
||||||
my $job_action = $self->$action_method;
|
my $job_action = $self->$action_method;
|
||||||
|
|
||||||
my $host = NetAddr::IP::Lite->new($job->device);
|
|
||||||
|
|
||||||
my $filter_method = $job_type .'_filter';
|
my $filter_method = $job_type .'_filter';
|
||||||
my $job_filter = $self->$filter_method;
|
my $job_filter = $self->$filter_method;
|
||||||
|
|
||||||
unless ($job_filter->($host->addr)) {
|
unless ($job_filter->($node)) {
|
||||||
return job_defer("$job_type deferred: $host is not ${job_type}able");
|
return job_defer("$job_type deferred: $node is not ${job_type}able");
|
||||||
}
|
}
|
||||||
|
|
||||||
$job_action->($host->addr);
|
$job_action->($node, $now);
|
||||||
|
|
||||||
return job_done("Ended $job_type for ". $host->addr);
|
# would be ignored if wrapped in a loop
|
||||||
|
return job_done("Ended $job_type for $node");
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
package App::Netdisco::Daemon::Worker::Poller::Nbtstat;
|
package App::Netdisco::Daemon::Worker::Poller::Nbtstat;
|
||||||
|
|
||||||
|
use Dancer qw/:moose :syntax :script/;
|
||||||
|
use Dancer::Plugin::DBIC 'schema';
|
||||||
|
|
||||||
use App::Netdisco::Core::Nbtstat 'do_nbtstat';
|
use App::Netdisco::Core::Nbtstat 'do_nbtstat';
|
||||||
use App::Netdisco::Util::Node 'is_nbtstatable';
|
use App::Netdisco::Util::Node 'is_nbtstatable';
|
||||||
|
use App::Netdisco::Util::Device qw/get_device is_discoverable/;
|
||||||
|
use App::Netdisco::Daemon::Util ':all';
|
||||||
|
|
||||||
|
use NetAddr::IP::Lite ':lower';
|
||||||
|
use Time::HiRes 'gettimeofday';
|
||||||
|
|
||||||
use Role::Tiny;
|
use Role::Tiny;
|
||||||
use namespace::clean;
|
use namespace::clean;
|
||||||
@@ -10,9 +18,40 @@ with 'App::Netdisco::Daemon::Worker::Poller::Common';
|
|||||||
|
|
||||||
sub nbtstat_action { \&do_nbtstat }
|
sub nbtstat_action { \&do_nbtstat }
|
||||||
sub nbtstat_filter { \&is_nbtstatable }
|
sub nbtstat_filter { \&is_nbtstatable }
|
||||||
sub nbtstat_ip_version { 4 }
|
sub nbtstat_layer { 2 }
|
||||||
|
|
||||||
sub nbtwalk { (shift)->_walk_nodes_body('nbtstat', @_) }
|
sub nbtwalk { (shift)->_walk_body('nbtstat', @_) }
|
||||||
sub nbtstat { (shift)->_single_node_body('nbtstat', @_) }
|
|
||||||
|
sub nbtstat {
|
||||||
|
my ($self, $job) = @_;
|
||||||
|
|
||||||
|
my $host = NetAddr::IP::Lite->new($job->device);
|
||||||
|
my $device = get_device($host->addr);
|
||||||
|
|
||||||
|
unless (is_discoverable($device->ip)) {
|
||||||
|
return job_defer("nbtstat deferred: $host is not discoverable");
|
||||||
|
}
|
||||||
|
|
||||||
|
# get list of nodes on device
|
||||||
|
my $interval = (setting('nbt_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;
|
||||||
|
my $now = 'to_timestamp('. (join '.', gettimeofday) .')';
|
||||||
|
|
||||||
|
$self->_single_node_body('nbtstat', $_, $now)
|
||||||
|
for @nodes;
|
||||||
|
|
||||||
|
return job_done("Ended nbtstat for ". $host->addr);
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -43,6 +43,21 @@ sub add_job {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# we have a separate list for jobs needing a device to avoid queueing
|
||||||
|
# such a job when there's no device param (it could still be duff, tho).
|
||||||
|
my %jobs = map { $_ => 1} qw/
|
||||||
|
discover
|
||||||
|
macsuck
|
||||||
|
arpnip
|
||||||
|
nbtstat
|
||||||
|
/;
|
||||||
|
my %jobs_all = map {$_ => 1} qw/
|
||||||
|
discoverall
|
||||||
|
macwalk
|
||||||
|
arpwalk
|
||||||
|
nbtwalk
|
||||||
|
/;
|
||||||
|
|
||||||
foreach my $jobtype (keys %jobs_all, keys %jobs) {
|
foreach my $jobtype (keys %jobs_all, keys %jobs) {
|
||||||
ajax "/ajax/control/admin/$jobtype" => require_role admin => sub {
|
ajax "/ajax/control/admin/$jobtype" => require_role admin => sub {
|
||||||
send_error('Missing device', 400)
|
send_error('Missing device', 400)
|
||||||
|
|||||||
@@ -145,6 +145,8 @@
|
|||||||
<button class="btn btn-info btn-small nd_adminbutton" name="arpnip">Arpnip</button>
|
<button class="btn btn-info btn-small nd_adminbutton" name="arpnip">Arpnip</button>
|
||||||
<input type="hidden" data-form="macsuck" value="[% d.ip %]" name="device"/>
|
<input type="hidden" data-form="macsuck" value="[% d.ip %]" name="device"/>
|
||||||
<button class="btn btn-info btn-small nd_adminbutton" name="macsuck">Macsuck</button>
|
<button class="btn btn-info btn-small nd_adminbutton" name="macsuck">Macsuck</button>
|
||||||
|
<input type="hidden" data-form="nbtstat" value="[% d.ip %]" name="device"/>
|
||||||
|
<button class="btn btn-info btn-small nd_adminbutton" name="nbtstat">NBTstat</button>
|
||||||
|
|
||||||
<button class="btn btn-danger btn-small pull-right"
|
<button class="btn btn-danger btn-small pull-right"
|
||||||
data-toggle="modal" data-target="#nd_devdel" type="button">Delete</button>
|
data-toggle="modal" data-target="#nd_devdel" type="button">Delete</button>
|
||||||
|
|||||||
@@ -108,7 +108,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<form method="post" class="nd_inline-form" action="[% uri_for('/admin/nbtwalk') %]">
|
<form method="post" class="nd_inline-form" action="[% uri_for('/admin/nbtwalk') %]">
|
||||||
<button type="submit" class="btn btn-link nd_btn-link">Nbtstat All</button>
|
<button type="submit" class="btn btn-link nd_btn-link">NBTstat All</button>
|
||||||
</form>
|
</form>
|
||||||
</li>
|
</li>
|
||||||
[% IF settings._admin_tasks.size %]
|
[% IF settings._admin_tasks.size %]
|
||||||
|
|||||||
Reference in New Issue
Block a user