Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
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

Replies are listed 'Best First'.
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?
[marto]: good morning all
[Corion]: Hi marto!
[Corion]: The fun show at $work continues, as The Big Project is now in its second week of frantic live-bugfixing and weekend releases where nobody knows what went live. Nothing has been tested anyway.
erix mutters cantankerously under his breath
Corion watches from the sidelines. Or rather, from behind, as my system only gets output from that process and my programs adhere strictly to the GIGO design principle.
[erix]: ah, that's nice to hear Corion :)
[Corion]: erix: Yeah, the sad thing is that all I can do is document things, so I can point fingers when the auditors come :-/
[Corion]: "I'm here to open tickets and point fingers. And I'm all out of tickets."
[erix]: didn't Sybase have pretty good auditing? :) (this is a vague memory)

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (8)
As of 2017-03-28 08:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Should Pluto Get Its Planethood Back?



    Results (328 votes). Check out past polls.