Beefy Boxes and Bandwidth Generously Provided by pair Networks chromatic writing perl on a camel
No such thing as a small change
 
PerlMonks  

Hash of Hashes, referencing, dereferencing and Net::SNMP

by smullis (Pilgrim)
on Oct 06, 2004 at 10:58 UTC ( #396945=perlquestion: print w/ replies, xml ) Need Help??
smullis has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

Here goes:

We have around 3000 routers and a configuration database with entries created when the devices are commissioned. In order to ensure the integrity and accuracy of the recorded data I have a bash shell script that grabs the list of all devices and a few config variables (such as community strings, device type, line speed etc) and then double checks the validity of the config against the live device settings.

I am in the process of converting to Perl (from the original, and very slow bash script).

(Obviously, "perl -w" and "use strict" are used!)

So, I grab the list using LWP:

my $browser = LWP::UserAgent->new(); my $source_data = $browser->get( $config{source_file} ); die( "Couldn't GET $config{source_file}\n" ) unless defined $source_da +ta; print "Got source data\n"; my $results_table; my @all_results = split /\n/, $source_data->{_content}; for ( @all_results ) { next if $_ =~ m/^\#/; my ( $site_name, $line_speed, $mgmt_ip, $switch_port, $ro_community, +$group, $site_code ) = split /\|/;
I then populate a HoH:
$results_table->{$group}->{$site_name} = { line_speed => $line_spee +d, mgmt_ip => $mgmt_ip, switch_port => $switch_po +rt, ro_community => $ro_commun +ity, site_code => $site_code +, oss_device => $oss_devic +e, snmp_status => '', sysobjid => '', };
At this point I set up non-blocking Net::SNMP sessions and use callback to launch a subfunction to, in this example, add the mib2 sysobjid to the HoH:
my ($session, $error) = Net::SNMP->session( -community => $results_table->{$group}->{$site_name}->{ro_commun +ity}, -hostname => $results_table->{$group}->{$site_name}->{mgmt_ip +}, -nonblocking => 0x1, # Create non-blocking objects ); if (!defined($session)) { printf("ERROR: %s.\n", $error); exit 1; }
And:
$session->get_request( -varbindlist => [ $oids{sysobjid} ], -callback => [ \&store_sysobjid, \$group, \$site_name ] );
Now, close the for loop and get the ball rolling:
} snmp_dispatcher();
The subfunction:
sub store_sysobjid { my ($session, $group, $site_name ) = @_; if (!defined($session->var_bind_list)) { $results_table->{$$group}}->{$$site_name} = { sysobjid => "unknown", snmp_status => "NOT OK +", }; printf("%-15s ERROR: %s\n", $session->hostname, $session->error); } else { $results_table->{$$group}->{$$site_name} = { sysobjid => ${$session +->var_bind_list}{$oids{sysobjid}}, snmp_status => "OK"}; } }

Now, it has taken me a little while to get the referencing / dereferencing syntax working correctly but this seems OK now.

My questions:

1. When I use Data::Dumper to get the contents of \$results_table the sysbojid and snmp_status variables seem to have zapped the rest of the data on the HoH for that site out of existence. Is the syntax incorrect? If I remove the sysobjid => unknown code then any site that is down (i.e. has its snmp allowed managers configured incorrectly) retains the line_speed / mgmt_ip data correctly.

2. Is using a HoH an appropriate approach? My thoughts were to use a HoH so that when I have all of the data I can chuck out all of the relevant HTML pages quite easily.

FYI - Using non-blocking Net::SNMP has reduced the runtime of this from around 20-30 minutes for the shell script (which ran serially) to around 24 seconds (WoooHooo!)

Any comments / suggestions / criticisms are more than welcome.

I am here to learn.

Thanks

smullis

Comment on Hash of Hashes, referencing, dereferencing and Net::SNMP
Select or Download Code
Re: Hash of Hashes, referencing, dereferencing and Net::SNMP
by matija (Priest) on Oct 06, 2004 at 12:16 UTC
    Well, the problem is here:
    $results_table->{$$group}}->{$$site_name} = { sysobjid => "unknown", snmp_status => "NOT OK +", };
    Contrary to what might be convenient, you are assigning a whole new hash reference (and leaving the old hash orphaned and subject to garbage collection).

    You will have to break the statement down into two parts:

    results_table->{$$group}}->{$$site_name}->{sysobjid}="unknown; results_table->{$$group}}->{$$site_name}->{snmp_status}="NOT OK";
      You will have to break the statement down into two parts:
      results_table->{$$group}}->{$$site_name}->{sysobjid}="unknown; results_table->{$$group}}->{$$site_name}->{snmp_status}="NOT OK";

      If you want to put the convenience back then use a fake loop to avoid the repetition:

      for ($results_table->{$$group}{$$site_name}) { $_->{sysobjid} = 'unknown'; $_->{snmp_status} = 'NOT OK'; }
      Smylers
      You will have to break the statement down into two parts

      Another approach would be using a hash slice:

      my $site = results_table->{$$group}->{$$site_name}; # for convenience @{ $site }{("sysobjid", "snmp_status")} = ("unknown", "NOT OK");
Re: Hash of Hashes, referencing, dereferencing and Net::SNMP
by Smylers (Pilgrim) on Oct 06, 2004 at 15:45 UTC
    Any comments / suggestions / criticisms are more than welcome.

    I think you're making life overly complicated for yourself by passing $group and $sitename by reference. If you omit the backslashes from before them in the -callback line and then use single rather than double dollar signs inside store_sysobjid everything should still work.

    Smylers

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://396945]
Approved by Paulster2
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (9)
As of 2014-04-16 05:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (414 votes), past polls