#!/opt/vdops/bin/perl # This script reports the name of the image running on the targets # V Who When What # --------------------------------------------------------------------------- # 1.9.0 skendric 02-21-2011 Upgrade to Netops 1.4.0 # 1.8.0 skendric 12-23-2009 Remove Net::SNMP support # 1.7.6 skendric 12-16-2008 Fiddle with columns # 1.7.5 skendric 05-12-2008 Add hvac # 1.7.4 skendric 03-21-2007 Stylistic mods # 1.7.3 skendric 10-24-2006 Replace Object Values with OIDs # 1.7.2 skendric 07-11-2006 Tighten report columns # 1.7.1 skendric 11-05-2005 Upgrade to new WI::VDOPS module structure # 1.7.0 skendric 05-09-2005 Support Netops.pm-1.2 # 1.6.1 skendric 02-24-2005 Increase error-checking in do_the_work # 1.6.0 skendric 05-09-2004 Migrate common functions to Netops.pm # 1.5.0 skendric 04-30-2004 Enhance command-line options # 1.4.5 skendric 11-17-2003 Strip 'sysID' from hardware string # 1.4.4 skendric 11-03-2003 Use Net::Ping::External # 1.4.3 skendric 08-10-2003 Minor bug fixes # 1.4.2 skendric 07-27-2003 Added support for Altiga VPN concentrators # 1.4.1 skendric 04-29-2003 Fiddled with report format # 1.4.0 skendric 03-28-2003 Numerous minor updates # 1.3.0 skendric 03-26-2003 Added support for HP, Allied Telesyn # 1.2.3 skendric 02-24-2003 Added support for Aironet 1200 # 1.2.2 skendric 01-26-2003 Tightened scoping, changed $debug to $debug # 1.2.1 skendric 12-18-2002 Added support for Aironet # 1.2.0 skendric 11-13-2002 Added @version, improved build_target() # 1.1.2 skendric 10-20-2002 Fixed bug in use of $grab_hosts # 1.1.1 skendric 08-05-2002 Additional error handling # 1.1.0 skendric 05-01-2002 Support manually specified targets # 1.0.0 skendric 04-29-2002 First Version # # Author: Stuart Kendrick, sbk {put at sign here} skendric {put dot here} com # # Source: http://www.skendric.com/device # # This software is available under the GNU GENERAL PUBLIC LICENSE, see # http://www.fsf.org/licenses/gpl.html # # # This script takes the following approach: # -Parses the hosts table for a list of targets (or accepts a command- # line list) # -Uses a variety of methods to ask each target for the name # of the image it is running and the name of its hardware type # -Produces a report # # # Requirements: # -The following MIB modules stashed in /opt/vdops/share/snmp/mibs, # or wherever it is that you store MIB modules: # CISCO-PRODUCTS-MIB.my # # -PERL modules: the WI::Netops collection # # # Assumptions: # # # Tested on: # -perl-5.12.2 # -net-snmp-5.6 # # # Instructions: # -Customize the script for your site: find the 'user-configurable # variables' section and modify as appropriate # -Type "inv-image" to see the command-line options # -Try it out # # # # Caveats: # # # Known Bugs: # # # To do: # -Add support for SNMPv3 # # Begin script # Load modules use strict; use warnings; use feature 'say'; use feature 'switch'; use Carp qw(carp cluck croak confess); use Data::Dumper; use English qw( -no_match_vars ); use Getopt::Std; use WI::Netops::HostTools 1.0.4; use WI::Netops::NetopsTools 2.2.3; use WI::Netops::NetopsData 1.4.0; use WI::Netops::PingTools 1.1.7; use WI::Netops::SNMPTools 1.5.3; use WI::Netops::Utilities 1.4.4; # Declare global variables my @results; # Contents of report # Define global variables $program_name = 'inv-image'; $usage = 'Usage: inv-image -s {yes|no} [-d {integer}] [-r] [-a | -e {expr} | -f {filename} | target1 target2 target3 ...]'; $version = '1.9.0'; # Grab arguments getopts('ad:e:f:rs:', \%option); @target = @ARGV; # Set mode if ($option{r}) { $mode = 'report' } elsif (-t STDIN) { $mode = 'interactive' } else { $mode = 'batch' } ### Begin Main Program ############################################### { check_args(); # Check arguments read_config(); # Read config file compile_mibs(); # Compile MIB files build_target(); # Populate @target target_check(); # Look for errors in @target basic_info(); # Gather information do_the_work(); # Do the work build_report(); # Organize the data in a useful way print_report(); # Print report } ##### End Main Program ############################################### ######################################################################## # Build the report ######################################################################## sub build_report { my @a_fields; my @b_fields; my @raw; # If running in test mode, skip this routine return 1 unless $dome; # Debug trace trace_location('begin') if $debug; # Create an array containing the information I want to print for (my $i = 0; $i < @target; $i++) { my $target = $target[$i]; $raw[$i] = $target . ',' . $box{$target} . ',' . $boot_image{$target}; } # Create a sorted version of @raw @results = map { $_->[0] } sort { @a_fields = @$a[1..$#$a]; @b_fields = @$b[1..$#$b]; $a_fields[1] cmp $b_fields[1] || $a_fields[0] cmp $b_fields[0] } map { [ $_, split /,/ ] } @raw; # Debug trace trace_location('end') if $debug; return 1; } ######################################################################## # Do the work: acquire image name ######################################################################## sub do_the_work { my @remove; # Debug trace trace_location('begin') if $debug; # Notify operator print_it('Acquiring image names...'); # Loop through targets TARGET: for my $target (@target) { # Acquire images if ($dome) { ($boot_device{$target}, $boot_image{$target}) = which_image($target); unless (defined $boot_device{$target} and defined $boot_image{$target}) { print $DOT if $mode eq 'interactive'; push @remove, $target; next TARGET; } } # Entertain operator print $BANG if $mode eq 'interactive'; } # Make things look pretty say "\n" if $mode eq 'interactive'; # Remove entries which failed checks prune_basic(@remove); # Debug trace trace_location('end') if $debug; return 1; } ######################################################################## # Tell the operator what I discovered ######################################################################## sub print_report { my @fields; my $handle; my $total = @target; my $now = get_now(); # Debug trace trace_location('begin') if $debug; # If we are running in test mode, skip this routine unless ($dome) { print_it("Running in test mode, cannot print a meaningful report\n"); return 1; } # Direct output to screen or to file if ($mode eq 'interactive') { $handle = *STDOUT; } else { open $handle, '>', $report_file or die "Cannot open $report_file: $!\n"; } print {$handle} <