#!/usr/bin/python
#
# Contributed by Nagy Zsombor.
# Support for GLUE 2.0r1 by Gabor Roczei.
# Released under the Apache License with permission from Gabor Roczei.
# See also http://bugzilla.nordugrid.org/show_bug.cgi?id=1983.

import httplib
import urlparse
import sys
try:
    import xml.etree.ElementTree as ET
except ImportError:
    import elementtree.ElementTree as ET
import getopt
import signal
import traceback

glue_schemas = [
    'http://schemas.ogf.org/glue/2008/05/spec_2.0_d41_r01',
    'http://schemas.ogf.org/glue/2009/03/spec_2.0_r1',
]

timeout = 10

def handler(signum, frame):
    print "ARCSERVICE UNKNOWN:", "Check has timed out (after %s seconds)" % timeout
    sys.exit(3)
    
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout)

def usage():
    print """Usage: check_arcservice -u <URL> -k <key_file> -c <cert_file> -t <timeout> --debug
    
    -u <URL>        the URL of the service to check (mandatory)
    -t <timeout>    after this amount of seconds the check will return UNKNOWN (default: 10)
    -k <key_file>   path of the key file (default: /etc/grid-security/hostkey.pem)
    -c <cert_file>  path of the cert file (default: /etc/grid-security/hostcert.pem)
    --debug         print some debugging information
    """
    sys.exit(3)

try:
    options, args = getopt.getopt(sys.argv[1:],"u:k:c:t:",["debug"])
except getopt.GetoptError:
    usage()
    
key_file = '/etc/grid-security/hostkey.pem'
cert_file = '/etc/grid-security/hostcert.pem'
url = ''
debug = False

for name, value in options:
    if name in ['-k']:
        key_file = value
    if name in ['-c']:
        cert_file = value
    if name in ['-u']:
        url = value
    if name in ['--debug']:
        debug = True
    if name in ['-t']:
        timeout = int(value)
        signal.alarm(timeout)
        
if not key_file or not cert_file or not url:
    usage()

try:
    parsed = urlparse.urlparse(url)
    https = (parsed[0] == 'https')
    hostport = parsed[1]
    path = parsed[2]
except:
    print "ARCSERVICE UNKNOWN: Error parsing URL", url


get_resource_property_document_request = '''<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <SOAP-ENV:Header>
        <wsa:Action>http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest</wsa:Action>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <wsrf-rp:GetResourcePropertyDocument/>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>'''

if https:
    connection = httplib.HTTPSConnection(host = hostport, key_file = key_file, cert_file = cert_file)
else:
    connection = httplib.HTTPConnection(host = hostport)
try:
    connection.request('POST', path, get_resource_property_document_request)
except Exception, e:
    print "ARCSERVICE CRITICAL:", "Connecting to", url, "failed (%s)" % e 
    if debug:
        traceback.print_exc()
    sys.exit(2)
response = connection.getresponse()
if response.status == 200:
    data = response.read()
    try:
        et = ET.fromstring(data)
	health_state = None
	for glue_schema in glue_schemas:
	    health_state = et.findtext(".//{%s}HealthState"%glue_schema)
	    if health_state:
		break

        if health_state is None:
            print "ARCSERVICE UNKNOWN:", "Service's health state is unknown"
            if debug:
                print data
            sys.exit(3)

	if health_state == 'ok':
            print "ARCSERVICE OK:", "Service's health state is", health_state
            if debug:
                print data
            sys.exit(0)
        else:
            print "ARCSERVICE CRITICAL:", "Service's health state is", health_state
            if debug:
                print data
            sys.exit(2)
    except StandardError, e:
        print "ARCSERVICE UNKNOWN:", "Unable to parse respone (%s)" % e
        if debug:
            print data
        sys.exit(3)
else:
    print "ARCSERVICE CRITICAL:", "Invalid response from server (%s, %s)" % (response.status, response.reason)
    if debug:
        print response.read()
    sys.exit(2)

