test_zabbix.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. from enum import Enum
  2. from flexmock import flexmock
  3. import borgmatic.hooks.monitor
  4. from borgmatic.hooks import zabbix as module
  5. SERVER = 'https://zabbix.com/zabbix/api_jsonrpc.php'
  6. ITEMID = 55105
  7. USERNAME = 'testuser'
  8. PASSWORD = 'fakepassword'
  9. API_KEY = 'fakekey'
  10. HOST = 'borg-server'
  11. KEY = 'borg.status'
  12. VALUE = 'fail'
  13. DATA_HOST_KEY = {
  14. "jsonrpc": "2.0",
  15. "method": "history.push",
  16. "params": {"host": HOST, "key": KEY, "value": VALUE},
  17. "id": 1,
  18. }
  19. DATA_HOST_KEY_WITH_TOKEN = {
  20. "jsonrpc": "2.0",
  21. "method": "history.push",
  22. "params": {"host": HOST, "key": KEY, "value": VALUE},
  23. "id": 1,
  24. "auth": "3fe6ed01a69ebd79907a120bcd04e494"
  25. }
  26. DATA_ITEMID = {
  27. "jsonrpc": "2.0",
  28. "method": "history.push",
  29. "params": {"itemid": ITEMID, "value": VALUE},
  30. "id": 1,
  31. }
  32. DATA_HOST_KEY_WITH_TOKEN = {
  33. "jsonrpc": "2.0",
  34. "method": "history.push",
  35. "params": {"itemid": ITEMID, "value": VALUE},
  36. "id": 1,
  37. "auth": "3fe6ed01a69ebd79907a120bcd04e494"
  38. }
  39. DATA_USER_LOGIN = {
  40. "jsonrpc": "2.0",
  41. "method": "user.login",
  42. "params": {"username": USERNAME, "password": PASSWORD},
  43. "id": 1,
  44. }
  45. AUTH_HEADERS_API_KEY = {
  46. 'Content-Type': 'application/json-rpc',
  47. 'Authorization': f'Bearer {API_KEY}'
  48. }
  49. AUTH_HEADERS_USERNAME_PASSWORD = {
  50. 'Content-Type': 'application/json-rpc'
  51. }
  52. def test_ping_monitor_config_with_api_key_only_exit_early():
  53. # This test should exit early since only providing an API KEY is not enough
  54. # for the hook to work
  55. hook_config = {
  56. 'api_key': API_KEY
  57. }
  58. flexmock(module.logger).should_receive('warning').once()
  59. module.ping_monitor(
  60. hook_config,
  61. {},
  62. 'config.yaml',
  63. borgmatic.hooks.monitor.State.FAIL,
  64. monitoring_log_level=1,
  65. dry_run=False,
  66. )
  67. def test_ping_monitor_config_with_host_only_exit_early():
  68. # This test should exit early since only providing a HOST is not enough
  69. # for the hook to work
  70. hook_config = {
  71. 'host': HOST
  72. }
  73. flexmock(module.logger).should_receive('warning').once()
  74. module.ping_monitor(
  75. hook_config,
  76. {},
  77. 'config.yaml',
  78. borgmatic.hooks.monitor.State.FAIL,
  79. monitoring_log_level=1,
  80. dry_run=False,
  81. )
  82. def test_ping_monitor_config_with_key_only_exit_early():
  83. # This test should exit early since only providing a KEY is not enough
  84. # for the hook to work
  85. hook_config = {
  86. 'key': KEY
  87. }
  88. flexmock(module.logger).should_receive('warning').once()
  89. module.ping_monitor(
  90. hook_config,
  91. {},
  92. 'config.yaml',
  93. borgmatic.hooks.monitor.State.FAIL,
  94. monitoring_log_level=1,
  95. dry_run=False,
  96. )
  97. def test_ping_monitor_config_with_server_only_exit_early():
  98. # This test should exit early since only providing a SERVER is not enough
  99. # for the hook to work
  100. hook_config = {
  101. 'server': SERVER
  102. }
  103. flexmock(module.logger).should_receive('warning').once()
  104. module.ping_monitor(
  105. hook_config,
  106. {},
  107. 'config.yaml',
  108. borgmatic.hooks.monitor.State.FAIL,
  109. monitoring_log_level=1,
  110. dry_run=False,
  111. )
  112. def test_ping_monitor_config_user_password_no_zabbix_data_exit_early():
  113. # This test should exit early since there are HOST/KEY or ITEMID provided to publish data to
  114. hook_config = {
  115. 'server': SERVER,
  116. 'username': USERNAME,
  117. 'password': PASSWORD
  118. }
  119. flexmock(module.logger).should_receive('warning').once()
  120. module.ping_monitor(
  121. hook_config,
  122. {},
  123. 'config.yaml',
  124. borgmatic.hooks.monitor.State.FAIL,
  125. monitoring_log_level=1,
  126. dry_run=False,
  127. )
  128. def test_ping_monitor_config_api_key_no_zabbix_data_exit_early():
  129. # This test should exit early since there are HOST/KEY or ITEMID provided to publish data to
  130. hook_config = {
  131. 'server': SERVER,
  132. 'api_key': API_KEY
  133. }
  134. flexmock(module.logger).should_receive('warning').once()
  135. module.ping_monitor(
  136. hook_config,
  137. {},
  138. 'config.yaml',
  139. borgmatic.hooks.monitor.State.FAIL,
  140. monitoring_log_level=1,
  141. dry_run=False,
  142. )
  143. def test_ping_monitor_config_itemid_no_auth_data_exit_early():
  144. # This test should exit early since there is no authentication provided
  145. # and Zabbix requires authentication to use it's API
  146. hook_config = {
  147. 'server': SERVER,
  148. 'itemid': ITEMID
  149. }
  150. flexmock(module.logger).should_receive('warning').once()
  151. module.ping_monitor(
  152. hook_config,
  153. {},
  154. 'config.yaml',
  155. borgmatic.hooks.monitor.State.FAIL,
  156. monitoring_log_level=1,
  157. dry_run=False,
  158. )
  159. def test_ping_monitor_config_host_and_key_no_auth_data_exit_early():
  160. # This test should exit early since there is no authentication provided
  161. # and Zabbix requires authentication to use it's API
  162. hook_config = {
  163. 'server': SERVER,
  164. 'host': HOST,
  165. 'key': KEY
  166. }
  167. flexmock(module.logger).should_receive('warning').once()
  168. module.ping_monitor(
  169. hook_config,
  170. {},
  171. 'config.yaml',
  172. borgmatic.hooks.monitor.State.FAIL,
  173. monitoring_log_level=1,
  174. dry_run=False,
  175. )
  176. def test_ping_monitor_config_host_and_key_with_api_key_auth_data_successful():
  177. # This test should simulate a successful POST to a Zabbix server. This test uses API_KEY
  178. # to authenticate and HOST/KEY to know which item to populate in Zabbix.
  179. hook_config = {
  180. 'server': SERVER,
  181. 'host': HOST,
  182. 'key': KEY,
  183. 'api_key': API_KEY
  184. }
  185. flexmock(module.requests).should_receive('post').with_args(
  186. f'{SERVER}',
  187. headers=AUTH_HEADERS_API_KEY,
  188. json=DATA_HOST_KEY,
  189. ).and_return(flexmock(ok=True)).once()
  190. flexmock(module.logger).should_receive('warning').never()
  191. module.ping_monitor(
  192. hook_config,
  193. {},
  194. 'config.yaml',
  195. borgmatic.hooks.monitor.State.FAIL,
  196. monitoring_log_level=1,
  197. dry_run=False,
  198. )
  199. def test_ping_monitor_config_host_and_key_with_username_password_auth_data_successful():
  200. # This test should simulate a successful POST to a Zabbix server. This test uses USERNAME/PASSWORD
  201. # to authenticate and HOST/KEY to know which item to populate in Zabbix.
  202. hook_config = {
  203. 'server': SERVER,
  204. 'host': HOST,
  205. 'key': KEY,
  206. 'username': USERNAME,
  207. 'password': PASSWORD
  208. }
  209. auth_response = flexmock(ok=True)
  210. auth_response.should_receive('json').and_return({"jsonrpc":"2.0","result":"3fe6ed01a69ebd79907a120bcd04e494","id":1})
  211. flexmock(module.requests).should_receive('post').with_args(
  212. f'{SERVER}',
  213. headers=AUTH_HEADERS_USERNAME_PASSWORD,
  214. json=DATA_USER_LOGIN,
  215. ).and_return(auth_response).once()
  216. flexmock(module.logger).should_receive('warning').never()
  217. flexmock(module.requests).should_receive('post').with_args(
  218. f'{SERVER}',
  219. headers=AUTH_HEADERS_USERNAME_PASSWORD,
  220. json=DATA_HOST_KEY_WITH_TOKEN,
  221. ).and_return(flexmock(ok=True)).once()
  222. module.ping_monitor(
  223. hook_config,
  224. {},
  225. 'config.yaml',
  226. borgmatic.hooks.monitor.State.FAIL,
  227. monitoring_log_level=1,
  228. dry_run=False,
  229. )
  230. def test_ping_monitor_config_itemid_with_api_key_auth_data_successful():
  231. # This test should simulate a successful POST to a Zabbix server. This test uses API_KEY
  232. # to authenticate and HOST/KEY to know which item to populate in Zabbix.
  233. hook_config = {
  234. 'server': SERVER,
  235. 'itemid': ITEMID,
  236. 'api_key': API_KEY
  237. }
  238. flexmock(module.requests).should_receive('post').with_args(
  239. f'{SERVER}',
  240. headers=AUTH_HEADERS_API_KEY,
  241. json=DATA_ITEMID,
  242. ).and_return(flexmock(ok=True)).once()
  243. flexmock(module.logger).should_receive('warning').never()
  244. module.ping_monitor(
  245. hook_config,
  246. {},
  247. 'config.yaml',
  248. borgmatic.hooks.monitor.State.FAIL,
  249. monitoring_log_level=1,
  250. dry_run=False,
  251. )
  252. def test_ping_monitor_config_itemid_with_username_password_auth_data_successful():
  253. # This test should simulate a successful POST to a Zabbix server. This test uses USERNAME/PASSWORD
  254. # to authenticate and HOST/KEY to know which item to populate in Zabbix.
  255. hook_config = {
  256. 'server': SERVER,
  257. 'itemid': ITEMID,
  258. 'username': USERNAME,
  259. 'password': PASSWORD
  260. }
  261. auth_response = flexmock(ok=True)
  262. auth_response.should_receive('json').and_return({"jsonrpc":"2.0","result":"3fe6ed01a69ebd79907a120bcd04e494","id":1})
  263. flexmock(module.requests).should_receive('post').with_args(
  264. f'{SERVER}',
  265. headers=AUTH_HEADERS_USERNAME_PASSWORD,
  266. json=DATA_USER_LOGIN,
  267. ).and_return(auth_response).once()
  268. flexmock(module.logger).should_receive('warning').never()
  269. flexmock(module.requests).should_receive('post').with_args(
  270. f'{SERVER}',
  271. headers=AUTH_HEADERS_USERNAME_PASSWORD,
  272. json=DATA_HOST_KEY_WITH_TOKEN,
  273. ).and_return(flexmock(ok=True)).once()
  274. module.ping_monitor(
  275. hook_config,
  276. {},
  277. 'config.yaml',
  278. borgmatic.hooks.monitor.State.FAIL,
  279. monitoring_log_level=1,
  280. dry_run=False,
  281. )
  282. test_ping_monitor_config_itemid_with_username_password_auth_data_successful()