flapjack 1.6.0 → 2.0.0b1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -6
  3. data/.gitmodules +1 -1
  4. data/.rspec +1 -1
  5. data/.ruby-version +1 -1
  6. data/.travis.yml +12 -13
  7. data/CHANGELOG.md +2 -9
  8. data/CONTRIBUTING.md +7 -2
  9. data/Gemfile +4 -13
  10. data/LICENCE +1 -0
  11. data/README.md +8 -2
  12. data/Rakefile +2 -2
  13. data/bin/flapjack +3 -12
  14. data/build.sh +4 -2
  15. data/etc/flapjack_config.toml.example +273 -0
  16. data/features/ack_after_sched_maint.feature +18 -21
  17. data/features/cli.feature +11 -71
  18. data/features/cli_flapjack-feed-events.feature +14 -15
  19. data/features/cli_flapjack-nagios-receiver.feature +12 -41
  20. data/features/cli_flapper.feature +12 -41
  21. data/features/cli_purge.feature +5 -6
  22. data/features/cli_receive-events.feature +6 -7
  23. data/features/cli_simulate-failed-check.feature +5 -6
  24. data/features/events.feature +206 -181
  25. data/features/events_check_names.feature +4 -7
  26. data/features/notification_rules.feature +144 -223
  27. data/features/notifications.feature +65 -57
  28. data/features/rollup.feature +45 -47
  29. data/features/steps/cli_steps.rb +4 -5
  30. data/features/steps/events_steps.rb +163 -373
  31. data/features/steps/notifications_steps.rb +408 -264
  32. data/features/steps/packaging-lintian_steps.rb +0 -4
  33. data/features/steps/time_travel_steps.rb +0 -26
  34. data/features/support/daemons.rb +6 -31
  35. data/features/support/env.rb +65 -74
  36. data/flapjack.gemspec +22 -24
  37. data/lib/flapjack.rb +14 -7
  38. data/lib/flapjack/cli/flapper.rb +74 -173
  39. data/lib/flapjack/cli/maintenance.rb +278 -109
  40. data/lib/flapjack/cli/migrate.rb +950 -0
  41. data/lib/flapjack/cli/purge.rb +19 -22
  42. data/lib/flapjack/cli/receiver.rb +150 -326
  43. data/lib/flapjack/cli/server.rb +8 -235
  44. data/lib/flapjack/cli/simulate.rb +42 -57
  45. data/lib/flapjack/configuration.rb +51 -37
  46. data/lib/flapjack/coordinator.rb +138 -129
  47. data/lib/flapjack/data/acknowledgement.rb +177 -0
  48. data/lib/flapjack/data/alert.rb +97 -158
  49. data/lib/flapjack/data/check.rb +611 -0
  50. data/lib/flapjack/data/condition.rb +70 -0
  51. data/lib/flapjack/data/contact.rb +226 -456
  52. data/lib/flapjack/data/event.rb +96 -184
  53. data/lib/flapjack/data/extensions/associations.rb +59 -0
  54. data/lib/flapjack/data/extensions/short_name.rb +25 -0
  55. data/lib/flapjack/data/medium.rb +428 -0
  56. data/lib/flapjack/data/metrics.rb +194 -0
  57. data/lib/flapjack/data/notification.rb +22 -281
  58. data/lib/flapjack/data/rule.rb +473 -0
  59. data/lib/flapjack/data/scheduled_maintenance.rb +244 -0
  60. data/lib/flapjack/data/state.rb +221 -0
  61. data/lib/flapjack/data/statistic.rb +112 -0
  62. data/lib/flapjack/data/tag.rb +277 -0
  63. data/lib/flapjack/data/test_notification.rb +182 -0
  64. data/lib/flapjack/data/unscheduled_maintenance.rb +159 -0
  65. data/lib/flapjack/data/validators/id_validator.rb +20 -0
  66. data/lib/flapjack/exceptions.rb +6 -0
  67. data/lib/flapjack/filters/acknowledgement.rb +23 -16
  68. data/lib/flapjack/filters/base.rb +0 -5
  69. data/lib/flapjack/filters/delays.rb +53 -43
  70. data/lib/flapjack/filters/ok.rb +23 -14
  71. data/lib/flapjack/filters/scheduled_maintenance.rb +3 -3
  72. data/lib/flapjack/filters/unscheduled_maintenance.rb +12 -3
  73. data/lib/flapjack/gateways/aws_sns.rb +65 -49
  74. data/lib/flapjack/gateways/aws_sns/alert.text.erb +2 -2
  75. data/lib/flapjack/gateways/aws_sns/alert_subject.text.erb +2 -2
  76. data/lib/flapjack/gateways/aws_sns/rollup_subject.text.erb +1 -1
  77. data/lib/flapjack/gateways/email.rb +107 -90
  78. data/lib/flapjack/gateways/email/alert.html.erb +19 -18
  79. data/lib/flapjack/gateways/email/alert.text.erb +20 -14
  80. data/lib/flapjack/gateways/email/alert_subject.text.erb +2 -1
  81. data/lib/flapjack/gateways/email/rollup.html.erb +14 -13
  82. data/lib/flapjack/gateways/email/rollup.text.erb +13 -10
  83. data/lib/flapjack/gateways/jabber.rb +679 -671
  84. data/lib/flapjack/gateways/jabber/alert.text.erb +9 -6
  85. data/lib/flapjack/gateways/jsonapi.rb +164 -350
  86. data/lib/flapjack/gateways/jsonapi/data/join_descriptor.rb +44 -0
  87. data/lib/flapjack/gateways/jsonapi/data/method_descriptor.rb +21 -0
  88. data/lib/flapjack/gateways/jsonapi/helpers/headers.rb +63 -0
  89. data/lib/flapjack/gateways/jsonapi/helpers/miscellaneous.rb +136 -0
  90. data/lib/flapjack/gateways/jsonapi/helpers/resources.rb +227 -0
  91. data/lib/flapjack/gateways/jsonapi/helpers/serialiser.rb +313 -0
  92. data/lib/flapjack/gateways/jsonapi/helpers/swagger_docs.rb +322 -0
  93. data/lib/flapjack/gateways/jsonapi/methods/association_delete.rb +115 -0
  94. data/lib/flapjack/gateways/jsonapi/methods/association_get.rb +288 -0
  95. data/lib/flapjack/gateways/jsonapi/methods/association_patch.rb +178 -0
  96. data/lib/flapjack/gateways/jsonapi/methods/association_post.rb +116 -0
  97. data/lib/flapjack/gateways/jsonapi/methods/metrics.rb +71 -0
  98. data/lib/flapjack/gateways/jsonapi/methods/resource_delete.rb +119 -0
  99. data/lib/flapjack/gateways/jsonapi/methods/resource_get.rb +186 -0
  100. data/lib/flapjack/gateways/jsonapi/methods/resource_patch.rb +239 -0
  101. data/lib/flapjack/gateways/jsonapi/methods/resource_post.rb +197 -0
  102. data/lib/flapjack/gateways/jsonapi/middleware/array_param_fixer.rb +27 -0
  103. data/lib/flapjack/gateways/jsonapi/{rack → middleware}/json_params_parser.rb +7 -6
  104. data/lib/flapjack/gateways/jsonapi/middleware/request_timestamp.rb +18 -0
  105. data/lib/flapjack/gateways/oobetet.rb +222 -170
  106. data/lib/flapjack/gateways/pager_duty.rb +388 -0
  107. data/lib/flapjack/gateways/pager_duty/alert.text.erb +13 -0
  108. data/lib/flapjack/gateways/slack.rb +56 -48
  109. data/lib/flapjack/gateways/slack/alert.text.erb +1 -1
  110. data/lib/flapjack/gateways/slack/rollup.text.erb +1 -1
  111. data/lib/flapjack/gateways/sms_aspsms.rb +155 -0
  112. data/lib/flapjack/gateways/sms_aspsms/alert.text.erb +7 -0
  113. data/lib/flapjack/gateways/sms_aspsms/rollup.text.erb +2 -0
  114. data/lib/flapjack/gateways/sms_messagenet.rb +77 -57
  115. data/lib/flapjack/gateways/sms_messagenet/alert.text.erb +3 -2
  116. data/lib/flapjack/gateways/sms_nexmo.rb +53 -51
  117. data/lib/flapjack/gateways/sms_nexmo/alert.text.erb +2 -2
  118. data/lib/flapjack/gateways/sms_nexmo/rollup.text.erb +1 -1
  119. data/lib/flapjack/gateways/sms_twilio.rb +79 -62
  120. data/lib/flapjack/gateways/sms_twilio/alert.text.erb +3 -2
  121. data/lib/flapjack/gateways/web.rb +437 -345
  122. data/lib/flapjack/gateways/web/middleware/request_timestamp.rb +18 -0
  123. data/lib/flapjack/gateways/web/public/css/bootstrap.css +3793 -4340
  124. data/lib/flapjack/gateways/web/public/css/bootstrap.css.map +1 -0
  125. data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.eot +0 -0
  126. data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.svg +273 -214
  127. data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  128. data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.woff +0 -0
  129. data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
  130. data/lib/flapjack/gateways/web/public/js/bootstrap.js +1637 -1607
  131. data/lib/flapjack/gateways/web/public/js/self_stats.js +1 -2
  132. data/lib/flapjack/gateways/web/views/_pagination.html.erb +19 -0
  133. data/lib/flapjack/gateways/web/views/check.html.erb +159 -121
  134. data/lib/flapjack/gateways/web/views/checks.html.erb +82 -41
  135. data/lib/flapjack/gateways/web/views/contact.html.erb +59 -71
  136. data/lib/flapjack/gateways/web/views/contacts.html.erb +32 -8
  137. data/lib/flapjack/gateways/web/views/index.html.erb +2 -2
  138. data/lib/flapjack/gateways/web/views/{layout.erb → layout.html.erb} +7 -23
  139. data/lib/flapjack/gateways/web/views/self_stats.html.erb +32 -33
  140. data/lib/flapjack/gateways/web/views/tag.html.erb +32 -0
  141. data/lib/flapjack/gateways/web/views/tags.html.erb +51 -0
  142. data/lib/flapjack/logger.rb +34 -3
  143. data/lib/flapjack/notifier.rb +180 -112
  144. data/lib/flapjack/patches.rb +8 -63
  145. data/lib/flapjack/pikelet.rb +185 -143
  146. data/lib/flapjack/processor.rb +323 -191
  147. data/lib/flapjack/record_queue.rb +33 -0
  148. data/lib/flapjack/redis_proxy.rb +66 -0
  149. data/lib/flapjack/utility.rb +21 -15
  150. data/lib/flapjack/version.rb +2 -1
  151. data/libexec/httpbroker.go +218 -14
  152. data/libexec/oneoff.go +13 -10
  153. data/spec/lib/flapjack/configuration_spec.rb +286 -0
  154. data/spec/lib/flapjack/coordinator_spec.rb +103 -157
  155. data/spec/lib/flapjack/data/check_spec.rb +175 -0
  156. data/spec/lib/flapjack/data/contact_spec.rb +26 -349
  157. data/spec/lib/flapjack/data/event_spec.rb +76 -291
  158. data/spec/lib/flapjack/data/medium_spec.rb +19 -0
  159. data/spec/lib/flapjack/data/rule_spec.rb +43 -0
  160. data/spec/lib/flapjack/data/scheduled_maintenance_spec.rb +976 -0
  161. data/spec/lib/flapjack/data/unscheduled_maintenance_spec.rb +34 -0
  162. data/spec/lib/flapjack/gateways/aws_sns_spec.rb +111 -60
  163. data/spec/lib/flapjack/gateways/email_spec.rb +194 -161
  164. data/spec/lib/flapjack/gateways/jabber_spec.rb +961 -162
  165. data/spec/lib/flapjack/gateways/jsonapi/methods/check_links_spec.rb +155 -0
  166. data/spec/lib/flapjack/gateways/jsonapi/methods/checks_spec.rb +426 -0
  167. data/spec/lib/flapjack/gateways/jsonapi/methods/contact_links_spec.rb +217 -0
  168. data/spec/lib/flapjack/gateways/jsonapi/methods/contacts_spec.rb +425 -0
  169. data/spec/lib/flapjack/gateways/jsonapi/methods/events_spec.rb +271 -0
  170. data/spec/lib/flapjack/gateways/jsonapi/methods/media_spec.rb +257 -0
  171. data/spec/lib/flapjack/gateways/jsonapi/methods/medium_links_spec.rb +163 -0
  172. data/spec/lib/flapjack/gateways/jsonapi/methods/metrics_spec.rb +8 -0
  173. data/spec/lib/flapjack/gateways/jsonapi/methods/rule_links_spec.rb +212 -0
  174. data/spec/lib/flapjack/gateways/jsonapi/methods/rules_spec.rb +289 -0
  175. data/spec/lib/flapjack/gateways/jsonapi/methods/scheduled_maintenance_links_spec.rb +49 -0
  176. data/spec/lib/flapjack/gateways/jsonapi/methods/scheduled_maintenances_spec.rb +242 -0
  177. data/spec/lib/flapjack/gateways/jsonapi/methods/tag_links_spec.rb +274 -0
  178. data/spec/lib/flapjack/gateways/jsonapi/methods/tags_spec.rb +302 -0
  179. data/spec/lib/flapjack/gateways/jsonapi/methods/unscheduled_maintenance_links_spec.rb +49 -0
  180. data/spec/lib/flapjack/gateways/jsonapi/methods/unscheduled_maintenances_spec.rb +339 -0
  181. data/spec/lib/flapjack/gateways/jsonapi_spec.rb +1 -1
  182. data/spec/lib/flapjack/gateways/oobetet_spec.rb +151 -79
  183. data/spec/lib/flapjack/gateways/pager_duty_spec.rb +353 -0
  184. data/spec/lib/flapjack/gateways/slack_spec.rb +53 -53
  185. data/spec/lib/flapjack/gateways/sms_aspsms_spec.rb +106 -0
  186. data/spec/lib/flapjack/gateways/sms_messagenet_spec.rb +111 -54
  187. data/spec/lib/flapjack/gateways/sms_nexmo_spec.rb +50 -51
  188. data/spec/lib/flapjack/gateways/sms_twilio_spec.rb +108 -48
  189. data/spec/lib/flapjack/gateways/web_spec.rb +144 -216
  190. data/spec/lib/flapjack/notifier_spec.rb +132 -1
  191. data/spec/lib/flapjack/pikelet_spec.rb +111 -50
  192. data/spec/lib/flapjack/processor_spec.rb +210 -40
  193. data/spec/lib/flapjack/redis_proxy_spec.rb +45 -0
  194. data/spec/lib/flapjack/utility_spec.rb +11 -15
  195. data/spec/service_consumers/fixture_data.rb +547 -0
  196. data/spec/service_consumers/pact_helper.rb +21 -32
  197. data/spec/service_consumers/pacts/flapjack-diner_v2.0.json +4652 -0
  198. data/spec/service_consumers/provider_states_for_flapjack-diner.rb +279 -322
  199. data/spec/service_consumers/provider_support.rb +8 -0
  200. data/spec/spec_helper.rb +34 -44
  201. data/spec/support/erb_view_helper.rb +1 -1
  202. data/spec/support/factories.rb +58 -0
  203. data/spec/support/jsonapi_helper.rb +15 -26
  204. data/spec/support/mock_logger.rb +43 -0
  205. data/spec/support/xmpp_comparable.rb +24 -0
  206. data/src/flapjack/transport_test.go +30 -1
  207. data/tasks/dump_keys.rake +82 -0
  208. data/tasks/events.rake +7 -7
  209. data/tasks/support/flapjack_config_benchmark.toml +28 -0
  210. data/tasks/support/flapjack_config_benchmark.yaml +0 -2
  211. metadata +175 -222
  212. data/Guardfile +0 -14
  213. data/etc/flapjack_config.yaml.example +0 -477
  214. data/features/cli_flapjack-populator.feature +0 -90
  215. data/features/support/silent_system.rb +0 -4
  216. data/lib/flapjack/cli/import.rb +0 -108
  217. data/lib/flapjack/data/entity.rb +0 -652
  218. data/lib/flapjack/data/entity_check.rb +0 -1044
  219. data/lib/flapjack/data/message.rb +0 -56
  220. data/lib/flapjack/data/migration.rb +0 -234
  221. data/lib/flapjack/data/notification_rule.rb +0 -425
  222. data/lib/flapjack/data/semaphore.rb +0 -44
  223. data/lib/flapjack/data/tagged.rb +0 -48
  224. data/lib/flapjack/gateways/jsonapi/check_methods.rb +0 -206
  225. data/lib/flapjack/gateways/jsonapi/check_presenter.rb +0 -221
  226. data/lib/flapjack/gateways/jsonapi/contact_methods.rb +0 -186
  227. data/lib/flapjack/gateways/jsonapi/entity_methods.rb +0 -223
  228. data/lib/flapjack/gateways/jsonapi/medium_methods.rb +0 -185
  229. data/lib/flapjack/gateways/jsonapi/metrics_methods.rb +0 -132
  230. data/lib/flapjack/gateways/jsonapi/notification_rule_methods.rb +0 -141
  231. data/lib/flapjack/gateways/jsonapi/pagerduty_credential_methods.rb +0 -139
  232. data/lib/flapjack/gateways/jsonapi/report_methods.rb +0 -146
  233. data/lib/flapjack/gateways/pagerduty.rb +0 -318
  234. data/lib/flapjack/gateways/pagerduty/alert.text.erb +0 -10
  235. data/lib/flapjack/gateways/web/public/css/select2-bootstrap.css +0 -87
  236. data/lib/flapjack/gateways/web/public/css/select2.css +0 -615
  237. data/lib/flapjack/gateways/web/public/css/tablesort.css +0 -67
  238. data/lib/flapjack/gateways/web/public/img/select2-spinner.gif +0 -0
  239. data/lib/flapjack/gateways/web/public/img/select2.png +0 -0
  240. data/lib/flapjack/gateways/web/public/img/select2x2.png +0 -0
  241. data/lib/flapjack/gateways/web/public/js/backbone.js +0 -1581
  242. data/lib/flapjack/gateways/web/public/js/backbone.jsonapi.js +0 -322
  243. data/lib/flapjack/gateways/web/public/js/flapjack.js +0 -82
  244. data/lib/flapjack/gateways/web/public/js/jquery.tablesorter.js +0 -1640
  245. data/lib/flapjack/gateways/web/public/js/jquery.tablesorter.widgets.js +0 -1390
  246. data/lib/flapjack/gateways/web/public/js/modules/contact.js +0 -520
  247. data/lib/flapjack/gateways/web/public/js/modules/entity.js +0 -28
  248. data/lib/flapjack/gateways/web/public/js/modules/medium.js +0 -40
  249. data/lib/flapjack/gateways/web/public/js/select2.js +0 -3397
  250. data/lib/flapjack/gateways/web/public/js/tablesort.js +0 -44
  251. data/lib/flapjack/gateways/web/public/js/underscore.js +0 -1276
  252. data/lib/flapjack/gateways/web/views/edit_contacts.html.erb +0 -173
  253. data/lib/flapjack/gateways/web/views/entities.html.erb +0 -30
  254. data/lib/flapjack/gateways/web/views/entity.html.erb +0 -51
  255. data/lib/flapjack/rack_logger.rb +0 -47
  256. data/lib/flapjack/redis_pool.rb +0 -42
  257. data/spec/lib/flapjack/data/entity_check_spec.rb +0 -1418
  258. data/spec/lib/flapjack/data/entity_spec.rb +0 -872
  259. data/spec/lib/flapjack/data/message_spec.rb +0 -30
  260. data/spec/lib/flapjack/data/migration_spec.rb +0 -104
  261. data/spec/lib/flapjack/data/notification_rule_spec.rb +0 -232
  262. data/spec/lib/flapjack/data/notification_spec.rb +0 -53
  263. data/spec/lib/flapjack/data/semaphore_spec.rb +0 -24
  264. data/spec/lib/flapjack/filters/acknowledgement_spec.rb +0 -6
  265. data/spec/lib/flapjack/filters/delays_spec.rb +0 -6
  266. data/spec/lib/flapjack/filters/ok_spec.rb +0 -6
  267. data/spec/lib/flapjack/filters/scheduled_maintenance_spec.rb +0 -6
  268. data/spec/lib/flapjack/filters/unscheduled_maintenance_spec.rb +0 -6
  269. data/spec/lib/flapjack/gateways/jsonapi/check_methods_spec.rb +0 -315
  270. data/spec/lib/flapjack/gateways/jsonapi/check_presenter_spec.rb +0 -223
  271. data/spec/lib/flapjack/gateways/jsonapi/contact_methods_spec.rb +0 -131
  272. data/spec/lib/flapjack/gateways/jsonapi/entity_methods_spec.rb +0 -389
  273. data/spec/lib/flapjack/gateways/jsonapi/medium_methods_spec.rb +0 -231
  274. data/spec/lib/flapjack/gateways/jsonapi/notification_rule_methods_spec.rb +0 -169
  275. data/spec/lib/flapjack/gateways/jsonapi/pagerduty_credential_methods_spec.rb +0 -114
  276. data/spec/lib/flapjack/gateways/jsonapi/report_methods_spec.rb +0 -590
  277. data/spec/lib/flapjack/gateways/pagerduty_spec.rb +0 -249
  278. data/spec/lib/flapjack/gateways/web/views/check.html.erb_spec.rb +0 -21
  279. data/spec/lib/flapjack/gateways/web/views/contact.html.erb_spec.rb +0 -24
  280. data/spec/lib/flapjack/gateways/web/views/index.html.erb_spec.rb +0 -16
  281. data/spec/lib/flapjack/redis_pool_spec.rb +0 -29
  282. data/spec/service_consumers/pacts/flapjack-diner_v1.0.json +0 -4702
  283. data/tasks/entities.rake +0 -151
  284. data/tasks/profile.rake +0 -282
  285. data/tmp/acknowledge.rb +0 -13
  286. data/tmp/create_config_yaml.rb +0 -16
  287. data/tmp/create_event_ok.rb +0 -30
  288. data/tmp/create_event_unknown.rb +0 -30
  289. data/tmp/create_events_failure.rb +0 -34
  290. data/tmp/create_events_ok.rb +0 -32
  291. data/tmp/create_events_ok_fail_ack_ok.rb +0 -53
  292. data/tmp/create_events_ok_failure.rb +0 -41
  293. data/tmp/create_events_ok_failure_ack.rb +0 -53
  294. data/tmp/dummy_contacts.json +0 -43
  295. data/tmp/dummy_entities.json +0 -37
  296. data/tmp/generate_nagios_test_hosts.rb +0 -16
  297. data/tmp/notification_rules.rb +0 -73
  298. data/tmp/parse_config_yaml.rb +0 -7
  299. data/tmp/redis_find_spurious_unknown_states.rb +0 -52
  300. data/tmp/test_json_post.rb +0 -19
  301. data/tmp/test_notification_rules_api.rb +0 -171
