support for arpwalk and macwalk and all jobs via web

This commit is contained in:
Oliver Gorwits
2013-05-30 05:50:34 +01:00
parent 8bc7d83c98
commit dc62382112
6 changed files with 101 additions and 20 deletions

View File

@@ -33,7 +33,7 @@ sub capacity_for {
debug "checking local capacity for action $action"; debug "checking local capacity for action $action";
my $action_map = { my $action_map = {
Poller => [qw/discoverall discover arpnip macsuck/], Poller => [qw/discoverall discover arpwalk arpnip macwalk macsuck/],
Interactive => [qw/location contact portcontrol portname vlan power/], Interactive => [qw/location contact portcontrol portname vlan power/],
}; };

View File

@@ -14,7 +14,7 @@ my $fqdn = hostfqdn || 'localhost';
my $role_map = { my $role_map = {
(map {$_ => 'Poller'} (map {$_ => 'Poller'}
qw/discoverall discover arpnip macsuck/), qw/discoverall discover arpwalk arpnip macwalk macsuck/),
(map {$_ => 'Interactive'} (map {$_ => 'Interactive'}
qw/location contact portcontrol portname vlan power/) qw/location contact portcontrol portname vlan power/)
}; };

View File

@@ -13,6 +13,36 @@ use NetAddr::IP::Lite ':lower';
use Role::Tiny; use Role::Tiny;
use namespace::clean; use namespace::clean;
# queue an arpnip job for all devices known to Netdisco
sub arpwalk {
my ($self, $job) = @_;
my $devices = schema('netdisco')->resultset('Device')->get_column('ip');
my $jobqueue = schema('netdisco')->resultset('Admin');
schema('netdisco')->txn_do(sub {
# clean up user submitted jobs older than 1min,
# assuming skew between schedulers' clocks is not greater than 1min
$jobqueue->search({
action => 'arpnip',
status => 'queued',
entered => { '<' => \"(now() - interval '1 minute')" },
})->delete;
# is scuppered by any user job submitted in last 1min (bad), or
# any similar job from another scheduler (good)
$jobqueue->populate([
map {{
device => $_,
action => 'arpnip',
status => 'queued',
}} ($devices->all)
]);
});
return job_done("Queued arpnip job for all devices");
}
sub arpnip { sub arpnip {
my ($self, $job) = @_; my ($self, $job) = @_;

View File

@@ -13,6 +13,36 @@ use NetAddr::IP::Lite ':lower';
use Role::Tiny; use Role::Tiny;
use namespace::clean; use namespace::clean;
# queue a macsuck job for all devices known to Netdisco
sub macwalk {
my ($self, $job) = @_;
my $devices = schema('netdisco')->resultset('Device')->get_column('ip');
my $jobqueue = schema('netdisco')->resultset('Admin');
schema('netdisco')->txn_do(sub {
# clean up user submitted jobs older than 1min,
# assuming skew between schedulers' clocks is not greater than 1min
$jobqueue->search({
action => 'macsuck',
status => 'queued',
entered => { '<' => \"(now() - interval '1 minute')" },
})->delete;
# is scuppered by any user job submitted in last 1min (bad), or
# any similar job from another scheduler (good)
$jobqueue->populate([
map {{
device => $_,
action => 'macsuck',
status => 'queued',
}} ($devices->all)
]);
});
return job_done("Queued macsuck job for all devices");
}
sub macsuck { sub macsuck {
my ($self, $job) = @_; my ($self, $job) = @_;

View File

@@ -12,10 +12,10 @@ use namespace::clean;
my $jobactions = { my $jobactions = {
map {$_ => undef} qw/ map {$_ => undef} qw/
discoverall discoverall
arpwalk
macwalk
/ /
# saveconfigs # saveconfigs
# macwalk
# arpwalk
# nbtwalk # nbtwalk
# backup # backup
}; };

View File

@@ -4,32 +4,53 @@ use Dancer ':syntax';
use Dancer::Plugin::Ajax; use Dancer::Plugin::Ajax;
use Dancer::Plugin::DBIC; use Dancer::Plugin::DBIC;
sub add_discover_job { sub add_job {
my $ip = NetAddr::IP::Lite->new(shift); my ($jobtype, $device) = @_;
return unless $ip
and $ip->addr ne '0.0.0.0'; if ($device) {
$device = NetAddr::IP::Lite->new($device);
return unless $device
and $device->addr ne '0.0.0.0';
}
schema('netdisco')->resultset('Admin')->create({ schema('netdisco')->resultset('Admin')->create({
device => $ip->addr, ($device ? (device => $device->addr) : ()),
action => 'discover', action => $jobtype,
status => 'queued', status => 'queued',
username => session('user'), username => session('user'),
userip => request->remote_address, userip => request->remote_address,
}); });
} }
ajax '/ajax/control/admin/discover' => sub { # we have a separate list for jobs needing a device to avoid queueing
return unless var('user') and var('user')->admin; # such a job when there's no device param (it could still be duff, tho).
add_discover_job(param('device')); my %jobs = map { $_ => 1} qw/
}; discover
macsuck
arpnip
/;
my %jobs_all = map {$_ => 1} qw/
discoverall
macwalk
arpwalk
/;
post '/admin/discover' => sub { foreach my $jobtype (keys %jobs_all, keys %jobs) {
return unless var('user') and var('user')->admin; ajax "/ajax/control/admin/$jobtype" => sub {
add_discover_job(param('device')); return unless var('user') and var('user')->admin;
return if exists $jobs{$jobtype} and not param('device');
add_job($jobtype, param('device'));
};
status(302); post "/admin/$jobtype" => sub {
header(Location => uri_for('/admin/jobqueue')->path_query()); return unless var('user') and var('user')->admin;
}; return if exists $jobs{$jobtype} and not param('device');
add_job($jobtype, param('device'));
status(302);
header(Location => uri_for('/admin/jobqueue')->path_query());
};
}
get '/admin/*' => sub { get '/admin/*' => sub {
my ($tag) = splat; my ($tag) = splat;