#!/opt/vdops/bin/perl # This script reports information about the management cards inserted # into APC devices # V Who When What # --------------------------------------------------------------------------- # 1.1.0 skendric 2011-02-21 Upgrade to Netops 1.4.0 # 1.0.0 skendric 2010-03-30 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) # -Queries sysDescr and a bunch of APC-specific variables # -Produces a report # # # Requirements: # -The target(s) must be pingable # # -The following MIB modules stashed in /opt/vdops/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-mgmt-card" 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 %card_model; # model number my %date; # manufacturing date my %hardware; # hardware revision my %model; # Hacked version of %apc_device_model my %serial; # serial number # Define global variables $program_name = 'apc-mgmt-card'; $usage = 'Usage: apc-mgmt-card -s {yes|no} [-d {integer}] [-r] [-a | -e {expr} | -f {filename} | target1 target2 target3 ...]'; $version = '1.1.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 { my %arg; # Args for snmpGet my $val; # Result of snmpGet # Debug trace trace_location('begin') if $debug; # Notify operator print_it('Parsing sysDescr and querying variables...'); unless ($dome) { sleep $short; return 1; } # Loop through targets for my $target (@target) { my $model; # Debug info say " Parsing $target" if $debug; # Look for management card details given ($sysDescr{$target}) { when ('AP9605') { ($card_model{$target}) = ($sysDescr{$target} =~ /MOD:\s*(.*?),\s*Mfg:/); ($hardware{$target}) = ($sysDescr{$target} =~ /HW\s*(.*?),\s* MOD:/); ($serial{$target}) = ($sysDescr{$target} =~ /SN:\s*(.*?)\)/); ($date{$target}) = ($sysDescr{$target} =~ /Mfg:\s*(.*?),\s*SN:/); } default { ($card_model{$target}) = ($sysDescr{$target} =~ /MN:\s*(.*?)\s*HR:/); ($hardware{$target}) = ($sysDescr{$target} =~ /HR:\s*(.*?)\s* SN:/); ($serial{$target}) = ($sysDescr{$target} =~ /SN:\s*(.*?)\s* MD:/); ($date{$target}) = ($sysDescr{$target} =~ /MD:\s*(.*?)\)/); } } # Handle the unexpected $card_model{$target} //= $QUERY; $date{$target} //= $QUERY; $hardware{$target} //= $QUERY; $serial{$target} //= $QUERY; # Convert two-digit years to four digits my ($date, $month, $day, $year); $date = $date{$target}; ($month, $day, $year) = split $SLASH, $date; given ($year) { when (undef) { $date = $date } when ($_ < 10) { $year = '20' . $year } when ($_ > 10 and $_ < 100) { $year = '19' . $year } } $date = $month . $SLASH . $day . $SLASH . $year if defined $year; $date{$target} = $date; # Shrink apc_device_model $model = $apc_device_model{$target}; given ($model) { when (/Battery/) { $model = 'BMS' } when (/Environmental Manager/) { $model = 'EnvMgr' } when (/Environmental Monitor/) { $model = 'EnvMon' } when (/NetBotz/i) { $model = 'NetBotz' } when (/PDU/) { $model = 'PDU' } when (/Silcon/) { $model = 'Silcon' } when (/Smart-UPS/i) { $model = 'Smart-UPS' } when (/Symmetra/) { $model = 'Symmetra' } default { $model = 'unknown' } } $model{$target} = $model; # Entertain operator print $BANG if $mode eq 'interactive'; } # Make things look pretty say('') 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; # 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; } # Debug trace trace_location('begin') if $debug; # 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} <