Major Changes.

1. Changed internal storage of function data from iid -> attr -> val to attr -> iid -> val
2. Changed object name space :
    $info{name}  is a object variable
    $info{_name} is a cached entry or flag for cached entry
3. Added error reporting for silent usage of class with $self->error()
4. Added more object instance methods for instance data for more OO like behavior
5. API HAS CHANGED -- load_all() and all() return new data structure.  These were internal functions,
   but listed in example (groan)
This commit is contained in:
Max Baker
2003-04-21 21:43:39 +00:00
parent f2754b80bb
commit 69645321cd

220
Info.pm
View File

@@ -7,7 +7,7 @@
# See COPYRIGHT below # See COPYRIGHT below
package SNMP::Info; package SNMP::Info;
$VERSION = 0.3; $VERSION = 0.4;
use strict; use strict;
use Exporter; use Exporter;
@@ -26,7 +26,7 @@ SNMP::Info - Perl5 Interface to Network devices through SNMP.
=head1 VERSION =head1 VERSION
SNMP::Info - Version 0.3 SNMP::Info - Version 0.4
=head1 AUTHOR =head1 AUTHOR
@@ -359,7 +359,7 @@ Creates a new object and connects via SNMP::Session.
'Version' => 2 'Version' => 2
) or die; ) or die;
Arguments : SNMP::Info Specific Arguments :
AutoSpecify = Returns an object of a more specific device class AutoSpecify = Returns an object of a more specific device class
*See specify() entry* *See specify() entry*
@@ -379,23 +379,20 @@ sub new {
my $new_obj = {}; my $new_obj = {};
bless $new_obj,$class; bless $new_obj,$class;
$new_obj->{_class} = $class; $new_obj->{class} = $class;
# load references to all the subclass data structures # load references to all the subclass data structures
{ {
no strict 'refs'; no strict 'refs';
$new_obj->{_init} = \${$class . '::INIT'}; $new_obj->{init} = \${$class . '::INIT'};
$new_obj->{_mibs} = \%{$class . '::MIBS'}; $new_obj->{mibs} = \%{$class . '::MIBS'};
$new_obj->{_globals} = \%{$class . '::GLOBALS'}; $new_obj->{globals} = \%{$class . '::GLOBALS'};
$new_obj->{_funcs} = \%{$class . '::FUNCS'}; $new_obj->{funcs} = \%{$class . '::FUNCS'};
$new_obj->{_munge} = \%{$class . '::MUNGE'}; $new_obj->{munge} = \%{$class . '::MUNGE'};
} }
# SNMP version
$new_obj->{_version} = $args{Version};
$new_obj->{_community} = $args{Community};
# Initialize mibs if not done # Initialize mibs if not done
my $init_ref = $new_obj->{_init}; my $init_ref = $new_obj->{init};
unless ( $$init_ref ) { unless ( $$init_ref ) {
$new_obj->init(); $new_obj->init();
$$init_ref=1; $$init_ref=1;
@@ -421,23 +418,26 @@ sub new {
delete $args{BigInt}; delete $args{BigInt};
} }
# Save Args for later
$new_obj->{_args} = \%args;
# Connects to device unless open session is provided. # Connects to device unless open session is provided.
$sess = new SNMP::Session( 'UseEnums' => 1, $sess = new SNMP::Session( 'UseEnums' => 1, %args )
%args unless defined $sess;
) unless defined $sess;
unless (defined $sess){ unless (defined $sess){
$DEBUG and carp("SNMP::Info::new() Failed to Create Session. ", defined $sess->{ErrorStr} ? $sess->{ErrorStr} : '', "\n"); $new_obj->{error} = "SNMP::Info::new() Failed to Create Session. ".
$sess->{ErrorStr} || '';
$DEBUG and carp($new_obj->error());
return undef; return undef;
} }
$new_obj->{sess} = $sess; # Table function store
my $store = {}; my $store = {};
# Save Args for later
$new_obj->{store} = $store; $new_obj->{store} = $store;
$new_obj->{sess} = $sess;
$new_obj->{args} = \%args;
$new_obj->{snmp_ver} = $args{Version};
$new_obj->{snmp_comm} = $args{Community};
return $auto_specific ? return $auto_specific ?
$new_obj->specify() : $new_obj; $new_obj->specify() : $new_obj;
@@ -562,6 +562,8 @@ Returns an object of a more-specific subclass.
# Returns more specific object type # Returns more specific object type
$info = $info->specific(); $info = $info->specific();
Usually this method is called internally from new(AutoSpecify => 1)
See device_type() entry for how a sub class is chosen. See device_type() entry for how a sub class is chosen.
=cut =cut
@@ -570,8 +572,9 @@ sub specify {
my $device_type = $self->device_type(); my $device_type = $self->device_type();
unless (defined $device_type) { unless (defined $device_type) {
carp("SNMP::Info::specify() - Could not get info from device.\n"); $self->{error} = "SNMP::Info::specify() - Could not get info from device";
return $self; $DEBUG and print $self->error();
return undef;
} }
return $self if $device_type eq 'SNMP::Info'; return $self if $device_type eq 'SNMP::Info';
@@ -579,7 +582,7 @@ sub specify {
# By evaling a string the contents of device_type now becomes a bareword. # By evaling a string the contents of device_type now becomes a bareword.
eval "require $device_type;"; eval "require $device_type;";
if ($@) { if ($@) {
print "SNMP::Info::specify() Loading $device_type Failed. $@\n"; croak "SNMP::Info::specify() Loading $device_type Failed. $@\n";
} }
my $args = $self->args(); my $args = $self->args();
@@ -587,7 +590,8 @@ sub specify {
my $sub_obj = $device_type->new(%$args,'Session'=>$session); my $sub_obj = $device_type->new(%$args,'Session'=>$session);
unless (defined $sub_obj) { unless (defined $sub_obj) {
carp("SNMP::Info::specify() - Could not connect with new class ($device_type).\n"); $self->{error} = "SNMP::Info::specify() - Could not connect with new class ($device_type).";
carp($self->error() );
return $self; return $self;
} }
@@ -1239,11 +1243,6 @@ Used internally. Loads all entries in %MIBS.
sub init { sub init {
my $self = shift; my $self = shift;
my $ver = $self->{_version};
if (defined $ver and $ver == 1){
# do nothing
}
&SNMP::initMib; &SNMP::initMib;
my $version = $SNMP::VERSION; my $version = $SNMP::VERSION;
@@ -1264,7 +1263,7 @@ sub init {
&SNMP::loadModules("$mib"); &SNMP::loadModules("$mib");
unless (defined $SNMP::MIB{$mibs->{$mib}}){ unless (defined $SNMP::MIB{$mibs->{$mib}}){
croak "The $mib did not load. See README for $self->{_class}\n"; croak "The $mib did not load. See README for $self->{class}\n";
} }
} }
@@ -1291,7 +1290,7 @@ Returns a reference to the argument hash supplied to SNMP::Session
=cut =cut
sub args { sub args {
my $self = shift; my $self = shift;
return $self->{_args}; return $self->{args};
} }
=item $info->class() =item $info->class()
@@ -1301,7 +1300,28 @@ Returns the class name of the object.
=cut =cut
sub class { sub class {
my $self=shift; my $self=shift;
return $self->{_class}; return $self->{class};
}
=item $info->error(no_new_line)
Returns Error message if error, or undef if not.
Pass a 1 as the first argument if you don't want a new line.
=cut
sub error {
my $self = shift;
my $no_nl = shift;
my $err = $self->{error};
if (defined $no_nl and $no_nl and $err =~ /\n$/) {
$err =~ s/\n$//;
return $err;
}
if ($err !~ /\n$/) {
$err .= "\n";
}
return $err;
} }
=item $info->funcs() =item $info->funcs()
@@ -1311,17 +1331,7 @@ Returns a reference to the %FUNCS hash.
=cut =cut
sub funcs { sub funcs {
my $self=shift; my $self=shift;
return $self->{_funcs}; return $self->{funcs};
}
=item $info->mibs()
Returns a reference to the %MIBS hash.
=cut
sub mibs {
my $self=shift;
return $self->{_mibs};
} }
=item $info->globals() =item $info->globals()
@@ -1331,10 +1341,20 @@ Returns a reference to the %GLOBALS hash.
=cut =cut
sub globals { sub globals {
my $self=shift; my $self=shift;
return $self->{_globals}; return $self->{globals};
} }
=item $info->mibs()
Returns a reference to the %MIBS hash.
=cut
sub mibs {
my $self=shift;
return $self->{mibs};
}
=item $info->munge() =item $info->munge()
Returns a reference ot the %MUNGE hash. Returns a reference ot the %MUNGE hash.
@@ -1342,7 +1362,7 @@ Returns a reference ot the %MUNGE hash.
=cut =cut
sub munge { sub munge {
my $self=shift; my $self=shift;
return $self->{_munge}; return $self->{munge};
} }
=item $info->session() =item $info->session()
@@ -1356,6 +1376,39 @@ sub session {
return $self->{sess}; return $self->{sess};
} }
=item $info->snmp_comm()
Returns SNMP Community string used in conncetion
=cut
sub snmp_comm {
my $self = shift;
return $self->{snmp_comm};
}
=item $info->snmp_ver()
Returns SNMP Version used for this connection
=cut
sub snmp_ver {
my $self = shift;
return $self->{snmp_ver};
}
=item $info->store()
Returns hash store for Table functions.
$info->store = { attribute => { iid => value , iid2 => value2, ... } };
=cut
sub store {
my $self = shift;
return $self->{store};
}
=back =back
=head3 Functions for SNMP Scalars (%GLOBALS) =head3 Functions for SNMP Scalars (%GLOBALS)
@@ -1372,7 +1425,7 @@ Example: $info->name() calls autoload which calls $info->_global('name').
sub _global{ sub _global{
my $self = shift; my $self = shift;
my $attr = shift; my $attr = shift;
my $sess = $self->{sess}; my $sess = $self->session();
return undef unless defined $sess; return undef unless defined $sess;
my $globals = $self->globals(); my $globals = $self->globals();
@@ -1388,17 +1441,20 @@ sub _global{
my $val = $sess->get($oid); my $val = $sess->get($oid);
if ($sess->{ErrorStr} ){ if ($sess->{ErrorStr} ){
$DEBUG and print "SNMP::Info::_global($attr) $sess->{ErrorStr}\n"; $self->{error} = "SNMP::Info::_global($attr) $sess->{ErrorStr}";
$DEBUG and print $self->error();
return undef; return undef;
} }
if (defined $val and $val eq 'NOSUCHOBJECT'){ if (defined $val and $val eq 'NOSUCHOBJECT'){
$DEBUG and print "SNMP::Info::_global($attr) NOSUCHOBJECT\n"; $self->{error} = "SNMP::Info::_global($attr) NOSUCHOBJECT";
$DEBUG and print $self->error();
return undef; return undef;
} }
if (defined $val and $val eq 'NOSUCHINSTANCE'){ if (defined $val and $val eq 'NOSUCHINSTANCE'){
$DEBUG and print "SNMP::Info::_global($attr) NOSUCHINSTANCE\n"; $self->{error} = "SNMP::Info::_global($attr) NOSUCHINSTANCE";
$DEBUG and print $self->error();
return undef; return undef;
} }
# Get the callback hash for data munging # Get the callback hash for data munging
@@ -1411,7 +1467,7 @@ sub _global{
} }
# Save Cached Value # Save Cached Value
$self->{"__$attr"} = $val; $self->{"_$attr"} = $val;
return $val; return $val;
} }
@@ -1432,7 +1488,7 @@ sub _set {
$iid = ".$iid" unless $iid =~ /^\./; $iid = ".$iid" unless $iid =~ /^\./;
my $sess = $self->{sess}; my $sess = $self->session();
return undef unless defined $sess; return undef unless defined $sess;
my $funcs = $self->funcs(); my $funcs = $self->funcs();
@@ -1444,18 +1500,21 @@ sub _set {
$oid = $funcs->{$attr} if defined $funcs->{$attr}; $oid = $funcs->{$attr} if defined $funcs->{$attr};
unless (defined $oid) { unless (defined $oid) {
print "SNMP::Info::_set($attr,$val) - Failed to find $attr in \%GLOBALS or \%FUNCS \n"; $self->{error} = "SNMP::Info::_set($attr,$val) - Failed to find $attr in \%GLOBALS or \%FUNCS";
carp($self->error());
return undef; return undef;
} }
$oid .= $iid; $oid .= $iid;
print "SNMP::Info::_set $attr$iid ($oid) = $val\n" if $DEBUG; $DEBUG and print "SNMP::Info::_set $attr$iid ($oid) = $val\n";
my $rv = $sess->set($oid,$val); my $rv = $sess->set($oid,$val);
print "SNMP::Info::_set $attr$iid $sess->{ErrorStr}\n" if ($sess->{ErrorStr}){
if ($DEBUG and $sess->{ErrorStr}); $self->{error} = "SNMP::Info::_set $attr$iid $sess->{ErrorStr}";
$DEBUG and print $self->error();
}
return $rv; return $rv;
} }
@@ -1468,15 +1527,18 @@ sub _set {
=item $info->load_all() =item $info->load_all()
Runs $info->load_METHOD() for each entry in %FUNCS. Loads all possible function data for this class.
Returns { iid => values_hash } where value_hash is in the format: Runs $info->load_METHOD() for each entry in $info->funcs();
{ attribute => value }
Returns $info->store() -- See store() entry.
Note return value has changed since version 0.3
=cut =cut
sub load_all { sub load_all {
my $self = shift; my $self = shift;
my $sess = $self->{sess}; my $sess = $self->session();
return undef unless defined $sess; return undef unless defined $sess;
my $funcs = $self->funcs(); my $funcs = $self->funcs();
@@ -1488,24 +1550,26 @@ sub load_all {
$self->{_all}++; $self->{_all}++;
return $self->{store} if defined wantarray; return $self->store() if defined wantarray;
} }
=item $info->all() =item $info->all()
Runs $info->load_all() once then returns the cached data. Runs $info->load_all() once then returns $info->store();
Use $info->load_all() to reload the data. Use $info->load_all() to reload the data.
Note return value has changed since version 0.3
=cut =cut
sub all { sub all {
my $self = shift; my $self = shift;
my $sess = $self->{sess}; my $sess = $self->session();
return undef unless defined $sess; return undef unless defined $sess;
$self->load_all() unless defined $self->{_all}; $self->load_all() unless defined $self->{_all};
return $self->{store}; return $self->store();
} }
@@ -1520,8 +1584,8 @@ sub _load_attr {
my $self = shift; my $self = shift;
my ($attr,$leaf) = @_; my ($attr,$leaf) = @_;
my $sess = $self->{sess}; my $sess = $self->session();
my $store = $self->{store}; my $store = $self->store();
return undef unless defined $sess; return undef unless defined $sess;
# Get the callback hash for data munging # Get the callback hash for data munging
@@ -1558,7 +1622,7 @@ sub _load_attr {
$val = &$subref($val); $val = &$subref($val);
} }
$store->{$iid}->{$attr}=$val; $store->{$attr}->{$iid}=$val;
} }
# mark data as loaded # mark data as loaded
@@ -1580,20 +1644,9 @@ sub _show_attr {
my $self = shift; my $self = shift;
my $attr = shift; my $attr = shift;
my $store = $self->{store}; my $store = $self->store();
return undef unless (scalar keys %$store);
my %ret_hash; return $store->{$attr};
foreach my $iid (keys %$store){
next unless (defined $store->{$iid}->{$attr});
my $val = $store->{$iid}->{$attr};
$ret_hash{$iid}= $val;
}
return \%ret_hash;
} }
=back =back
@@ -1641,7 +1694,8 @@ sub AUTOLOAD {
unless( defined $funcs{$attr} or unless( defined $funcs{$attr} or
defined $globals{$attr} ) { defined $globals{$attr} ) {
#print "$attr not found in ",join(',',keys %funcs),"\n"; $self->{error} = "SNMP::Info::AUTOLOAD($attr) Attribute not found in this device class.";
$DEBUG and print($self->error());
return; return;
} }
@@ -1658,7 +1712,7 @@ sub AUTOLOAD {
# First check %GLOBALS and return _scalar(global) # First check %GLOBALS and return _scalar(global)
if (defined $globals{$attr} ){ if (defined $globals{$attr} ){
# Return Cached Value if exists # Return Cached Value if exists
return $self->{"__${attr}"} if defined $self->{"__${attr}"}; return $self->{"_${attr}"} if defined $self->{"_${attr}"};
# Fetch New Value # Fetch New Value
return $self->_global( $attr ); return $self->_global( $attr );
} }