[#197] Change IP address of device with "renumber" option to netdisco-do

This commit is contained in:
Oliver Gorwits
2015-02-04 15:00:00 +00:00
parent b4b71bbf85
commit 9179b410e7
5 changed files with 130 additions and 15 deletions

View File

@@ -4,6 +4,7 @@
* [#171] Log files now rotate at 10MB up to seven times
* Delete device from CLI with new "delete" option to netdisco-do
* [#197] Change IP address of device with "renumber" option to netdisco-do
[ENHANCEMENTS]

View File

@@ -113,7 +113,8 @@ unless ($action) {
}
use App::Netdisco::Util::SNMP ();
use App::Netdisco::Util::Device qw/get_device delete_device/;
use App::Netdisco::Util::Device
qw/get_device delete_device renumber_device/;
use NetAddr::IP::Lite ':lower';
use Scalar::Util 'blessed';
@@ -154,6 +155,27 @@ unless ($action) {
delete_device($dev->ip, $archive, $extra);
return ('done', "Deleted device $device.");
}
sub renumber {
my $ip = NetAddr::IP::Lite->new($device)
or return ('error', "Bad host or IP: $device");
my $dev = get_device($ip->addr);
unless (blessed $dev and $dev->in_storage) {
return ('error', "Don't know device: $device");
}
my $old_ip = $dev->ip;
my $new_ip = NetAddr::IP::Lite->new($extra)
or return ('error', "Bad host or IP: $extra");
my $new_dev = get_device($new_ip->addr);
unless ($new_dev and not $new_dev->in_storage) {
return ('error', "Already know new device: $device");
}
renumber_device($dev->ip, $new_dev->ip);
return ('done', sprintf 'Renumbered device %s from %s to %s.',
$device, $old_ip, $new_dev->ip);
}
}
my $worker = MyWorker->new();
@@ -237,6 +259,17 @@ the C<-e> parameter. Optionally request for associated nodes to be archived
~netdisco/bin/netdisco-do delete -d 192.0.2.1 -e 'older than the sun'
~netdisco/bin/netdisco-do delete -d 192.0.2.1 -e '1,older than the sun'
=head2 renumber
Change the canonical IP address of a device (specified with C<-d>). Pass the
new IP address in the C<-e> parameter. All related records such as topology,
log and node information will also be updated to refer to the new device.
Note that I<no> check is made as to whether the new IP is reachable for future
polling.
~netdisco/bin/netdisco-do renumber -d 192.0.2.1 -e 192.0.2.254
=head2 nbtstat
Run an nbtstat on the node (specified with C<-d>).

View File

@@ -6,6 +6,7 @@ package App::Netdisco::DB::Result::Device;
use strict;
use warnings;
use NetAddr::IP::Lite ':lower';
use base 'DBIx::Class::Core';
__PACKAGE__->table("device");
@@ -186,6 +187,69 @@ Returns the row from the community string table, if one exists.
__PACKAGE__->might_have(
community => 'App::Netdisco::DB::Result::Community', 'ip');
=head1 ADDITIONAL METHODS
=head2 renumber( $new_ip )
Will update this device and all related database records to use the new IP
C<$new_ip>. Returns C<undef> if $new_ip seems invalid, otherwise returns the
Device row object.
=cut
sub renumber {
my ($device, $ip) = @_;
my $schema = $device->result_source->schema;
my $new_ip = NetAddr::IP::Lite->new($ip)
or return;
foreach my $set (qw/
DeviceIp
DeviceModule
DevicePower
DeviceVlan
DevicePort
DevicePortLog
DevicePortPower
DevicePortSsid
DevicePortVlan
DevicePortWireless
Community
/) {
$schema->resultset($set)
->search({ip => $device->ip})
->update({ip => $new_ip->addr});
}
$schema->resultset('DevicePort')
->search({remote_ip => $device->ip})
->update({remote_ip => $new_ip->addr});
$schema->resultset('DeviceIp')
->search({alias => $device->ip})
->update({alias => $new_ip->addr});
$schema->resultset('Admin')
->search({device => $device->ip})
->update({device => $new_ip->addr});
$schema->resultset('Node')
->search({switch => $device->ip})
->update({switch => $new_ip->addr});
$schema->resultset('Topology')
->search({dev1 => $device->ip})
->update({dev1 => $new_ip->addr});
$schema->resultset('Topology')
->search({dev2 => $device->ip})
->update({dev2 => $new_ip->addr});
$device->update({ip => $new_ip->addr});
return $device;
}
=head1 ADDITIONAL COLUMNS
=head2 port_count

View File

@@ -195,20 +195,6 @@ __PACKAGE__->might_have(
}
);
=head2 ssid
Returns a row from the C<device_port_ssid> table if one refers to this
device port.
=cut
__PACKAGE__->might_have(
ssid => 'App::Netdisco::DB::Result::DevicePortSsid',
{ 'foreign.ip' => 'self.ip',
'foreign.port' => 'self.port',
}
);
=head2 wireless
Returns a row from the C<device_port_wireless> table if one refers to this

View File

@@ -9,6 +9,7 @@ our @EXPORT = ();
our @EXPORT_OK = qw/
get_device
delete_device
renumber_device
check_device_no
check_device_only
is_discoverable
@@ -95,6 +96,36 @@ sub delete_device {
return $happy;
}
=head2 renumber_device( $current_ip, $new_ip )
Will update all records in Netdisco referring to the device with
C<$current_ip> to use C<$new_ip> instead, followed by renumbering the device
iteself.
Returns true if the transaction completes, else returns false.
=cut
sub renumber_device {
my ($ip, $new_ip) = @_;
my $device = get_device($ip) or return 0;
return 0 if not $device->in_storage;
my $happy = 0;
schema('netdisco')->txn_do(sub {
schema('netdisco')->resultset('UserLog')->create({
username => session('logged_in_user'),
userip => scalar eval {request->remote_address},
event => "Renumbered device from $ip to $new_ip",
});
$device->renumber($new_ip);
$happy = 1;
});
return $happy;
}
=head2 check_device_no( $ip, $setting_name )
Given the IP address of a device, returns true if the configuration setting