#!/usr/bin/env python

import requests, urllib3, json
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import argparse
import sys
import base64

# Dell EMC Isilon - NagiosXI Hardware Health Check Script - v1.0
# Tristan Self
# The script uses the EMC Isilon REST API to query for some basic cluster health and node information, a read-only account is recommended to use to query the array for information.
#
# Release History
# 20/02/2020 - v1.0 - Inital release.

#############################################################################################
# Argument Collection
#############################################################################################

# Parse the arguments passed from the command line.
parser = argparse.ArgumentParser()
parser.add_argument('-e','--endpointurl',help='Endpoint URL (e.g. https://arrayname.domain.com:8080)',required=True)
parser.add_argument('-u','--username',help='API Username',required=True)
parser.add_argument('-p','--password',help='API Password (in single quotes, if you have weird characters!)',required=True)

# Assign each arguments to the relevant variables.
arguments = vars(parser.parse_args())
strAPIBaseURL = arguments['endpointurl']
strAPIPassword = arguments['password']
strAPIUsername = arguments['username']

# Need to convert username and password into Base64 to add to the authorization string...
# Username and password provided in the format:   <username>:<password> (without pointy brackets) then turn into Base64 representation.

strBase64Raw = "{}:{}".format(strAPIUsername,strAPIPassword)
strBase64Bytes = strBase64Raw.encode("utf-8")
strBase64Encoded = base64.b64encode(strBase64Bytes)
strBase64Encoded = str(strBase64Encoded)

# Build the Headers to be passed to the REST API with the username/password base64 encoded string.
headers = {
        'Content-Type': 'application/json', 'Authorization': 'Basic {}'.format(strBase64Encoded)
}

# Initalise the report status text for the check response.
strReportStatus = ""
intReportStatus = 0

# Query the REST API to gather the health information from the Isilon array.
objClusterHealth = requests.get(strAPIBaseURL+'/platform/1/statistics/current?key=cluster.health', headers=headers, verify=False)
objClusterHealthJSON = json.dumps(objClusterHealth.json(),indent=2)
objClusterHealthDict = json.loads(objClusterHealthJSON)
intClusterHealthValue =  (objClusterHealthDict['stats'][0]['value'])

objNodeCount = requests.get(strAPIBaseURL+'/platform/1/statistics/current?key=cluster.node.count.all', headers=headers, verify=False)
objNodeCountJSON = json.dumps(objNodeCount.json(),indent=2)
objNodeCountDict = json.loads(objNodeCountJSON)
intNodeCountValue =  (objNodeCountDict['stats'][0]['value'])

objNodeCountUp = requests.get(strAPIBaseURL+'/platform/1/statistics/current?key=cluster.node.count.up', headers=headers, verify=False)
objNodeCountUpJSON = json.dumps(objNodeCountUp.json(),indent=2)
objNodeCountUpDict = json.loads(objNodeCountUpJSON)
intNodeCountUpValue =  (objNodeCountUpDict['stats'][0]['value'])

objNodeCountDown = requests.get(strAPIBaseURL+'/platform/1/statistics/current?key=cluster.node.count.down', headers=headers, verify=False)
objNodeCountDownJSON = json.dumps(objNodeCountDown.json(),indent=2)
objNodeCountDownDict = json.loads(objNodeCountDownJSON)
intNodeCountDownValue =  (objNodeCountDownDict['stats'][0]['value'])

#Determine the status of the array based on the result of the queries.
if intClusterHealthValue == 0:
    strClusterHealthValue = "HEALTHY"
    strReportStatus = "OK"
    intReportStatus = 0
elif intClusterHealthValue == 1:
    strClusterHealthValue = "DEGRADED"
    strReportStatus = "WARNING"
    intReportStatus = 1
else:
    strClusterHealthValue == "FAILED"
    strReportStatus = "CRITICAL"
    intReportStatus = 2

# Build string and print to the screen.
print ("{} - Cluster Status: {}, {} Nodes, Up:{} Down:{}".format(strReportStatus,strClusterHealthValue,intNodeCountValue,intNodeCountUpValue,intNodeCountDownValue))

# Return the status to the calling program.
sys.exit(intClusterHealthValue)