#!/usr/bin/python3 # # # Uses the oDATA API to query information on a Citrix XenApp/XenDesktop environment. # # #Header Info __author__ = 'Wagner Garcez' __email__ = 'wagner.garcez@interop.com.br' __license__ = 'GPLv3' #import modules try: import re import sys import json import signal import requests from requests_ntlm import HttpNtlmAuth from optparse import OptionParser, OptionGroup except Exception as e: print ('UNKNOWN - {}'.format(e)) sys.exit(opme['UNKNOWN']) #fs = { 1:'None', # 2:'FailedToStart', # 3:'StuckOnBoot', # 4:'Unregistered', # 5:'MaximumLoad' # return API: MaxCapacity , return Director: MaximumLoad #} # get parameters def parse_args(): parser = OptionParser() parser.add_option('-b', '--broker' , dest = 'broker', default = None , help = 'Broker machine | controller') parser.add_option('-m', '--machine' , dest = 'machine', default = None , help = 'Machine name') parser.add_option('-u', '--username' , dest = 'user_name', default = None , help = 'User Name for API connection') parser.add_option('-p', '--password' , dest = 'password', default = None , help = 'Passwors for API connection') parser.add_option('-v', '--version' , dest = 'version', default = 'v1' , help = 'Use v1 in XenDesktop 7') parser.add_option('-o', '--option' , dest = 'option', default = None , help = 'The type of data you want to query') parser.add_option('-w', '--warning' , dest = 'warning', default = None , help = 'Warning threshold') parser.add_option('-c', '--critical' , dest = 'critical', default = None , help = 'Critical threshold') parser.add_option('-V', '--verbose' , dest = 'verbose', default = False, help = 'Verbose Mode', action = 'store_true') (options, args) = parser.parse_args() if len(sys.argv) < 2: usage() test = validate_args(options) if test != '': print (test) sys.exit(opme['UNKNOWN']) else: return options # validar argumentos recebidos def validate_args(o): miss = '' if (o.broker is None or o.user_name is None or o.password is None or o.machine is None): miss = 'UNKNOWN - Missing argument' if o.broker is None: miss += ' -b ' if o.user_name is None: miss += ' -u ' if o.password is None: miss += ' -p ' if o.machine is None: miss += ' -m ' return miss if (o.warning is None or o.critical is None) and (o.option == 'load_index' or o.option == 'load_index' or o.option == 'session_count'): miss += "UNKNOWN - Missing argument -w or -c = 0: load = int(load / 100) output = 'Citrix Load of server {} is {}'.format(options.machine, load) # aplicar metricas return validate_load(load, output) else: output = 'UNKNOWN - Value {} is not number'.format(load) return output, opme['UNKNOWN'] def get_desktop_groups(u, s): url = u + 'DesktopGroups?$select=Id,Name&$format=json' r = (s.get(url)) json_data = json.loads(r.text) if ((json_data['value'])): return json_data else: print ("UNKNOWN - Unable to collect desktop group Ids") sys.exit(opme['UNKNOWN']) def get_machine_info(u, s, m): selects = 'DnsName,IPAddress,IsInMaintenanceMode,FaultState,OSType,CurrentLoadIndexId,DesktopGroupId,CurrentSessionCount' url = u + 'Machines?$filter=startswith(DnsName, \'{}\')&$select={}&$format=json'.format(m, selects) try: r = (s.get(url)) r.raise_for_status() except requests.exceptions.HTTPError as errh: print ("UNKNOWN - Http Error:",errh) sys.exit(opme['UNKNOWN']) except requests.exceptions.ConnectionError as errc: print ("UNKNOWN - Error Connecting:",errc) sys.exit(opme['UNKNOWN']) except requests.exceptions.Timeout as errt: print ("UNKNOWN - Timeout Error:",errt) sys.exit(opme['UNKNOWN']) except requests.exceptions.RequestException as err: print ("UNKNOWN - Something is wrong [get_machine_info]",err) sys.exit(opme['UNKNOWN']) json_data = json.loads(r.text) if ((json_data['value'])): return json_data else: print ("UNKNOWN - Unable to collect information on machine '{}'".format(options.machine)) sys.exit(opme['UNKNOWN']) def get_index_group_id (dg, dgi): index = 0 for i in dgi: if i['DesktopGroupId'] is not None: return index else: index += 1 pass # group ID nulo = dois registros referente ao mesmo server else: print ('UNKNOWN - Not Found Desktop Group Id') sys.exit(opme['UNKNOWN']) # main function def main(): indice = 0 url_api = 'http://{}/Citrix/Monitor/OData/{}/Data/'.format(options.broker, options.version) # sessao, autenticacao session = requests.Session() session.auth = HttpNtlmAuth(options.user_name, options.password) # json com informacoes sobre a maquina alvo data = get_machine_info (url_api, session, options.machine) # json com informacoes com o nome e o ID de todos os grupos criados desktop_groups = get_desktop_groups (url_api, session) vprint ('Desktop Groups:\n-------------') vprint (desktop_groups) # indice do grupo pertencente a maquina alvo index = get_index_group_id (desktop_groups, data['value']) # descobrir o nome do grupo atraves do ID group = search_desktop_group_by_id (desktop_groups, data['value'][index]['DesktopGroupId']) # adciona nome do grupo ao json com informacoes da maquina data['value'][index].update({'DesktopGroupName': group}) # verbose vprint ('\nAll Registers: \n ----------') vprint (data) vprint ('\nData Target: \n ----------') vprint (data['value'][index]) vprint ('\n DNS Name: {}'.format(data['value'][index]['DnsName'])) vprint (' Desktop Group Name: {}'.format(data['value'][index]['DesktopGroupName'])) vprint (' Operating System: {} \n'.format(data['value'][index]['OSType'])) opt = options.option # opcoes disponiveis no script if opt == 'load_index': if data['value'][index]['CurrentLoadIndexId'] is not None: out, code = get_load_by_id(url_api, session, data['value'][index]['CurrentLoadIndexId']) else: (out , code ) = "UNKNOWN - Invalid option for machine '" + str(options.machine) + "' " , '3' elif opt == 'session_count': out, code = get_session_count(data['value'][index]['CurrentSessionCount']) elif opt == 'maintenance_mode': out, code = get_maintenance_mode(data['value'][index]['IsInMaintenanceMode']) elif opt == 'fault_state': out, code = get_fault_state(url_api, session, data['value'][index]['FaultState'], data['value'][index]['DesktopGroupName']) elif opt == 'info': out, code = get_info(data['value'][index]) else: (out , code ) = "UNKNOWN - Invalid option: '-o " + str(opt) + "' " , '3' # output print (out) sys.exit(int(code)) # call main function if __name__ == '__main__': opme = {'OK':0,'WARNING':1,'CRITICAL':2,'UNKNOWN':3} options = parse_args() signal.signal(signal.SIGINT, sigint_handler) main()