@@ -6,7 +6,7 @@ describe 'Flapjack::Gateways::JSONAPI', :sinatra => true, :logger => true do
6
6
  include_context "jsonapi"
7
7
 
8
8
  it "handles a route matching failure" do
9
- aget "/this/route/doesn't/exist"
9
+ get "/this/route/doesn't/exist"
10
10
  expect(last_response.status).to eq(404)
11
11
  end
12
12
 
@@ -10,121 +10,193 @@ describe Flapjack::Gateways::Oobetet, :logger => true do
10
10
  'alias' => 'flapjack',
11
11
  'watched_check' => 'PING',
12
12
  'watched_entity' => 'foo.bar.net',
13
+ 'pagerduty_contact' => 'pdservicekey',
13
14
  'rooms' => ['flapjacktest@conference.example.com']
14
15
  }
15
16
  }
16
17
 
17
- let(:stanza) { double('stanza') }
18
+ let(:now) { Time.now }
18
19
 
19
- it "raises an error if a required config setting is not set" do
20
- expect(Socket).to receive(:gethostname).and_return('thismachine')
20
+ let(:lock) { double(Monitor) }
21
21
 
22
- fo = Flapjack::Gateways::Oobetet.new(:config => config.delete('watched_check'), :logger => @logger)
22
+ context 'notifications' do
23
23
 
