Files
netdisco/lib/App/Netdisco/Web/AdminTask.pm
Oliver Gorwits 949aeb9eea delete hook (#1032)
* make log_message optional in delete_device

* add hooks support to delete job

* make delete job high prio

* web delete now queues job instead of inline delete

* move web logging into web package and remove userlog from device delete helper

* submit delete job for expire device instead of inline delete

* fixes to get web submit form for delete device to work

* enable delete hook functionality
2023-04-30 22:58:42 +01:00

128 lines
4.2 KiB
Perl
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package App::Netdisco::Web::AdminTask;
use Dancer ':syntax';
use Dancer::Plugin::Ajax;
use Dancer::Plugin::DBIC;
use Dancer::Plugin::Auth::Extensible;
use NetAddr::IP qw/:rfc3021 :lower/;
use App::Netdisco::JobQueue 'jq_insert';
use App::Netdisco::Util::Device qw/renumber_device/;
sub add_job {
my ($action, $device, $extra, $port) = @_;
my $net = NetAddr::IP->new($device);
return if
($device and (!$net or $net->num == 0 or $net->addr eq '0.0.0.0'));
my @hostlist = $device ? ($net->hostenum) : (undef);
my $happy = jq_insert([map {{
action => $action,
($_ ? (device => $_->addr) : ()),
($port ? (port => $port) : ()),
($extra ? (extra => $extra) : ()),
username => session('logged_in_user'),
userip => scalar eval {request->remote_address},
}} @hostlist]);
foreach my $h (@hostlist) {
next unless defined $h;
my $msg = ($happy ? "Queued job to $action device \%s"
: "Failed to queue job to $action device \%s");
schema(vars->{'tenant'})->resultset('UserLog')->create({
username => session('logged_in_user'),
userip => scalar eval {request->remote_address},
event => (sprintf $msg, $h->addr),
details => ($extra || 'no user log supplied'),
});
}
return $happy;
}
foreach my $action (@{ setting('job_prio')->{high} },
@{ setting('job_prio')->{normal} }) {
next if $action and $action =~ m/^hook::/; # skip hooks
ajax "/ajax/control/admin/$action" => require_role admin => sub {
add_job($action, param('device'), param('extra'), param('port'))
or send_error('Bad device', 400);
};
post "/admin/$action" => require_role admin => sub {
add_job($action, param('device'), param('extra'), param('port'))
? redirect uri_for('/admin/jobqueue')->path
: redirect uri_for('/')->path;
};
}
ajax qr{/ajax/control/admin/(?:\w+/)?renumber} => require_role setting('defanged_admin') => sub {
send_error('Missing device', 400) unless param('device');
send_error('Missing new IP', 400) unless param('newip');
my $device = NetAddr::IP->new(param('device'));
send_error('Bad device', 400)
if ! $device or $device->addr eq '0.0.0.0';
my $newip = NetAddr::IP->new(param('newip'));
send_error('Bad new IP', 400)
if ! $newip or $newip->addr eq '0.0.0.0';
return renumber_device( $device->addr, $newip->addr );
};
ajax "/ajax/control/admin/snapshot_req" => require_role admin => sub {
my $device = NetAddr::IP->new(param('device'));
send_error('Bad device', 400)
if ! $device or $device->addr eq '0.0.0.0';
add_job('loadmibs')
if not schema(vars->{'tenant'})->resultset('SNMPObject')->count();
# will store for download and for browsing
add_job('snapshot', $device->addr, 'yes') or send_error('Bad device', 400);
};
get "/ajax/content/admin/snapshot_get" => require_role admin => sub {
my $device = NetAddr::IP->new(param('device'));
send_error('Bad device', 400)
if ! $device or $device->addr eq '0.0.0.0';
my $content = schema(vars->{'tenant'})->resultset('DeviceSnapshot')->find($device->addr)->cache;
send_file( \$content, content_type => 'text/plain', filename => ($device->addr .'-snapshot.txt') );
};
ajax "/ajax/control/admin/snapshot_del" => require_role setting('defanged_admin') => sub {
my $device = NetAddr::IP->new(param('device'));
send_error('Bad device', 400)
if ! $device or $device->addr eq '0.0.0.0';
schema(vars->{'tenant'})->resultset('DeviceSnapshot')->find($device->addr)->delete;
schema(vars->{'tenant'})->resultset('DeviceBrowser')->search({ip => $device->addr})->delete;
};
get '/admin/*' => require_role admin => sub {
my ($tag) = splat;
if (exists setting('_admin_tasks')->{ $tag }) {
# trick the ajax into working as if this were a tabbed page
params->{tab} = $tag;
var(nav => 'admin');
template 'admintask', {
task => setting('_admin_tasks')->{ $tag },
}, { layout => 'main' };
}
else {
var('notfound' => true);
status 'not_found';
template 'index', {}, { layout => 'main' };
}
};
true;