package App::Netdisco::Worker::Plugin::Discover::CanonicalIP; use Dancer ':syntax'; use App::Netdisco::Worker::Plugin; use aliased 'App::Netdisco::Worker::Status'; use App::Netdisco::Transport::SNMP (); use App::Netdisco::Util::Permission 'check_acl_only'; use App::Netdisco::Util::DNS 'ipv4_from_hostname'; use Dancer::Plugin::DBIC 'schema'; register_worker({ stage => 'second', driver => 'snmp' }, sub { my ($job, $workerconf) = @_; my $device = $job->device; my $snmp = App::Netdisco::Transport::SNMP->reader_for($device) or return Status->defer("discover failed: could not SNMP connect to $device"); my $old_ip = $device->ip; my $new_ip = $old_ip; my $revofname = ipv4_from_hostname($snmp->name); if (setting('reverse_sysname') and $revofname) { if ($snmp->snmp_connect_ip( $new_ip )) { $new_ip = $revofname; } else { debug sprintf ' [%s] device - cannot renumber to %s - SNMP connect failed', $old_ip, $revofname; } } if (scalar @{ setting('device_identity') }) { my @idmaps = @{ setting('device_identity') }; my $devips = $device->device_ips->order_by('alias'); ALIAS: while (my $alias = $devips->next) { next if $alias->alias eq $old_ip; foreach my $map (@idmaps) { next unless ref {} eq ref $map; foreach my $key (sort keys %$map) { # lhs matches device, rhs matches device_ip if (check_acl_only($device, $key) and check_acl_only($alias, $map->{$key})) { if ($snmp->snmp_connect_ip( $alias->alias )) { $new_ip = $alias->alias; last ALIAS; } else { debug sprintf ' [%s] device - cannot renumber to %s - SNMP connect failed', $old_ip, $alias->alias; } } } } } # ALIAS } return Status->done('Ended discover for '. $device->ip) if $new_ip eq $old_ip; schema('netdisco')->txn_do(sub { # delete target device with the same vendor and serial number schema('netdisco')->resultset('Device')->search({ ip => $new_ip, vendor => $device->vendor, serial => $device->serial, })->delete; # if target device exists then this will die $device->renumber($new_ip) or die "cannot renumber to: $new_ip"; # rollback debug sprintf ' [%s] device - changed IP to %s (%s)', $old_ip, $device->ip, ($device->dns || ''); }); return Status->done('Ended discover for '. $device->ip); }); true;