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
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'securerandom'
4
+
5
+ require 'swagger/blocks'
6
+
7
+ require 'flapjack/data/extensions/short_name'
8
+
9
+ module Flapjack
10
+ module Data
11
+ class Metrics
12
+
13
+ extend ActiveModel::Naming
14
+
15
+ include Swagger::Blocks
16
+
17
+ include Flapjack::Data::Extensions::ShortName
18
+
19
+ def total_keys
20
+ Flapjack.redis.dbsize
21
+ end
22
+
23
+ def event_queue_length
24
+ Flapjack.redis.llen('events')
25
+ end
26
+
27
+ def processed_events
28
+ global_stats = Flapjack::Data::Statistic.
29
+ intersect(:instance_name => 'global').all.first
30
+
31
+ [:all_events, :ok_events, :failure_events, :action_events,
32
+ :invalid_events].each_with_object({}) do |event_type, memo|
33
+
34
+ memo[event_type] = global_stats.nil? ? 0 : global_stats.send(event_type)
35
+ end
36
+ end
37
+
38
+ def check_freshness
39
+ ages = [0, 60, 300, 900, 3600]
40
+
41
+ start_time = Time.now
42
+
43
+ current_checks = Flapjack::Data::Check.intersect(:enabled => true).all
44
+
45
+ skeleton = {}
46
+ ages.each {|a| skeleton[a] = 0 }
47
+ age_ranges = ages.reverse.each_cons(2)
48
+
49
+ current_checks.each_with_object(skeleton) do |check, memo|
50
+ current_state = check.current_state
51
+ last_update = current_state.nil? ? nil : current_state.updated_at
52
+ next if last_update.nil?
53
+ check_age = start_time - last_update
54
+ check_age = 0 unless check_age > 0
55
+ if check_age >= ages.last
56
+ memo[ages.last] += 1
57
+ else
58
+ age_range = age_ranges.detect {|a, b| (check_age < a) && (check_age >= b) }
59
+ memo[age_range.last] += 1 unless age_range.nil?
60
+ end
61
+ end
62
+ end
63
+
64
+ def check_counts
65
+ {
66
+ :all => Flapjack::Data::Check.count,
67
+ :enabled => Flapjack::Data::Check.intersect(:enabled => true).count,
68
+ :failing => Flapjack::Data::Check.intersect(:failing => true).count
69
+ }
70
+ end
71
+
72
+ swagger_schema :data_Metrics do
73
+ key :required, [:data]
74
+ property :data do
75
+ key :"$ref", :Metrics
76
+ end
77
+ property :links do
78
+ key :"$ref", :Links
79
+ end
80
+ end
81
+
82
+ swagger_schema :Metrics do
83
+ key :required, [:type, :total_keys,
84
+ :event_queue_length, :processed_events,
85
+ :check_freshness, :check_counts]
86
+ property :type do
87
+ key :type, :string
88
+ key :enum, [Flapjack::Data::Metrics.short_model_name.singular]
89
+ end
90
+ property :total_keys do
91
+ key :type, :integer
92
+ key :minimum, 0
93
+ end
94
+ property :event_queue_length do
95
+ key :type, :integer
96
+ key :minimum, 0
97
+ end
98
+ property :processed_events do
99
+ key :"$ref", :MetricsProcessedEventCounts
100
+ end
101
+ property :check_freshness do
102
+ key :"$ref", :MetricsCheckFreshnessCounts
103
+ end
104
+ property :check_counts do
105
+ key :"$ref", :MetricsCheckCounts
106
+ end
107
+ end
108
+
109
+ swagger_schema :MetricsProcessedEventCounts do
110
+ key :required, [:all_events, :ok_events, :failure_events,
111
+ :action_events, :invalid_events]
112
+ property :all_events do
113
+ key :type, :integer
114
+ key :minimum, 0
115
+ end
116
+ property :ok_events do
117
+ key :type, :integer
118
+ key :minimum, 0
119
+ end
120
+ property :failure_events do
121
+ key :type, :integer
122
+ key :minimum, 0
123
+ end
124
+ property :action_events do
125
+ key :type, :integer
126
+ key :minimum, 0
127
+ end
128
+ property :invalid_events do
129
+ key :type, :integer
130
+ key :minimum, 0
131
+ end
132
+ end
133
+
134
+ swagger_schema :MetricsCheckFreshnessCounts do
135
+ key :required, [:"0", :"60", :"300", :"900", :"3600"]
136
+ property :"0" do
137
+ key :type, :integer
138
+ key :minimum, 0
139
+ end
140
+ property :"60" do
141
+ key :type, :integer
142
+ key :minimum, 0
143
+ end
144
+ property :"300" do
145
+ key :type, :integer
146
+ key :minimum, 0
147
+ end
148
+ property :"900" do
149
+ key :type, :integer
150
+ key :minimum, 0
151
+ end
152
+ property :"3600" do
153
+ key :type, :integer
154
+ key :minimum, 0
155
+ end
156
+ end
157
+
158
+ swagger_schema :MetricsCheckCounts do
159
+ key :required, [:all, :enabled, :failing]
160
+ property :all do
161
+ key :type, :integer
162
+ key :minimum, 0
163
+ end
164
+ property :enabled do
165
+ key :type, :integer
166
+ key :minimum, 0
167
+ end
168
+ property :failing do
169
+ key :type, :integer
170
+ key :minimum, 0
171
+ end
172
+ end
173
+
174
+ def self.swagger_included_classes
175
+ # hack -- hardcoding for now
176
+ []
177
+ end
178
+
179
+ def self.jsonapi_methods
180
+ @jsonapi_methods ||= {
181
+ :get => Flapjack::Gateways::JSONAPI::Data::MethodDescriptor.new(
182
+ :attributes => [:total_keys, :processed_events, :event_queue_length,
183
+ :check_freshness, :check_counts],
184
+ :description => "Get global metrics and event counter values."
185
+ )
186
+ }
187
+ end
188
+
189
+ def self.jsonapi_associations
190
+ @jsonapi_associations ||= {}
191
+ end
192
+ end
193
+ end
194
+ end
@@ -1,298 +1,39 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'flapjack/data/contact'
4
- require 'flapjack/data/event'
5
- require 'flapjack/data/message'
3
+ # 'Notification' refers to the template object created when an event occurs,
4
+ # from which individual 'Message' objects are created, one for each
5
+ # contact+media recipient.
6
+
7
+ require 'zermelo/records/redis'
6
8
 