24
- expect {
25
- fo.setup
26
- }.to raise_error
27
- end
24
+ it "raises an error if a required config setting is not set" do
25
+ expect {
26
+ Flapjack::Gateways::Oobetet::Notifier.new(:config => config.delete('watched_check'))
27
+ }.to raise_error("Flapjack::Oobetet: watched_check must be defined in the config")
28
+ end
28
29
 
29
- it "hooks up event handlers to the appropriate methods" do
30
- fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger)
30
+ it "starts and is stopped by an exception" do
31
+ expect(Kernel).to receive(:sleep).with(10).and_raise(Flapjack::PikeletStop)
31
32
 
32
- expect(EventMachine::Synchrony).to receive(:next_tick).exactly(3).times.and_yield
33
+ expect(lock).to receive(:synchronize).and_yield
33
34
 
34
- expect(fo).to receive(:register_handler).with(:ready).and_yield(stanza)
35
- expect(fo).to receive(:on_ready).with(stanza)
35
+ fon = Flapjack::Gateways::Oobetet::Notifier.new(:lock => lock,
36
+ :config => config)
37
+ expect(fon).to receive(:check_timers)
38
+ expect { fon.start }.to raise_error(Flapjack::PikeletStop)
39
+ end
36
40
 
37
- expect(fo).to receive(:register_handler).with(:message, :groupchat?).and_yield(stanza)
38
- expect(fo).to receive(:on_groupchat).with(stanza)
41
+ it "checks for a breach and emits notifications" do
42
+ time_check = double(Flapjack::Gateways::Oobetet::TimeChecker)
43
+ expect(time_check).to receive(:respond_to?).with(:announce).and_return(false)
44
+ expect(time_check).to receive(:respond_to?).with(:breach?).and_return(true)
45
+ expect(time_check).to receive(:breach?).
46
+ and_return("haven't seen a test problem notification in the last 300 seconds")
39
47
 
