diff --git a/lib/App/Netdisco/Util/Device.pm b/lib/App/Netdisco/Util/Device.pm
index 472fc543..3cb3c08b 100644
--- a/lib/App/Netdisco/Util/Device.pm
+++ b/lib/App/Netdisco/Util/Device.pm
@@ -77,7 +77,7 @@ Returns true if the transaction completes, else returns false.
=cut
sub delete_device {
- my ($ip, $archive, $log) = @_;
+ my ($ip, $archive) = @_;
my $device = get_device($ip) or return 0;
return 0 if not $device->in_storage;
@@ -87,13 +87,6 @@ sub delete_device {
schema(vars->{'tenant'})->resultset('Device')
->search({ ip => $device->ip })->delete({archive_nodes => $archive});
- schema(vars->{'tenant'})->resultset('UserLog')->create({
- username => session('logged_in_user'),
- userip => scalar eval {request->remote_address},
- event => (sprintf "Delete device %s", $device->ip),
- details => $log,
- });
-
$happy = 1;
});
diff --git a/lib/App/Netdisco/Web/AdminTask.pm b/lib/App/Netdisco/Web/AdminTask.pm
index 9eb9322c..7e1f8859 100644
--- a/lib/App/Netdisco/Web/AdminTask.pm
+++ b/lib/App/Netdisco/Web/AdminTask.pm
@@ -7,10 +7,10 @@ use Dancer::Plugin::Auth::Extensible;
use NetAddr::IP qw/:rfc3021 :lower/;
use App::Netdisco::JobQueue 'jq_insert';
-use App::Netdisco::Util::Device qw/delete_device renumber_device/;
+use App::Netdisco::Util::Device qw/renumber_device/;
sub add_job {
- my ($action, $device, $subaction) = @_;
+ my ($action, $device, $extra, $port) = @_;
my $net = NetAddr::IP->new($device);
return if
@@ -18,15 +18,29 @@ sub add_job {
my @hostlist = $device ? ($net->hostenum) : (undef);
- jq_insert([map {{
- ($_ ? (device => $_->addr) : ()),
+ my $happy = jq_insert([map {{
action => $action,
- ($subaction ? (subaction => $subaction) : ()),
+ ($_ ? (device => $_->addr) : ()),
+ ($port ? (port => $port) : ()),
+ ($extra ? (extra => $extra) : ()),
username => session('logged_in_user'),
- userip => request->remote_address,
+ userip => scalar eval {request->remote_address},
}} @hostlist]);
- true;
+ 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} },
@@ -35,12 +49,12 @@ foreach my $action (@{ setting('job_prio')->{high} },
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'))
+ 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'))
+ add_job($action, param('device'), param('extra'), param('port'))
? redirect uri_for('/admin/jobqueue')->path
: redirect uri_for('/')->path;
};
@@ -61,18 +75,6 @@ ajax qr{/ajax/control/admin/(?:\w+/)?renumber} => require_role setting('defanged
return renumber_device( $device->addr, $newip->addr );
};
-ajax qr{/ajax/control/admin/(?:\w+/)?delete} => require_role setting('defanged_admin') => sub {
- send_error('Missing device', 400) unless param('device');
-
- my $device = NetAddr::IP->new(param('device'));
- send_error('Bad device', 400)
- if ! $device or $device->addr eq '0.0.0.0';
-
- return delete_device(
- $device->addr, param('archive'), param('log'),
- );
-};
-
ajax "/ajax/control/admin/snapshot_req" => require_role admin => sub {
my $device = NetAddr::IP->new(param('device'));
send_error('Bad device', 400)
diff --git a/lib/App/Netdisco/Worker/Plugin/Delete.pm b/lib/App/Netdisco/Worker/Plugin/Delete.pm
index 5597b7e2..a1e4e8b6 100644
--- a/lib/App/Netdisco/Worker/Plugin/Delete.pm
+++ b/lib/App/Netdisco/Worker/Plugin/Delete.pm
@@ -14,11 +14,21 @@ register_worker({ phase => 'check' }, sub {
register_worker({ phase => 'main' }, sub {
my ($job, $workerconf) = @_;
- my ($device, $port, $extra) = map {$job->$_} qw/device port extra/;
+ my ($device, $port) = map {$job->$_} qw/device port/;
+
+ # support for Hooks
+ vars->{'hook_data'} = { $device->get_columns };
+ delete vars->{'hook_data'}->{'snmp_comm'}; # for privacy
$port = ($port ? 1 : 0);
- delete_device($device, $port, $extra);
- return Status->done("Deleted device: $device");
+ my $happy = delete_device($device, $port);
+
+ if ($happy) {
+ return Status->done("Deleted device: $device")
+ }
+ else {
+ return Status->error("Failed to delete device: $device")
+ }
});
true;
diff --git a/lib/App/Netdisco/Worker/Plugin/Delete/Hooks.pm b/lib/App/Netdisco/Worker/Plugin/Delete/Hooks.pm
new file mode 100644
index 00000000..062f913f
--- /dev/null
+++ b/lib/App/Netdisco/Worker/Plugin/Delete/Hooks.pm
@@ -0,0 +1,31 @@
+package App::Netdisco::Worker::Plugin::Delete::Hooks;
+
+use Dancer ':syntax';
+use App::Netdisco::Worker::Plugin;
+use aliased 'App::Netdisco::Worker::Status';
+
+use App::Netdisco::Util::Worker;
+use App::Netdisco::Util::Permission qw/check_acl_no check_acl_only/;
+
+register_worker({ phase => 'late' }, sub {
+ my ($job, $workerconf) = @_;
+ my $count = 0;
+
+ foreach my $conf (@{ setting('hooks') }) {
+ my $no = ($conf->{'filter'}->{'no'} || []);
+ my $only = ($conf->{'filter'}->{'only'} || []);
+
+ next if check_acl_no( $job->device, $no );
+ next unless check_acl_only( $job->device, $only);
+
+ if ($conf->{'event'} eq 'delete') {
+ $count += queue_hook('delete', $conf);
+ debug sprintf ' [%s] hooks - %s queued', 'delete', $job->device;
+ }
+ }
+
+ return Status
+ ->info(sprintf ' [%s] hooks - %d queued', $job->device, $count);
+});
+
+true;
diff --git a/lib/App/Netdisco/Worker/Plugin/Expire.pm b/lib/App/Netdisco/Worker/Plugin/Expire.pm
index 03093f48..934ed136 100644
--- a/lib/App/Netdisco/Worker/Plugin/Expire.pm
+++ b/lib/App/Netdisco/Worker/Plugin/Expire.pm
@@ -5,6 +5,7 @@ use App::Netdisco::Worker::Plugin;
use aliased 'App::Netdisco::Worker::Status';
use Dancer::Plugin::DBIC 'schema';
+use App::Netdisco::JobQueue 'jq_insert';
use App::Netdisco::Util::Statistics 'update_stats';
use App::Netdisco::DB::ExplicitLocking ':modes';
@@ -13,11 +14,16 @@ register_worker({ phase => 'main' }, sub {
if (setting('expire_devices') and setting('expire_devices') > 0) {
schema('netdisco')->txn_do(sub {
- schema('netdisco')->resultset('Device')->search({
- -or => [ 'vendor' => undef, 'vendor' => { '!=' => 'netdisco' }],
+ my @hostlist = schema('netdisco')->resultset('Device')->search({
+ -not_bool => 'is_pseudo',
last_discover => \[q/< (LOCALTIMESTAMP - ?::interval)/,
(setting('expire_devices') * 86400)],
- })->delete();
+ })->get_column('ip')->all;
+
+ my $happy = jq_insert([map {{
+ device => $_,
+ action => 'delete',
+ }} @hostlist]);
});
}
diff --git a/share/config.yml b/share/config.yml
index 3a9f8f0a..c5ae8026 100644
--- a/share/config.yml
+++ b/share/config.yml
@@ -472,6 +472,7 @@ job_prio:
- power
- snapshot
- vlan
+ - delete
normal:
- arpnip
- arpwalk
@@ -493,6 +494,7 @@ worker_plugins:
- 'Arpwalk'
- 'Contact'
- 'Delete'
+ - 'Delete::Hooks'
- 'Discover'
- 'Discover::CanonicalIP'
- 'Discover::Entities'
diff --git a/share/views/ajax/admintask/duplicatedevices.tt b/share/views/ajax/admintask/duplicatedevices.tt
index 44315131..9eeececa 100644
--- a/share/views/ajax/admintask/duplicatedevices.tt
+++ b/share/views/ajax/admintask/duplicatedevices.tt
@@ -51,9 +51,9 @@
+ placeholder="Enter a log message" name="extra">
diff --git a/share/views/ajax/device/details.tt b/share/views/ajax/device/details.tt
index 77fe3505..d380e4fb 100644
--- a/share/views/ajax/device/details.tt
+++ b/share/views/ajax/device/details.tt
@@ -243,9 +243,9 @@
+ placeholder="Enter a log message" name="extra">
diff --git a/share/views/js/device.js b/share/views/js/device.js
index 56b7948d..5031ef93 100644
--- a/share/views/js/device.js
+++ b/share/views/js/device.js
@@ -176,7 +176,7 @@
}
}
else {
- toastr.success('Deleted device '+ tr.data('for-device'));
+ toastr.success('Queued job to delete '+ tr.data('for-device'));
}
}
// skip any error reporting for now