7
9
  module Flapjack
8
10
  module Data
9
11
  class Notification
10
12
 
11
- attr_reader :type, :event_id, :state
12
-
13
- def self.type_for_event(event)
14
- case event.type
15
- when 'service'
16
- case event.state
17
- when 'ok'
18
- 'recovery'
19
- when 'warning', 'critical', 'unknown'
20
- 'problem'
21
- end
22
- when 'action'
23
- case event.state
24
- when 'acknowledgement'
25
- 'acknowledgement'
26
- when 'test_notifications'
27
- 'test'
28
- end
29
- else
30
- 'unknown'
31
- end
32
- end
33
-
34
- def self.severity_for_event(event, max_notified_severity)
35
- if ([event.state, max_notified_severity] & ['critical', 'test_notifications']).any?
36
- 'critical'
37
- elsif [event.state, max_notified_severity].include?('warning')
38
- 'warning'
39
- elsif [event.state, max_notified_severity].include?('unknown')
40
- 'unknown'
41
- else
42
- 'ok'
43
- end
44
- end
45
-
46
- def self.add(queue, event, opts = {})
47
- raise "Redis connection not set" unless redis = opts[:redis]
48
-
49
- last_state = opts[:last_state] || {}
50
-
51
- tag_data = event.tags.is_a?(Set) ? event.tags.to_a : nil
52
- notif = {'event_id' => event.id,
53
- 'event_hash' => event.id_hash,
54
- 'state' => event.state,
55
- 'summary' => event.summary,
56
- 'details' => event.details,
57
- 'time' => event.time,
58
- 'duration' => event.duration,
59
- 'count' => event.counter,
60
- 'last_state' => last_state[:state],
61
- 'last_summary' => last_state[:summary],
62
- 'state_duration' => opts[:state_duration],
63
- 'type' => opts[:type] || type_for_event(event),
64
- 'severity' => opts[:severity],
65
- 'tags' => tag_data }
66
-
67
- redis.rpush(queue, Flapjack.dump_json(notif))
68
- end
69
-
70
- def self.next(queue, opts = {})
71
- raise "Redis connection not set" unless redis = opts[:redis]
72
-
73
- defaults = { :block => true }
74
- options = defaults.merge(opts)
75
-
76
- if options[:block]
77
- raw = redis.blpop(queue, 0)[1]
78
- else
79
- raw = redis.lpop(queue)
80
- return unless raw
81
- end
82
- begin
83
- parsed = ::Flapjack.load_json( raw )
84
- rescue Oj::Error => e
85
- if options[:logger]
86
- options[:logger].warn("Error deserialising notification json: #{e}, raw json: #{raw.inspect}")
87
- end
88
- return
89
- end
90
- return if 'shutdown'.eql?(parsed['type'])
91
- self.new( parsed )
92
- end
93
-
94
- def ok?
95
- @state && ['ok', 'up'].include?(@state)
96
- end
97
-
98
- def acknowledgement?
99
- @state && ['acknowledgement'].include?(@state)
100
- end
101
-
102
- def test?
103
- @state && ['test_notifications'].include?(@state)
104
- end
105
-
106
- def contents
107
- @contents ||= {'event_id' => @event_id,
108
- 'event_hash' => @event_hash,
109
- 'state' => @state,
110
- 'summary' => @summary,
111
- 'duration' => @duration,
112
- 'last_state' => @last_state,
113
- 'last_summary' => @last_summary,
114
- 'state_duration' => @state_duration,
115
- 'details' => @details,
116
- 'time' => @time,
117
- 'notification_type' => @type,
118
- 'event_count' => @count,
119
- 'tags' => @tags
120
- }
121
- end
122
-
123
- def messages(contacts, opts = {})
124
- return [] if contacts.nil? || contacts.empty?
125
-
126
- default_timezone = opts[:default_timezone]
127
- logger = opts[:logger]
128
-
129
- @messages ||= contacts.collect do |contact|
130
- contact_id = contact.id
131
- rules = contact.notification_rules
132
- media = contact.media
13
+ include Zermelo::Records::RedisSet
14
+ include Flapjack::Data::Extensions::ShortName
133
15
 
