migrate from EUMM to Module::Build
This commit is contained in:
35
t/docmunge
35
t/docmunge
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/perl -i.bak
|
||||
#
|
||||
# [Re-]write POD to create cross-links between Required MIBs, GLOBALS
|
||||
# and TABLE METHODS sections.
|
||||
# This is a horrible jumble of heuristics, but works with
|
||||
# all of the existing files. It has only one false positive: HP.pm's
|
||||
# mention of an SNMP::Info version number.
|
||||
#
|
||||
$section = undef;
|
||||
$waiting = 0;
|
||||
while (<>) {
|
||||
if (eof) {
|
||||
$section = undef;
|
||||
$waiting = 0;
|
||||
}
|
||||
if (/^=head(\d)/) {
|
||||
$sl = $1;
|
||||
if ($sl <= $level) {
|
||||
$section = undef;
|
||||
}
|
||||
if (/(TABLE METHODS|GLOBALS|Required MIBs)/) {
|
||||
$section = $1;
|
||||
$level = $sl;
|
||||
if ($section eq 'TABLE METHODS' || $section eq 'GLOBALS') {
|
||||
$waiting = 1;
|
||||
}
|
||||
}
|
||||
if ($waiting && /imported/i) {
|
||||
$waiting = 0;
|
||||
}
|
||||
} elsif (defined($section) && !$waiting && /^[^=]/ && /SNMP::Info/) {
|
||||
s,(?:L<)?(SNMP::Info[a-zA-Z0-9:]*)(?:/[^>]+)?(?:>)?,L<$1/"$section">,g;
|
||||
}
|
||||
print;
|
||||
}
|
||||
@@ -1,338 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# $Id$
|
||||
|
||||
$DevMatrix = '../DeviceMatrix.txt';
|
||||
$DevHTML = 'DeviceMatrix.html';
|
||||
$DevPNG = 'DeviceMatrix.png';
|
||||
$Attributes= {};
|
||||
|
||||
# Parse Data File
|
||||
$matrix = parse_data($DevMatrix);
|
||||
|
||||
# Graph it for fun
|
||||
eval "use GraphViz::Data::Structure;";
|
||||
if ($@) {
|
||||
print "GraphViz::Data::Structure not installed. $@\n";
|
||||
} else {
|
||||
my %graph = ();
|
||||
foreach my $vendor (sort sort_nocase keys %$matrix){
|
||||
$graph{$vendor} = {};
|
||||
foreach my $family (sort sort_nocase keys %{$matrix->{$vendor}->{families}} ){
|
||||
my @models;
|
||||
foreach my $mod (keys %{$matrix->{$vendor}->{families}->{$family}->{models}}){
|
||||
push(@models,split(/\s*,\s*/,$mod));
|
||||
}
|
||||
if (scalar @models){
|
||||
$graph{$vendor}->{$family}=\@models;
|
||||
} else {
|
||||
$graph{$vendor}->{$family}=[];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
my $now = scalar localtime;
|
||||
my $gvds = GraphViz::Data::Structure->new(\%graph,Orientation=>'vertical',
|
||||
Colors=> 'Deep',
|
||||
graph => {label=>"SNMP::Info and Netdisco Supported Devices \n $now",'fontpath'=>'/usr/local/netdisco','fontname'=>'lucon',concentrate=>'true','overlap'=>'false',spline=>'true',bgcolor=>'wheat'},
|
||||
node => {fontname=>'lucon'},
|
||||
);
|
||||
$gvds->graph()->as_png($DevPNG);
|
||||
}
|
||||
|
||||
print "Creating $DevHTML\n";
|
||||
open (HTML, "> $DevHTML") or die "Can't open $DevHTML. $!\n";
|
||||
$old_fh = select(HTML);
|
||||
&html_head;
|
||||
print_vendors($matrix);
|
||||
foreach my $vendor (sort sort_nocase keys %$matrix){
|
||||
print "<A NAME=\"$vendor\"><SPAN CLASS=\"vendor\"><B>$vendor</B></SPAN></A>\n";
|
||||
print "<DL>\n";
|
||||
|
||||
my $vendor_defaults = $matrix->{$vendor}->{defaults};
|
||||
print_notes($vendor_defaults,1);
|
||||
|
||||
my $families = $matrix->{$vendor}->{families};
|
||||
foreach my $family (sort sort_nocase keys %$families ) {
|
||||
print "<DT>$family Family\n";
|
||||
|
||||
my $family_defaults = $families->{$family}->{defaults};
|
||||
print_notes($family_defaults,2);
|
||||
|
||||
my $models = $families->{$family}->{models};
|
||||
foreach my $model (sort sort_nocase keys %$models ){
|
||||
my $model_defaults = $models->{$model}->{defaults};
|
||||
print "<DD>$model\n";
|
||||
print "<DL>\n";
|
||||
print_notes($model_defaults,3);
|
||||
|
||||
print "<DT><DD><TABLE BORDER=1>\n";
|
||||
print_headers();
|
||||
print "<TR>\n";
|
||||
foreach my $a (sort sort_nocase keys %$Attributes) {
|
||||
my $val;
|
||||
next if $a eq 'note';
|
||||
$val = ['-'];
|
||||
$class = 'none';
|
||||
if (defined $model_defaults->{$a}) {
|
||||
$val = $model_defaults->{$a};
|
||||
$class = 'model';
|
||||
} elsif (defined $family_defaults->{$a}){
|
||||
$val = $family_defaults->{$a};
|
||||
$class = 'family';
|
||||
} elsif (defined $vendor_defaults->{$a}){
|
||||
$val = $vendor_defaults->{$a};
|
||||
$class = 'vendor';
|
||||
}
|
||||
print " <TD CLASS='$class'>",join("<BR>\n",@$val),"</TD>\n";
|
||||
}
|
||||
print "</TR></TABLE>\n";
|
||||
print "</DL>\n";
|
||||
}
|
||||
}
|
||||
print "</DL>\n";
|
||||
}
|
||||
|
||||
|
||||
&html_tail;
|
||||
|
||||
select ($old_fh);
|
||||
close (HTML) or die "Can't write $DevHTML. $!\n";
|
||||
|
||||
# Data Structures
|
||||
|
||||
# Matrix =
|
||||
# ( vendor => { families => { family => family_hash },
|
||||
# defaults => { cmd => [values] },
|
||||
# }
|
||||
# )
|
||||
|
||||
# Family Hash
|
||||
# ( models => { model => model_hash },
|
||||
# defaults => { cmd => [values] }
|
||||
# )
|
||||
|
||||
# Model Hash
|
||||
# ( defaults => { cmd => [values] } )
|
||||
sub parse_data {
|
||||
my $file = shift;
|
||||
my %ignore = map { $_ => 1 } @_;
|
||||
my $Matrix;
|
||||
|
||||
my @Lines;
|
||||
open (DM, "< $file") or die "Can't open $file. $!\n";
|
||||
{
|
||||
@Lines = <DM>;
|
||||
}
|
||||
close (DM);
|
||||
|
||||
my ($device,$family,$vendor,$class);
|
||||
foreach my $line (@Lines){
|
||||
chomp($line);
|
||||
# Comments
|
||||
$line =~ s/#.*//;
|
||||
|
||||
# Blank Lines
|
||||
next if $line =~ /^\s*$/;
|
||||
|
||||
# Trim whitespace
|
||||
$line =~ s/^\s+//;
|
||||
$line =~ s/\s+$//;
|
||||
|
||||
my ($cmd,$value);
|
||||
if ($line =~ /^([a-z-_]+)\s*:\s*(.*)$/) {
|
||||
$cmd = $1; $value = $2;
|
||||
} else {
|
||||
print "What do i do with this line : $line \n";
|
||||
next;
|
||||
}
|
||||
|
||||
if (exists $ignore{$cmd}){
|
||||
print "Ignoring $cmd\n";
|
||||
}
|
||||
# Set Class {vendor,family,device}
|
||||
if ($cmd eq 'device-vendor'){
|
||||
$vendor = $value;
|
||||
$family = $model = undef;
|
||||
$Matrix->{$vendor} = {} unless defined $Matrix->{$vendor};
|
||||
$class = $Matrix->{$vendor};
|
||||
$class->{defaults}->{type}='vendor';
|
||||
next;
|
||||
}
|
||||
|
||||
if ($cmd eq 'device-family'){
|
||||
$family = $value;
|
||||
$model = undef;
|
||||
print "$family has no vendor.\n" unless defined $vendor;
|
||||
$Matrix->{$vendor}->{families}->{$family} = {}
|
||||
unless defined $Matrix->{$vendor}->{families}->{$family};
|
||||
$class = $Matrix->{$vendor}->{families}->{$family};
|
||||
$class->{defaults}->{type}='family';
|
||||
next;
|
||||
}
|
||||
|
||||
if ($cmd eq 'device') {
|
||||
$model = $value;
|
||||
print "$model has no family.\n" unless defined $family;
|
||||
print "$model has no vendor.\n" unless defined $vendor;
|
||||
$Matrix->{$vendor}->{families}->{$family}->{models}->{$model} = {}
|
||||
unless defined $Matrix->{$vendor}->{families}->{$family}->{models}->{$model};
|
||||
$class = $Matrix->{$vendor}->{families}->{$family}->{models}->{$model};
|
||||
$class->{defaults}->{type}='device';
|
||||
next;
|
||||
}
|
||||
|
||||
# Store attribute
|
||||
push (@{$class->{defaults}->{$cmd}} , $value);
|
||||
$Attributes->{$cmd}++;
|
||||
}
|
||||
|
||||
return $Matrix;
|
||||
}
|
||||
|
||||
sub sort_nocase {
|
||||
return lc($a) cmp lc($b);
|
||||
}
|
||||
|
||||
sub print_notes {
|
||||
my $defaults = shift;
|
||||
my $level = shift;
|
||||
my $notes = $defaults->{note} || [];
|
||||
foreach my $note (@$notes){
|
||||
if ($note =~ s/^!//){
|
||||
$note = '<SPAN CLASS="note">' . $note . '</SPAN>';
|
||||
}
|
||||
}
|
||||
if (scalar @$notes){
|
||||
print "<DT>\n";
|
||||
my $print_note = join("\n<LI>",@$notes);
|
||||
print "<UL TYPE='square'><LI>$print_note</UL>\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub print_vendors {
|
||||
my $matrix=shift;
|
||||
print "<h1>Device Vendors</h1>\n";
|
||||
foreach my $vendor (sort sort_nocase keys %$matrix){
|
||||
print "[<A HREF=\"#$vendor\">$vendor</A>]\n";
|
||||
}
|
||||
print "<HR>\n";
|
||||
}
|
||||
|
||||
sub html_head {
|
||||
print <<"end_head";
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>SNMP::Info - Device Compatibility Matrix</TITLE>
|
||||
<STYLE TYPE="text/css" MEDIA="screen">
|
||||
<!--
|
||||
BODY { font-family:arial,helvetica,sans-serif; font-size:12pt; }
|
||||
TD { font-family:arial,helvetica,sans-serif; font-size:10pt; }
|
||||
TH { font-family:arial,helvetica,sans-serif; font-size:10pt; background:#F0F0F0; }
|
||||
H1 { font-family:arial,helvetica,sans-serif; font-size:14pt; }
|
||||
.vendor { font-size:12pt; color:#777777; }
|
||||
.family { font-size:12pt; color:blue; }
|
||||
.model { font-size:12pt; color:red; }
|
||||
.note { color:red; }
|
||||
//-->
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<h1>SNMP::Info - Device Compatibility Matrix</h1>
|
||||
<P>
|
||||
end_head
|
||||
}
|
||||
|
||||
sub html_tail {
|
||||
print <<'end_tail';
|
||||
<HR>
|
||||
<h1>Color Key</h1>
|
||||
[<SPAN CLASS="model">Model Attribute</SPAN>]
|
||||
[<SPAN CLASS="family">Family Attribute</SPAN>]
|
||||
[<SPAN CLASS="vendor">Vendor Attribute</SPAN>]
|
||||
<h1>Attribute Key</h1>
|
||||
A value of <B>-</B> signifies the information is not specified and can not
|
||||
be assumed working.
|
||||
<TABLE BORDER=1>
|
||||
<TR>
|
||||
<TD>Arpnip</TD>
|
||||
<TD>Ability to collect ARP tables for MAC to IP translation.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Class</TD>
|
||||
<TD>SNMP::Info Class the the device currently uses. Devices using more generic
|
||||
interfaces like <tt>Layer2</tt> or <tt>Layer3</tt> may eventually get their
|
||||
own subclass.
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Duplex</TD>
|
||||
<TD>Ability to cull duplex settings from device.<BR>
|
||||
<UL>
|
||||
<LI><tt>no</tt> - Can't recover current or admin setting.
|
||||
<LI><tt>link</tt> - Can get current setting only.
|
||||
<LI><tt>both</tt> - Can get admin and link setting.
|
||||
<LI><tt>write</tt> - Can get admin and link setting and perform sets.
|
||||
</UL>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Macsuck</TD>
|
||||
<TD>Ability to get CAM tables for MAC to switch port mapping.<BR>
|
||||
<UL>
|
||||
<LI><TT>no</TT> - Have not found an SNMP method to get data yet.
|
||||
<LI><TT>yes</TT> - Can get through normal SWITCH-MIB method.
|
||||
<LI><TT>vlan</TT> - Have to re-connect to each VLAN and then fetch with normal
|
||||
method.
|
||||
</UL>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Modules</TD>
|
||||
<TD>Ability to gather hardware module information.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Portmac</TD>
|
||||
<TD>Whether the device will list the MAC address of the switch port on each
|
||||
switch port when doing a Macsuck.
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Topo</TD>
|
||||
<TD>Ability to get Layer 2 Topology Information from device if the
|
||||
protocol is enabled. SNMP::Info supports querying Link Layer
|
||||
Discovery Protocol (LLDP), Cisco Discovery Protocol (CDP),
|
||||
SynOptics/Bay/Nortel/Avaya Network Management Protocol (SONMP),
|
||||
Foundry/Brocade Discovery Protocol (FDP), Extreme Discovery
|
||||
Protocol (EDP), and Alcatel Mapping Adjacency Protocol (AMAP).
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Ver</TD>
|
||||
<TD>SNMP Protocol Version the device has to use.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Vlan</TD>
|
||||
<TD>Ability to get VLAN port assignments.<BR>
|
||||
<UL>
|
||||
<LI><TT>no</TT> - Have not found an SNMP method to get data yet.
|
||||
<LI><TT>yes</TT> - Can read information.
|
||||
<LI><TT>write</TT> - Can read and write (set).
|
||||
</UL>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</BODY>
|
||||
</HTML>
|
||||
end_tail
|
||||
|
||||
}
|
||||
|
||||
sub print_headers {
|
||||
print "<TR>\n";
|
||||
foreach my $a (sort sort_nocase keys %$Attributes) {
|
||||
next if $a eq 'note';
|
||||
print " <TH>$a</TH>\n";
|
||||
}
|
||||
print "</TR>\n";
|
||||
}
|
||||
94
t/prereq.t
94
t/prereq.t
@@ -1,94 +0,0 @@
|
||||
#!/usr/local/bin/perl -w
|
||||
# prereq.t - Test file for prerequesites for SNMP::Info
|
||||
# $Id$
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests=> 3;
|
||||
|
||||
# Check for SNMP Module
|
||||
my $have_snmp=0;
|
||||
|
||||
eval {
|
||||
require SNMP;
|
||||
};
|
||||
|
||||
if ($@){
|
||||
print STDERR <<'end_snmp';
|
||||
|
||||
Net-SNMP not found. Net-SNMP installs the perl modules SNMP and
|
||||
SNMP::Session.
|
||||
|
||||
Versions 4.2.1 to 5.3 the Perl modules are not distributed on CPAN, you must
|
||||
install from the distribution.
|
||||
|
||||
Install Net-SNMP from http://net-snmp.sourceforge.net and make sure you run
|
||||
configure with the --with-perl-modules switch!
|
||||
|
||||
Note to Redhat Users: Redhat, in its infinite wisdom, does not install the
|
||||
Perl modules as part of their 8.0 RPMS. Please uninstall them and install the
|
||||
newest version by hand.
|
||||
|
||||
Versions 5.3.1 and higher are once again available from CPAN.
|
||||
|
||||
end_snmp
|
||||
ok(0,'Net-SNMP not installed, or missing Perl modules.');
|
||||
} else {
|
||||
$have_snmp=1;
|
||||
ok(1,'Net-SNMP installed');
|
||||
}
|
||||
|
||||
# Check for version
|
||||
SKIP: {
|
||||
skip('SNMP not installed, no further testing',2) unless $have_snmp;
|
||||
|
||||
my $VERSION = $SNMP::VERSION;
|
||||
ok(defined $VERSION ? 1 : 1, "found version for SNMP");
|
||||
|
||||
my ($ver_maj,$ver_min,$ver_rev) = split(/\./,$VERSION);
|
||||
|
||||
ok ($ver_maj >= 4, 'Net-SNMP ver 4 or higher');
|
||||
|
||||
if ($ver_maj == 4 and $ver_min == 2 and $ver_rev == 0){
|
||||
print STDERR << "end_420";
|
||||
|
||||
SNMP module version 4.2.0 found. Please triple check that you have
|
||||
version 4.2.0 of Net-SNMP installed, and that you did not accidently install
|
||||
the SNMP module found on CPAN. All newer versions are bundled with
|
||||
Net-SNMP, and are not available on CPAN. Please find them at
|
||||
http://net-snmp.sourceforge.net . Make sure you run configure with the
|
||||
--with-perl-modules switch.
|
||||
|
||||
end_420
|
||||
}
|
||||
|
||||
if( $ver_maj == 5 and $ver_min == 0 and $ver_rev == 1 ){
|
||||
print STDERR << "end_501";
|
||||
|
||||
|
||||
Perl module of Net-SNMP 5.0.1 is buggy. Please upgrade.
|
||||
|
||||
|
||||
end_501
|
||||
}
|
||||
|
||||
if(( $ver_maj == 5 and $ver_min == 3 and $ver_rev == 1 ) or
|
||||
( $ver_maj == 5 and $ver_min == 2 and $ver_rev == 3 )) {
|
||||
print STDERR << "end_bulkwalk";
|
||||
|
||||
|
||||
Perl module of Net-SNMP Versions 5.3.1 and 5.2.3 have issues with bulkwalk,
|
||||
turn off bulkwalk. Please upgrade.
|
||||
|
||||
end_bulkwalk
|
||||
}
|
||||
}
|
||||
|
||||
print STDERR << "end_mibs";
|
||||
|
||||
|
||||
Make sure you download and install the MIBS needed for SNMP::Info.
|
||||
See Man page or perldoc for SNMP::Info.
|
||||
|
||||
end_mibs
|
||||
# vim:syntax=perl
|
||||
47
t/push_ver
47
t/push_ver
@@ -1,47 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# $Id$
|
||||
|
||||
use File::Glob qw/bsd_glob/;
|
||||
|
||||
my @pms = glob_rec("../Info");
|
||||
|
||||
$new_version = shift @ARGV || '3.01';
|
||||
|
||||
foreach my $p (@pms) {
|
||||
print "$p\n";
|
||||
|
||||
rename($p,"$p.orig");
|
||||
open (O,"<$p.orig") or die;
|
||||
open (P,">$p") or die "Can't open $p for write. $!\n";
|
||||
|
||||
while (<O>) {
|
||||
s/^\s*\$VERSION\s+=\s*'[^']+'\s*;/\$VERSION = '$new_version';/;
|
||||
print P;
|
||||
}
|
||||
|
||||
close O;
|
||||
close P or die "Can't write $p. $!\n";
|
||||
unlink("$p.orig");
|
||||
#last;
|
||||
}
|
||||
|
||||
sub glob_rec {
|
||||
my $dir = shift;
|
||||
|
||||
my @files = bsd_glob("$dir/*");
|
||||
|
||||
my @pms;
|
||||
|
||||
foreach my $f (@files) {
|
||||
next if $f eq '\.$';
|
||||
|
||||
if (-d $f) {
|
||||
push @pms, glob_rec($f);
|
||||
next;
|
||||
}
|
||||
|
||||
push @pms,$f if $f =~ /.pm$/;
|
||||
}
|
||||
|
||||
return @pms;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Run this from ../
|
||||
/usr/local/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/$1
|
||||
346
t/test_class.pl
346
t/test_class.pl
@@ -1,346 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# test_class.pl
|
||||
#
|
||||
# Copyright (c) 2013 Eric Miller
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the University of California, Santa Cruz nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp;
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
use SNMP::Info;
|
||||
|
||||
my $EMPTY = q{};
|
||||
|
||||
# Default Values
|
||||
my $class = $EMPTY;
|
||||
my @dump = ();
|
||||
my $debug = 0;
|
||||
my $cache = 0;
|
||||
my $device = '';
|
||||
my $comm = '';
|
||||
my $ver = 2;
|
||||
my $ignore = 0;
|
||||
my $help = 0;
|
||||
my $nobulk = 0;
|
||||
my $mibdirs;
|
||||
my %dumped;
|
||||
|
||||
GetOptions(
|
||||
'c|class=s' => \$class,
|
||||
'd|dev=s' => \$device,
|
||||
's|comm=s' => \$comm,
|
||||
'v|ver=i' => \$ver,
|
||||
'i|ignore' => \$ignore,
|
||||
'p|print=s' => \@dump,
|
||||
'm|mibdir=s' => \$mibdirs,
|
||||
'n|nobulk' => \$nobulk,
|
||||
'x|debug+' => \$debug,
|
||||
'k|cache' => \$cache,
|
||||
'h|?|help' => sub { pod2usage(1); },
|
||||
);
|
||||
|
||||
unless ( $device and $comm ) {
|
||||
pod2usage(2);
|
||||
}
|
||||
|
||||
if ( $ignore && !defined $mibdirs ) {
|
||||
print "mibdirs must be provided if ignoring snmp.conf \n\n";
|
||||
pod2usage(1);
|
||||
}
|
||||
|
||||
local $ENV{'SNMPCONFPATH'} = $EMPTY if $ignore;
|
||||
local $ENV{'MIBDIRS'} = "$mibdirs" if $ignore;
|
||||
|
||||
if ( defined $mibdirs ) {
|
||||
SNMP::addMibDirs($mibdirs);
|
||||
}
|
||||
|
||||
$class = $class ? "SNMP::Info::$class" : 'SNMP::Info';
|
||||
|
||||
( my $mod = "$class.pm" )
|
||||
=~ s{::}{/}xg; # SNMP::Info::Layer3 => SNMP/Info/Layer3.pm
|
||||
if ( !eval { require $mod; 1; } ) {
|
||||
croak "Could not load $class. Error Message: $@\n";
|
||||
}
|
||||
|
||||
my $class_ver = $class->VERSION();
|
||||
|
||||
print
|
||||
"Class $class ($class_ver) loaded from SNMP::Info $SNMP::Info::VERSION.\n";
|
||||
|
||||
if ( scalar @dump ) { print 'Dumping : ', join( q{,}, @dump ), "\n" }
|
||||
|
||||
my %args = ();
|
||||
if ($nobulk) {
|
||||
$args{BulkWalk} = 0;
|
||||
}
|
||||
|
||||
my $dev = $class->new(
|
||||
'AutoSpecify' => 0,
|
||||
'AutoVerBack' => 0,
|
||||
'Debug' => $debug,
|
||||
'Version' => $ver,
|
||||
'DestHost' => $device,
|
||||
'Community' => $comm,
|
||||
%args
|
||||
) or die "\n";
|
||||
|
||||
print "Connected to $device.\n";
|
||||
print 'Detected Class: ', $dev->device_type(), "\n";
|
||||
print "Using Class: $class (-c to change)\n";
|
||||
|
||||
my $layers = $dev->layers();
|
||||
my $descr = $dev->description();
|
||||
|
||||
if ( !defined $layers || !defined $descr ) {
|
||||
die
|
||||
"Are you sure you got the right community string and version?\nCan't fetch layers or description.\n";
|
||||
}
|
||||
|
||||
print "\nFetching base info...\n\n";
|
||||
|
||||
my @base_fns = qw/vendor model os os_ver description contact location
|
||||
layers mac serial/;
|
||||
|
||||
foreach my $fn (@base_fns) {
|
||||
test_global( $dev, $fn );
|
||||
}
|
||||
|
||||
print "\nFetching interface info...\n\n";
|
||||
|
||||
my @fns = qw/interfaces i_type i_ignore i_description i_mtu i_speed i_mac i_up
|
||||
i_up_admin i_name i_duplex i_duplex_admin i_stp_state
|
||||
i_vlan i_pvid i_lastchange/;
|
||||
|
||||
foreach my $fn (@fns) {
|
||||
test_fn( $dev, $fn );
|
||||
}
|
||||
|
||||
print "\nFetching VLAN info...\n\n";
|
||||
|
||||
my @vlan = qw/v_index v_name/;
|
||||
|
||||
foreach my $fn (@vlan) {
|
||||
test_fn( $dev, $fn );
|
||||
}
|
||||
|
||||
print "\nFetching topology info...\n\n";
|
||||
|
||||
my @topo = qw/c_if c_ip c_port c_id c_platform/;
|
||||
|
||||
foreach my $fn (@topo) {
|
||||
test_fn( $dev, $fn );
|
||||
}
|
||||
|
||||
print "\nFetching module info...\n\n";
|
||||
|
||||
my @modules = qw/e_descr e_type e_parent e_name e_class e_pos e_hwver
|
||||
e_fwver e_swver e_model e_serial e_fru/;
|
||||
|
||||
foreach my $fn (@modules) {
|
||||
test_fn( $dev, $fn );
|
||||
}
|
||||
|
||||
foreach my $fn (@dump) {
|
||||
if ( !$dumped{$fn} ) { test_fn( $dev, $fn ) }
|
||||
}
|
||||
|
||||
if ($cache) {
|
||||
eval {
|
||||
require Data::Printer;
|
||||
} && eval {
|
||||
print "\nDumping cache...\n\n";
|
||||
Data::Printer::p $dev;
|
||||
};
|
||||
}
|
||||
|
||||
#--------------------------------
|
||||
|
||||
sub test_global {
|
||||
my $info = shift;
|
||||
my $method = shift;
|
||||
|
||||
my $value = $info->$method();
|
||||
|
||||
if ( !defined $value ) {
|
||||
printf "%-20s Does not exist.\n", $method;
|
||||
return 0;
|
||||
}
|
||||
$value =~ s/[[:cntrl:]]+/ /gx;
|
||||
if ( length $value > 60 ) {
|
||||
$value = substr $value, 0, 60;
|
||||
$value .= '...';
|
||||
}
|
||||
printf "%-20s %s \n", $method, $value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub test_fn {
|
||||
my $info = shift;
|
||||
my $method = shift;
|
||||
|
||||
my $results = $info->$method();
|
||||
|
||||
# If accidentally called on a global, pass it along nicely.
|
||||
if ( defined $results && !ref $results ) {
|
||||
return test_global( $dev, $method );
|
||||
}
|
||||
if ( !defined $results && !scalar keys %{$results} ) {
|
||||
printf "%-20s Empty Results.\n", $method;
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf "%-20s %d rows.\n", $method, scalar keys %{$results};
|
||||
if ( grep {/^$method$/x} @dump ) {
|
||||
$dumped{$method} = 1;
|
||||
foreach my $iid ( keys %{$results} ) {
|
||||
print " $iid : ";
|
||||
if ( ref( $results->{$iid} ) eq 'ARRAY' ) {
|
||||
print '[ ', join( ', ', @{ $results->{$iid} } ), ' ]';
|
||||
}
|
||||
else {
|
||||
print $results->{$iid};
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
test_class.pl - Test a device against an SNMP::Info class.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Eric Miller
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
test_class.pl [options]
|
||||
|
||||
Options:
|
||||
|
||||
-c|class SNMP::Info class to use, Layer2::Catalyst
|
||||
-d|dev Device
|
||||
-s|comm SNMP community
|
||||
-v|ver SNMP version
|
||||
-p|print Print values
|
||||
-i|ignore Ignore Net-SNMP configuration file
|
||||
-m|mibdir Directory containing MIB Files
|
||||
-n|nobulk Disable bulkwalk
|
||||
-x|debug Debugging flag
|
||||
-k|cache Dump cache (requires Data::Printer to be installed)
|
||||
-h|?|help Brief help message
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<-class>
|
||||
|
||||
Specific SNMP::Info class to use. Defaults to SNMP::Info if no specific
|
||||
class provided.
|
||||
|
||||
-class Layer2::Catalyst
|
||||
|
||||
=item B<-dev>
|
||||
|
||||
Device to test against. No default and a mandatory option.
|
||||
|
||||
-dev 1.2.3.4
|
||||
|
||||
=item B<-comm>
|
||||
|
||||
SNMP community string. No default and a mandatory option.
|
||||
|
||||
-comm public
|
||||
|
||||
=item B<-ver>
|
||||
|
||||
SNMP version. Default 2.
|
||||
|
||||
-ver 1
|
||||
|
||||
=item B<-print>
|
||||
|
||||
Print values of a class method rather than summarizing. May be repeated
|
||||
multiple times.
|
||||
|
||||
-print i_description -print i_type
|
||||
|
||||
=item B<-ignore >
|
||||
|
||||
Ignore Net-SNMP configuration file snmp.conf. If this used mibdirs must be
|
||||
provided.
|
||||
|
||||
-ignore
|
||||
|
||||
=item B<-mibdir>
|
||||
|
||||
Directory containing MIB Files. Multiple directories should be separated by a
|
||||
colon ':'.
|
||||
|
||||
-mibdir /usr/local/share/snmp/mibs/rfc:/usr/local/share/snmp/mibs/net-snmp
|
||||
|
||||
=item B<-nobulk >
|
||||
|
||||
Disable SNMP bulkwalk. Default bulkwalk is on and utilized with version 2.
|
||||
|
||||
-nobulk
|
||||
|
||||
=item B<-debug>
|
||||
|
||||
Turns on SNMP::Info debug.
|
||||
|
||||
-debug
|
||||
|
||||
=item B<-cache>
|
||||
|
||||
Dumps the table and leaf cache at the end of running. Requires that the
|
||||
L<Data::Printer> module be installed, otherwise does nothing.
|
||||
|
||||
-cache
|
||||
|
||||
=item B<-help>
|
||||
|
||||
Print help message and exits.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<test_class.pl> will test a device against a specfied SNMP::Info class.
|
||||
This allows debugging and testing of live devices to include validating
|
||||
device support with existing classes.
|
||||
|
||||
=cut
|
||||
@@ -1,207 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# make_snmpdata.pl
|
||||
#
|
||||
# Copyright (c) 2012 Eric Miller
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the University of California, Santa Cruz nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp;
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
use SNMP;
|
||||
|
||||
local $| = 1;
|
||||
|
||||
my $mibdirs = ['/usr/local/share/snmp/mibs'];
|
||||
my $comm = 'public';
|
||||
my $ver = '2c';
|
||||
my $dev;
|
||||
my $ignore = 0;
|
||||
my $help = 0;
|
||||
|
||||
GetOptions(
|
||||
'community=s' => \$comm,
|
||||
'device=s' => \$dev,
|
||||
'ignore' => \$ignore,
|
||||
'mibdir=s' => \$mibdirs,
|
||||
'version' => \$ver,
|
||||
'help|?' => sub { pod2usage(2); },
|
||||
) or pod2usage(2);
|
||||
|
||||
unless ( defined $dev && $ver =~ /[1|2c]/ ) {
|
||||
pod2usage(1);
|
||||
}
|
||||
|
||||
local $ENV{'SNMPCONFPATH'} = '' if $ignore;
|
||||
local $ENV{'MIBDIRS'} = "$mibdirs" if $ignore;
|
||||
|
||||
SNMP::addMibDirs($mibdirs);
|
||||
|
||||
# Connect to Device
|
||||
my $sess = SNMP::Session->new(
|
||||
'UseEnums' => 1,
|
||||
'RetryNoSuch' => 1,
|
||||
'DestHost' => $dev,
|
||||
'Community' => $comm,
|
||||
'Version' => $ver,
|
||||
'UseSprintValue' => 1
|
||||
);
|
||||
|
||||
my $sysdescr = $sess->get('sysDescr.0');
|
||||
unless ( defined $sysdescr ) {
|
||||
die "Couldn't connect to $dev via snmp.\n";
|
||||
}
|
||||
|
||||
SNMP::loadModules(@ARGV);
|
||||
|
||||
# Create a hash of MIB Modules for which we want results
|
||||
my %mib_hash = map {$_ => 1} @ARGV;
|
||||
# Add the common MIB Modules we always want
|
||||
my @common_mibs = ('SNMPv2-MIB', 'IF-MIB');
|
||||
foreach my $mib (@common_mibs) {
|
||||
$mib_hash{$mib} = 1;
|
||||
}
|
||||
|
||||
foreach my $key ( sort( keys %SNMP::MIB ) ) {
|
||||
my $module = $SNMP::MIB{$key}{moduleID} || '';
|
||||
# IMPORTS pulls in many modules we don't want to walk
|
||||
# Only walk those we've specified
|
||||
next unless (defined $mib_hash{$module});
|
||||
my $access = $SNMP::MIB{$key}{'access'} || '';
|
||||
next unless ( $access =~ /Read|Create/x );
|
||||
|
||||
my $label = SNMP::translateObj( $key, 0, 1 ) || '';
|
||||
snmpwalk($label);
|
||||
}
|
||||
|
||||
sub snmpwalk {
|
||||
return unless defined $sess;
|
||||
my $label = shift;
|
||||
my $var = SNMP::Varbind->new( [$label] );
|
||||
my $e = 0;
|
||||
my $last_iid = '';
|
||||
my %seen = ();
|
||||
while ( !$e ) {
|
||||
$sess->getnext($var);
|
||||
$e = $sess->{ErrorNum};
|
||||
|
||||
return if $var->[0] ne $label;
|
||||
my $iid = $var->[1];
|
||||
my $val = $var->[2];
|
||||
return unless defined $iid;
|
||||
|
||||
# Check to see if we've already seen this IID (looping)
|
||||
if ( defined $seen{$iid} and $seen{$iid} ) {
|
||||
warn "Looping on $label iid:$iid. Skipped.\n";
|
||||
return;
|
||||
}
|
||||
else { $seen{$iid}++; }
|
||||
|
||||
# why is it looping?
|
||||
return if $last_iid eq $iid;
|
||||
$last_iid = $iid;
|
||||
|
||||
my $line = "$label.$iid = $val";
|
||||
print "$line\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
make_snmpdata.pl - Tool to get SNMP data for the SNMP::Info testing framework
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Eric Miller
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
make_snmpdata.pl [options] MIB-MODULE-1 MIB-MODULE-2
|
||||
|
||||
Options:
|
||||
|
||||
-community SNMP Community
|
||||
-device IP Address to query
|
||||
-ignore Ignore Net-SNMP configuration file
|
||||
-mibdir Directory containing MIB Files
|
||||
-version SNMP version to use
|
||||
-help Brief help message
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<-community>
|
||||
|
||||
SNMP Community, either 1 or 2c. Defaults to version 2c
|
||||
|
||||
-community 2c
|
||||
|
||||
=item B<-device>
|
||||
|
||||
IP Address to query for the SNMP data. No default and a mandatory option.
|
||||
|
||||
-device 127.0.0.1
|
||||
|
||||
=item B<-ignore >
|
||||
|
||||
Ignore Net-SNMP configuration file snmp.conf. If this used mibdirs must be
|
||||
provided
|
||||
|
||||
-ignore
|
||||
|
||||
=item B<-mibdir>
|
||||
|
||||
Directory containing MIB Files. Mutiple directories should be separated by a
|
||||
colon ':'. Defaults to /usr/local/share/snmp/mibs.
|
||||
|
||||
-mibdir /usr/local/share/snmp/mibs/rfc:/usr/local/share/snmp/mibs/net-snmp
|
||||
|
||||
=item B<-version>
|
||||
|
||||
SNMP version to use. Only version 1 and 2c are supported. Defaults to 2c
|
||||
|
||||
-version 2c
|
||||
|
||||
=item B<-help>
|
||||
|
||||
Print help message and exits.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<make_snmpdata.pl> will gather SNMP data by walking specified MIB files and
|
||||
output the data to a file which can be used by the SNMP::Info testing
|
||||
framework.
|
||||
|
||||
=cut
|
||||
@@ -1,454 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# test_class_mocked.pl
|
||||
#
|
||||
# Copyright (c) 2012 Eric Miller
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the University of California, Santa Cruz nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp;
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../../..";
|
||||
use File::Slurp qw(slurp);
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
use SNMP::Info;
|
||||
use Test::MockObject::Extends;
|
||||
|
||||
my $EMPTY = q{};
|
||||
|
||||
# Default Values
|
||||
my $class = $EMPTY;
|
||||
my @dump = ();
|
||||
my $debug = 0;
|
||||
my $mibdirs;
|
||||
my $ignore = 0;
|
||||
my $help = 0;
|
||||
my $file;
|
||||
my %dumped;
|
||||
|
||||
GetOptions(
|
||||
'c|class=s' => \$class,
|
||||
'i|ignore' => \$ignore,
|
||||
'p|print=s' => \@dump,
|
||||
'x|debug+' => \$debug,
|
||||
'm|mibdir=s' => \$mibdirs,
|
||||
'file=s' => \$file,
|
||||
'h|?|help' => sub { pod2usage(1); },
|
||||
);
|
||||
|
||||
if ( !$file ) {
|
||||
pod2usage(1);
|
||||
}
|
||||
|
||||
if ( $ignore && !defined $mibdirs ) {
|
||||
print "mibdirs must be provided if ignoring snmp.conf \n\n";
|
||||
pod2usage(1);
|
||||
}
|
||||
|
||||
local $ENV{'SNMPCONFPATH'} = $EMPTY if $ignore;
|
||||
local $ENV{'MIBDIRS'} = "$mibdirs" if $ignore;
|
||||
|
||||
if ( defined $mibdirs ) {
|
||||
SNMP::addMibDirs($mibdirs);
|
||||
}
|
||||
|
||||
$class = $class ? "SNMP::Info::$class" : 'SNMP::Info';
|
||||
|
||||
( my $mod = "$class.pm" )
|
||||
=~ s{::}{/}g; # SNMP::Info::Layer3 => SNMP/Info/Layer3.pm
|
||||
if ( !eval { require $mod; 1; } ) {
|
||||
croak "Could not load $class. Error Message: $@\n";
|
||||
}
|
||||
|
||||
my $class_ver = $class->VERSION();
|
||||
|
||||
print
|
||||
"Class $class ($class_ver) loaded from SNMP::Info $SNMP::Info::VERSION.\n";
|
||||
|
||||
if ( scalar @dump ) { print 'Dumping : ', join( q{,}, @dump ), "\n" }
|
||||
|
||||
my $mocked = create_mock_session();
|
||||
|
||||
my $dev = $class->new(
|
||||
'AutoSpecify' => 0,
|
||||
'BulkWalk' => 0,
|
||||
'Debug' => $debug,
|
||||
'Session' => $mocked,
|
||||
) or die "\n";
|
||||
|
||||
print 'Detected Class: ', $dev->device_type(), "\n";
|
||||
print "Using Class: $class (-c to change)\n";
|
||||
|
||||
my $layers = $dev->layers();
|
||||
my $descr = $dev->description();
|
||||
|
||||
if ( !defined $layers || !defined $descr ) {
|
||||
die "Are you sure you specified a file created with make_snmpdata.pl ?\n";
|
||||
}
|
||||
|
||||
print "\nFetching base info...\n\n";
|
||||
|
||||
my @base_fns = qw/vendor model os os_ver description contact location
|
||||
layers mac serial/;
|
||||
|
||||
foreach my $fn (@base_fns) {
|
||||
test_global( $dev, $fn );
|
||||
}
|
||||
|
||||
print "\nFetching interface info...\n\n";
|
||||
|
||||
my @fns = qw/interfaces i_type i_ignore i_description i_mtu i_speed i_mac i_up
|
||||
i_up_admin i_name i_duplex i_duplex_admin i_stp_state
|
||||
i_vlan i_pvid i_lastchange/;
|
||||
|
||||
foreach my $fn (@fns) {
|
||||
test_fn( $dev, $fn );
|
||||
}
|
||||
|
||||
print "\nFetching VLAN info...\n\n";
|
||||
|
||||
my @vlan = qw/v_index v_name/;
|
||||
|
||||
foreach my $fn (@vlan) {
|
||||
test_fn( $dev, $fn );
|
||||
}
|
||||
|
||||
print "\nFetching topology info...\n\n";
|
||||
|
||||
my @topo = qw/c_if c_ip c_port c_id c_platform/;
|
||||
|
||||
foreach my $fn (@topo) {
|
||||
test_fn( $dev, $fn );
|
||||
}
|
||||
|
||||
print "\nFetching module info...\n\n";
|
||||
|
||||
my @modules = qw/e_descr e_type e_parent e_name e_class e_pos e_hwver
|
||||
e_fwver e_swver e_model e_serial e_fru/;
|
||||
|
||||
foreach my $fn (@modules) {
|
||||
test_fn( $dev, $fn );
|
||||
}
|
||||
|
||||
foreach my $fn (@dump) {
|
||||
if ( !$dumped{$fn} ) { test_fn( $dev, $fn ) }
|
||||
}
|
||||
|
||||
#--------------------------------
|
||||
|
||||
sub load_snmpdata {
|
||||
my $data_file = shift;
|
||||
|
||||
my @lines = slurp($data_file);
|
||||
|
||||
my $snmp_data = {};
|
||||
foreach my $line (@lines) {
|
||||
next if !$line;
|
||||
next if ( $line =~ /^#/ );
|
||||
if ( $line =~ /^(\S+::\w+)[.]?(\S+)*\s=\s(.*)$/ ) {
|
||||
my ( $leaf, $iid, $val ) = ( $1, $2, $3 );
|
||||
next if !$leaf;
|
||||
$iid ||= 0;
|
||||
$val =~ s/\"//g;
|
||||
$snmp_data->{$leaf}->{$iid} = $val;
|
||||
}
|
||||
}
|
||||
return $snmp_data;
|
||||
}
|
||||
|
||||
sub create_mock_session {
|
||||
|
||||
my $snmp_data = load_snmpdata($file);
|
||||
|
||||
my $session = SNMP::Session->new(
|
||||
UseEnums => 1,
|
||||
RetryNoSuch => 1,
|
||||
Data => $snmp_data,
|
||||
DestHost => '127.0.0.1',
|
||||
Community => 'public',
|
||||
Version => 2,
|
||||
);
|
||||
|
||||
my $mock_session = Test::MockObject::Extends->new($session);
|
||||
|
||||
mock_get($mock_session);
|
||||
mock_getnext($mock_session);
|
||||
|
||||
return $mock_session;
|
||||
}
|
||||
|
||||
sub mock_get {
|
||||
my $mock_session = shift;
|
||||
|
||||
$mock_session->mock(
|
||||
'get',
|
||||
sub {
|
||||
my $self = shift;
|
||||
my $vars = shift;
|
||||
my ( $leaf, $iid, $oid, $oid_name );
|
||||
my $c_data = $self->{Data};
|
||||
|
||||
# From SNMP::Info get will only be passed either an OID or
|
||||
# SNMP::Varbind with a fully qualified leaf and potentially
|
||||
# a partial
|
||||
if ( ref($vars) =~ /SNMP::Varbind/ ) {
|
||||
( $leaf, $iid ) = @{$vars};
|
||||
}
|
||||
else {
|
||||
$oid = $vars;
|
||||
$oid_name = SNMP::translateObj( $oid, 0, 1 ) || $EMPTY;
|
||||
( $leaf, $iid ) = $oid_name =~ /^(\S+::\w+)[.]?(\S+)*$/;
|
||||
}
|
||||
|
||||
$iid ||= 0;
|
||||
my $new_iid = $iid;
|
||||
my $val = $EMPTY;
|
||||
my $data = $c_data->{$leaf} || {};
|
||||
my $count = scalar keys %{$data} || 0;
|
||||
if ( $count > 1 ) {
|
||||
my $found = 0;
|
||||
foreach my $d_iid ( sort keys %{$data} ) {
|
||||
if ( $d_iid eq $iid ) {
|
||||
$val = $data->{$d_iid};
|
||||
$found = 1;
|
||||
next;
|
||||
}
|
||||
elsif ( $found == 1 ) {
|
||||
$new_iid = $d_iid;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ( $found && ( $new_iid eq $iid ) ) {
|
||||
$leaf = 'unknown';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$val = $data->{$iid};
|
||||
$leaf = 'unknown';
|
||||
}
|
||||
|
||||
if ( ref $vars =~ /SNMP::Varbind/ ) {
|
||||
$vars->[0] = $leaf;
|
||||
$vars->[1] = $new_iid;
|
||||
$vars->[2] = $val;
|
||||
}
|
||||
return ( wantarray() ? $vars : $val );
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
sub mock_getnext {
|
||||
my $mock_session = shift;
|
||||
|
||||
$mock_session->mock(
|
||||
'getnext',
|
||||
sub {
|
||||
my $self = shift;
|
||||
my $vars = shift;
|
||||
my ( $leaf, $iid, $oid, $oid_name );
|
||||
my $c_data = $self->{Data};
|
||||
|
||||
# From SNMP::Info getnext will only be passed a SNMP::Varbind
|
||||
# with a fully qualified leaf and potentially a partial
|
||||
( $leaf, $iid ) = @{$vars};
|
||||
|
||||
unless (defined $iid) {
|
||||
$iid = -1;
|
||||
}
|
||||
my $new_iid = $iid;
|
||||
my $val = $EMPTY;
|
||||
my $data = $c_data->{$leaf};
|
||||
my $count = scalar keys %{$data} || 0;
|
||||
if ( $count ) {
|
||||
my $found = 0;
|
||||
foreach my $d_iid ( sort keys %{$data} ) {
|
||||
if ( $d_iid gt $iid && !$found ) {
|
||||
$val = $data->{$d_iid};
|
||||
$new_iid = $d_iid;
|
||||
$found = 1;
|
||||
next;
|
||||
}
|
||||
elsif ( $found == 1 ) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ( $found && ( $new_iid eq $iid ) ) {
|
||||
$leaf = 'unknown';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$val = $data->{$iid};
|
||||
$leaf = 'unknown';
|
||||
}
|
||||
|
||||
$vars->[0] = $leaf;
|
||||
$vars->[1] = $new_iid;
|
||||
$vars->[2] = $val;
|
||||
return ( wantarray() ? $vars : $val );
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
sub test_global {
|
||||
my $device = shift;
|
||||
my $method = shift;
|
||||
|
||||
my $value = $device->$method();
|
||||
|
||||
if ( !defined $value ) {
|
||||
printf "%-20s Does not exist.\n", $method;
|
||||
return 0;
|
||||
}
|
||||
$value =~ s/[[:cntrl:]]+/ /g;
|
||||
if ( length $value > 60 ) {
|
||||
$value = substr $value, 0, 60;
|
||||
$value .= '...';
|
||||
}
|
||||
printf "%-20s %s \n", $method, $value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub test_fn {
|
||||
my $device = shift;
|
||||
my $method = shift;
|
||||
|
||||
my $results = $device->$method();
|
||||
|
||||
# If accidentally called on a global, pass it along nicely.
|
||||
if ( defined $results && !ref $results ) {
|
||||
return test_global( $dev, $method );
|
||||
}
|
||||
if ( !defined $results && !scalar keys %{$results} ) {
|
||||
printf "%-20s Empty Results.\n", $method;
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf "%-20s %d rows.\n", $method, scalar keys %{$results};
|
||||
if ( grep {/^$method$/} @dump ) {
|
||||
$dumped{$method} = 1;
|
||||
foreach my $iid ( keys %{$results} ) {
|
||||
print " $iid : ";
|
||||
if ( ref( $results->{$iid} ) eq 'ARRAY' ) {
|
||||
print '[ ', join( ', ', @{ $results->{$iid} } ), ' ]';
|
||||
}
|
||||
else {
|
||||
print $results->{$iid};
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
test_class_mocked.pl - Test a device against an SNMP::Info class using
|
||||
output from make_snmpdata.pl stored in a text file.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Eric Miller
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
test_class_mocked.pl [options]
|
||||
|
||||
Options:
|
||||
|
||||
-class SNMP::Info class to use, Layer2::Catalyst
|
||||
-file File containing data gathered using make_snmpdata.pl
|
||||
-print Print values
|
||||
-debug Debugging flag
|
||||
-ignore Ignore Net-SNMP configuration file
|
||||
-mibdir Directory containing MIB Files
|
||||
-help Brief help message
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<-class>
|
||||
|
||||
Specific SNMP::Info class to use. Defaults to SNMP::Info if no specific
|
||||
class provided.
|
||||
|
||||
-class Layer2::Catalyst
|
||||
|
||||
=item B<-file>
|
||||
|
||||
File containing data gathered using make_snmpdata.pl. No default and a
|
||||
mandatory option.
|
||||
|
||||
-file /data/mydevice.txt
|
||||
|
||||
=item B<-print>
|
||||
|
||||
Print values of a class method rather than summarizing. May be repeated
|
||||
multiple times.
|
||||
|
||||
-print i_description -print i_type
|
||||
|
||||
=item B<-debug>
|
||||
|
||||
Turns on SNMP::Info debug.
|
||||
|
||||
-debug
|
||||
|
||||
=item B<-ignore >
|
||||
|
||||
Ignore Net-SNMP configuration file snmp.conf. If this used mibdirs must be
|
||||
provided.
|
||||
|
||||
-ignore
|
||||
|
||||
=item B<-mibdir>
|
||||
|
||||
Directory containing MIB Files. Multiple directories should be separated by a
|
||||
colon ':'.
|
||||
|
||||
-mibdir /usr/local/share/snmp/mibs/rfc:/usr/local/share/snmp/mibs/net-snmp
|
||||
|
||||
=item B<-help>
|
||||
|
||||
Print help message and exits.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<test_class_mocked.pl> will test a device against an SNMP::Info class using
|
||||
snmpwalk output from the utility B<make_snmpdata.pl> stored in a text file.
|
||||
This allows debugging and testing without requiring network access to the
|
||||
device being tested.
|
||||
|
||||
=cut
|
||||
Reference in New Issue
Block a user