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
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'securerandom'
4
-
5
- module Flapjack
6
- module Data
7
-
8
- # http://redis.io/commands/set
9
- class Semaphore
10
-
11
- SEMAPHORE_KEYSPACE = 'semaphores:'
12
-
13
- attr_reader :token, :expiry, :resource
14
-
15
- class ResourceLocked < RuntimeError
16
- end
17
-
18
- def initialize(resource, options)
19
- raise "redis connection must be passed in options" unless @redis = options[:redis]
20
- @resource = resource
21
- @token = options[:token] || SecureRandom.uuid
22
- @expiry = options[:expiry] || 30
23
-
24
- @key = "#{SEMAPHORE_KEYSPACE}#{@resource}"
25
-
26
- raise Flapjack::Data::Semaphore::ResourceLocked.new unless @redis.set(@key, @token, {:nx => true, :ex => @expiry})
27
- end
28
-
29
- def release
30
- unlock_script = '
31
- if redis.call("get",KEYS[1]) == ARGV[1]
32
- then
33
- return redis.call("del",KEYS[1])
34
- else
35
- return 0
36
- end
37
- '
38
- @redis.eval(unlock_script, [@key], [@token])
39
- end
40
-
41
- end
42
- end
43
- end
44
-
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # mixed in to some of the Flapjack data classes
4
-
5
- module Flapjack
6
-
7
- module Tagged
8
-
9
- def tag_prefix
10
- self.class.name.split('::').last.downcase + '_tag'
11
- end
12
-
13
- def known_key
14
- "known_tags:#{tag_prefix}"
15
- end
16
-
17
- # return the set of tags for this object
18
- def tags
19
- return @tags unless @tags.nil?
20
- @tags ||= Set.new( @redis.smembers(known_key).inject([]) {|memo, t|
21
- tag_key = "#{tag_prefix}:#{t}"
22
- memo << t if @redis.sismember(tag_key, @id.to_s)
23
- memo
24
- })
25
- end
26
-
27
- # adds tags to this object
28
- def add_tags(*enum)
29
- enum.each do |t|
30
- @redis.sadd(known_key, t)
31
- @redis.sadd("#{tag_prefix}:#{t}", @id)
32
- tags.add(t)
33
- end
34
- end
35
-
36
- # removes tags from this object
37
- def delete_tags(*enum)
38
- enum.each do |t|
39
- tag_key = "#{tag_prefix}:#{t}"
40
- @redis.srem(tag_key, @id)
41
- tags.delete(t)
42
- @redis.srem(known_key, t) if (@redis.scard(tag_key) == 0)
43
- end
44
- end
45
-
46
- end
47
-
48
- end
@@ -1,206 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'sinatra/base'
4
-
5
- require 'flapjack/data/event'
6
-
7
- module Flapjack
8
-
9
- module Gateways
10
-
11
- class JSONAPI < Sinatra::Base
12
-
13
- module CheckMethods
14
-
15
- module Helpers
16
-
17
- def checks_for_check_names(check_names)
18
- return if check_names.nil?
19
- entity_cache = {}
20
- check_names.inject([]) do |memo, check_name|
21
- entity_name, check = check_name.split(':', 2)
22
- entity = (entity_cache[entity_name] ||= find_entity(entity_name))
23
- memo << find_entity_check(entity, check)
24
- memo
25
- end
26
- end
27
-
28
- end
29
-
30
- def self.registered(app)
31
- app.helpers Flapjack::Gateways::JSONAPI::Helpers
32
- app.helpers Flapjack::Gateways::JSONAPI::CheckMethods::Helpers
33
-
34
- app.get %r{^/checks(?:/)?(.+)?$} do
35
- requested_checks = if params[:captures] && params[:captures][0]
36
- params[:captures][0].split(',').uniq
37
- else
38
- nil
39
- end
40
-
41
- checks = if requested_checks
42
- requested_checks.collect do|req_check|
43
- Flapjack::Data::EntityCheck.for_event_id(req_check, :logger => logger, :redis => redis)
44
- end
45
- else
46
- Flapjack::Data::EntityCheck.all(:logger => logger, :redis => redis)
47
- end
48
- checks.compact!
49
-
50
- if requested_checks && checks.empty?
51
- raise Flapjack::Gateways::JSONAPI::EntityChecksNotFound.new(requested_checks)
52
- end
53
-
54
- check_ids = checks.collect {|c| "#{c.entity.name}:#{c.check}" }
55
-
56
- enabled_ids = Flapjack::Data::EntityCheck.enabled_for(check_ids, :redis => redis)
57
-
58
- linked_entity_ids = checks.empty? ? [] : checks.inject({}) do |memo, check|
59
- entity = check.entity
60
- memo["#{entity.name}:#{check.check}"] = [entity.id]
61
- memo
62
- end
63
-
64
- checks_json = checks.collect {|check|
65
- check_name = "#{check.entity.name}:#{check.check}"
66
- check.to_jsonapi(:enabled => enabled_ids.include?(check_name),
67
- :entity_ids => linked_entity_ids[check_name])
68
- }.join(",")
69
-
70
- '{"checks":[' + checks_json + ']}'
71
- end
72
-
73
- app.post '/checks' do
74
- checks = wrapped_params('checks')
75
-
76
- check_names = checks.collect{|check_data|
77
- check = Flapjack::Data::EntityCheck.add(check_data, :redis => redis)
78
- "#{check.entity.name}:#{check.check}"
79
- }
80
-
81
- response.headers['Location'] = "#{request.base_url}/checks/#{check_names.join(',')}"
82
- status 201
83
- Flapjack.dump_json(check_names)
84
- end
85
-
86
- app.patch %r{^/checks/(.+)$} do
87
- checks_for_check_names(params[:captures][0].split(',')).each do |check|
88
- apply_json_patch('checks') do |op, property, linked, value|
89
- case op
90
- when 'replace'
91
- case property
92
- when 'enabled'
93
- # explicitly checking for true/false being passed in
94
- case value
95
- when TrueClass
96
- check.enable!
97
- when FalseClass
98
- check.disable!
99
- end
100
- end
101
- when 'add'
102
- case linked
103
- when 'tags'
104
- value.respond_to?(:each) ? check.add_tags(*value) :
105
- check.add_tags(value)
106
- end
107
- when 'remove'
108
- case linked
109
- when 'tags'
110
- value.respond_to?(:each) ? check.delete_tags(*value) :
111
- check.delete_tags(value)
112
- end
113
- end
114
- end
115
- end
116
-
117
- status 204
118
- end
119
-
120
- # create a scheduled maintenance period for a check on an entity
121
- app.post %r{^/scheduled_maintenances/checks/(.+)$} do
122
- scheduled_maintenances = wrapped_params('scheduled_maintenances')
123
- checks_for_check_names(params[:captures][0].split(',')).each do |check|
124
- scheduled_maintenances.each do |wp|
125
- start_time = validate_and_parsetime(wp['start_time'])
126
- halt( err(403, "start time must be provided") ) unless start_time
127
-
128
- check.create_scheduled_maintenance(start_time,
129
- wp[:duration].to_i, :summary => wp[:summary])
130
- end
131
- end
132
-
133
- status 204
134
- end
135
-
136
- # create an acknowledgement for a service on an entity
137
- # NB currently, this does not acknowledge a specific failure event, just
138
- # the entity-check as a whole
139
- app.post %r{^/unscheduled_maintenances/checks/(.+)$} do
140
- unscheduled_maintenances = wrapped_params('unscheduled_maintenances', false)
141
- checks_for_check_names(params[:captures][0].split(',')).each do |check|
142
- unscheduled_maintenances.each do |wp|
143
- dur = wp['duration'] ? wp['duration'].to_i : nil
144
- duration = (dur.nil? || (dur <= 0)) ? (4 * 60 * 60) : dur
145
- summary = wp['summary']
146
-
147
- opts = {:duration => duration}
148
- opts[:summary] = summary if summary
149
-
150
- Flapjack::Data::Event.create_acknowledgement(
151
- check.entity_name, check.check, {:redis => redis}.merge(opts))
152
- end
153
- end
154
-
155
- status 204
156
- end
157
-
158
- app.patch %r{^/unscheduled_maintenances/checks/(.+)$} do
159
- checks_for_check_names(params[:captures][0].split(',')).each do |check|
160
- apply_json_patch('unscheduled_maintenances') do |op, property, linked, value|
161
- case op
162
- when 'replace'
163
- if ['end_time'].include?(property)
164
- end_time = validate_and_parsetime(value)
165
- check.end_unscheduled_maintenance(end_time.to_i)
166
- end
167
- end
168
- end
169
- end
170
- status 204
171
- end
172
-
173
- app.delete %r{^/scheduled_maintenances/checks/(.+)$} do
174
- start_time = validate_and_parsetime(params[:start_time])
175
- halt( err(403, "start time must be provided") ) unless start_time
176
-
177
- checks_for_check_names(params[:captures][0].split(',')).each do |check|
178
- check.end_scheduled_maintenance(start_time.to_i)
179
- end
180
- status 204
181
- end
182
-
183
- app.post %r{^/test_notifications/checks/(.+)$} do
184
- test_notifications = wrapped_params('test_notifications', false)
185
- checks_for_check_names(params[:captures][0].split(',')).each do |check|
186
- test_notifications.each do |wp|
187
- summary = wp['summary'] ||
188
- "Testing notifications to all contacts interested in entity #{check.entity.name}"
189
- Flapjack::Data::Event.test_notifications(
190
- check.entity_name, check.check,
191
- :summary => summary,
192
- :redis => redis)
193
- end
194
- end
195
- status 204
196
- end
197
-
198
- end
199
-
200
- end
201
-
202
- end
203
-
204
- end
205
-
206
- end
@@ -1,221 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Formats entity/check data for presentation by the API methods in Flapjack::Gateways::API.
4
-
5
- require 'sinatra/base'
6
-
7
- require 'flapjack/data/entity_check'
8
-
9
- module Flapjack
10
-
11
- module Gateways
12
-
13
- class JSONAPI < Sinatra::Base
14
-
15
- class CheckPresenter
16
-
17
- def initialize(entity_check)
18
- @entity_check = entity_check
19
- end
20
-
21
- def status
22
- {'name' => @entity_check.check,
23
- 'state' => @entity_check.state,
24
- 'enabled' => @entity_check.enabled?,
25
- 'summary' => @entity_check.summary,
26
- 'details' => @entity_check.details,
27
- 'perfdata' => @entity_check.perfdata,
28
- 'in_unscheduled_maintenance' => @entity_check.in_unscheduled_maintenance?,
29
- 'in_scheduled_maintenance' => @entity_check.in_scheduled_maintenance?,
30
- 'initial_failure_delay' => @entity_check.initial_failure_delay,
31
- 'repeat_failure_delay' => @entity_check.repeat_failure_delay,
32
- 'last_update' => @entity_check.last_update,
33
- 'last_change' => @entity_check.last_change,
34
- 'last_problem_notification' => @entity_check.last_notification_for_state(:problem)[:timestamp],
35
- 'last_recovery_notification' => @entity_check.last_notification_for_state(:recovery)[:timestamp],
36
- 'last_acknowledgement_notification' => @entity_check.last_notification_for_state(:acknowledgement)[:timestamp]}
37
- end
38
-
39
- def outage(start_time, end_time, options = {})
40
- # hist_states is an array of hashes, with [state, timestamp, summary] keys
41
- hist_states = @entity_check.historical_states(start_time, end_time)
42
- return {:outages => []} if hist_states.empty?
43
-
44
- initial = @entity_check.historical_state_before(hist_states.first[:timestamp])
45
- hist_states.unshift(initial) if initial
46
-
47
- # TODO the following works, but isn't the neatest
48
- num_states = hist_states.size
49
-
50
- index = 0
51
- result = []
52
- obj = nil
53
-
54
- while index < num_states do
55
- last_obj = obj
56
- obj = hist_states[index]
57
- index += 1
58
-
59
- next if obj[:state] == 'ok'
60
-
61
- if last_obj && (last_obj[:state] == obj[:state])
62
- # TODO maybe build up arrays of these instead, and leave calling
63
- # classes to join them together if needed?
64
- result.last[:summary] << " / #{obj[:summary]}"
65
- result.last[:details] << " / #{obj[:details]}"
66
- next
67
- end
68
-
69
- ts = obj[:timestamp]
70
-
71
- obj_st = (last_obj || !start_time) ? ts : [ts, start_time].max
72
-
73
- next_ts_obj = hist_states[index..-1].detect {|hs| hs[:state] != obj[:state] }
74
- obj_et = next_ts_obj ? next_ts_obj[:timestamp] : end_time
75
-
76
- obj_dur = obj_et ? obj_et - obj_st : nil
77
-
78
- result << {:state => obj[:state],
79
- :start_time => obj_st,
80
- :end_time => obj_et,
81
- :duration => obj_dur,
82
- :summary => obj[:summary] || '',
83
- :details => obj[:details] || ''
84
- }
85
- end
86
-
87
- {:outages => result}
88
- end
89
-
90
- def unscheduled_maintenance(start_time, end_time)
91
- # unsched_maintenance is an array of hashes, with [duration, timestamp, summary] keys
92
- unsched_maintenance = @entity_check.maintenances(start_time, end_time,
93
- :scheduled => false)
94
-
95
- # to see if we start in an unscheduled maintenance period, we must check all unscheduled
96
- # maintenances before the period and their durations
97
- start_in_unsched = start_time.nil? ? [] :
98
- @entity_check.maintenances(nil, start_time, :scheduled => false).select {|pu|
99
- pu[:end_time] >= start_time
100
- }
101
-
102
- {:unscheduled_maintenances => (start_in_unsched + unsched_maintenance)}
103
- end
104
-
105
- def scheduled_maintenance(start_time, end_time)
106
- # sched_maintenance is an array of hashes, with [duration, timestamp, summary] keys
107
- sched_maintenance = @entity_check.maintenances(start_time, end_time,
108
- :scheduled => true)
109
-
110
- # to see if we start in a scheduled maintenance period, we must check all scheduled
111
- # maintenances before the period and their durations
112
- start_in_sched = start_time.nil? ? [] :
113
- @entity_check.maintenances(nil, start_time, :scheduled => true).select {|ps|
114
- ps[:end_time] >= start_time
115
- }
116
-
117
- {:scheduled_maintenances => (start_in_sched + sched_maintenance)}
118
- end
119
-
120
- # TODO test whether the below overlapping logic is prone to off-by-one
121
- # errors; the numbers may line up more neatly if we consider outages to
122
- # start one second after the maintenance period ends.
123
- #
124
- # TODO test performance with larger data sets
125
- def downtime(start_time, end_time)
126
- outs = outage(start_time, end_time)[:outages]
127
-
128
- total_secs = {}
129
- percentages = {}
130
-
131
- outs.collect {|obj| obj[:state]}.uniq.each do |st|
132
- total_secs[st] = 0
133
- percentages[st] = (start_time.nil? || end_time.nil?) ? nil : 0
134
- end
135
-
136
- unless outs.empty?
137
-
138
- # Initially we need to check for cases where a scheduled
139
- # maintenance period is fully covered by an outage period.
140
- # We then create two new outage periods to cover the time around
141
- # the scheduled maintenance period, and remove the original.
142
-
143
- sched_maintenances = scheduled_maintenance(start_time, end_time)[:scheduled_maintenances]
144
-
145
- sched_maintenances.each do |sm|
146
-
147
- split_outs = []
148
-
149
- outs.each { |o|
150
- next unless o[:end_time] && (o[:start_time] < sm[:start_time]) &&
151
- (o[:end_time] > sm[:end_time])
152
- o[:delete] = true
153
- split_outs += [{:state => o[:state],
154
- :start_time => o[:start_time],
155
- :end_time => sm[:start_time],
156
- :duration => sm[:start_time] - o[:start_time],
157
- :summary => "#{o[:summary]} [split start]"},
158
- {:state => o[:state],
159
- :start_time => sm[:end_time],
160
- :end_time => o[:end_time],
161
- :duration => o[:end_time] - sm[:end_time],
162
- :summary => "#{o[:summary]} [split finish]"}]
163
- }
164
-
165
- outs.reject! {|o| o[:delete]}
166
- outs += split_outs
167
- # not strictly necessary to keep the data sorted, but
168
- # will make more sense while debgging
169
- outs.sort! {|a,b| a[:start_time] <=> b[:start_time]}
170
- end
171
-
172
- sched_maintenances.each do |sm|
173
-
174
- outs.each do |o|
175
- next unless o[:end_time] && (sm[:start_time] < o[:end_time]) &&
176
- (sm[:end_time] > o[:start_time])
177
-
178
- if sm[:start_time] <= o[:start_time] &&
179
- sm[:end_time] >= o[:end_time]
180
-
181
- # outage is fully overlapped by the scheduled maintenance
182
- o[:delete] = true
183
-
184
- elsif sm[:start_time] <= o[:start_time]
185
- # partially overlapping on the earlier side
186
- o[:start_time] = sm[:end_time]
187
- o[:duration] = o[:end_time] - o[:start_time]
188
- elsif sm[:end_time] >= o[:end_time]
189
- # partially overlapping on the later side
190
- o[:end_time] = sm[:start_time]
191
- o[:duration] = o[:end_time] - o[:start_time]
192
- end
193
- end
194
-
195
- outs.reject! {|o| o[:delete]}
196
- end
197
-
198
- total_secs = outs.inject(total_secs) {|ret, o|
199
- ret[o[:state]] += o[:duration] if o[:duration]
200
- ret
201
- }
202
-
203
- unless (start_time.nil? || end_time.nil?)
204
- total_secs.each_pair do |st, ts|
205
- percentages[st] = (total_secs[st] * 100.0) / (end_time.to_f - start_time.to_f)
206
- end
207
- total_secs['ok'] = (end_time - start_time) - total_secs.values.reduce(:+)
208
- percentages['ok'] = 100 - percentages.values.reduce(:+)
209
- end
210
- end
211
-
212
- {:total_seconds => total_secs, :percentages => percentages, :downtime => outs}
213
- end
214
-
215
- end
216
-
217
- end
218
-
219
- end
220
-
221
- end