#!/opt/vdops/bin/perl # This script verifies that it has SNMP access to a list of targets, # notifying an operator for those which don't respond # V Who When What # --------------------------------------------------------------------------- # 1.1.0 skendric 2011-02-21 Upgrade to Netops 1.4.0 # 1.0.5 skendric 2011-01-21 Fix bug around handling of down_for_maintenance # 1.0.4 skendric 2010-12-17 Futz with owner/owner_backup # 1.0.3 skendric 2010-11-21 Add @down_for_maintenance # 1.0.2 skendric 2010-07-22 List successful boxes accurately # 1.0.1 skendric 2008-05-04 Include SNMP write access # 1.0.0 skendric 2008-05-04 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) # -Attempts to speak SNMP to each target # -Produces a report listing the targets which responded and the targets # which did not respond # # # Requirements: # -PERL modules: the WI::Netops collection # # # Assumptions: # # # Tested on: # -perl-5.10.1 # -net-snmp-5.5 # # # Instructions: # -Customize the script for your site: find the 'user-configurable # variables' section and modify as appropriate # -Type "verify-snmp-access-alarm" 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 List::MoreUtils qw(any uniq); 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 @blind_read; # List of targets which aren't responding to # SNMP Gets my @blind_write; # List of targets which aren't responding to # SNMP Sets my @read_only; # List of targets which will not respond to our # write string (typically because they don't # support SNMP Sets) my %read_result; # Hash of strings (Success|Failure) describing # whether or not we can speak SNMP to this box, # using a read string, keyed by target my @success; # List of targets which respond to GETs and # possibly SETs my %write_result; # Hash of strings (Success|Failure) describing # whether or not we can speak SNMP to this box, # using a write string, keyed by target # Define global variables $program_name = 'verify-snmp-access-alarm'; $usage = 'Usage: verify-snmp-access-alarm -s {yes|no} [-d {integer}] [-r] [-a | -e {expr} | -f {filename} | target1 target2 target3 ...]'; $version = '1.1.0'; # Target details @read_only = qw/-fw -ips -vpn -wism -wlc/; # 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 do_the_work(); # Do we have a problem? identify_alarms(); # Count devices with alarms write_alarm_log(); # Record issues print_report(); # Print report notify_staff(); # Mail report } ##### End Main Program ############################################### ######################################################################## # Query variables ######################################################################## sub do_the_work { # Debug trace trace_location('begin') if $debug; # Notify operator say 'Testing SNMP strings...' if $mode eq 'interactive'; # Test strings for my $target (@target) { snmp_char($target); # Summarize read results if (defined $snmp_read{$target}) { $read_result{$target} = 'Success'; push @success, $target; } else { $read_result{$target} = 'Failure'; push @blind_read, $target unless any {$target eq $_} @down_for_maintenance; $alarm_count{$target}++; log_it("Unable to perform SNMP Gets on $target"); } # Summarize write results if (defined $snmp_write{$target}) { $write_result{$target} = 'Success'; } else { if (any { $target =~ /$_/ } @read_only) { $write_result{$target} = 'NA'; } else { $write_result{$target} = 'Failure'; push @blind_write, $target unless any {$target eq $_} @down_for_maintenance; $alarm_count{$target}++; log_it("Unable to perform SNMP Sets on $target"); } } # Entertain the operator print $BANG if $mode eq 'interactive'; } # Make things look pretty say "\n" if $mode eq 'interactive'; # Populate alarm_list push @alarm_list, @blind_read, @blind_write; @alarm_list = uniq @alarm_list; # Debug trace trace_location('end') if $debug; return 1; } ######################################################################## # Tell the operator what I discovered ######################################################################## sub print_report { 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} <