#!/usr/bin/perl
#########################################################################
# Description:  Checks PRTG sensors by its API
#  Cf https://www.fr.paessler.com/blog/2008/08/19/all-about-prtg/introducing-the-prtg-network-monitor-api				
# version 1.0
# Date : May 02 2016
# Author:       Fabrice Le Dorze
# Licence : GPL - http://www.fsf.org/licenses/gpl.txt
#########################################################################
#
use strict;
use Getopt::Long;
use Data::Dumper;
use XML::Simple;

my $PROGNAME=`basename $0`;
chomp $PROGNAME;

#-----------------------------------------------------
# Usage function
#-----------------------------------------------------
sub Print_Usage() {
	print <<USAGE;

Usage: $PROGNAME -H <host> -u <login> -p <password> -U <PRTG API URL> -s <sensor> [ -w <<warning> -c <critical>] [ -t <timout>][-d]
USAGE
}

#-----------------------------------------------------
# Parameters
#-----------------------------------------------------
my %STATES=(
0 => 'OK',
1 => 'WARNING',
2 => 'CRITICAL',
3 => 'UNKNOWN'
);

my %PRTG_STATES=(
"Up " => 0,
"Warning " => 1,
"Critical " => 2,
"Down " => 2,
"Paused (paused)" => 3
);

# Help function
#-----------------------------------------------------
sub Print_Help
{
         print <<HELP;
This plugin checks a PRTG sensor through PRTG WEB API
HELP
&Print_Usage;
         print <<HELP;
	-H <host> : PRTG device
	-U <URL> : PRTG API URL
        -s <sensor> : PRTG sensor
        -u <login> : PRTG login
        -p <password> : PRTG password
        -w : warning threshold
        -c : critical threshold
        -r : sensor name is used as a regexp
	-t : timeout. Default is 15s.
        -d : debug

HELP

exit 3;
}

#-----------------------------------------------------
# Get user-given variables
#-----------------------------------------------------
my ($host, $sensor, $login, $password, $url, $sensor, $warning, $critical, $help, $debug, $timeout, $regexp);
Getopt::Long::Configure ("bundling");
GetOptions (
'H=s' => \$host,
'U=s' => \$url,
's=s' => \$sensor,
'u=s' => \$login,
'p=s' => \$password,
't=s' => \$timeout,
'd' => \$debug,
'w=s' => \$warning,
'c=s' => \$critical,
'r' => \$regexp,
'h' => \$help
);

$timeout="15" unless ($timeout);

&Print_Help if ($help);
&Print_Help unless ($host && $sensor && $url && $login && $password);

my $curl="/usr/bin/curl -k -s \"".$url."?content=sensors&columns=device,sensor,status,message,lastvalue&username=".$login."&password=".$password."\"";
my $output=`$curl`;
unless ($output and $?==0)
{
   print "UNKNOWN : could not get sensors from PRTG API '$url'." and exit 3;
}

my $xs=XML::Simple->new;
my $perl = $xs->XMLin($output);
my @items=@{$perl->{'item'}};

my %service;
foreach my $item (@items)
{
    if ($$item{'device'} eq $host and (($regexp and $$item{'sensor'}=~/$sensor/) or $$item{'sensor'} eq $sensor))
    {
        %service=%{$item};
        $sensor=$$item{'sensor'};
        last;
    }
}

print "No Sensor '$sensor' for Host '$host' found in PRTG" and exit 3 unless (%service);

#-----------------------------------------------------
# Loop on selected subtypes
#-----------------------------------------------------
my $critstate=0;
my $warnstate=0;
my $i=0;
my @details;
my @failed;
my @perfs;
my @indexes;

###
# Output
###
print Dumper %service if ($debug);
my ($value, $perfs, $unity);

($critical)=($service{'message_raw'}=~/.*critical limit of (\d+)/) unless ($critical);
($warning)=($service{'message_raw'}=~/.*warning limit of (\d+)/) unless ($warning);
my $code=$PRTG_STATES{$service{'status'}};
my $status=$sensor." ".$STATES{$code}." : ".$service{'message_raw'}."(".$service{'lastvalue'}.")";
$status=$sensor." ".$STATES{$code}." (".$service{'lastvalue'}.")" if($code==0);
my ($value,$unity)=($service{'lastvalue'}=~/(\d+) ?(.*)/);

# It is a value that should not be below thresholds
if ($service{'message_raw'}=~/below/)
{
    if ($value<$critical) { $code=2, $status=$sensor." ".$STATES{$code}." : ".$value.$unity."<".$critical; }
    elsif ($value<$warning) { $code=1, $status=$sensor." ".$STATES{$code}." : ".$value.$unity."<".$warning; }
    elsif ($value>$warning) { $code=0, $status=$sensor." ".$STATES{$code}." : ".$value.$unity.">".$warning; }
}
# It is a value that should not be above thresholds
elsif ($service{'message_raw'}=~/above/)
{
    my ($value,$unity)=($service{'lastvalue'}=~/(\d+) ?(.*)/);
    if ($value>$critical) {$code=2 and $status=$sensor." ".$STATES{$code}." : ".$value.$unity.">".$critical; } 
    elsif ($value>$warning) { $code=1 and $status=$sensor." ".$STATES{$code}." : ".$value.$unity.">".$warning; }
    elsif ($value<$warning) {  $code=0 and $status=$sensor." ".$STATES{$code}." : ".$value.$unity."<".$warning; }
}

# The value is OK or is juste a status
#else
#{
#
#}


$value=$code unless ($value);
$perfs="'$sensor';$value;$warning;$critical";
print $status."|".$perfs;
print "\n";
exit $code;