40
- expect(fo).to receive(:register_handler).with(:disconnected).and_yield(stanza)
41
- expect(fo).to receive(:on_disconnect).with(stanza).and_return(true)
48
+ bot = double(Flapjack::Gateways::Oobetet::Bot)
49
+ expect(bot).to receive(:respond_to?).with(:announce).and_return(true)
50
+ expect(bot).to receive(:announce).with(/^Flapjack Self Monitoring is Critical/)
42
51
 
43
- fo.register_handlers
44
- end
52
+ # TODO be more specific about the request body
53
+ req = stub_request(:post, "https://events.pagerduty.com/generic/2010-04-15/create_event.json").
54
+ to_return(:status => 200, :body => Flapjack.dump_json('status' => 'success'))
45
55
 
46
- it "joins a chat room after connecting" do
47
- fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger)
56
+ fon = Flapjack::Gateways::Oobetet::Notifier.new(:lock => lock, :config => config)
57
+ fon.instance_variable_set('@siblings', [time_check, bot])
58
+ fon.send(:check_timers)
48
59
 
49
- expect(fo).to receive(:write).with(an_instance_of(Blather::Stanza::Presence))
50
- expect(fo).to receive(:write).with(an_instance_of(Blather::Stanza::Message))
60
+ expect(req).to have_been_requested
61
+ end
51
62
 
