#!/usr/bin/perl

##################################################################################
##################################################################################
######################  Made by Tytus Kurek in November 2012  ####################
##################################################################################
##################################################################################
####  This is a Nagios Plugin destined to check the status of APC Automatic   ####
####  Transform Switch. The plugin checks status of both inputs and output.   ####
##################################################################################
##################################################################################

use strict;
use vars qw($community $IP);

use Getopt::Long;
use Pod::Usage;

# Subroutines execution

getParameters ();
checkATSStatus ();

# Subroutines definition

sub checkATSStatus ()	# Checks APC ATS status
{
	my $OID = 'enterprises.318.1.1.8.5';
	my $inputOID = '.3';
	my $outputOID = '.4';
	my $tableOID = '.2.1';
	my $phaseTableOID = '.3.1';
	my $bankTableOID= '.5.1';
	my $frequencyOID = '.4';
	my $nameOID = '.6';
	my $voltageOID = '.3';
	my $bankVoltageOID = '.6.1';
	my $version = '2c';

	my $command = "/usr/bin/snmpwalk -v $version -c $community $IP $OID 2>&1";
	my $result = `$command`;

	if ($result =~ m/^Timeout.*$/)
	{
		my $output = "UNKNOWN! No SNMP response from $IP.";
		my $code = 3;
		exitScript ($output, $code);
	}

	my $atsOutputFrequencyOID = $OID . $outputOID . $tableOID . $frequencyOID . '.1';
	my $command = "/usr/bin/snmpget -v $version -c $community $IP $atsOutputFrequencyOID";
	$result = `$command`;
	$result =~ m/^SNMPv2-SMI::$atsOutputFrequencyOID\s=\sINTEGER:\s(\d+)$/;
	my $atsOutputFrequency = $1;

	my $atsOutputVoltageOID = $OID . $outputOID . $bankTableOID . $bankVoltageOID;
	$command = "/usr/bin/snmpget -v $version -c $community $IP $atsOutputVoltageOID";
	$result = `$command`;
	$result =~ m/^SNMPv2-SMI::$atsOutputVoltageOID\s=\sINTEGER:\s(\d+)$/;
	my $atsOutputVoltage = $1;

	my %atsInputValues;

	for (my $i = 1; $i <= 2; $i++)
	{
		my $atsInputFrequencyOID = $OID . $inputOID . $tableOID . $frequencyOID . ".$i";
		my $command = "/usr/bin/snmpget -v $version -c $community $IP $atsInputFrequencyOID";
		$result = `$command`;
		$result =~ m/^SNMPv2-SMI::$atsInputFrequencyOID\s=\sINTEGER:\s(\d+)$/;
		my $atsInputFrequency = $1;

		my $atsInputNameOID = $OID . $inputOID . $tableOID . $nameOID . ".$i";
		$command = "/usr/bin/snmpget -v $version -c $community $IP $atsInputNameOID";
		$result = `$command`;
		$result =~ m/^SNMPv2-SMI::$atsInputNameOID\s=\sSTRING:\s"(\w+)"$/;
		my $atsInputName = $1;

		my $atsInputVoltageOID = $OID . $inputOID . $phaseTableOID . $voltageOID . ".$i.1.1";
		$command = "/usr/bin/snmpget -v $version -c $community $IP $atsInputVoltageOID";
		$result = `$command`;
		$result =~ m/^SNMPv2-SMI::$atsInputVoltageOID\s=\sINTEGER:\s(\d+)$/;
		my $atsInputVoltage = $1;

		$atsInputValues{$i} = {name => $atsInputName, frequency => $atsInputFrequency, voltage => $atsInputVoltage};
	}

	if (($atsOutputFrequency == 0) and ($atsOutputVoltage == 0))
	{
		my $output = "CRITICAL! Output power supply is down. Output: $atsOutputVoltage V, $atsOutputFrequency Hz. Input: $atsInputValues{1}{'name'}: $atsInputValues{1}{'voltage'} V, $atsInputValues{1}{'frequency'} Hz; $atsInputValues{2}{'name'}: $atsInputValues{2}{'voltage'} V, $atsInputValues{2}{'frequency'} Hz.";
		my $code = 2;
		exitScript ($output, $code);	
	}

	if ((($atsInputValues{1}{'frequency'} == 0) and ($atsInputValues{1}{'voltage'} == 0)) or (($atsInputValues{2}{'frequency'} == 0) and ($atsInputValues{1}{'voltage'} == 0)))
	{
		my $output = "CRITICAL! One of input power supplies is down. Output: $atsOutputVoltage V, $atsOutputFrequency Hz. Input: $atsInputValues{1}{'name'}: $atsInputValues{1}{'voltage'} V, $atsInputValues{1}{'frequency'} Hz; $atsInputValues{2}{'name'}: $atsInputValues{2}{'voltage'} V, $atsInputValues{2}{'frequency'} Hz.";
		my $code = 2;
		exitScript ($output, $code);	
	}

	else
	{
		my $output = "OK! Output: $atsOutputVoltage V, $atsOutputFrequency Hz. Input: $atsInputValues{1}{'name'}: $atsInputValues{1}{'voltage'} V, $atsInputValues{1}{'frequency'} Hz; $atsInputValues{2}{'name'}: $atsInputValues{2}{'voltage'} V, $atsInputValues{2}{'frequency'} Hz.";
		my $code = 0;
		exitScript ($output, $code);	
	}
}

sub exitScript ()	# Exits the script with an appropriate message and code
{
	print "$_[0]\n";
	exit $_[1];
}

sub getParameters ()	# Obtains script parameters and prints help if needed
{
	my $help = '';

	GetOptions ('help|?' => \$help,
		    'C=s' => \$community,
		    'H=s' => \$IP)

	or pod2usage (1);
	pod2usage (1) if $help;
	pod2usage (1) if (($community eq '') || ($IP eq ''));
	pod2usage (1) if ($IP !~ m/^\d+\.\d+\.\d+\.\d+$/);

=head1 SYNOPSIS

check_aoc_ats.pl [options] (-help || -?)

=head1 OPTIONS

Mandatory:

-H	IP address of monitored APC ATS

-C	SNMP community

=cut
}
