flapjack 1.6.0 → 2.0.0b1

Sign up to get free protection for your applications and to get access to all the features.
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