Changeset 5319
- Timestamp:
- 05/30/14 16:02:32 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
monitoring/plugins/mpi/generic_tla_monitoring.py
r5318 r5319 1 #!/usr/bin/python2 2 3 import sys, getopt, httplib, xml.etree.ElementTree, subprocess, re, pdb, traceback, datetime, urlparse, urllib 4 import simplejson as json 5 import pwd, os 6 7 nagios_codes = { 8 'OK' : 0, 9 'WARNING' : 1, 10 'CRITICAL' : 2, 11 'UNKNOWN' : 3, 12 'DEPENDENT' : 4 13 } 14 15 def nagios_return(code, response) : 16 """ prints the response message 17 and exits the script with one 18 of the defined exit codes 19 DOES NOT RETURN 20 """ 21 print code + ": " + response 22 sys.exit(nagios_codes[code]) 23 24 def nagios_return_complex(results, reporter) : 25 def deal_with_result(result, reporter) : 26 print "[" + reporter + "] " + result['code'] + ": " + result['message'] 27 return result['code'] 28 29 #pdb.set_trace() 30 31 # Scan all condition/status check results and create a list of appropriate exit codes. 32 exit_code_keys = map(lambda result : deal_with_result(result, reporter), results) 33 suggested_exit_codes = list(map(lambda key : nagios_codes[key], exit_code_keys)) 34 35 # Exit with the highest suggested exit code, because the higher the exit code the more problematic the status is and problems have priority over harmony. 36 sys.exit(max(suggested_exit_codes)) 37 38 def usage(command_line_parameters_usage_string) : 39 """ returns Nagios status UNKNOWN with 40 a one line usage description 41 usage() calls nagios_return() 42 """ 43 nagios_return('UNKNOWN', 44 "command line usage: \n" + sys.argv[0] + command_line_parameters_usage_string) 45 46 def generic_validator(data, 47 descriptive_string, 48 kwargs, 49 special_validator) : 50 51 special_plugin_file_name = kwargs['special_plugin_file_name'] # X- 52 53 timestamp = datetime.datetime.today().isoformat() 54 valid = False 55 56 try : 57 valid = special_validator(data, 58 descriptive_string, 59 kwargs) 60 except : 61 traceback_string = traceback.format_exc() 62 #pdb.set_trace() 63 64 err_log_file_path = os.path.normpath("/tmp/" + special_plugin_file_name + "_err_generic_validator__" + descriptive_string.replace('/' , '%2F') + "__" + timestamp + ".log") 65 66 with open(name = err_log_file_path, 67 mode = "wt") as debugging_output_file : 68 debugging_output_file.write(traceback_string) 69 #sys.exit(999) # X- exit with some special error status 70 71 return valid 72 73 74 def check_HTML_wellformedness(data, 75 descriptive_string, 76 **kwargs) : # X- 77 78 def special_validator(data, 79 descriptive_string, 80 kwargs) : 81 pattern = '.*<html.*>.+</html>.*' 82 pattern_regex = re.compile(pattern, re.MULTILINE | re.IGNORECASE | re.DOTALL) 83 results = pattern_regex.search(data) 84 85 # special_plugin_file_name 86 87 if results is not None : 88 return True 89 else : 90 return False 91 92 #pdb.set_trace() 93 94 # X- Do PROPER wellformedness check - once the tools are availble. 95 wellformedness = generic_validator(data, 96 descriptive_string, 97 kwargs, 98 special_validator) 99 100 return wellformedness 101 102 103 def check_JSON_wellformedness(data, 104 descriptive_string, 105 **kwargs) : 106 def special_validator(data, 107 descriptive_string, 108 kwargs) : 109 110 try : 111 json.loads(data) 112 except JSONDecodeError : 113 valid = False 114 else : 115 valid = True 116 117 return valid 118 119 wellformedness = generic_validator(data, 120 descriptive_string, 121 kwargs, 122 special_validator) 123 124 return wellformedness 125 126 127 def check_XML_validity(data, 128 descriptive_string, 129 **kwargs) : 130 131 def special_validator(data, 132 descriptive_string, 133 kwargs) : 134 135 try : 136 data_tree_root_element = xml.etree.ElementTree.XML(text = data) 137 138 if data_tree_root_element.tag == kwargs['valid_root_element_tag'] : 139 return True 140 else : 141 return False 142 except : 143 return False 144 145 wellformedness = generic_validator(data, 146 descriptive_string, 147 kwargs, 148 special_validator) 149 return wellformedness 150 151 152 def check_LDAP_validity(data, 153 descriptive_string, 154 **kwargs) : 155 156 def special_validator(data, 157 descriptive_string, 158 kwargs) : 159 try : 160 return True # X- 161 except : 162 return False 163 164 wellformedness = generic_validator(data, 165 descriptive_string, 166 kwargs, 167 special_validator) 168 return wellformedness 169 170 171 def check_ldap(host, 172 bind_DN) : 173 174 OpenDJ_directory_path = '/srv/LDAP/OpenDJ-2.5.0-Xpress1/' 175 176 base_DN = 'dc=clarin,dc=eu' 177 query = '(objectClass=CLARINPerson)' 178 179 command = [OpenDJ_directory_path + "/bin/ldapsearch", 180 '--port', '10389', 181 '--baseDN', base_DN, 182 '--useStartTLS', 183 '--trustAll', 184 '--hostname', host, 185 '--bindDN', bind_DN, 186 "--bindPasswordFile", '/root/LDAP_passwdfile', 187 query, 188 'isMemberOf'] 189 190 # Run OpenDJ's "ldapsearch" command line utility 191 #pdb.set_trace() 192 193 OpenDJ_uid = pwd.getpwnam('opendj')[2] 194 Nagios_uid = pwd.getpwnam('nagios')[2] 195 196 #import multiprocessing 197 198 def LDAP_query(OpenDJ_uid, command) : 199 200 #pdb.set_trace() 201 202 try : 203 os.setuid(0) # OpenDJ_uid 204 except OSError, e : 205 raise e 206 else : 207 process = subprocess.Popen(command, 208 stdout = subprocess.PIPE, 209 stderr = subprocess.PIPE) 210 211 #print " ".join(command) 212 213 stdout, stderr = process.communicate() 214 215 if process.returncode == 0 : 216 return True 217 #LDAP_result_queue.put(True) 218 else : 219 return False 220 #LDAP_result_queue.put(False) 221 222 223 # LDAP_result_queue = multiprocessing.Queue() 224 # LDAP_query_process = multiprocessing.Process(target = LDAP_query, args = (OpenDJ_uid, command, LDAP_result_queue)) 225 # LDAP_query_process.start() 226 # result = LDAP_result_queue.get() 227 # LDAP_query_process.join() 228 229 result = LDAP_query(OpenDJ_uid, command) 230 231 if result == True: 232 return { "code" : "OK", 233 "message" : 'Host %s is up and responds as expected to a query "%s" with base DN "%s".' % (host, query, base_DN) 234 } 235 else : 236 return { "code" : "CRITICAL", 237 "message" : 'Host %s is not up or does not respond as expected to a query "%s" with base DN "%s".' % (host, query, base_DN) 238 } 239 240 # current_process_ID = os.fork() 241 242 # if current_process_ID == 0 : 243 # ## Child process code 244 245 246 247 # os._exit(0) 248 249 # ## Parent process code. Wait for ldapsearch child process. 250 # os.waitpid(current_process_ID, 0) 251 252 # try : 253 # os.setuid(Nagios_uid) 254 # except OSError, e : 255 # raise e 256 257 #print stdout 258 #print stderr 259 #pdb.set_trace() 260 261 return result 262 263 264 def check_condition(host, 265 http_path, 266 protocol, 267 HTTP_method, 268 port_number, 269 authorize, 270 validator, 271 **validator_arguments) : 272 273 #pdb.set_trace() 274 # X- remove implicit argument values 275 #if port_number is None : port_number = 80 276 #if authorize is None : authorize = True 277 278 try : 279 port_number = int(port_number) 280 except ValueError : 281 return { "code" : "CRITICAL", 282 "message" : 'The port number specified, "{0}", cannot be converted to an integer.'.format(port_number) 283 } 284 except TypeError : 285 port_number = None 286 287 def handle_connection_failure(problem_description) : 288 err_log_file_path = os.path.normpath("/tmp/" + special_plugin_file_name + "_err_connection_failure__" + http_path.replace('/' , '%2F') + "__" + timestamp + ".log") 289 290 with open(name = err_log_file_path, 291 mode = "wt") as debugging_output_file : 292 debugging_output_file.write(problem_description) 293 294 special_plugin_file_name = validator_arguments['special_plugin_file_name'] # X- 295 296 #http_path = str(urllib.quote_plus(http_path)) 297 298 timestamp = datetime.datetime.today().isoformat() 299 300 try : 301 if protocol == 'http' : 302 conn = httplib.HTTPConnection(host = host, 303 port = port_number, 304 strict = True) 305 elif protocol == 'https' : 306 conn = httplib.HTTPSConnection(host = host, 307 port = port_number, 308 strict = True) 309 request = conn.request(HTTP_method, 310 http_path) 311 except : 312 traceback_string = traceback.format_exc() 313 314 handle_connection_failure(traceback_string + "\nThis problem originates from location 1 in '" + special_plugin_file_name + "'.\n") 315 316 return { 317 "code" : "CRITICAL", 318 "message" : '{protocol} connection on port {port_number} to host "{host}" failed.'.format(protocol = protocol, 319 port_number = port_number, 320 host = host) 321 } 322 else : 323 try : 324 response = conn.getresponse() 325 326 data = response.read() 327 328 conn.close() 329 except : 330 traceback_string = traceback.format_exc() 331 332 handle_connection_failure(traceback_string + "\nThis problem originates from location 2 in '" + special_plugin_file_name + "'.\n") 333 else : 334 335 redirecting_responses = frozenset([ 336 httplib.MOVED_PERMANENTLY, 337 httplib.FOUND, 338 httplib.SEE_OTHER, 339 httplib.TEMPORARY_REDIRECT, 340 ]) 341 342 if response.status == httplib.OK : 343 # HTTP status codes 200 and 302 344 # X- Resolve redirect in case of HTTP status == 302 345 well_formed = validator(data = data, 346 descriptive_string = http_path, 347 **validator_arguments) # ['validator_arguments']) 348 349 if well_formed : 350 return { 351 "code" : "OK", 352 "message" : 'Host "{host}" is up and returns well-formed data at "{http_path}".'.format(host = host, http_path = http_path) 353 } 354 else : 355 return { 356 "code" : "CRITICAL", 357 "message" : 'Host "{host}" is up but returns non-well-formed data at "{http_path}".'.format(host = host, http_path = http_path) 358 } 359 360 elif response.status in redirecting_responses : 361 new_location_URL = dict(response.getheaders())['location'] 362 363 parsed_new_location_URL = urlparse.urlsplit(new_location_URL) 364 new_http_path = parsed_new_location_URL.path 365 if parsed_new_location_URL.query != '' : 366 new_http_path = new_http_path + '?' + parsed_new_location_URL.query 367 368 if parsed_new_location_URL.scheme == protocol and host == parsed_new_location_URL.netloc and http_path == new_http_path : 369 return { 370 "code" : "CRITICAL", 371 "message" : 'Host "{host}" is up but the response to GET "{http_path}" implies an infinite redirection to itself.'.format(host = host, http_path = http_path) 372 } 373 374 else : 375 376 #pdb.set_trace() 377 378 return check_condition(host = parsed_new_location_URL.netloc, 379 http_path = new_http_path, 380 protocol = parsed_new_location_URL.scheme, 381 HTTP_method = HTTP_method, 382 port_number = parsed_new_location_URL.port, 383 authorize = authorize, 384 validator = validator, 385 **validator_arguments) # special_plugin_file_name = validator_arguments['special_plugin_file_name'] 386 387 elif response.status == httplib.UNAUTHORIZED and authorize == False : 388 return { 389 "code" : "OK", 390 "message" : 'Host "{host}" is up and requests authorization at "{http_path}".'.format(host = host, http_path = http_path) 391 } 392 393 else : 394 #pdb.set_trace() 395 handle_connection_failure("Unreachable URL! HTTP response code: " + str(response.status) + 396 "\nThis problem originates from location 3 in '" + special_plugin_file_name + "'.\n") 397 398 return { 399 "code" : "CRITICAL", 400 "message" : 'Host "{host}" has a problem with the URL path component "{http_path}".'.format(host = host, http_path = http_path) 401 } 402 403 def main(special_main_subroutine, 404 command_line_parameters) : 405 406 ## Process plugin-specific command line parameters. 407 command_line_parameters_getopt_string = command_line_parameters_usage_string = "\\ \n" 408 for (parameter, description) in command_line_parameters : 409 command_line_parameters_usage_string = command_line_parameters_usage_string + parameter + " " + description + "\\ \n" 410 command_line_parameters_getopt_string = command_line_parameters_getopt_string + parameter.lstrip("-") + ":" 411 412 try : 413 opts = filter(None, getopt.getopt(sys.argv[1:], command_line_parameters_getopt_string)) 414 if len(opts) > 0 : opts = opts[0] 415 except getopt.GetoptError, err : 416 usage(command_line_parameters_usage_string) 417 else : 418 if len(command_line_parameters) == len(opts) : 419 ## main_subroutine_argument_values is based on the argument order of special_main_subroutine(). They are not mapped to the argument names! 420 ## Therefore, command_line_parameters must be in the same order as special_main_subroutine()'s arguments. 421 main_subroutine_argument_values = [parameter_value for parameter_name, parameter_value in opts] 422 # pdb.set_trace() 423 special_main_subroutine(*main_subroutine_argument_values) 424 else : 425 usage(command_line_parameters_usage_string) 426 427 428 if __name__ == "__main__" : 429 main()
Note: See TracChangeset
for help on using the changeset viewer.