#!/usr/bin/php -c /etc/php.ini
<?php
error_reporting(0);

if (!isset($argv[1]) || !isset($argv[2]) || !isset($argv[3]) || !isset($argv[4]) || !isset($argv[5]))
{echo "Please, run with parameters: <IPStarwindServer1> <ISCSI port> <Starwind user> <Starwind password> <Starwind HA device name>\nExample: ./check_stardwind_health.php 192.168.3.1 3261 root starwind HAImage1\n"; die;}
else 
{
$Server=$argv[1];
$Port=$argv[2];
$Login=$argv[3];
$Password=$argv[4];
$Device=$argv[5];
}

$cfgTimeOut = 20; //Session timeout

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    echo "CRITICAL: Cannot execute socket_create(). Reason: " . socket_strerror(socket_last_error()) . "\n";
	exit(2);
}

//Try to connect to Starwind iSCSI server:
$result = socket_connect($socket, $Server, $Port);
if ($result === false) {
    echo "CRITICAL: Cannot execute socket_connect() к ".$Server.":".$Port.". Reason: (".$result.") " . socket_strerror(socket_last_error($socket)) . "\n";
	exit(2);
}

$telnet = @fsockopen($Server, $Port, $errno, $errstr, $cfgTimeOut);

fputs ($telnet, "login $Login $Password\r\n");
fputs ($telnet, "list\r\n");
fputs ($telnet, "exit\r\n");

while (!feof($telnet))
{
    $string = fgets($telnet);
    $explode = explode("=", $string);
    if ($explode[0] == "DeviceName")
    {
        $counter++;
    }
    if (isset($explode[1]))
    {
        $values[$counter][$explode[0]] = str_replace("\"", "", $explode[1]);
    }
}

//Debug:
//print_r ($values);

function findDevice($arr,$Device){
    foreach($arr as $sample){
	$sample = preg_replace('~[\r\n]+~', '', $sample);
        if($sample['DeviceName']==$Device){
            return array($sample['DeviceName'],$sample['DeviceId'],$sample['state'],$sample['ha_synch_status'],$sample['ha_synch_percent'],$sample['ha_partner_node1_sync_status'],$sample['ha_partner_node1_is_exist_heartbeat_valid_connection'],$sample['ha_partner_node1_is_exist_sync_valid_connection'],$sample['ha_partner_node1_heartbeat_channels'],$sample['ha_partner_node1_sync_channels'],$sample[ha_partner_node1_sync_percent]);
         }
    }
    return null;
}

