#!/opt/vdops/bin/perl # This script queries Cisco Unity variables, alarms if it # doesn't like what it sees, and produces a report # V Who When What # --------------------------------------------------------------------------- # 1.1.0 skendric 2011-02-21 Upgrade to Netops 1.4.0 # 1.0.0 skendric 2011-01-17 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 a bunch of CISCO-UNITY-MIB 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: # CISCO-PRODUCTS-MIB.my # # -PERL modules: the FHCRC::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 # -Try it out # # # Caveats: # # # Known Bugs: # # # To do: # -Add support for SNMPv3 # # Begin script # Load modules use v5.12.0; use strict; use warnings FATAL => 'all'; 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(first_index); use Sys::Hostname; use FHCRC::Netops::CiscoTools 1.4.4; use FHCRC::Netops::HostTools 1.0.5; use FHCRC::Netops::NetopsTools 2.3.1; use FHCRC::Netops::NetopsData 1.4.4; use FHCRC::Netops::PingTools 1.2.0; use FHCRC::Netops::SNMPTools 1.5.4; use FHCRC::Netops::Utilities 1.4.5; # Declare global variables. All hashes keyed by target my %msg_length_lic; # ciscoUnityLicMaxMsgRecLenIsLic my %primary_lic; # ciscoUnityLicPrimaryServerIsLic my %secondary_lic; # ciscoUnityLicSecondaryServerIsLic my %unity_state; # ccmStatus my %unity_version; # ciscoUnityVersion my %vpim_lic; # ciscoUnityLicVPIMIsLicensed # Define global variables $program_name = 'unity-alarm'; $usage = 'Usage: unity-alarm -s {yes|no} [-d {integer}] [-r] [-z {netops_global_config}] [-y {netops_alarm_config}] [-a | -e {expr} | -f {filename} | target1 target2 target3 ...]'; $version = '1.1.0'; # Grab arguments getopts('ad:e:f:rs:y:z:', \%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(); # Sanity check do_the_work(); # Do it 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 print_it('Querying targets...'); unless ($dome) { sleep $short; return 1; } # Loop through the list of targets for my $target (@target) { my $val; say "Processing $target" if $debug; # ciscoUnityServerState $val = snmpGet( {host => $target, oid => 'ciscoUnityServerState.0'} ); $val //= $QUERY; unless ($val eq 'running') { log_it("For $target, ciscoUnityServerState = $val"); push @{$alarms{$target}}, "ciscoUnityServerState is $val"; $alarm_count{$target}++; } $unity_state{$target} = $val; # ciscoUnityLicPrimaryServerIsLic $val = snmpGet({host => $target, oid => 'ciscoUnityLicPrimaryServerIsLic.0'}); $val //= $QUERY; unless ($val eq 'true') { log_it("For $target, ciscoUnityLicPrimaryServerIsLic = $val"); push @{$alarms{$target}}, "ciscoUnityLicPrimaryServerIsLic is $val"; $alarm_count{$target}++; } $primary_lic{$target} = $val; # ciscoUnityLicSecondServerIsLic $val = snmpGet({host => $target, oid => 'ciscoUnityLicSecondServerIsLic.0'}); $val //= $QUERY; unless ($val eq 'true') { log_it("For $target, ciscoUnityLicSecondServerIsLic = $val"); push @{$alarms{$target}}, "ciscoUnityLicSecondServerIsLic is $val"; $alarm_count{$target}++; } $secondary_lic{$target} = $val; # ciscoUnityLicMaxMsgRecLenIsLic $val = snmpGet({host => $target, oid => 'ciscoUnityLicMaxMsgRecLenIsLic.0'}); $val //= $QUERY; unless ($val eq 'true') { log_it("For $target, ciscoUnityLicMaxMsgRecLenIsLic = $val"); push @{$alarms{$target}}, "ciscoUnityLicMaxMsgRecLenIsLic is $val"; $alarm_count{$target}++; } $msg_length_lic{$target} = $val; # ciscoUnityLicVPIMIsLicensed $val = snmpGet({host => $target, oid => 'ciscoUnityLicVPIMIsLicensed.0'}); $val //= $QUERY; unless ($val eq 'true') { log_it("For $target, ciscoUnityLicVPIMIsLicensed = $val"); push @{$alarms{$target}}, "ciscoUnityLicVPIMIsLicensed is $val"; $alarm_count{$target}++; } $vpim_lic{$target} = $val; # Entertain operator print $BANG if $mode eq 'interactive'; } # Debug info if ($debug > 2) { for my $target (@target) { if (defined $alarm_count{$target} and $alarm_count{$target} > 0) { say "alarm_count{$target} = $alarm_count{$target}"; } } } # Make things look pretty say "\n" if $mode eq 'interactive'; # Debug trace trace_location('end') if $debug; return 1; } ######################################################################### # Sanity check ######################################################################## sub sanity_check { my @remove; # Debug trace trace_location('begin') if $debug; # Notify operator print_it('Sanity check...'); # Loop through targets, looking for problems TARGET: for my $target (@target) { my $val; # Identify presence of Cisco Unity MIB $val = snmpGet({host => $target, oid => 'ciscoUnityVersion.0'} ); unless (defined $val) { say "\n$target does not support CISCO-UNITY-MIB, ignoring" if $debug; push @remove, $target; print $DOT if $mode eq 'interactive'; } else { $unity_version{$target} = $val; print $BANG if $mode eq 'interactive'; } } # Remove entries which failed checks prune_basic(@remove); @insane = @remove; # 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 $total = @target; my $now = get_now(); # 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} <