134
- logger.debug "Notification#messages: creating messages for contact: #{contact_id} " +
135
- "event_id: \"#{@event_id}\" state: #{@state} event_tags: #{Flapjack.dump_json(@tags)} media: #{media.inspect}"
136
- rlen = rules.length
137
- logger.debug "found #{rlen} rule#{(rlen == 1) ? '' : 's'} for contact #{contact_id}"
16
+ define_attributes :severity => :string,
17
+ :duration => :integer,
18
+ :condition_duration => :float,
19
+ :event_hash => :string
138
20
 
139
- media_to_use = if rules.empty?
140
- media
141
- else
142
- # matchers are rules of the contact that have matched the current event
143
- # for time, entity and tags
144
- matchers = rules.select do |rule|
145
- begin
146
- logger.debug("considering rule with entities: #{rule.entities}, entities regex: #{rule.regex_entities},
147
- tags: #{Flapjack.dump_json(rule.tags)} and regex tags: #{Flapjack.dump_json(rule.regex_tags)}")
148
- rule_has_tags = rule.tags ? (rule.tags.length > 0) : false
149
- rule_has_regex_tags = rule.regex_tags ? (rule.regex_tags.length > 0) : false
150
- rule_has_entities = rule.entities ? (rule.entities.length > 0) : false
151
- rule_has_regex_entities = rule.regex_entities ? (rule.regex_entities.length > 0) : false
21
+ belongs_to :check, :class_name => 'Flapjack::Data::Check',
22
+ :inverse_of => :notifications
152
23
 
153
- matches_tags = rule_has_tags ? rule.match_tags?(@tags) : true
154
- matches_regex_tags = rule_has_regex_tags ? rule.match_regex_tags?(@tags) : true
155
- matches_entity = rule_has_entities ? rule.match_entity?(@event_id) : true
156
- matches_regex_entities = rule_has_regex_entities ? rule.match_regex_entities?(@event_id) : true
24
+ has_one :state, :class_name => 'Flapjack::Data::State',
25
+ :inverse_of => :notification, :after_clear => :destroy_state
157
26
 
158
- ((matches_entity && matches_regex_entities && matches_tags && matches_regex_tags) || ! rule.is_specific?) &&
159
- rule_occurring_now?(rule, :contact => contact, :default_timezone => default_timezone,
160
- :logger => logger)
161
- rescue RegexpError => e
162
- logger.error "rule with entities regex: #{rule.regex_entities} and regex tags: #{Flapjack.dump_json(rule.regex_tags)} has invalid regex: #{e.message}"
163
- false
164
- end
165
- end
166
-
167
- logger.debug "#{matchers.length} matchers remain for this contact after time, entity and tags are matched:"
168
- matchers.each do |matcher|
169
- logger.debug " - #{matcher.to_jsonapi}"
170
- end
171
-
172
- # delete any general matchers if there are more specific matchers left
173
- if matchers.any? {|matcher| matcher.is_specific? }
174
-
175
- num_matchers = matchers.length
176
-
177
- matchers.reject! {|matcher| !matcher.is_specific? }
178
-
179
- if num_matchers != matchers.length
180
- logger.debug("removal of general matchers when entity specific matchers are present: number of matchers changed from #{num_matchers} to #{matchers.length} for contact id: #{contact_id}")
181
- matchers.each do |matcher|
182
- logger.debug " - #{matcher.to_jsonapi}"
183
- end
184
- end
185
- end
186
-
187
- # delete media based on blackholes
188
- blackhole_matchers = matchers.map {|matcher| matcher.blackhole?(@severity) ? matcher : nil }.compact
189
- if blackhole_matchers.length > 0
190
- logger.debug "dropping this media as #{blackhole_matchers.length} blackhole matchers are present:"
191
- blackhole_matchers.each {|bm|
192
- logger.debug " - #{bm.to_jsonapi}"
193
- }
194
- next
195
- else
196
- logger.debug "no blackhole matchers matched"
197
- end
198
-
199
- rule_media = matchers.collect{|matcher|
200
- matcher.media_for_severity(@severity)
201
- }.flatten.uniq
202
-
203
- logger.debug "collected media_for_severity(#{@severity}): #{rule_media}"
204
- rule_media = rule_media.reject {|medium|
205
- contact.drop_notifications?(:media => medium,
206
- :check => @event_id,
207
- :state => @state)
208
- }
209
-
210
- logger.debug "media after contact_drop?: #{rule_media}"
211
-
212
- media.select {|medium, address| rule_media.include?(medium) }
213
- end
214
-
215
- logger.debug "media_to_use: #{media_to_use}"
216
-
217
- # here begins rollup madness
218
- media_to_use.each_pair.inject([]) do |ret, (media, address)|
219
- rollup_type = nil
220
-
221
- contact.add_alerting_check_for_media(media, @event_id) unless ok? || acknowledgement? || test?
222
-
223
- # expunge checks in (un)scheduled maintenance from the alerting set
224
- recovered = contact.clean_alerting_checks_for_media(media)
225
- logger.debug("cleaned alerting checks for #{media}: recovered? #{recovered}")
226
-
227
- # pagerduty is an example of a medium which should never be rolled up
228
- unless ['pagerduty'].include?(media)
229
- alerting_checks = contact.count_alerting_checks_for_media(media)
230
- rollup_threshold = contact.rollup_threshold_for_media(media)
231
-
232
- case
233
- when rollup_threshold.nil?
234
- # back away slowly
235
- when alerting_checks >= rollup_threshold
236
- next ret if contact.drop_rollup_notifications_for_media?(media)
237
- contact.update_sent_rollup_alert_keys_for_media(media, :delete => ok?)
238
- rollup_type = 'problem'
239
- when recovered
240
- # alerting checks was just cleaned such that it is now below the rollup threshold
241
- contact.update_sent_rollup_alert_keys_for_media(media, :delete => true)
242
- rollup_type = 'recovery'
243
- end
244
- logger.debug "rollup decisions: #{@event_id} #{@state} #{media} #{address} rollup_type: #{rollup_type}"
245
- end
246
-
247
- m = Flapjack::Data::Message.for_contact(contact,
248
- :medium => media, :address => address, :rollup => rollup_type)
249
- ret << m
250
- ret
251
- end
252
- end.compact.flatten # @messages ||= contacts.collect do ...
253
- end
254
-
255
- private
256
-
257
- # created from parsed JSON, so opts keys are in strings
258
- def initialize(opts = {})
259
- @event_id = opts['event_id']
260
- @state = opts['state']
261
- @summary = opts['summary']
262
- @details = opts['details']
263
- @time = opts['time']
264
- @count = opts['count']
265
- @duration = opts['duration']
266
- @last_state = opts['last_state']
267
- @last_summary = opts['last_summary']
268
- @state_duration = opts['state_duration']
269
- @type = opts['type']
270
- @severity = opts['severity']
271
- @tags = opts['tags'].is_a?(Array) ? Set.new(opts['tags']) : nil
27
+ def self.destroy_state(notification_id, st_id)
28
+ # won't be deleted if still referenced elsewhere -- see the State
29
+ # before_destroy callback
30
+ Flapjack::Data::State.intersect(:id => st_id).destroy_all
272
31
  end
273
32
 
274
- # # time restrictions match?
275
- # nil rule.time_restrictions matches
276
- # times (start, end) within time restrictions will have any UTC offset removed and will be
277
- # considered to be in the timezone of the contact
278
- def rule_occurring_now?(rule, options = {})
279
- contact = options[:contact]
280
- def_tz = options[:default_timezone]
281
-
282
- return true if rule.time_restrictions.nil? or rule.time_restrictions.empty?
283
-
284
- time_zone = contact.time_zone || def_tz
285
- usertime = time_zone.now
286
-
287
- rule.time_restrictions.any? do |tr|
288
- # add contact's time_zone to the time restriction schedule
289
- schedule = Flapjack::Data::NotificationRule.
290
- time_restriction_to_icecube_schedule(tr, time_zone, :logger => options[:logger])
291
- schedule && schedule.occurring_at?(usertime)
292
- end
293
- end
33
+ validates :severity,
34
+ :inclusion => {:in => Flapjack::Data::Condition.unhealthy.keys +
35
+ Flapjack::Data::Condition.healthy.keys }
294
36
 
295
37
  end
296
38
  end
297
39
  end
298
-