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";
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/],
};

View File

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

View File

@@ -13,6 +13,36 @@ use NetAddr::IP::Lite ':lower';
use Role::Tiny;
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 {
my ($self, $job) = @_;

View File

@@ -13,6 +13,36 @@ use NetAddr::IP::Lite ':lower';
use Role::Tiny;
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 {
my ($self, $job) = @_;

View File

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

View File

@@ -4,32 +4,53 @@ use Dancer ':syntax';
use Dancer::Plugin::Ajax;
use Dancer::Plugin::DBIC;
sub add_discover_job {
my $ip = NetAddr::IP::Lite->new(shift);
return unless $ip
and $ip->addr ne '0.0.0.0';
sub add_job {
my ($jobtype, $device) = @_;
if ($device) {
$device = NetAddr::IP::Lite->new($device);
return unless $device
and $device->addr ne '0.0.0.0';
}
schema('netdisco')->resultset('Admin')->create({
device => $ip->addr,
action => 'discover',
($device ? (device => $device->addr) : ()),
action => $jobtype,
status => 'queued',
username => session('user'),
userip => request->remote_address,
});
}
ajax '/ajax/control/admin/discover' => sub {
return unless var('user') and var('user')->admin;
add_discover_job(param('device'));
};
# 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
/;
my %jobs_all = map {$_ => 1} qw/
discoverall
macwalk
arpwalk
/;
post '/admin/discover' => sub {
return unless var('user') and var('user')->admin;
add_discover_job(param('device'));
foreach my $jobtype (keys %jobs_all, keys %jobs) {
ajax "/ajax/control/admin/$jobtype" => sub {
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());
};
post "/admin/$jobtype" => sub {
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 {
my ($tag) = splat;