52
- fo.on_ready(stanza)
53
63
  end
54
64
 
55
- it "reconnects when disconnected (if not quitting)" do
56
- fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger)
65
+ context 'time checking' do
66
+
67
+ let(:now) { Time.now }
68
+ let(:a_minute_ago) { now.to_i - 60 }
69
+ let(:a_day_ago) { now.to_i - (60 * 60 * 24) }
70
+
71
+ it "starts and is stopped by a signal" do
72
+ expect(lock).to receive(:synchronize).and_yield
73
+ stop_cond = double(MonitorMixin::ConditionVariable)
74
+ expect(stop_cond).to receive(:wait_until)
75
+
76
+ fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :stop_condition => stop_cond,
77
+ :config => config)
78
+ fot.start
79
+ end
80
+
81
+ it "records times of a problem status message" do
82
+ expect(lock).to receive(:synchronize).and_yield
83
+ fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config)
84
+ fot.send(:receive_status, 'problem', now.to_i)
85
+ fot_times = fot.instance_variable_get('@times')
86
+ expect(fot_times).not_to be_nil
87
+ expect(fot_times).to have_key(:last_problem)
88
+ expect(fot_times[:last_problem]).to eq(now.to_i)
89
+ end
90
+
91
+ it "records times of a recovery status message" do
92
+ expect(lock).to receive(:synchronize).and_yield
93
+ fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config)
94
+ fot.send(:receive_status, 'recovery', now.to_i)
95
+ fot_times = fot.instance_variable_get('@times')
96
+ expect(fot_times).not_to be_nil
97
+ expect(fot_times).to have_key(:last_recovery)
98
+ expect(fot_times[:last_recovery]).to eq(now.to_i)
99
+ end
100
+
101
+ it "records times of an acknowledgement status message" do
102
+ expect(lock).to receive(:synchronize).and_yield
103
+ fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config)
104
+ fot.send(:receive_status, 'acknowledgement', now.to_i)
105
+ fot_times = fot.instance_variable_get('@times')
106
+ expect(fot_times).not_to be_nil
107
+ expect(fot_times).to have_key(:last_ack)
108
+ expect(fot_times[:last_ack]).to eq(now.to_i)
109
+ end
110
+
111
+ it "detects a time period with no test problem alerts" do
112
+ expect(lock).to receive(:synchronize).and_yield
113
+ fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config)
114
+ fot_times = fot.instance_variable_get('@times')
115
+
116
+ fot_times[:last_problem] = a_day_ago
117
+ fot_times[:last_recovery] = a_minute_ago
118
+ fot_times[:last_ack] = a_minute_ago
119
+ fot_times[:last_ack_sent] = a_minute_ago
120
+
121
+ breach = fot.breach?(now.to_i)
122
+ expect(breach).not_to be_nil
123
+ expect(breach).to eq("haven't seen a test problem notification in the last 300 seconds")
124
+ end
125
+
126
+ it "detects a time period with no test recovery alerts" do
127
+ expect(lock).to receive(:synchronize).and_yield
128
+ fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config)
129
+ fot_times = fot.instance_variable_get('@times')
130
+
131
+ fot_times[:last_problem] = a_minute_ago
132
+ fot_times[:last_recovery] = a_day_ago
133
+ fot_times[:last_ack] = a_minute_ago
134
+ fot_times[:last_ack_sent] = a_minute_ago
135
+
136
+ breach = fot.breach?(now.to_i)
137
+ expect(breach).not_to be_nil
138
+ expect(breach).to eq("haven't seen a test recovery notification in the last 300 seconds")
139
+ end
57
140
 
58
- expect(EventMachine::Timer).to receive(:new).with(1).and_yield
59
- expect(fo).to receive(:connect)
60
-
61
- ret = fo.on_disconnect(stanza)
62
- expect(ret).to be true
63
141
  end
64
142
 
65
- it "records times of a problem status messages" do
66
- fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger)
67
- fo.setup
143
+ context 'XMPP' do
68
144
 
69
- t = Time.now
145
+ let(:muc_client) { double(::Jabber::MUC::SimpleMUCClient) }
70
146
 
71
- expect(stanza).to receive(:body).and_return( %q{PROBLEM: "PING" on foo.bar.net} )
72
- expect(Time).to receive(:now).and_return(t)
147
+ it "raises an error if a required config setting is not set" do
148
+ expect {
149
+ Flapjack::Gateways::Oobetet::Bot.new(:config => config.delete('watched_check'))
150
+ }.to raise_error("Flapjack::Oobetet: watched_check must be defined in the config")
151
+ end
73
152
 
74
- fo.on_groupchat(stanza)
75
- fo_times = fo.instance_variable_get('@times')
76
- expect(fo_times).not_to be_nil
77
- expect(fo_times).to have_key(:last_problem)
78
- expect(fo_times[:last_problem]).to eq(t.to_i)
79
- end
153
+ it "starts and is stopped by a signal" do
154
+ t = now.to_i
80
155
 
81
- it "records times of a recovery status messages" do
82
- fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger)
83
- fo.setup
156
+ time_checker = double(Flapjack::Gateways::Oobetet::TimeChecker)
157
+ expect(time_checker).to receive(:respond_to?).with(:receive_status).and_return(true)
158
+ expect(time_checker).to receive(:receive_status).with('recovery', t)
84
159
 
85
- t = Time.now
160
+ client = double(::Jabber::Client)
161
+ expect(client).to receive(:connect)
162
+ expect(client).to receive(:auth).with('password')
163
+ expect(client).to receive(:send).with(an_instance_of(::Jabber::Presence))
86
164
 
87
- expect(stanza).to receive(:body).and_return( %q{RECOVERY: "PING" on foo.bar.net} )
88
- expect(Time).to receive(:now).and_return(t)
165
+ expect(muc_client).to receive(:on_message).and_yield(t, 'test', 'Recovery "PING" on foo.bar.net')
166
+ expect(muc_client).to receive(:join).with('flapjacktest@conference.example.com/flapjack')
167
+ expect(muc_client).to receive(:say).with(/^flapjack oobetet gateway started/)
89
168
 
