mirror of
				https://github.com/Icinga/icinga2.git
				synced 2025-10-31 03:03:52 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			278 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			278 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python
 | |
| from __future__ import unicode_literals
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| import time
 | |
| import socket
 | |
| 
 | |
| import utils
 | |
| 
 | |
| 
 | |
| LIVESTATUS_PATH = '/var/run/icinga2/cmd/livestatus'
 | |
| LS_HOST_COLUMNS = [
 | |
|     'name',
 | |
|     'name',
 | |
|     'display_name',
 | |
|     'display_name',
 | |
|     None,
 | |
|     'state',
 | |
|     'state_type',
 | |
|     'current_attempt',
 | |
|     'max_check_attempts',
 | |
|     None,
 | |
|     'last_state',
 | |
|     None,
 | |
|     'last_state_change',
 | |
|     None,
 | |
|     'latency',
 | |
|     'execution_time',
 | |
|     'plugin_output',
 | |
|     None,
 | |
|     'last_check',
 | |
|     'address',
 | |
|     'address6'
 | |
|     ]
 | |
| 
 | |
| LS_SVC_COLUMNS = [
 | |
|     'description',
 | |
|     'display_name',
 | |
|     'display_name',
 | |
|     None,
 | |
|     'state',
 | |
|     'state_type',
 | |
|     'current_attempt',
 | |
|     'max_check_attempts',
 | |
|     None,
 | |
|     'last_state',
 | |
|     None,
 | |
|     'last_state_change',
 | |
|     None,
 | |
|     'latency',
 | |
|     'execution_time',
 | |
|     'plugin_output',
 | |
|     'perf_data',
 | |
|     'last_check',
 | |
|     'host_num_services',
 | |
|     'host_num_services_ok',
 | |
|     'host_num_services_warn',
 | |
|     'host_num_services_unknown',
 | |
|     'host_num_services_crit'
 | |
|     ]
 | |
| 
 | |
| STATE_MAP = {
 | |
|     'SOFT': 0,
 | |
|     'HARD': 1
 | |
|     }
 | |
| 
 | |
| 
 | |
| def send_command(command):
 | |
|     try:
 | |
|         return send_query('COMMAND [{0}] {1}'.format(int(time.time()), command))
 | |
|     except utils.LiveStatusError, error:
 | |
|         sys.stderr.write('Failed to execute command: {0}\n\n{1}\n'
 | |
|                          ''.format(command, error))
 | |
| 
 | |
| 
 | |
| def send_query(query):
 | |
|     response = LIVESTATUS.query(query + '\nColumnHeaders: on')
 | |
|     if response:
 | |
|         header, result = response.pop(0), {}
 | |
|         return [dict((header[i], v) for i, v in enumerate(r)) for r in response]
 | |
|     return []
 | |
| 
 | |
| 
 | |
| def get_one(query):
 | |
|     return next(iter(send_query(query)), {})
 | |
| 
 | |
| 
 | |
| def get_event_output():
 | |
|     try:
 | |
|         with open('/tmp/test_event.out') as f:
 | |
|             remove = True
 | |
|             return f.read().rstrip().split('|')
 | |
|     except (IOError, OSError):
 | |
|         remove = False
 | |
|     finally:
 | |
|         if remove:
 | |
|             os.system('sudo rm -f /tmp/test_event.out')
 | |
| 
 | |
| 
 | |
| def convert_output(value):
 | |
|     try:
 | |
|         return int(value)
 | |
|     except ValueError:
 | |
|         try:
 | |
|             return float(value)
 | |
|         except ValueError:
 | |
|             return STATE_MAP.get(value, value)
 | |
| 
 | |
| 
 | |
| def validate_time_format(inputstr, formatstr):
 | |
|     try:
 | |
|         time.strptime(inputstr, formatstr)
 | |
|     except ValueError:
 | |
|         return False
 | |
|     else:
 | |
|         return True
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     send_command('CHANGE_HOST_EVENT_HANDLER;localhost;test_event')
 | |
|     host_info = get_one('GET hosts\nFilter: name = localhost'
 | |
|                         '\nColumns: event_handler')
 | |
|     if host_info.get('event_handler') != 'test_event':
 | |
|         utils.Logger.fail('Could not assign eventcommand "test_event"'
 | |
|                           ' to host "localhost"\n')
 | |
|         return 1
 | |
