refactor snmp_connect to handle versions and device classes

This commit is contained in:
Oliver Gorwits
2013-04-13 19:07:44 +01:00
parent ca9edd114a
commit 78554e5516
2 changed files with 74 additions and 25 deletions

View File

@@ -95,7 +95,7 @@ sub store_device {
$device->$property( $snmp->$property );
}
$device->snmp_class( $snmp->class );
$device->snmp_class( $snmp->device_type );
$device->last_discover(\'now()');
schema('netdisco')->txn_do(sub {

View File

@@ -60,6 +60,30 @@ sub _snmp_connect_generic {
# get device details from db
my $device = get_device($ip);
# TODO: only supporing v2c at the moment
my %snmp_args = (
DestHost => $device->ip,
Retries => (setting('snmpretries') || 2),
Timeout => (setting('snmptimeout') || 1000000),
MibDirs => [ _build_mibdirs() ],
IgnoreNetSNMPConf => 1,
Debug => ($ENV{INFO_TRACE} || 0),
);
# TODO: add version force support
# use existing SNMP version or try 2, 1
my @versions = (($device->snmp_ver || setting('snmpver') || 2));
push @versions, 1;
# use existing or new device class
my @classes = ('SNMP::Info');
if ($device->snmp_class) {
unshift @classes, $device->snmp_class;
}
else {
$snmp_args{AutoSpecity} = 1;
}
# get the community string(s)
my $comm_type = pop;
my @communities = @{ setting($comm_type) || []};
@@ -67,32 +91,57 @@ sub _snmp_connect_generic {
if length $device->snmp_comm
and length $comm_type and $comm_type eq 'community';
# TODO: only supporing v2c at the moment
my %snmp_args = (
DestHost => $device->ip,
Version => ($device->snmp_ver || setting('snmpver') || 2),
Retries => (setting('snmpretries') || 2),
Timeout => (setting('snmptimeout') || 1000000),
MibDirs => [ _build_mibdirs() ],
AutoSpecify => 1,
IgnoreNetSNMPConf => 1,
Debug => ($ENV{INFO_TRACE} || 0),
my $info = undef;
VERSION: foreach my $ver (@versions) {
next unless length $ver;
CLASS: foreach my $class (@classes) {
next unless length $class;
COMMUNITY: foreach my $comm (@communities) {
next unless length $comm;
$info = _try_connect($ver, $class, $comm, \%snmp_args)
and last VERSION;
}
}
}
return $info;
}
sub _try_connect {
my ($ver, $class, $comm, $snmp_args) = @_;
my $info = undef;
try {
debug
sprintf '[%s] try_connect with ver: %s, class: %s, comm: %s',
$snmp_args->{DestHost}, $ver, $class, $comm;
eval "require $class";
$info = $class->new(%$snmp_args, Version => $ver, Community => $comm);
undef $info unless (
(not defined $info->error)
and length $info->uptime
and ($info->layers or $info->description)
and $info->class
);
my $info = undef;
my $last_comm = 0;
COMMUNITY: foreach my $c (@communities) {
next unless defined $c and length $c;
try {
$info = SNMP::Info->new(%snmp_args, Community => $c);
++$last_comm if (
$info
and (not defined $info->error)
and length $info->uptime
);
};
last COMMUNITY if $last_comm;
# first time a device is discovered, re-instantiate into specific class
if ($info and $info->device_type ne $class) {
$class = $info->device_type;
debug
sprintf '[%s] try_connect with ver: %s, new class: %s, comm: %s',
$snmp_args->{DestHost}, $ver, $class, $comm;
eval "require $class";
$info = $class->new(%$snmp_args, Version => $ver, Community => $comm);
}
}
catch {
debug $_;
};
return $info;
}