90
- fo.on_groupchat(stanza)
91
- fo_times = fo.instance_variable_get('@times')
92
- expect(fo_times).not_to be_nil
93
- expect(fo_times).to have_key(:last_recovery)
94
- expect(fo_times[:last_recovery]).to eq(t.to_i)
95
- end
169
+ expect(muc_client).to receive(:active?).and_return(true)
170
+ expect(muc_client).to receive(:exit)
96
171
 
97
- it "records times of an acknowledgement status messages" do
98
- fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger)
99
- fo.setup
172
+ expect(client).to receive(:close)
100
173
 
101
- t = Time.now
174
+ expect(::Jabber::Client).to receive(:new).and_return(client)
175
+ expect(::Jabber::MUC::SimpleMUCClient).to receive(:new).and_return(muc_client)
102
176
 
103
- expect(stanza).to receive(:body).and_return( %q{ACKNOWLEDGEMENT: "PING" on foo.bar.net} )
104
- expect(Time).to receive(:now).and_return(t)
177
+ expect(lock).to receive(:synchronize).and_yield
178
+ stop_cond = double(MonitorMixin::ConditionVariable)
179
+ expect(stop_cond).to receive(:wait_until)
105
180
 
106
- fo.on_groupchat(stanza)
107
- fo_times = fo.instance_variable_get('@times')
108
- expect(fo_times).not_to be_nil
109
- expect(fo_times).to have_key(:last_ack)
110
- expect(fo_times[:last_ack]).to eq(t.to_i)
111
- end
181
+ fob = Flapjack::Gateways::Oobetet::Bot.new(:lock => lock, :stop_condition => stop_cond,
182
+ :config => config)
183
+ fob.instance_variable_set('@siblings', [time_checker])
184
+ fob.start
185
+ end
186
+
187
+ it "announces to jabber rooms" do
188
+ muc_client2 = double(::Jabber::MUC::SimpleMUCClient)
112
189
 
113
- it "runs a loop checking for recorded problems" do
114
- timer = double('timer')
115
- expect(timer).to receive(:cancel)
116
- expect(EM::Synchrony).to receive(:add_periodic_timer).with(60).and_return(timer)
190
+ expect(muc_client).to receive(:say).with('hello!')
191
+ expect(muc_client2).to receive(:say).with('hello!')
117
192
 
118
- fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger)
119
- expect(fo).to receive(:register_handler).exactly(3).times
120
- expect(fo).to receive(:connect)
193
+ expect(lock).to receive(:synchronize).and_yield
121
194
 
122
- expect(EM::Synchrony).to receive(:sleep).with(10) {
123
- fo.instance_variable_set('@should_quit', true)
124
- nil
125
- }
195
+ fob = Flapjack::Gateways::Oobetet::Bot.new(:lock => lock, :config => config)
196
+ fob.instance_variable_set('@muc_clients', {'room1' => muc_client, 'room2' => muc_client2})
197
+ fob.announce('hello!')
198
+ end
126
199
 
127
- fo.start
128
200
  end
129
201
 
130
202
  end
