zabbix.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import json
  2. import logging
  3. import requests
  4. logger = logging.getLogger(__name__)
  5. def initialize_monitor(
  6. ping_url, config, config_filename, monitoring_log_level, dry_run
  7. ): # pragma: no cover
  8. '''
  9. No initialization is necessary for this monitor.
  10. '''
  11. pass
  12. def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run):
  13. '''
  14. Update the configured Zabbix item using either the itemid, or a host and key.
  15. If this is a dry run, then don't actually update anything.
  16. '''
  17. run_states = hook_config.get('states', ['fail'])
  18. if state.name.lower() not in run_states:
  19. return
  20. dry_run_label = ' (dry run; not actually updating)' if dry_run else ''
  21. state_config = hook_config.get(
  22. state.name.lower(),
  23. {
  24. 'value': state.name.lower(),
  25. },
  26. )
  27. server = hook_config.get('server')
  28. username = hook_config.get('username')
  29. password = hook_config.get('password')
  30. api_key = hook_config.get('api_key')
  31. itemid = hook_config.get('itemid')
  32. host = hook_config.get('host')
  33. key = hook_config.get('key')
  34. value = state_config.get('value')
  35. headers = {'Content-Type': 'application/json-rpc'}
  36. logger.info(f'{config_filename}: Updating Zabbix{dry_run_label}')
  37. logger.debug(f'{config_filename}: Using Zabbix URL: {server}')
  38. if server is None:
  39. logger.warning(f'{config_filename}: Server missing for Zabbix')
  40. return
  41. # Determine the zabbix method used to store the value: itemid or host/key
  42. if itemid is not None:
  43. logger.info(f'{config_filename}: Updating {itemid} on Zabbix')
  44. data = {
  45. "jsonrpc": "2.0",
  46. "method": "history.push",
  47. "params": {"itemid": itemid, "value": value},
  48. "id": 1,
  49. }
  50. elif (host and key) is not None:
  51. logger.info(f'{config_filename}: Updating Host:{host} and Key:{key} on Zabbix')
  52. data = {
  53. "jsonrpc": "2.0",
  54. "method": "history.push",
  55. "params": {"host": host, "key": key, "value": value},
  56. "id": 1,
  57. }
  58. elif host is not None:
  59. logger.warning(f'{config_filename}: Key missing for Zabbix')
  60. return
  61. elif key is not None:
  62. logger.warning(f'{config_filename}: Host missing for Zabbix.')
  63. return
  64. else:
  65. logger.warning(f'{config_filename}: No zabbix itemid or host/key provided.')
  66. return
  67. # Determine the authentication method: API key or username/password
  68. if api_key is not None:
  69. logger.info(f'{config_filename}: Using API key auth for Zabbix')
  70. headers['Authorization'] = 'Bearer ' + api_key
  71. elif (username and password) is not None:
  72. logger.info(f'{config_filename}: Using user/pass auth with user {username} for Zabbix')
  73. auth_data = {
  74. "jsonrpc": "2.0",
  75. "method": "user.login",
  76. "params": {
  77. "username": username,
  78. "password": password
  79. },
  80. "id": 1
  81. }
  82. if not dry_run:
  83. logging.getLogger('urllib3').setLevel(logging.ERROR)
  84. try:
  85. response = requests.post(server, headers=headers, json=auth_data)
  86. data['auth'] = response.json().get('result')
  87. if not response.ok:
  88. response.raise_for_status()
  89. except requests.exceptions.RequestException as error:
  90. logger.warning(f'{config_filename}: Zabbix error: {error}')
  91. elif username is not None:
  92. logger.warning(f'{config_filename}: Password missing for Zabbix authentication')
  93. return
  94. elif password is not None:
  95. logger.warning(f'{config_filename}: Username missing for Zabbix authentication')
  96. return
  97. else:
  98. logger.warning(f'{config_filename}: Authentication data missing for Zabbix')
  99. return
  100. if not dry_run:
  101. logging.getLogger('urllib3').setLevel(logging.ERROR)
  102. try:
  103. response = requests.post(server, headers=headers, json=data)
  104. if not response.ok:
  105. response.raise_for_status()
  106. except requests.exceptions.RequestException as error:
  107. logger.warning(f'{config_filename}: Zabbix error: {error}')
  108. def destroy_monitor(
  109. ping_url_or_uuid, config, config_filename, monitoring_log_level, dry_run
  110. ): # pragma: no cover
  111. '''
  112. No destruction is necessary for this monitor.
  113. '''
  114. pass