#!/usr/bin/perl 
# -w 
############################## check_snmp_load #################
my $Version='1.0';
# Date : July 27 2012
# Author  : Marco Kloepfer (marco #a#t# kingmarco.de)
# Licence : GPL - http://www.fsf.org/licenses/gpl.txt
# Contributors : HP MSA Documantation !!!
#################################################################
#
# Help : ./check_snmp_load.pl -h
#

use LWP::UserAgent;
use Digest::MD5 qw(md5_hex);
use XML::LibXML;
use Getopt::Long;
use Switch;

$response_success = 0 ;
$disk_counter = 0;

### Usage description
sub usage () {
    print "Usage: ";
    print "$PROGNAME\n";
    print "   -H (--hostname)   Hostname to query - (required)\n";
    print "   -u (--username)   username \n";
    print "   -p (--password)   password\n";
    print "   -d (--disks)      disk1[,disk2]... - disks to check, defaults to all\n";
# comming soon # print "   -s (--spares)     disk1:spare1[,disk2:spare2]... - check spares for specified disks\n";
    print "   -V (--version)    Plugin version\n";
    print "   -v (--verbose)    verbose output\n";
    print "   -h (--help)       usage help\n\n" ;
}

$PROGNAME = $0;
### Get options from command line
Getopt::Long::Configure('bundling');
GetOptions
    ("h"   => \$opt_h, "help"         => \$opt_h,
     "u=s" => \$opt_u, "username=s"   => \$opt_u,
     "p=s" => \$opt_p, "password=s"   => \$opt_p,
     "d=s" => \$opt_d, "disks=s"      => \$opt_d,
 #    "s=s" => \$opt_s, "spares=s"     => \$opt_s,
     "V"   => \$opt_V, "version"      => \$opt_V,
     "v"   => \$opt_v, "verbose"      => \$opt_v,
     "H=s" => \$opt_H, "hostname=s"   => \$opt_H);

if ($opt_V) {
    print "$PROGNAME $Version\n";
    exit(0);
}

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

### Split by comma separated disks and write to one line.
%disks = ();
if (defined($opt_d))
{
  @l = split(/,/, $opt_d);
  foreach (@l) { $disks{$_}++; }
  foreach $a (keys %disks){ $disks_list .= $a .' '} ;
}
### Generate MD5 hash using given username/password
my $md5_data = $opt_u . "_" . $opt_p ;
my $md5_hash = md5_hex( $md5_data );
if (defined($opt_v)) { print "$md5_hash\n";}
### Create the URL and send an http GET request
$ua = LWP::UserAgent->new;
$url = 'http://' . $opt_H .'/api/login/' . $md5_hash;
if (defined($opt_v)) { print ("Sending to $url\n"); }
$req = HTTP::Request->new(GET => $url);
$res = $ua->request($req);
### Parse the XML content using LibXML to obtain the session key 
if (defined($opt_v)) { print $res->content; }
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string( $res->content );
my $root = $doc->getDocumentElement;
my @objects = $root->getElementsByTagName('OBJECT');
my @props = $objects[0]->getElementsByTagName('PROPERTY');
my $sessionKey;
### Get session key
foreach my $prop ( @props ) {
    my $name = $prop->getAttribute('name');
    if( $name eq 'response' ) {
        $sessionKey = $prop->textContent;
    }

}
if (defined($opt_v)) { print "Session Key = $sessionKey\n";}

### Request the right URL to Get vdisks information in XML
$url = 'http://' . $opt_H . '/api/show/vdisks/' . $disks_list ;# Add disks to URL if they given 
$req = HTTP::Request->new(GET => $url);
$req->header('sessionKey' => $sessionKey );
$req->header('dataType' => 'ipa' );
$res = $ua->request($req);

### Pasre XML 
 $parser = XML::LibXML->new();
 $doc = $parser->parse_string( $res->content );
 $root = $doc->getDocumentElement;
 @objects = $root->getElementsByTagName('OBJECT');
$i = 0 ;
### Loop for XML tag GROUPS
     foreach my $objects_count (@objects) {
    @props = $objects[$i]->getElementsByTagName('PROPERTY');
     if ( $objects_count->getAttribute('basetype') eq "virtual-disks" ) { 
$sessionKey;
### Loop for XML tag PROPERTYS	
        foreach my $prop ( @props ) { 
        my $name = $prop->getAttribute('name');
         if( $name eq 'name' ) { $disks_state{'name'}[$i] = $prop->textContent };
	  if( $name eq 'status' ) { $disks_state{'state'}[$i] = $prop->textContent };   
	   if( $name eq 'serial-number' ) { $disks_state{'serial'}[$i] = $prop->textContent };
            if( $name eq 'size' ) { $disks_state{'size'}[$i] = $prop->textContent };
	     if( $name eq 'freespace' ) { $disks_state{'freespace'}[$i] = $prop->textContent };	
              if( $name eq 'raidtype' ) { $disks_state{'raidtype'}[$i] = $prop->textContent }; 
	       if( $name eq 'job-running' ) { $disks_state{'job-running'}[$i] = $prop->textContent };
                if( $name eq 'current-job' ) { $disks_state{'current-job'}[$i] = $prop->textContent };	        
		    $ii++;
                                    } 
     $disk_counter++;
                         } else { 
### Check Response OK
         foreach my $prop ( @props ) {
         my $name = $prop->getAttribute('name');
          if( $name eq 'response-type' && $prop->textContent eq "Success" ) { $response_success = 1 }
                                     }

 ;}
              
$i++;
}

### Output Response 
if (defined($opt_v)) { print "Response OK:" . $response_success ."\n" }
### Logoff from HTTP API
if (defined($opt_v)) { print "Loggin off\n" }
$url2 = 'http://10.0.0.2/api/exit';
$req2 = HTTP::Request->new(GET => $url3);
$req2->header('sessionKey' => $sessionKey );
$req2->header('dataType' => 'api' );
$res2 = $ua->request($req2);
$i = 0;

### Loop to read State's from disks saved in array $disks_state
do { 
switch ($disks_state{'state'}[$i]) {
case("FTOL") { $exit_message .= "$disks_state{'name'}[$i] is online. " }
case("OFFL") { { if ( $exit_status lt 2 ) { $exit_status = 2 } ; $exit_message .= "$disks_state{'name'}[$i] offline and failed. " } }
case("QTCR") { { if ( $exit_status lt 2 ) { $exit_status = 2 } ; $exit_message .= "$disks_state{'name'}[$i] has been quarantined - missing disks." } }
case("QTOF") { { if ( $exit_status lt 2 ) { $exit_status = 2 } ; $exit_message .= "$disks_state{'name'}[$i] has been quarantined - missing disks. " } }
case("UP") { { if ( $exit_status lt 1 ) { $exit_status = 1 } ; $exit_message .= "$disks_state{'name'}[$i] not fault tolerant. " } }
else { if ( $exit_status lt 2 ) { $exit_status = 2 }$exit_message .= "$disks_state{'name'}[$i] unknown state: $disks_state{'state'}[$i]. " }
}
$i++; } while ( $i < $disk_counter );


### exit with message and state
print $exit_message ."\n" ;
exit $exit_status;