@@ -0,0 +1,353 @@
1
+ require 'spec_helper'
2
+
3
+ require 'flapjack/gateways/pager_duty'
4
+
5
+ describe Flapjack::Gateways::PagerDuty, :logger => true do
6
+
7
+ let(:config) { {
8
+ 'queue' => 'pagerduty_notifications',
9
+ 'credentials' => {'subdomain' => 'flpjck'}
10
+ } }
11
+
12
+ let(:now) { Time.new }
13
+
14
+ let(:redis) { double(Redis) }
15
+ let(:lock) { double(Monitor) }
16
+
17
+ let(:check) { double(Flapjack::Data::Check, :id => SecureRandom.uuid,
18
+ :name => 'app-02:ping') }
19
+
20
+ before(:each) do
21
+ allow(Flapjack).to receive(:redis).and_return(redis)
22
+ end
23
+
24
+ context 'notifications' do
25
+
26
+ let(:queue) { double(Flapjack::RecordQueue) }
27
+ let(:alert) { double(Flapjack::Data::Alert) }
28
+
29
+ it "starts and is stopped by an exception" do
30
+ expect(Kernel).to receive(:sleep).with(10)
31
+
32
+ expect(Flapjack::RecordQueue).to receive(:new).with('pagerduty_notifications',
33
+ Flapjack::Data::Alert).and_return(queue)
34
+
35
+ expect(lock).to receive(:synchronize).and_yield
36
+ expect(queue).to receive(:foreach).and_yield(alert)
37
+ expect(queue).to receive(:wait).and_raise(Flapjack::PikeletStop)
38
+
39
+ expect(redis).to receive(:quit)
40
+
41
+ fpn = Flapjack::Gateways::PagerDuty::Notifier.new(:lock => lock,
42
+ :config => config)
43
+ expect(fpn).to receive(:handle_alert).with(alert)
44
+ expect(Flapjack::Gateways::PagerDuty).to receive(:test_pagerduty_connection).twice.and_return(false, true)
45
+ expect { fpn.start }.to raise_error(Flapjack::PikeletStop)
46
+ end
47
+
48
+ it "tests the pagerduty connection" do
49
+ req = stub_request(:post, "https://events.pagerduty.com/generic/2010-04-15/create_event.json").
50
+ with(:body => Flapjack.dump_json(
51
+ 'service_key' => '11111111111111111111111111111111',
52
+ 'incident_key' => 'Flapjack is running a NOOP',
53
+ 'event_type' => 'nop',
54
+ 'description' => 'I love APIs with noops.'
55
+ )).
56
+ to_return(:status => 200, :body => Flapjack.dump_json('status' => 'success'))
57
+
58
+ Flapjack::Gateways::PagerDuty.send(:test_pagerduty_connection)
59
+ expect(req).to have_been_requested
60
+ end
61
+
62
+ it "handles notifications received via Redis" do
63
+ fpn = Flapjack::Gateways::PagerDuty::Notifier.new(:config => config)
64
+
65
+ req = stub_request(:post, "https://events.pagerduty.com/generic/2010-04-15/create_event.json").
66
+ with(:body => Flapjack.dump_json(
67
+ 'service_key' => 'pdservicekey',
68
+ 'incident_key' => check.name,
69
+ 'event_type' => 'trigger',
70
+ 'description' => 'Problem: "app-02:ping" is Critical'
71
+ )).
72
+ to_return(:status => 200, :body => Flapjack.dump_json('status' => 'success'))
73
+
74
+ expect(check).to receive(:name).exactly(4).times.and_return('app-02:ping')
75
+
76
+ expect(alert).to receive(:address).and_return('pdservicekey')
77
+ expect(alert).to receive(:check).twice.and_return(check)
78
+ expect(alert).to receive(:state).and_return('critical')
79
+ expect(alert).to receive(:state_title_case).and_return('Critical')
80
+ expect(alert).to receive(:summary).twice.and_return('')
81
+ expect(alert).to receive(:type).twice.and_return('problem')
82
+ expect(alert).to receive(:type_sentence_case).and_return('Problem')
83
+
84
+ fpn.send(:handle_alert, alert)
85
+ expect(req).to have_been_requested
86
+ end
87
+
88
+ end
89
+
90
+ context 'acknowledgements' do
91
+
92
+ let(:status_change) { {'id' => 'ABCDEFG',
93
+ 'name' => 'John Smith',
94
+ 'email' => 'johns@example.com',
95
+ 'html_url' => 'http://flpjck.pagerduty.com/users/ABCDEFG'}
96
+ }
97
+
98
+ let (:response) { {"incidents" =>
99
+ [{"incident_number" => 12,
100
+ "incident_key"=> check.name,
101
+ "status" => "acknowledged",
102
+ "last_status_change_by" => status_change}],
103
+ "limit"=>100,
104
+ "offset"=>0,
105
+ "total"=>1}
106
+ }
107
+
108
+ it "doesn't look for acknowledgements if this search is already running" do
109
+ expect(redis).to receive(:del).with('sem_pagerduty_acks_running')
110
+ expect(redis).to receive(:quit)
111
+
112
+ expect(Flapjack::Gateways::PagerDuty).to receive(:test_pagerduty_connection).and_return(true)
113
+
114
+ expect(redis).to receive(:setnx).with('sem_pagerduty_acks_running', 'true').and_return(0)
115
+
116
+ expect(Kernel).to receive(:sleep).with(10).and_raise(Flapjack::PikeletStop.new)
117
+
118
+ expect(lock).to receive(:synchronize).and_yield
119
+
120
+ fpa = Flapjack::Gateways::PagerDuty::AckFinder.new(:lock => lock,
121
+ :config => config)
122
+ expect { fpa.start }.to raise_error(Flapjack::PikeletStop)
123
+ end
124
+
125
+ it "looks for and creates acknowledgements if the search is not already running" do
126
+ expect(redis).to receive(:del).with('sem_pagerduty_acks_running').twice
127
+ expect(redis).to receive(:quit)
128
+
129
+ expect(Flapjack::Gateways::PagerDuty).to receive(:test_pagerduty_connection).and_return(true)
130
+
131
+ expect(redis).to receive(:setnx).with('sem_pagerduty_acks_running', 'true').and_return(1)
132
+ expect(redis).to receive(:expire).with('sem_pagerduty_acks_running', 3600)
133
+
134
+ expect(Flapjack::Data::Check).to receive(:lock).
135
+ with(Flapjack::Data::ScheduledMaintenance, Flapjack::Data::UnscheduledMaintenance).
136
+ and_yield
137
+
138
+ check_scope = double('check_scope')
139
+ expect(check_scope).to receive(:reject).
140
+ and_yield(check).
141
+ and_return([check])
142
+
143
+ expect(Flapjack::Data::Check).to receive(:intersect).
144
+ with(:failing => true).and_return(check_scope)
145
+
146
+ expect(Flapjack::Data::Check).to receive(:intersect).
147
+ with(:id => [check.id]).and_return(check_scope)
148
+
149
+ expect(check).to receive(:in_unscheduled_maintenance?).
150
+ with(an_instance_of(Time)).and_return(false)
151
+
152
+ expect(check).to receive(:in_scheduled_maintenance?).
153
+ with(an_instance_of(Time)).and_return(false)
154
+
155
+ expect(Flapjack::Data::Medium).to receive(:lock).
156
+ with(Flapjack::Data::Check, Flapjack::Data::Rule).
157
+ and_yield
158
+
159
+ medium = double(Flapjack::Data::Medium, :id => SecureRandom.uuid)
160
+ expect(medium).to receive(:pagerduty_subdomain).and_return('mydomain')
161
+ expect(medium).to receive(:pagerduty_token).and_return('abc')
162
+ expect(medium).to receive(:pagerduty_ack_duration).and_return(nil)
163
+
164
+ expect(medium).to receive(:checks).with(:initial_scope => check_scope,
165
+ :time => an_instance_of(Time)).and_return(check_scope)
166
+
167
+ expect(check_scope).to receive(:ids).and_return([check.id])
168
+
169
+ media_scope = double('media_scope', :all => [medium])
170
+
171
+ expect(Flapjack::Data::Medium).to receive(:intersect).
172
+ with(:transport => 'pagerduty').and_return(media_scope)
173
+
174
+ expect(Flapjack::Data::Event).to receive(:create_acknowledgements).with('events',
175
+ [check],
176
+ :summary => 'Acknowledged on PagerDuty by John Smith',
177
+ :duration => 14400)
178
+
179
+ expect(Kernel).to receive(:sleep).with(10).and_raise(Flapjack::PikeletStop.new)
180
+
181
+ expect(lock).to receive(:synchronize).and_yield
182
+
183
+ fpa = Flapjack::Gateways::PagerDuty::AckFinder.new(:lock => lock,
184
+ :config => config)
185
+ expect(fpa).to receive(:pagerduty_acknowledgements).
186
+ with(an_instance_of(Time), 'mydomain', 'abc', [check.name]).
187
+ and_return(response['incidents'])
188
+ expect { fpa.start }.to raise_error(Flapjack::PikeletStop)
189
+ end
190
+
191
+ # testing separately and stubbing above
192
+ it "looks for acknowledgements via the PagerDuty API" do
193
+ subdomain = 'mydomain'
194
+ token = 'abc'
195
+
196
+ since = (now.utc - (60*60*24*7)).iso8601 # the last week
197
+ unt = (now.utc + (60*60)).iso8601 # 1 hour in the future
198
+
199
+ req = stub_request(:get, "https://#{subdomain}.pagerduty.com/api/v1/incidents").
200
+ with(:headers => {'Content-type' => 'application/json',
201
+ 'Authorization' => "Token token=#{token}"},
202
+ :query => {
203
+ :fields => 'incident_key,incident_number,last_status_change_by',
204
+ :since => since, :until => unt, :status => 'acknowledged'
205
+ }
206
+ ).
207
+ to_return(:status => 200,
208
+ :body => Flapjack.dump_json(response),
209
+ :headers => {})
210
+
211
+ expect(redis).to receive(:del).with('sem_pagerduty_acks_running')
212
+
213
+ fpa = Flapjack::Gateways::PagerDuty::AckFinder.new(:config => config)
214
+ result = fpa.send(:pagerduty_acknowledgements, now, subdomain, token, [check.name])
215
+ expect(req).to have_been_requested
216
+
217
+ expect(result).to be_a(Array)
218
+ expect(result.size).to eq(1)
219
+ incident = result.first
220
+ expect(incident).to be_a(Hash)
221
+ pg_acknowledged_by = incident['last_status_change_by']
222
+ expect(pg_acknowledged_by).to be_a(Hash)
223
+ expect(pg_acknowledged_by).to have_key('id')
224
+ expect(pg_acknowledged_by['id']).to eq('ABCDEFG')
225
+ end
226
+
227
+ it 'gets all values in a paginated request for acknowledgements' do
228
+ subdomain = 'mydomain'
229
+ token = 'abc'
230
+
231
+ since = (now.utc - (60*60*24*7)).iso8601 # the last week
232
+ unt = (now.utc + (60*60)).iso8601 # 1 hour in the future
233
+
234
+ response_1 = {"incidents" => [{'incident_key' => check.name}] * 100,
235
+ "limit" => 100,
236
+ "offset" => 0,
237
+ "total" => 120}
238
+
239
+ response_2 = {"incidents" => [{'incident_key' => check.name}] * 20,
240
+ "limit" => 100,
241
+ "offset" => 100,
242
+ "total" => 120}
243
+
244
+ req = stub_request(:get, "https://#{subdomain}.pagerduty.com/api/v1/incidents").
245
+ with(:headers => {'Content-type' => 'application/json',
246
+ 'Authorization' => "Token token=#{token}"},
247
+ :query => {
248
+ :fields => 'incident_key,incident_number,last_status_change_by',
249
+ :since => since, :until => unt, :status => 'acknowledged'
250
+ }
251
+ ).
252
+ to_return(:status => 200,
253
+ :body => Flapjack.dump_json(response_1),
254
+ :headers => {})
255
+
256
+ req = stub_request(:get, "https://#{subdomain}.pagerduty.com/api/v1/incidents").
257
+ with(:headers => {'Content-type' => 'application/json',
258
+ 'Authorization' => "Token token=#{token}"},
259
+ :query => {
260
+ :fields => 'incident_key,incident_number,last_status_change_by',
261
+ :since => since, :until => unt, :status => 'acknowledged',
262
+ :offset => 100, :limit => 100
263
+ }
264
+ ).
265
+ to_return(:status => 200,
266
+ :body => Flapjack.dump_json(response_2),
267
+ :headers => {})
268
+
269
+ expect(redis).to receive(:del).with('sem_pagerduty_acks_running')
270
+
271
+ fpa = Flapjack::Gateways::PagerDuty::AckFinder.new(:config => config)
272
+ result = fpa.send(:pagerduty_acknowledgements, now, subdomain, token, [check.name])
273
+ expect(req).to have_been_requested
274
+
275
+ expect(result).to be_a(Array)
276
+ expect(result.size).to eq(120)
277
+ end
278
+
279
+ it 'uses a smaller time period for follow-up requests' do
280
+ subdomain = 'mydomain'
281
+ token = 'abc'
282
+
283
+ time_first = now.utc
284
+ time_second = (now + 10).utc
285
+
286
+ since_first = (time_first - (60 * 60 * 24 * 7)).iso8601 # the last week
287
+ since_second = (time_second - (60 * 15)).iso8601 # the last 15 minutes
288
+
289
+ unt_first = (time_first + (60 * 60)).iso8601 # 1 hour in the future
290
+ unt_second = (time_second + (60 * 60)).iso8601 # 1 hour in the future
291
+
292
+ req_first = stub_request(:get, "https://#{subdomain}.pagerduty.com/api/v1/incidents").
293
+ with(:headers => {'Content-type' => 'application/json',
294
+ 'Authorization' => "Token token=#{token}"},
295
+ :query => {
296
+ :fields => 'incident_key,incident_number,last_status_change_by',
297
+ :since => since_first, :until => unt_first, :status => 'acknowledged'
298
+ }
299
+ ).
300
+ to_return(:status => 200,
301
+ :body => Flapjack.dump_json(response),
302
+ :headers => {})
303
+
304
+ req_second = stub_request(:get, "https://#{subdomain}.pagerduty.com/api/v1/incidents").
305
+ with(:headers => {'Content-type' => 'application/json',
306
+ 'Authorization' => "Token token=#{token}"},
307
+ :query => {
308
+ :fields => 'incident_key,incident_number,last_status_change_by',
309
+ :since => since_second, :until => unt_second, :status => 'acknowledged'
310
+ }
311
+ ).
312
+ to_return(:status => 200,
313
+ :body => Flapjack.dump_json(response),
314
+ :headers => {})
315
+
316
+ expect(redis).to receive(:del).with('sem_pagerduty_acks_running')
317
+
318
+ fpa = Flapjack::Gateways::PagerDuty::AckFinder.new(:config => config)
319
+ fpa.send(:pagerduty_acknowledgements, now, subdomain, token, [check.name])
320
+ fpa.send(:pagerduty_acknowledgements, (now + 10), subdomain, token, [check.name])
321
+ expect(req_first).to have_been_requested
322
+ expect(req_second).to have_been_requested
323
+ end
324
+
325
+ it 'does not look for acknowledgements if no checks are failing & unacknowledged' do
326
+ expect(redis).to receive(:del).with('sem_pagerduty_acks_running').twice
327
+ expect(redis).to receive(:quit)
328
+
329
+ expect(Flapjack::Gateways::PagerDuty).to receive(:test_pagerduty_connection).and_return(true)
330
+
331
+ expect(redis).to receive(:setnx).with('sem_pagerduty_acks_running', 'true').and_return(1)
332
+ expect(redis).to receive(:expire).with('sem_pagerduty_acks_running', 3600)
333
+
334
+ expect(Flapjack::Data::Check).to receive(:lock).
335
+ with(Flapjack::Data::ScheduledMaintenance, Flapjack::Data::UnscheduledMaintenance).
336
+ and_yield
337
+
338
+ expect(Flapjack::Data::Check).to receive(:intersect).
339
+ with(:failing => true).and_return([])
340
+
341
+ expect(Flapjack::Data::Event).not_to receive(:create_acknowledgements)
342
+
343
+ expect(Kernel).to receive(:sleep).with(10).and_raise(Flapjack::PikeletStop.new)
344
+
345
+ expect(lock).to receive(:synchronize).and_yield
346
+
347
+ fpa = Flapjack::Gateways::PagerDuty::AckFinder.new(:lock => lock,
348
+ :config => config)
349
+ expect(fpa).not_to receive(:pagerduty_acknowledgements)
350
+ expect { fpa.start }.to raise_error(Flapjack::PikeletStop)
351
+ end
352
+ end
353
+ end