fix use of snmp_connect_ip which does not work for SNMPv3

This commit is contained in:
Oliver Gorwits
2017-11-16 22:10:18 +00:00
parent 68a56d35bb
commit 5aff19621c
3 changed files with 37 additions and 5 deletions

View File

@@ -1,6 +1,8 @@
package App::Netdisco::Transport::SNMP;
use Dancer qw/:syntax :script/;
use Dancer::Plugin::DBIC 'schema';
use App::Netdisco::Util::SNMP 'get_communities';
use App::Netdisco::Util::Device 'get_device';
use App::Netdisco::Util::Permission ':all';
@@ -9,6 +11,7 @@ use SNMP::Info;
use Try::Tiny;
use Module::Load ();
use Path::Class 'dir';
use NetAddr::IP::Lite ':lower';
use base 'Dancer::Object::Singleton';
@@ -61,6 +64,34 @@ sub reader_for {
= _snmp_connect_generic('read', $device, $useclass));
}
=head1 test_connection( $ip )
Similar to C<reader_for> but will use the literal IP address passed, and does
not support specifying the device class. The purpose is to test the SNMP
connectivity to the device before a renumber.
Attempts to have no side effect, however there will be a stored SNMP
authentication hint (tag) in the database if the connection is successful.
Returns C<undef> if the connection fails.
=cut
sub test_connection {
my ($class, $ip) = @_;
my $addr = NetAddr::IP::Lite->new($ip) or return undef;
# avoid renumbering to localhost loopbacks
return undef if $addr->addr eq '0.0.0.0'
or check_acl_no($addr->addr, 'group:__LOCAL_ADDRESSES__');
my $device = schema('netdisco')->resultset('Device')
->new_result({ ip => $addr->addr }) or return undef;
my $readers = $class->instance->readers or return undef;
return $readers->{$device->ip} if exists $readers->{$device->ip};
debug sprintf 'snmp reader cache warm: [%s]', $device->ip;
return ($readers->{$device->ip}
= _snmp_connect_generic('read', $device, $useclass));
}
=head1 writer_for( $ip, $useclass? )
Same as C<reader_for> but uses the read-write community strings from the

View File

@@ -1,6 +1,7 @@
package App::Netdisco::Util::SNMP;
use Dancer qw/:syntax :script/;
use App::Netdisco::Util::DNS 'hostname_from_ip';
use App::Netdisco::Util::Permission ':all';
use base 'Exporter';
@@ -138,7 +139,8 @@ sub get_communities {
# clean the community table of obsolete tags
eval { $device->community->update({$tag_name => undef}) }
if not $stored_tag or !exists $seen_tags->{ $stored_tag };
if $device->in_storage
and (not $stored_tag or !exists $seen_tags->{ $stored_tag });
return ( @communities, @$config );
}
@@ -147,7 +149,7 @@ sub _get_external_community {
my ($device, $mode) = @_;
my $cmd = setting('get_community');
my $ip = $device->ip;
my $host = $device->dns || $ip;
my $host = ($device->dns || hostname_from_ip($ip) || $ip);
if (defined $cmd and length $cmd) {
# replace variables

View File

@@ -22,7 +22,7 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub {
my $revofname = ipv4_from_hostname($snmp->name);
if (setting('reverse_sysname') and $revofname) {
if ($snmp->snmp_connect_ip( $new_ip )) {
if (App::Netdisco::Transport::SNMP->test_connection( $new_ip )) {
$new_ip = $revofname;
}
else {
@@ -46,8 +46,7 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub {
if (check_acl_only($device, $key)
and check_acl_only($alias, $map->{$key})) {
# if ($snmp->snmp_connect_ip( $alias->alias )) { FIXME
if (App::Netdisco::Transport::SNMP->reader_for( $alias->alias )) {
if (App::Netdisco::Transport::SNMP->test_connection( $alias->alias )) {
$new_ip = $alias->alias;
last ALIAS;
}