#!/usr/bin/env perl

## ###################################################################
## Plugin to check the availability of a JobScheduler Master
## see http://www.sos-berlin.com/jobscheduler
## Example:
## check_jobscheduler.pl -H galadriel.sos -p 4444 -t 20
## ###################################################################

use strict;
use Net::HTTP;
use Getopt::Long;
use MIME::Base64;
use vars qw($opt_H $opt_p $opt_t $opt_h $opt_a $opt_u);
use vars qw(%ERRORS &support);

my $host;
my $port;
my $timeout = 30;
my $auth;
our %ERROR;
%ERRORS = (
            'OK'       => 0,
            'CRITICAL' => 2,
            'ERROR'    => 2,
	        'UNKNOWN'  => 9,
          	'WARNING'  => 1,
         );


sub print_help ();
sub print_usage ();

Getopt::Long::Configure('bundling');
GetOptions
   ("h"   => \$opt_h, "help"        => \$opt_h,
    "H=s" => \$opt_H, "hostname=s"  => \$opt_H,
    "t=i" => \$opt_t, "timeout=i"   => \$opt_t,
    "p=i" => \$opt_p, "port=i"      => \$opt_p,
    "a=s" => \$opt_a, "auth=s"      => \$opt_a,
    "u=s" => \$opt_u, "user=s"      => \$opt_u);

if ($opt_h) {print_help(); exit 0;}

if ($opt_H ) {
	if ( $opt_H =~ /([-.A-Za-z0-9]+)/ ) {
	  $host = $opt_H;
	}
	($host) || print("Invalid host: $opt_H\n");
}
else {
	print("Host name/address not specified\n");
} 

if ($opt_p ) {
	if ($opt_p =~ /([0-9]+)/) {
		$port = $1 if ($opt_p =~ /([0-9]+)/);
	}
	($port < 0 || $port > 65535) && print("Invalid Port: $opt_p\n");
}
else {
	print("Port not specified\n");
}

if ($opt_t) { $timeout = $opt_t; }

if ($opt_a) { $auth = "Basic $opt_a"; }

if ($opt_u) { $auth = "Basic " . encode_base64($opt_u); }

if( !$host || !$port ) {
	print_usage();
	exit 1;
}


my $jobscheduler_answer_xml = get_answer();
my $jobscheduler_state_element = get_state_elem($jobscheduler_answer_xml);
my $jobscheduler_state = get_attribute_value("state",$jobscheduler_state_element); 
_report('OK', "OK: JobScheduler is up and " . $jobscheduler_state. "\n"); 


sub get_attribute_value {
	my ($attr_name, $elem_xml) = @_;
	$elem_xml =~ s/.*$attr_name\s*=\s*\"(.*?)\".*/$1/s;
	return $elem_xml;
}

sub get_state_elem {
	my $xml = shift;
	$xml =~ s/.*<spooler.*?>\s*<answer.*?>\s*(<state.*?>).*/$1/s;
	return $xml;
}       

sub get_answer {
  my $socket = Net::HTTP->new(Host => $host, PeerPort => $port, Timeout => $timeout);
  my $xmlAnswer = "";
  my $xmlRequest = "%3Cshow_state%20what=%22folders%20no_subfolders%22%20subsystems=%22folder%22%2F%3E";
  if ($socket) {
        if ($auth) {
			$socket->write_request(GET => $xmlRequest, 'Authorization' => $auth);
		}
		else {
			$socket->write_request(GET => $xmlRequest);
		}
     	my($code, $mess, %h) = $socket->read_response_headers;
     	if ($code == 200) {
     		while (1) {
      		my $buf;
      		my $n = $socket->read_entity_body($buf, 1024);
      		last unless $n;
      		$xmlAnswer .= $buf;
   			}
   		}
   		else {
   			_report('ERROR',"Connection to JobScheduler " . $host . ":" . $port . " failed: (" . $code . ") " . $mess . "\n");
     	} 
  }
  else {
     _report('CRITICAL',"Connection to JobScheduler " . $host . ":" . $port . " failed: " . $@ . "\n");
  }
  return $xmlAnswer;
}


sub print_help () {
   print $0. "\n";
   print "Copyright (c) 2012 SOS GmbH, info\@sos-berlin.com

This script tries to connect to given Job Scheduler

";
   print_usage();
   print "
-H, --hostname=HOST
   Name or IP address of host to check
-p, --port=INTEGER
   Port at host to check
-t, --timeout=INTEGER
   Timeout for HTTP connetion
-u, --user=<user:password>
   User and password for HTTP authentication
-h, --help
   This help
";
}

sub print_usage () {
   print  "Usage: $0 -H <host> -p <port> [-t <timeout>] [-u <user:password>]\n";
}

sub _report { 
	print $_[1]; 
  if (defined($ERRORS{$_[0]})) { exit $ERRORS{$_[0]}; }
  else { exit 0; }
}

