efficient device delete which does not walk nodes
This commit is contained in:
@@ -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;
|
||||
});
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -528,4 +528,44 @@ sub with_port_count {
|
||||
});
|
||||
}
|
||||
|
||||
=head1 SPECIAL METHODS
|
||||
|
||||
=head2 delete( \%options? )
|
||||
|
||||
Overrides the built-in L<DBIx::Class> 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;
|
||||
|
||||
@@ -133,4 +133,39 @@ sub with_vlan_count {
|
||||
});
|
||||
}
|
||||
|
||||
=head1 SPECIAL METHODS
|
||||
|
||||
=head2 delete( \%options? )
|
||||
|
||||
Overrides the built-in L<DBIx::Class> 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;
|
||||
|
||||
@@ -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<DBIx::Class> 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
data-target="#nd_devdel-[% count %]" type="button"><i class="icon-trash text-error"></i></button>
|
||||
|
||||
<div id="nd_devdel-[% count %]" class="nd_modal modal hide fade" tabindex="-1"
|
||||
role="dialog" aria-labelledby="nd_devdel_label-[% count %]" aria-hidden="true">
|
||||
role="dialog" aria-labelledby="nd_devdel-label-[% count %]" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
|
||||
<h3 id="nd_devdel_label-[% count %]">Are you sure?</h3>
|
||||
<h3 id="nd_devdel-label-[% count %]">Are you sure?</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<blockquote>
|
||||
|
||||
@@ -54,10 +54,10 @@
|
||||
data-target="#nd_devdel-[% count %]" type="button"><i class="icon-trash text-error"></i></button>
|
||||
|
||||
<div id="nd_devdel-[% count %]" class="nd_modal modal hide fade" tabindex="-1"
|
||||
role="dialog" aria-labelledby="nd_devdel_label-[% count %]" aria-hidden="true">
|
||||
role="dialog" aria-labelledby="nd_devdel-label-[% count %]" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
|
||||
<h3 id="nd_devdel_label-[% count %]">Are you sure?</h3>
|
||||
<h3 id="nd_devdel-label-[% count %]">Are you sure?</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<blockquote>
|
||||
|
||||
@@ -53,10 +53,10 @@
|
||||
data-target="#nd_devdel-[% count %]" type="button"><i class="icon-trash text-error"></i></button>
|
||||
|
||||
<div id="nd_devdel-[% count %]" class="nd_modal modal hide fade" tabindex="-1"
|
||||
role="dialog" aria-labelledby="nd_devdel_label-[% count %]" aria-hidden="true">
|
||||
role="dialog" aria-labelledby="nd_devdel-label-[% count %]" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
|
||||
<h3 id="nd_devdel_label-[% count %]">Are you sure?</h3>
|
||||
<h3 id="nd_devdel-label-[% count %]">Are you sure?</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<blockquote>
|
||||
|
||||
@@ -109,25 +109,29 @@
|
||||
data-toggle="modal" data-target="#nd_devdel" type="button">Delete</button>
|
||||
|
||||
<div id="nd_devdel" class="nd_modal modal hide fade" tabindex="-1"
|
||||
role="dialog" aria-labelledby="nd_devdel_label" aria-hidden="true">
|
||||
role="dialog" aria-labelledby="nd_devdel-label" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
|
||||
<h3 id="nd_devdel_label">Confirm Delete: [% d.dns || d.ip | html_entity %]</h3>
|
||||
<h3 id="nd_devdel-label">Confirm Delete: [% d.dns || d.ip | html_entity %]</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<blockquote>
|
||||
<ul>
|
||||
<li><p>This action is immediate and not reversible</p></li>
|
||||
<li><p>All associated Nodes will be removed from the database</p></li>
|
||||
<li><p>All associated Nodes may be removed from the database</p></li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<textarea class="input-block-level" rows="2" data-form="delete"
|
||||
<textarea id="nd_devdel-log" class="input-block-level" rows="2" data-form="delete"
|
||||
placeholder="Enter a log message" name="log"></textarea>
|
||||
<label class="checkbox">
|
||||
<input id="nd_devdel-archive" type="checkbox" data-form="delete" name="archive">
|
||||
<h4 class="nd_unbolden">Archive Nodes</h4>
|
||||
</label>
|
||||
<input type="hidden" data-form="delete" value="[% d.ip %]" name="device"/>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-success" data-dismiss="modal" aria-hidden="true">No !</button>
|
||||
<button class="btn btn-danger nd_adminbutton" name="delete" data-dismiss="modal">Really Delete</button>
|
||||
<button class="btn btn-success" data-dismiss="modal" aria-hidden="true">Cancel</button>
|
||||
<button class="btn btn-danger nd_adminbutton" name="delete" data-dismiss="modal">Confirm</button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -278,12 +278,12 @@
|
||||
<div id="nd_portlog" class="nd_modal nd_deep-horizon modal hide fade" tabindex="-1"
|
||||
role="dialog" aria-hidden="true">
|
||||
<div class="modal-body">
|
||||
<textarea id="nd_portlog_log" class="input-block-level" rows="2" name="log"
|
||||
<textarea id="nd_portlog-log" class="input-block-level" rows="2" name="log"
|
||||
placeholder="Enter a log message"></textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
|
||||
<button id="nd_portlog_submit" class="btn btn-info" data-dismiss="modal">Continue</button>
|
||||
<button id="nd_portlog-submit" class="btn btn-info" data-dismiss="modal">Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
[% END %]
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
</div>
|
||||
</div>
|
||||
[% ELSE %]
|
||||
<div class="span4 alert alert-info">No devices found. Do you need to run a Discover?</div>
|
||||
<div class="span4 alert alert-info">No devices found. Do you need to run a
|
||||
<a href="[% uri_for('/') %]">Discover?</a></div>
|
||||
[% END %]
|
||||
</div>
|
||||
|
||||
@@ -104,12 +104,12 @@
|
||||
,url: uri_base + '/ajax/control/admin/' + mode
|
||||
,data: tr.find('input[data-form="' + mode + '"],textarea[data-form="' + mode + '"]').serializeArray()
|
||||
,success: function() {
|
||||
toastr.info('Queued '+ mode +' for device '+ tr.data('for-device'));
|
||||
toastr.info('Requested '+ mode +' for device '+ tr.data('for-device'));
|
||||
}
|
||||
// skip any error reporting for now
|
||||
// TODO: fix sanity_ok in Netdisco Web
|
||||
,error: function() {
|
||||
toastr.error('Failed to queue '+ mode +' for device '+ tr.data('for-device'));
|
||||
toastr.error('Failed to '+ mode +' for device '+ tr.data('for-device'));
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -122,4 +122,10 @@
|
||||
$('#ports_pane').on('hidden', '.nd_modal', function () {
|
||||
$(this).toggleClass('nd_deep-horizon');
|
||||
});
|
||||
|
||||
// clear any values in the delete confirm dialog
|
||||
$('#details_pane').on('hidden', '.nd_modal', function () {
|
||||
$('#nd_devdel-log').val('');
|
||||
$('#nd_devdel-archive').attr('checked', false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user