#! /usr/bin/perl
#
# cue_voicemail_time_check.pl - check (via SNMP) a Cisco Unity Express
# device (NM or AIM) to make sure we're not using more than a defined
# percentage of voicemail space.
#
# 2008 Andrew J. Cosgriff, In Systems <ajc@insys.com.au>
#
# based on the distributed Lithium service monitoring scripts.
#
##########
use XML::Simple;
use Net::SNMP;
use Data::Dumper;
use Time::HiRes qw(gettimeofday tv_interval);
use Data::Types qw(:all);

$NORMAL = "1";
$CONN_REFUSED = "2";
$CONN_TIMEOUT = "3";
$PROTO_TIMEOUT = "4";
$PROTO_ERROR = "5";

###################################
#  Script Configuration Variables
###################################
my $cuePercentTimeUsed = ".1.3.6.1.4.1.9.9.420.1.2.1.9.0";

%infostruct = (  'version' => '1.0',
                 'desc'  => "SNMP CUE Voicemail Time Check",
                 'proto' => "SNMP",
                 'port'  => "161",
                 'transport' => "UDP",
                 'info' => "Verifies the percentage of free voicemail space on a Cisco Unity Express system.",
                  'config_variable'=> [
		      {
			  'name' => 'community',
			  'desc' => 'SNMP Community String',
			  'required' => 1
		      },
		      {
			  'name' => 'max_percent',
			  'desc' => 'maximum percentage of voicemail space before raising an error.',
			  'required' => 1
		      }
                 ]
            );

%objectstruct = ();

###################################
#  Command processing
###################################

($ARGV[0] eq "info") and ($#ARGV == 0) and
   print &generateXml($xmlroot, \%infostruct);
 
($ARGV[0] eq "object") and ($#ARGV == 0) and
   print &generateXml($xmlroot, \%objectstruct);
 
($ARGV[0] eq "check") and ($#ARGV != 0) and
  checkService($ARGV[$#ARGV]);

###################################
# Service Check/Testing
###################################

sub checkService
{
  # 1 Parameter: Filename for the config XML
  my ($filename) = @_;

  # Extract Variables from XML and store in %variables Hash
  %variables = &getVariables($filename);
   
  # Set IP 
  my $ip;
  if (is_string(%variables->{alt_ip}->{value})) { $ip = %variables->{alt_ip}->{value}; }
  else { $ip = %variables->{dev_ip}->{value}; }

  # Set Port
  my $port;
  if (is_string(%variables->{alt_port}->{value})) { $port = %variables->{alt_port}->{value}; }
  else { $port = '161'; }

  # Set Communit String
  my $community;
  if (is_string(%variables->{community}->{value})) { $community = %variables->{community}->{value}; }
  else { $community = 'public'; }

  # Set max_percent
  my $max_percent;
  if (is_string(%variables->{max_percent}->{value})) { $max_percent = %variables->{max_percent}->{value}; }

  # Get Start Time
  $tstart = [gettimeofday];

  #print Dumper(%variables);

  my ($sess, $error) = Net::SNMP->session(
      -hostname  => $ip,
      -community => $community,
      -port      => $port
      );
  
  if (!defined($sess)) {
      $message = "ERROR: %s. " . $error;
      $status = 5;
  } elsif (defined $max_percent) {
      my $result = $sess->get_request(-varbindlist => [$cuePercentTimeUsed]);

      $tresp = [gettimeofday];

      if (defined $result->{$cuePercentTimeUsed} and
	  $result->{$cuePercentTimeUsed} ne "") {
	  my $percent = $result->{$cuePercentTimeUsed};
	  if ($percent <= $max_percent) {
	      $message="OK: $percent" . "% time used.";
	      $status = 1;
	  } else {
	      $message="ERROR: $percent" . "% time used.";
	      $status = 5;
	  }
      } else {
	  $message="ERROR: couldn't get cuePercentTimeUsed.";
	  $status = 5;
      }
  } else {
    $status = 5;
    $message = "ERROR: no max_percent defined for us to check."
  }

  $ttrans = [gettimeofday];

  %resultstruct = ('metric'=> [
                    { 'name' => 'status', 'value' => $status, },
                    { 'name' => 'resptime', 'value' => tv_interval($tstart, $tresp), },
                    { 'name' => 'transtime', 'value' => tv_interval($tstart, $ttrans), },
                    { 'name' => 'message', 'value' => $message, },
                  ]);
  print &generateXml($xmlroot, \%resultstruct);
}


###########################################
# Standard Functions
###########################################

sub generateXml
{
  # Create the XML from dictionary/array. 
  # You don't have to make changes to this sub.
  # To make changes to these XML Structures:
  #   Modify %configstruct %objectstruct at the 
  #   begining of this file

  # Parameter 1: Temporary XML File
  my ($xmlrool) = $_[0];
  my (%struct) = %{$_[1]};
  
  my $xml = new XML::Simple(NoAttr=>1, RootName=>"service_script",XMLDecl=>1);
  $data = $xml->XMLout(\%struct);
  return "$data";
}

sub getVariables 
{
  # Parameter: Filename for the XML
  my ($filename) = @_;

  # ------>Collect XML Info Here <----------
  my $xml = new XML::Simple; # create new XML object
  my $data = $xml->XMLin($filename);
  my %variables =%{$data->{variable}};
  return %variables;
}
