#!/opt/vdops/bin/perl # This script reports the software/firmware versions running on UPSes # V Who When What # --------------------------------------------------------------------------- # 1.7.0 skendric 02-21-2011 Upgrade to Netops 1.4.0 # 1.6.1 skendric 07-18-2010 Suport AP9630 # 1.6.0 skendric 03-30-2010 Upgrade to perl 5.10.1 # 1.5.8 skendric 04-27-2008 Fiddle with report text # 1.5.7 skendric 04-23-2008 Support range of modern APC cards # 1.5.6 skendric 09-27-2007 Report fiddles # 1.5.5 skendric 03-21-2007 Stylistic mods # 1.5.4 skendric 10-23-2006 Replace Object Values with OIDs # 1.5.3 skendric 09-22-2006 Change variable names # 1.5.2 skendric 11-05-2005 Upgrade to new WI::VDOPS module structure # 1.5.1 skendric 10-10-2005 Add support for EMU # 1.5.0 skendric 05-09-2005 Support Netops.pm-1.2 # 1.4.0 skendric 05-02-2004 Migrate common functions to Netops.pm # 1.3.0 skendric 04-30-2004 Enhance command-line options # 1.2.4 skendric 02-02-2004 Debugging fix # 1.2.3 skendric 01-07-2004 Enlarge pf column in report # 1.2.2 skendric 11-16-2003 Use Net::Ping::External # 1.2.1 skendric 08-10-2003 Minor bug fixes # 1.2.0 skendric 03-16-2003 Tighted scoping, changed DEBUG to $debug # 1.1.0 skendric 11-17-2002 Added @version, improved build_target() # 1.0.2 skendric 10-21-2002 Fixed bug in use of $grab_hosts # 1.0.1 skendric 10-18-2002 Added support for AP9605 # 1.0.0 skendric 09-30-2002 First Version # # Author: Stuart Kendrick, sbk@skendric.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) # -Queries sysDescr.0 # -Produces a report # # # Requirements: # -The target(s) must be pingable # # -The following MIB modules stashed in /opt/local/share/snmp/mibs, # or wherever it is that you store MIB modules: # PowerNet-MIB # # -PERL modules: the WI::Netops collection # # # Assumptions: # # # Tested on: # -APC 9606 Web/SNMP card, AP961x + AP963x Network Management Card, # SmartUPS, Symmetra, Silcon # -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 "apc-software" to see the command-line options # -Try it out # # # # Caveats: # # # Known Bugs: # # # To do: # # 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 List::MoreUtils qw(uniq);; use WI::Netops::APCTools 1.2.2; 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 %af; my %an; my %hr; my %mb; my %pf; my %pn; # Define global variables $program_name = 'apc-software'; $usage = 'Usage: apc-software -s {yes|no} [-d {integer}] [-r] [-a | -e {expr} | -f {filename} | target1 target2 target3 ...]'; $version = '1.7.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 Netops config file compile_mibs(); # Compile MIB files build_target(); # Populate @target target_check(); # Look for errors in @target basic_info(); # Gather information sanity_check(); # Check for major errors do_the_work(); # Do the work print_report(); # Print report } ##### End Main Program ############################################### ######################################################################## # Do the work: acquire image name ######################################################################## sub do_the_work { # Debug trace trace_location('begin') if $debug; # Notify operator print_it('Parsing sysDescr...'); unless ($dome) { sleep $short; return 1; } # Loop through targets for my $target (@target) { say " Parsing $target" if $debug; given ($apc_card_model{$target}) { when ('AP9605') { ($mb{$target}) = ($sysDescr{$target} =~ /.*FW\sv(.*?)\s*SW/); ($pf{$target}) = ($sysDescr{$target} =~ /.*SW\sv(.*?),\s*HW/); $pn{$target} = $DASH; $af{$target} = $DASH; $an{$target} = $DASH; } default { ($mb{$target}) = ($sysDescr{$target} =~ /.*MB:v(.*?)\s*PF:/); ($pf{$target}) = ($sysDescr{$target} =~ /.*PF:v(.*?)\s*PN:/); ($pn{$target}) = ($sysDescr{$target} =~ /.*PN:(.*?)\s*AF1:/); ($af{$target}) = ($sysDescr{$target} =~ /.*AF1:v(.*?)\s*AN1:/); ($an{$target}) = ($sysDescr{$target} =~ /.*AN1:(.*?)\s*MN:/); } } # Shrink AOS and Overlay image names given ($pn{$target}) { when (/hw02/) { $pn{$target} =~ s/apc_hw02_//; $an{$target} =~ s/apc_hw02_//; } when (/hw03/) { $pn{$target} =~ s/apc_hw03_//; $an{$target} =~ s/apc_hw03_//; } when (/hw04/) { $pn{$target} =~ s/apc_hw04_//; $an{$target} =~ s/apc_hw04_//; } when (/hw05/) { $pn{$target} =~ s/apc_hw05_//; $an{$target} =~ s/apc_hw05_//; } } # Entertain operator print $BANG if $mode eq 'interactive'; } # Make things look pretty say "\n" if $mode eq 'interactive'; # Debug trace trace_location('end') if $debug; return 1; } ######################################################################## # Tell the operator what I discovered ######################################################################## sub print_report { my $handle; my $now = get_now(); my $total = @target; # 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} <