if(($result=findDevice($values,$Device))!=null){
	$DevName=$result[0];
	$DevID=$result[1];
	$DevState=$result[2];
	$DevHASyncStatus=$result[3];
	$DevHASyncPerc=$result[4];
	$DevHANode1SyncStatus=$result[5];
	$DevHANode1HeartBeatConn=$result[6];
	$DevHANode1SyncConn=$result[7];
	$DevHANode1HeartBeatChannels=str_replace('$',':',$result[8]);
	$DevHANode1SyncChannels=str_replace('$',':',$result[9]);
	$DevHANode1SyncPerc=$result[10];

	/* print "--- RESPONSE ---\n";
	print "DevName: ".$DevName."\n";
	print "DevID: ".$DevID."\n";
	print "DevState: ".$DevState."\n";
	print "DevHASyncStatus: ".$DevHASyncStatus."\n";
	print "DevHASyncPerc: ".$DevHASyncPerc."\n";
	print "DevHANode1SyncStatus: ".$DevHANode1SyncStatus."\n";
	print "DevHANode1HeartBeatConn: ".$DevHANode1HeartBeatConn."\n";
	print "DevHANode1SyncConn: ".$DevHANode1SyncConn."\n";
	print "DevHANode1HeartBeatChannels: ".$DevHANode1HeartBeatChannels."\n";
	print "DevHANode1SyncChannels: ".$DevHANode1SyncChannels."\n";
	print "--- RESPONSE END ---\n";
	*/

	if($DevState == 0){
	$DevState="OK";
	}elseif($DevState != 0){
	$DevState="BAD";
	}else{
	$DevState=$result[2];
	}

	if($DevHASyncStatus == 1){
	$DevHASyncStatus="Synchronized";
	}elseif($DevHASyncStatus == 2){
	$DevHASyncStatus="Synchronizing";
	}else{
	$DevHASyncStatus=$result[3];
	}

	if($DevHANode1HeartBeatConn == 1){
	$DevHANode1HeartBeatConn = "established";
	}elseif($DevHASyncStatus != 1){
	$DevHANode1HeartBeatConn = "disconnected";
	}else{
	$DevHANode1HeartBeatConn = $result[6];
	}

	if($DevHANode1SyncConn == 1){
	$DevHANode1SyncConn = "established";
	}elseif($DevHANode1SyncConn != 1){
	$DevHANode1SyncConn = "disconnected";
	}else{
	$DevHANode1SyncConn = $result[6];
	}

	if($DevHANode1SyncStatus == 1){
	$DevHANode1SyncStatus = "synchronized";
	}elseif($DevHANode1SyncStatus == 2){
	$DevHANode1SyncStatus = "synchronizing";
	}elseif($DevHANode1SyncStatus == 0){
	$DevHANode1SyncStatus = "DOWN";
	}elseif($DevHANode1SyncStatus == 3){
	$DevHANode1SyncStatus = "NOT synchronized";
	}else{
	$DevHANode1SyncStatus = $result[6];
	}

	//Everything is OK:
	if(($DevState == "OK") AND ($DevHASyncStatus == "Synchronized") AND ($DevHASyncPerc == 100) AND ($DevHANode1SyncStatus == "synchronized") AND ($DevHANode1HeartBeatConn == "established") AND ($DevHANode1SyncConn == "established")){
		echo "OK: VSAN Volume ".$DevName. " health is OK. ".$DevHASyncStatus." ".$DevHASyncPerc."%. Details:\nPartner is ".$DevHANode1SyncStatus." (".$DevHANode1SyncPerc."%).\nHeartbeat Channels ".$DevHANode1HeartBeatChannels." is ".$DevHANode1HeartBeatConn.".\nSync Channels ".$DevHANode1SyncChannels." is ".$DevHANode1SyncConn.".\n";
		exit(0);
	//Condition for primay node, when secondary node syncing.
	}elseif(($DevState == "OK") AND ($DevHASyncStatus == "Synchronized") AND ($DevHASyncPerc == 100) AND ($DevHANode1SyncStatus == "synchronized" OR $DevHANode1SyncStatus == "synchronizing") AND ($DevHANode1HeartBeatConn == "established") AND ($DevHANode1SyncConn == "established")){
		echo "OK: VSAN Volume ".$DevName. " health is OK. ".$DevHASyncStatus." ".$DevHASyncPerc."%. Details:\nPartner is ".$DevHANode1SyncStatus." (".$DevHANode1SyncPerc."%).\nHeartbeat Channels ".$DevHANode1HeartBeatChannels." is ".$DevHANode1HeartBeatConn.".\nSync Channels ".$DevHANode1SyncChannels." is ".$DevHANode1SyncConn.".\n";
		exit(0); 
	//Condition for secondary node in syncing state:
	}elseif(($DevState == "OK") AND ($DevHASyncStatus == "Synchronizing") AND ($DevHASyncPerc != 100) AND ($DevHANode1SyncStatus == "synchronized" OR $DevHANode1SyncStatus == "synchronizing") AND ($DevHANode1HeartBeatConn == "established") AND ($DevHANode1SyncConn == "established")){
		echo "WARNING: VSAN Volume ".$DevName. " health is WARNING. ".$DevHASyncStatus." ".$DevHASyncPerc."%. Details:\nPartner is ".$DevHANode1SyncStatus." (".$DevHANode1SyncPerc."%).\nHeartbeat Channels ".$DevHANode1HeartBeatChannels." is ".$DevHANode1HeartBeatConn.".\nSync Channels ".$DevHANode1SyncChannels." is ".$DevHANode1SyncConn.".\n";
		exit(1); 
	//Condition, when partner is unreacheble, but VSAN Image is working:
	}elseif(($DevState == "OK") AND ($DevHASyncStatus == "Synchronized") AND ($DevHASyncPerc == 100) AND ($DevHANode1SyncStatus != "synchronized" OR $DevHANode1SyncStatus != "synchronizing") AND ($DevHANode1HeartBeatConn != "established") AND ($DevHANode1SyncConn != "established")){
		echo "WARNING: VSAN Volume ".$DevName. " health is WARNING. ".$DevHASyncStatus." ".$DevHASyncPerc."%. Details:\nPartner is ".$DevHANode1SyncStatus." (".$DevHANode1SyncPerc."%).\nHeartbeat Channels ".$DevHANode1HeartBeatChannels." is ".$DevHANode1HeartBeatConn.".\nSync Channels ".$DevHANode1SyncChannels." is ".$DevHANode1SyncConn.".\n";
		exit(1); 
	//All other cases is critical:
	}else{
		echo "CRITICAL: VSAN Volume ".$DevName. " health is CRITICAL. ".$DevHASyncStatus." ".$DevHASyncPerc."%. Details:\nPartner is ".$DevHANode1SyncStatus." (".$DevHANode1SyncPerc."%).\nHeartbeat Channels ".$DevHANode1HeartBeatChannels." is ".$DevHANode1HeartBeatConn.".\nSync Channels ".$DevHANode1SyncChannels." is ".$DevHANode1SyncConn.".\n";
		exit(2); 
	}	

}else{
 echo "UNKNOWN: Device ".$Device." is not found! Check login and password or check HA Device name.\n";
 exit(3);
}

?>