diff --git a/Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/DeviceActions.pm b/Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/DeviceActions.pm index effab7a4..0ac7c69b 100644 --- a/Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/DeviceActions.pm +++ b/Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/DeviceActions.pm @@ -22,7 +22,7 @@ sub _set_device_generic { $data ||= ''; # snmp connect using rw community - my $info = snmp_connect($ip) + my $info = snmp_connect_rw($ip) or return error("Failed to connect to device [$ip] to update $slot"); my $method = 'set_'. $slot; diff --git a/Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/PortActions.pm b/Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/PortActions.pm index 01c51740..59cf6c25 100644 --- a/Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/PortActions.pm +++ b/Netdisco/lib/App/Netdisco/Daemon/Worker/Interactive/PortActions.pm @@ -56,7 +56,7 @@ sub _set_port_generic { or return error("Unknown port name [$pn] on device [$ip]"); # snmp connect using rw community - my $info = snmp_connect($ip) + my $info = snmp_connect_rw($ip) or return error("Failed to connect to device [$ip] to control port"); my $iid = get_iid($info, $port) @@ -104,7 +104,7 @@ sub set_power { (my $data = $job->subaction) =~ s/-\w+//; # snmp connect using rw community - my $info = snmp_connect($ip) + my $info = snmp_connect_rw($ip) or return error("Failed to connect to device [$ip] to control port"); my $powerid = get_powerid($info, $port) diff --git a/Netdisco/lib/App/Netdisco/Util/SNMP.pm b/Netdisco/lib/App/Netdisco/Util/SNMP.pm index 56be3f00..27317bde 100644 --- a/Netdisco/lib/App/Netdisco/Util/SNMP.pm +++ b/Netdisco/lib/App/Netdisco/Util/SNMP.pm @@ -10,7 +10,7 @@ use Path::Class 'dir'; use base 'Exporter'; our @EXPORT = (); our @EXPORT_OK = qw/ - snmp_connect + snmp_connect snmp_connect_rw /; our %EXPORT_TAGS = (all => \@EXPORT_OK); @@ -33,16 +33,39 @@ Given an IP address, returns an L instance configured for and connected to that device. The IP can be any on the device, and the management interface will be connected to. +If the device is known to Netdisco and there is a cached SNMP community +string, this will be tried first, and then other community string(s) from the +application configuration will be tried. + Returns C if the connection fails. =cut -sub snmp_connect { +sub snmp_connect { _snmp_connect_generic(@_, 'community') } + +=head2 snmp_connect_rw( $ip ) + +Same as C but uses the read-write community string(s) from the +application configuration file. + +Returns C if the connection fails. + +=cut + +sub snmp_connect_rw { _snmp_connect_generic(@_, 'community_rw') } + +sub _snmp_connect_generic { my $ip = shift; # get device details from db - my $device = get_device($ip) - or return (); + my $device = get_device($ip); + + # get the community string(s) + my $comm_type = pop; + my @communities = @{ setting($comm_type) || []}; + unshift @communities, $device->snmp_comm + if length $device->snmp_comm + and length $comm_type and $comm_type eq 'community'; # TODO: only supporing v2c at the moment my %snmp_args = ( @@ -58,7 +81,7 @@ sub snmp_connect { my $info = undef; my $last_comm = 0; - COMMUNITY: foreach my $c ($device->snmp_comm, @{ setting('community_rw') || []}) { + COMMUNITY: foreach my $c (@communities) { next unless defined $c and length $c; try { $info = SNMP::Info->new(%snmp_args, Community => $c);