|     utils.Logger.ok('Successfully assigned an eventcommand'
 | |
|                     ' to host "localhost"\n')
 | |
| 
 | |
|     send_command('PROCESS_HOST_CHECK_RESULT;localhost;1;A negative result to'
 | |
|                  ' trigger an eventhandler|some interesting perfdata!')
 | |
|     event_output = get_event_output()
 | |
|     if not event_output:
 | |
|         send_command('CHANGE_HOST_EVENT_HANDLER;localhost;')
 | |
|         utils.Logger.fail('Could not trigger the eventcommand\n')
 | |
|         return 1
 | |
|     utils.Logger.ok('Successfully triggered the eventcommand\n')
 | |
|     failure = False
 | |
| 
 | |
|     utils.Logger.info('Checking host macros...\n')
 | |
|     host_info = get_one('GET hosts\nFilter: name = localhost\nColumns: {0}'
 | |
|                         ''.format(' '.join(c for c in LS_HOST_COLUMNS if c)))
 | |
|     if event_output[0] != host_info['name']*2:
 | |
|         failure = True
 | |
|         utils.Logger.fail('Escaping environment variables '
 | |
|                           'seems not to properly working\n')
 | |
|         utils.Logger.fail(' Expected: {0!r} Got: {1!r}\n'
 | |
|                           ''.format(host_info['name']*2, event_output[0]))
 | |
|     else:
 | |
|         utils.Logger.ok('Escaped environment variables'
 | |
|                         ' are properly processed\n')
 | |
|     for i, column in enumerate(LS_HOST_COLUMNS[1:], 1):
 | |
|         if column is not None:
 | |
|             macro_name, _, macro_value = event_output[i].partition('=')
 | |
|             output_value = convert_output(macro_value)
 | |
|             if output_value != host_info[column]:
 | |
|                 failure = True
 | |
|                 utils.Logger.fail('Macro "{0}" returns an incorrect value. '
 | |
|                                   'Expected "{2}" but got "{1}"\n'
 | |
|                                   ''.format(macro_name, output_value,
 | |
|                                             host_info[column]))
 | |
|             else:
 | |
|                 utils.Logger.ok('Macro "{0}" returns the correct value\n'
 | |
|                                 ''.format(macro_name))
 | |
| 
 | |
|     utils.Logger.info('Checking service macros...\n')
 | |
|     svc_info = get_one('GET services\nFilter: description = ping4\nColumns: {0}'
 | |
|                        ''.format(' '.join(c for c in LS_SVC_COLUMNS if c)))
 | |
|     for i, column in enumerate(LS_SVC_COLUMNS, len(LS_HOST_COLUMNS)):
 | |
|         if column is not None:
 | |
|             macro_name, _, macro_value = event_output[i].partition('=')
 | |
|             output_value = convert_output(macro_value)
 | |
|             if output_value != svc_info[column]:
 | |
|                 failure = True
 | |
|                 utils.Logger.fail('Macro "{0}" returns an incorrect value. '
 | |
|                                   'Expected "{2}" but got "{1}"\n'
 | |
|                                   ''.format(macro_name, output_value,
 | |
|                                             svc_info[column]))
 | |
|             else:
 | |
|                 utils.Logger.ok('Macro "{0}" returns the correct value\n'
 | |
|                                 ''.format(macro_name))
 | |
| 
 | |
|     utils.Logger.info('Checking global macros...\n')
 | |
|     timet = convert_output(event_output[-6].partition('=')[2])
 | |
|     if not isinstance(timet, int):
 | |
|         failure = True
 | |
|         utils.Logger.fail('Macro "TIMET" does not return a timestamp. '
 | |
|                           'Expected int but got: {0!r}\n'.format(timet))
 | |
|     else:
 | |
|         utils.Logger.ok('Macro "TIMET" returns the correct value\n')
 | |
|     longdatetime = event_output[-5].partition('=')[2]
 | |
|     longdatetime_format = '%Y-%m-%d %H:%M:%S +0000'
 | |
|     if not validate_time_format(longdatetime, longdatetime_format):
 | |
|         failure = True
 | |
|         utils.Logger.fail('Macro "LONGDATETIME" returns an incorrect value.'
 | |
|                           ' Expected value of format "{0}" but got "{1}"\n'
 | |
|                           ''.format(longdatetime_format, longdatetime))
 | |
|     else:
 | |
|         utils.Logger.ok('Macro "LONGDATETIME" returns the correct value\n')
 | |
