From be806d5ab1f0c78456c2770f29acba7df331c213 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 2 Sep 2013 21:27:22 +0100 Subject: [PATCH] efficient device delete which does not walk nodes --- Netdisco/lib/App/Netdisco/Core/Discover.pm | 10 +++- Netdisco/lib/App/Netdisco/DB/Result/Device.pm | 1 - .../lib/App/Netdisco/DB/ResultSet/Device.pm | 40 +++++++++++++ .../App/Netdisco/DB/ResultSet/DevicePort.pm | 35 ++++++++++++ .../lib/App/Netdisco/DB/ResultSet/Node.pm | 57 ++++++++++++++++++- Netdisco/lib/App/Netdisco/Web/AdminTask.pm | 16 ++++++ .../Web/Plugin/AdminTask/PseudoDevice.pm | 10 +--- Netdisco/share/public/css/netdisco.css | 5 ++ .../javascripts/netdisco_portcontrol.js | 6 +- .../views/ajax/admintask/pseudodevice.tt | 4 +- .../share/views/ajax/admintask/topology.tt | 4 +- Netdisco/share/views/ajax/admintask/users.tt | 4 +- Netdisco/share/views/ajax/device/details.tt | 16 ++++-- Netdisco/share/views/ajax/device/ports.tt | 4 +- Netdisco/share/views/inventory.tt | 3 +- Netdisco/share/views/js/device.js | 10 +++- 16 files changed, 193 insertions(+), 32 deletions(-) diff --git a/Netdisco/lib/App/Netdisco/Core/Discover.pm b/Netdisco/lib/App/Netdisco/Core/Discover.pm index 27244f25..53cca2c9 100644 --- a/Netdisco/lib/App/Netdisco/Core/Discover.pm +++ b/Netdisco/lib/App/Netdisco/Core/Discover.pm @@ -130,7 +130,15 @@ sub _set_canonical_ip { my $gone = $device->device_ips->delete; debug sprintf ' [%s] device - removed %s aliases', $oldip, $gone; - $device->delete; + + # our special delete which is more efficient + schema('netdisco')->resultset('Device') + ->search({ ip => $device->ip })->delete; + + # a new row object from the old one + $device = schema('netdisco')->resultset('Device') + ->new({ $device->get_columns }); + debug sprintf ' [%s] device - deleted self', $oldip; }); diff --git a/Netdisco/lib/App/Netdisco/DB/Result/Device.pm b/Netdisco/lib/App/Netdisco/DB/Result/Device.pm index 1d83f3d8..19aefbc2 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/Device.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/Device.pm @@ -78,7 +78,6 @@ __PACKAGE__->add_columns( ); __PACKAGE__->set_primary_key("ip"); - # Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:671/XuuvsO2aMB1+IRWFjg diff --git a/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm b/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm index 7be1cc07..f6a43046 100644 --- a/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm +++ b/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm @@ -528,4 +528,44 @@ sub with_port_count { }); } +=head1 SPECIAL METHODS + +=head2 delete( \%options? ) + +Overrides the built-in L delete method to more efficiently +handle the removal or archiving of nodes. + +=cut + +sub delete { + my $self = shift; + + my $schema = $self->result_source->schema; + my $devices = $self->search(undef, { columns => 'ip' }); + + foreach my $set (qw/ + Community + DeviceIp + DeviceVlan + DevicePower + DeviceModule + /) { + $schema->resultset($set)->search( + { ip => { '-in' => $devices->as_query }}, + )->delete; + } + + $schema->resultset('Admin')->search({ + device => { '-in' => $devices->as_query }, + action => { '-like' => 'queued%' }, + })->delete; + + $schema->resultset('DevicePort')->search( + { ip => { '-in' => $devices->as_query }}, + )->delete(@_); + + # now let DBIC do its thing + return $self->next::method(); +} + 1; diff --git a/Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm b/Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm index 832ffa1b..755aa568 100644 --- a/Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm +++ b/Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm @@ -133,4 +133,39 @@ sub with_vlan_count { }); } +=head1 SPECIAL METHODS + +=head2 delete( \%options? ) + +Overrides the built-in L delete method to more efficiently +handle the removal or archiving of nodes. + +=cut + +sub delete { + my $self = shift; + + my $schema = $self->result_source->schema; + my $ports = $self->search(undef, { columns => 'ip' }); + + foreach my $set (qw/ + DevicePortPower + DevicePortVlan + DevicePortWireless + DevicePortSsid + DevicePortLog + /) { + $schema->resultset($set)->search( + { ip => { '-in' => $ports->as_query }}, + )->delete; + } + + $schema->resultset('Node')->search( + { switch => { '-in' => $ports->as_query }}, + )->delete(@_); + + # now let DBIC do its thing + return $self->next::method(); +} + 1; diff --git a/Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm b/Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm index 12ad40a1..75636b12 100644 --- a/Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm +++ b/Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm @@ -8,7 +8,9 @@ __PACKAGE__->load_components(qw/ +App::Netdisco::DB::ExplicitLocking /); -=head1 search_by_mac( \%cond, \%attrs? ) +=head1 ADDITIONAL METHODS + +=head2 search_by_mac( \%cond, \%attrs? ) my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1}); @@ -63,4 +65,57 @@ sub search_by_mac { ->search($cond, $attrs); } +=head1 SPECIAL METHODS + +=head2 delete( \%options? ) + +Overrides the built-in L delete method to more efficiently +handle the removal or archiving of nodes. + +=cut + +sub delete { + my $self = shift; + my ($opts) = @_; + + my $schema = $self->result_source->schema; + my $nodes = $self->search(undef, { columns => 'mac' }); + + if (ref {} eq ref $opts + and exists $opts->{archive} and $opts->{archive}) { + + foreach my $set (qw/ + NodeIp + NodeNbt + NodeMonitor + Node + /) { + $schema->resultset($set)->search( + { mac => { '-in' => $nodes->as_query }}, + )->update({ active => \'false' }); + } + + $schema->resultset('NodeWireless') + ->search({ mac => { '-in' => $nodes->as_query }})->delete; + + # avoid letting DBIC delete nodes + return 0E0; + } + else { + foreach my $set (qw/ + NodeIp + NodeNbt + NodeMonitor + NodeWireless + /) { + $schema->resultset($set)->search( + { mac => { '-in' => $nodes->as_query }}, + )->delete; + } + + # now let DBIC do its thing + return $self->next::method(); + } +} + 1; diff --git a/Netdisco/lib/App/Netdisco/Web/AdminTask.pm b/Netdisco/lib/App/Netdisco/Web/AdminTask.pm index 332e3e9f..142fdd04 100644 --- a/Netdisco/lib/App/Netdisco/Web/AdminTask.pm +++ b/Netdisco/lib/App/Netdisco/Web/AdminTask.pm @@ -59,6 +59,22 @@ foreach my $jobtype (keys %jobs_all, keys %jobs) { }; } +ajax '/ajax/control/admin/delete' => require_role admin => sub { + send_error('Missing device', 400) unless param('device'); + + my $device = NetAddr::IP::Lite->new(param('device')); + send_error('Bad device', 400) + if ! $device or $device->addr eq '0.0.0.0'; + + schema('netdisco')->txn_do(sub { + my $device = schema('netdisco')->resultset('Device') + ->search({ip => param('device')}); + + # will delete everything related too... + $device->delete; + }); +}; + get '/admin/*' => require_role admin => sub { my ($tag) = splat; diff --git a/Netdisco/lib/App/Netdisco/Web/Plugin/AdminTask/PseudoDevice.pm b/Netdisco/lib/App/Netdisco/Web/Plugin/AdminTask/PseudoDevice.pm index 15df943b..740d0885 100644 --- a/Netdisco/lib/App/Netdisco/Web/Plugin/AdminTask/PseudoDevice.pm +++ b/Netdisco/lib/App/Netdisco/Web/Plugin/AdminTask/PseudoDevice.pm @@ -56,15 +56,7 @@ ajax '/ajax/control/admin/pseudodevice/add' => require_role admin => sub { ajax '/ajax/control/admin/pseudodevice/del' => require_role admin => sub { send_error('Bad Request', 400) unless _sanity_ok(); - - schema('netdisco')->txn_do(sub { - my $device = schema('netdisco')->resultset('Device') - ->find({ip => param('ip')}); - - $device->ports->delete; - $device->device_ips->delete; - $device->delete; - }); + forward '/ajax/control/admin/delete', { device => param('ip') }; }; ajax '/ajax/control/admin/pseudodevice/update' => require_role admin => sub { diff --git a/Netdisco/share/public/css/netdisco.css b/Netdisco/share/public/css/netdisco.css index e603a95f..e43de784 100644 --- a/Netdisco/share/public/css/netdisco.css +++ b/Netdisco/share/public/css/netdisco.css @@ -85,6 +85,11 @@ div.content > div.tab-content table.nd_floatinghead thead { z-index: -1000; } +/* for when we pinch h4 styling but don't want bold */ +.nd_unbolden { + font-weight: normal; +} + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* styles to adjust the hero box used for homepage + login */ diff --git a/Netdisco/share/public/javascripts/netdisco_portcontrol.js b/Netdisco/share/public/javascripts/netdisco_portcontrol.js index 0bea4ffa..bf478985 100644 --- a/Netdisco/share/public/javascripts/netdisco_portcontrol.js +++ b/Netdisco/share/public/javascripts/netdisco_portcontrol.js @@ -4,8 +4,8 @@ var nd_save_ok = false; // user clicked or asked for port changes to be submitted via ajax function port_control (e) { var td = $(e).closest('td'), - logmessage = $('#nd_portlog_log').val(); - $('#nd_portlog_log').val(''); + logmessage = $('#nd_portlog-log').val(); + $('#nd_portlog-log').val(''); if (nd_save_ok == false) { td.find('.nd_editable-cell-content').text(td.data('default')); @@ -109,7 +109,7 @@ $(document).ready(function() { }); // to tell whether bootstrap's modal had Submit button pressed :( - $('#ports_pane').on('click', '#nd_portlog_submit', function() { + $('#ports_pane').on('click', '#nd_portlog-submit', function() { nd_save_ok = true; }); diff --git a/Netdisco/share/views/ajax/admintask/pseudodevice.tt b/Netdisco/share/views/ajax/admintask/pseudodevice.tt index 0fe8f67e..0e4ad990 100644 --- a/Netdisco/share/views/ajax/admintask/pseudodevice.tt +++ b/Netdisco/share/views/ajax/admintask/pseudodevice.tt @@ -35,10 +35,10 @@ data-target="#nd_devdel-[% count %]" type="button">