|     shortdatetime = event_output[-4].partition('=')[2]
 | |
|     shortdatetime_format = '%Y-%m-%d %H:%M:%S'
 | |
|     if not validate_time_format(shortdatetime, shortdatetime_format):
 | |
|         failure = True
 | |
|         utils.Logger.fail('Macro "SHORTDATETIME" returns an incorrect value.'
 | |
|                           ' Expected value of format "{0}" but got "{1}"\n'
 | |
|                           ''.format(shortdatetime_format, shortdatetime))
 | |
|     else:
 | |
|         utils.Logger.ok('Macro "SHORTDATETIME" returns the correct value\n')
 | |
|     m_date = event_output[-3].partition('=')[2]
 | |
|     m_date_format = '%Y-%m-%d'
 | |
|     if not validate_time_format(m_date, m_date_format):
 | |
|         failure = True
 | |
|         utils.Logger.fail('Macro "DATE" returns an incorrect value. '
 | |
|                           'Expected value of format "{0}" but got "{1}"\n'
 | |
|                           ''.format(m_date_format, m_date))
 | |
|     else:
 | |
|         utils.Logger.ok('Macro "DATE" returns the correct value\n')
 | |
|     m_time = event_output[-2].partition('=')[2]
 | |
|     m_time_format = '%H:%M:%S +0000'
 | |
|     if not validate_time_format(m_time, m_time_format):
 | |
|         failure = True
 | |
|         utils.Logger.fail('Macro "TIME" returns an incorrect value. '
 | |
|                           'Expected value of format "{0}" but got "{1}"\n'
 | |
|                           ''.format(m_time_format, m_time))
 | |
|     else:
 | |
|         utils.Logger.ok('Macro "TIME" returns the correct value\n')
 | |
| 
 | |
|     utils.Logger.info('Checking command macros...\n')
 | |
|     if convert_output(event_output[-1].partition('=')[2]) != 1337:
 | |
|         failure = True
 | |
|         utils.Logger.fail('The command macro "custom_macro"'
 | |
|                           ' is not being substituted\n')
 | |
|     else:
 | |
|         utils.Logger.ok('The command macro "custom_macro"'
 | |
|                         ' is correctly substituted\n')
 | |
| 
 | |
|     send_command('DISABLE_HOST_EVENT_HANDLER;localhost')
 | |
|     send_command('PROCESS_HOST_CHECK_RESULT;localhost;0;A positive result that'
 | |
|                  ' should not trigger an eventhandler')
 | |
|     if get_event_output():
 | |
|         failure = True
 | |
|         utils.Logger.fail('Could not disable the eventcommand\n')
 | |
|     else:
 | |
|         utils.Logger.ok('Successfully disabled the eventcommand\n')
 | |
| 
 | |
|     send_command('ENABLE_HOST_EVENT_HANDLER;localhost')
 | |
|     host_info = get_one('GET hosts\nFilter: name = localhost'
 | |
|                         '\nColumns: event_handler_enabled')
 | |
|     if host_info['event_handler_enabled'] != 1:
 | |
|         failure = True
 | |
|         utils.Logger.fail('Could not re-enable the eventcommand\n')
 | |
|     else:
 | |
|         utils.Logger.ok('Successfully re-enabled the eventcommand\n')
 | |
| 
 | |
|     send_command('CHANGE_HOST_EVENT_HANDLER;localhost;')
 | |
|     host_info = get_one('GET hosts\nFilter: name = localhost'
 | |
|                         '\nColumns: event_handler')
 | |
|     if host_info['event_handler']:
 | |
|         failure = True
 | |
|         utils.Logger.fail('Could not remove eventcommand "test_event"'
 | |
|                           ' assigned to host "localhost"\n')
 | |
|     else:
 | |
|         utils.Logger.ok('Successfully removed the eventcommand'
 | |
|                         ' assigned to host "localhost"\n')
 | |
| 
 | |
|     return 1 if failure else 0
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     try:
 | |
|         with utils.LiveStatusSocket(LIVESTATUS_PATH) as LIVESTATUS:
 | |
|             sys.exit(main())
 | |
|     except (OSError, IOError, socket.error), e:
 | |
|         utils.Logger.error('Could not connect to Livestatus socket: {0} ({1})'
 | |
|                            '\n'.format(LIVESTATUS_PATH, unicode(e)))
 | |
| 
 |