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,65 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'thin'
4
- require 'redis'
5
-
6
- # we don't want to stop the entire EM reactor when we stop a web server
7
- # & @connections data type changed in thin 1.5.1
8
- module Thin
9
-
10
- # see https://github.com/flapjack/flapjack/issues/169
11
- class Request
12
- class EqlTempfile < ::Tempfile
13
- def eql?(obj)
14
- obj.equal?(self) && (obj == self)
15
- end
16
- end
17
-
18
- def move_body_to_tempfile
19
- current_body = @body
20
- current_body.rewind
21
- @body = Thin::Request::EqlTempfile.new(BODY_TMPFILE)
22
- @body.binmode
23
- @body << current_body.read
24
- @env[RACK_INPUT] = @body
25
- end
26
- end
27
-
28
- module Backends
29
- class Base
30
- def stop!
31
- @running = false
32
- @stopping = false
33
-
34
- # EventMachine.stop if EventMachine.reactor_running?
35
-
36
- case @connections
37
- when Array
38
- @connections.each { |connection| connection.close_connection }
39
- when Hash
40
- @connections.each_value { |connection| connection.close_connection }
41
- end
42
- close
43
- end
44
- end
45
- end
46
- end
3
+ require 'gli'
4
+ require 'logger'
47
5
 
48
- # As Redis::Future objects inherit from BasicObject, it's difficult to
49
- # distinguish between them and other objects in collected data from
50
- # pipelined queries.
51
- #
52
- # (One alternative would be to put other values in Futures ourselves, and
53
- # evaluate everything...)
54
- class Redis
55
- class Future
56
- def class
57
- ::Redis::Future
58
- end
59
- end
60
- end
6
+ # fix for webrick's assuming 1.8.7 Logger syntax
7
+ class ::Logger; alias_method :write, :<<; end
61
8
 
62
- module GLI
9
+ module ::GLI
63
10
  class Command
64
11
  attr_accessor :passthrough
65
12
  def _action
@@ -85,12 +32,10 @@ module GLI
85
32
  arguments = option_block_parser.parse!(arguments)
86
33
 
87
34
  parsed_command_options[command] = option_parser_factory.options_hash_with_defaults_set!
88
- command_finder = CommandFinder.new(command.commands,command.get_default_command)
35
+ command_finder = CommandFinder.new(command.commands, :default_command => command.get_default_command)
89
36
  next_command_name = arguments.shift
90
37
 
91
- gli_major_version, gli_minor_version = GLI::VERSION.split('.')
92
- required_options = [command.flags, parsing_result.command, parsed_command_options[command]]
93
- verify_required_options!(*required_options)
38
+ verify_required_options!(command.flags, command, parsed_command_options[command])
94
39
 
95
40
  begin
96
41
  command = command_finder.find_command(next_command_name)
@@ -99,7 +44,7 @@ module GLI
99
44
  break
100
45
  rescue UnknownCommand
101
46
  arguments.unshift(next_command_name)
102
- # Although command finder could certainy know if it should use
47
+ # Although command finder could certainly know if it should use
103
48
  # the default command, it has no way to put the "unknown command"
104
49
  # back into the argument stack. UGH.
105
50
  unless command.get_default_command.nil?
@@ -8,206 +8,248 @@
8
8
  # with butter, at afternoon tea, but can also be served at morning tea."
9
9
  # from http://en.wikipedia.org/wiki/Pancake
10
10
 
11
- # the redis/synchrony gems need to be required in this particular order, see
12
- # the redis-rb README for details
13
- require 'hiredis'
14
- require 'redis/connection/synchrony'
15
- require 'redis'
16
- require 'thin'
11
+ require 'monitor'
12
+
13
+ require 'puma'
14
+
15
+ require 'flapjack'
17
16
 
18
17
  require 'flapjack/notifier'
19
18
  require 'flapjack/processor'
19
+ require 'flapjack/gateways/web'
20
+ require 'flapjack/gateways/aws_sns'
21
+ require 'flapjack/gateways/email'
20
22
  require 'flapjack/gateways/jsonapi'
21
23
  require 'flapjack/gateways/jabber'
22
24
  require 'flapjack/gateways/oobetet'
23
- require 'flapjack/gateways/pagerduty'
24
- require 'flapjack/gateways/email'
25
- require 'flapjack/gateways/sms_messagenet'
25
+ require 'flapjack/gateways/pager_duty'
26
26
  require 'flapjack/gateways/slack'
27
- require 'flapjack/gateways/sms_twilio'
27
+ require 'flapjack/gateways/sms_messagenet'
28
28
  require 'flapjack/gateways/sms_nexmo'
29
- require 'flapjack/gateways/aws_sns'
30
- require 'flapjack/gateways/web'
29
+ require 'flapjack/gateways/sms_twilio'
30
+ require 'flapjack/gateways/sms_aspsms'
31
31
  require 'flapjack/logger'
32
- require 'thin/version'
33
-
34
- module Thin
35
- # disable Thin's loading of daemons
36
- # workaround for https://github.com/flapjack/flapjack/issues/133
37
- def self.win?
38
- true
39
- end
40
- end
41
32
 
42
33
  module Flapjack
43
34
 
44
35
  module Pikelet
45
36
 
46
- # TODO find a better way of expressing these two methods
47
- def self.is_pikelet?(type)
48
- type_klass = [Flapjack::Pikelet::Generic,
49
- Flapjack::Pikelet::Thin].detect do |kl|
50
-
51
- kl::PIKELET_TYPES[type]
52
-
53
- end
54
- !type_klass.nil?
55
- end
37
+ class Base
38
+ attr_accessor :siblings, :pikelet, :redis
56
39
 
57
- def self.create(type, opts = {})
58
- pikelet = nil
59
- [Flapjack::Pikelet::Generic,
60
- Flapjack::Pikelet::Thin].each do |kl|
61
- next unless kl::PIKELET_TYPES[type]
62
- break if pikelet = kl.create(type, opts)
63
- end
64
- pikelet
65
- end
40
+ def initialize(pikelet_class, shutdown, opts = {})
41
+ @pikelet_class = pikelet_class
66
42
 
67
- class Base
68
- attr_reader :type, :status
43
+ @config = opts[:config]
44
+ @boot_time = opts[:boot_time]
45
+ @logger_name = opts[:logger_name]
46
+ @shutdown = shutdown
69
47
 
70
- def initialize(type, pikelet_class, opts = {})
71
- @type = type
72
- @klass = pikelet_class
48
+ @siblings = []
73
49
 
74
- @config = opts[:config] || {}
75
- @redis_config = opts[:redis_config] || {}
76
- @boot_time = opts[:boot_time]
77
- @coordinator = opts[:coordinator]
50
+ @lock = Monitor.new
51
+ @stop_condition = @lock.new_cond
78
52
 
79
- @logger = Flapjack::Logger.new("flapjack-#{type}", @config['logger'])
53
+ @pikelet = @pikelet_class.new(:lock => @lock,
54
+ :stop_condition => @stop_condition, :config => @config,
55
+ :boot_time => @boot_time)
80
56
 
81
- @status = 'initialized'
57
+ @finished_condition = @lock.new_cond
82
58
  end
83
59
 
84
- def start
85
- @status = 'started'
60
+ def start(&block)
61
+ @pikelet.siblings = @siblings.map(&:pikelet) if @pikelet.respond_to?(:siblings=)
62
+
63
+ @thread = Thread.new do
64
+
65
+ Flapjack.configure_log(@logger_name, @config['logger'])
66
+
67
+ # TODO rename this, it's only relevant in the error case
68
+ max_runs = @config['max_runs'] || 1
69
+ runs = 0
70
+
71
+ keep_running = false
72
+ shutdown_all = false
73
+
74
+ loop do
75
+ begin
76
+ Flapjack.logger.debug "pikelet start for #{@pikelet_class.name}"
77
+ yield
78
+ rescue Flapjack::PikeletStop
79
+ Flapjack.logger.debug "pikelet exception stop for #{@pikelet_class.name}"
80
+ rescue Flapjack::GlobalStop
81
+ Flapjack.logger.debug "global exception stop for #{@pikelet_class.name}"
82
+ @shutdown_thread = @thread
83
+ shutdown_all = true
84
+ rescue Exception => e
85
+ Flapjack.logger.warn "#{e.class.name} #{e.message}"
86
+ trace = e.backtrace
87
+ Flapjack.logger.warn trace.join("\n") if trace
88
+ runs += 1
89
+ keep_running = (max_runs > 0) && (runs < max_runs)
90
+ shutdown_all = !keep_running
91
+ end
92
+
93
+ break unless keep_running
94
+ end
95
+
96
+ @lock.synchronize do
97
+ @finished = true
98
+ @finished_condition.signal
99
+ end
100
+
101
+ if shutdown_all
102
+ @shutdown.call
103
+ end
104
+ end
86
105
  end
87
106
 
88
- def reload(cfg)
89
- @logger.configure(cfg['logger'])
90
- true
107
+ def reload(cfg, &block)
108
+ Flapjack.logger.configure(cfg['logger'])
109
+ yield
91
110
  end
92
111
 
93
- def stop
94
- @status = 'stopping'
95
- end
112
+ def stop(&block)
113
+ fin = nil
114
+ @lock.synchronize do
115
+ fin = @finished
116
+ end
117
+ return if fin
118
+ if block_given?
119
+ yield
120
+ else
121
+ case @pikelet.stop_type
122
+ when :exception
123
+ @lock.synchronize do
124
+ Flapjack.logger.debug "triggering pikelet exception stop for #{@pikelet_class.name}"
125
+ @thread.raise Flapjack::PikeletStop
126
+ @finished_condition.wait_until { @finished }
127
+ end
128
+ when :signal
129
+ @lock.synchronize do
130
+ Flapjack.logger.debug "triggering pikelet signal stop for #{@pikelet_class.name}"
131
+ @pikelet.instance_variable_set('@should_quit', true)
132
+ @stop_condition.signal
133
+ @finished_condition.wait_until { @finished }
134
+ end
135
+ end
136
+ end
96
137
 
138
+ @thread.join
139
+ @thread = nil
140
+ end
97
141
  end
98
142
 
99
143
  class Generic < Flapjack::Pikelet::Base
100
144
 
101
- PIKELET_TYPES = {'notifier' => Flapjack::Notifier,
102
- 'processor' => Flapjack::Processor,
103
- 'jabber' => Flapjack::Gateways::Jabber,
104
- 'pagerduty' => Flapjack::Gateways::Pagerduty,
105
- 'oobetet' => Flapjack::Gateways::Oobetet,
106
- 'email' => Flapjack::Gateways::Email,
107
- 'sms' => Flapjack::Gateways::SmsMessagenet,
108
- 'slack' => Flapjack::Gateways::Slack,
109
- 'sms_twilio' => Flapjack::Gateways::SmsTwilio,
110
- 'sms_nexmo' => Flapjack::Gateways::SmsNexmo,
111
- 'sns' => Flapjack::Gateways::AwsSns}
112
-
113
- def self.create(type, opts = {})
114
- self.new(type, PIKELET_TYPES[type], :config => opts[:config],
115
- :redis_config => opts[:redis_config],
116
- :boot_time => opts[:boot_time],
117
- :coordinator => opts[:coordinator])
118
- end
119
-
120
- def initialize(type, pikelet_klass, opts = {})
121
- super(type, pikelet_klass, opts)
122
-
123
- @pikelet = @klass.new(opts.merge(:logger => @logger))
124
- end
145
+ TYPES = ['notifier', 'processor', 'jabber', 'pagerduty', 'oobetet',
146
+ 'email', 'sms', 'aws_sns', 'sms_twilio', 'sms_aspsms']
125
147
 
126
148
  def start
127
- @fiber = Fiber.new {
149
+ super do
128
150
  @pikelet.start
129
- }
130
- super
131
- @fiber.resume
151
+ end
132
152
  end
133
153
 
134
154
  # this should only reload if all changes can be applied -- will
135
155
  # return false to log warning otherwise
136
156
  def reload(cfg)
137
- @pikelet.respond_to?(:reload) ?
138
- (@pikelet.reload(cfg) && super(cfg)) : super(cfg)
139
- end
140
-
141
- def stop
142
- @pikelet.stop
143
- super
157
+ return false unless @pikelet.respond_to?(:reload)
158
+ super(cfg) { @pikelet.reload(cfg) }
144
159
  end
145
-
146
- def update_status
147
- return @status unless 'stopping'.eql?(@status)
148
- @status = 'stopped' if @fiber && !@fiber.alive?
149
- end
150
-
151
160
  end
152
161
 
153
- class Thin < Flapjack::Pikelet::Base
154
-
155
- PIKELET_TYPES = {'web' => Flapjack::Gateways::Web,
156
- 'jsonapi' => Flapjack::Gateways::JSONAPI}
162
+ class HTTP < Flapjack::Pikelet::Base
157
163
 
158
- def self.create(type, opts = {})
159
- ::Thin::Logging.silent = true
160
- self.new(type, PIKELET_TYPES[type], :config => opts[:config],
161
- :redis_config => opts[:redis_config],
162
- :boot_time => opts[:boot_time])
163
- end
164
-
165
- def initialize(type, pikelet_klass, opts = {})
166
- super(type, pikelet_klass, opts)
164
+ TYPES = ['jsonapi', 'web']
167
165
 
168
- pikelet_klass.instance_variable_set('@config', @config)
169
- pikelet_klass.instance_variable_set('@redis_config', @redis_config)
170
- pikelet_klass.instance_variable_set('@logger', @logger)
166
+ def start
167
+ @pikelet_class.instance_variable_set('@config', @config)
171
168
 
172
169
  if @config
173
- @bind_address = @config['bind_address']
174
- @port = @config['port']
175
- @port = @port.nil? ? nil : @port.to_i
176
- @timeout = @config['timeout']
177
- @timeout = @timeout.nil? ? 300 : @timeout.to_i
170
+ bind_address = @config['bind_address']
171
+ port = @config['port']
172
+ port = port.nil? ? nil : port.to_i
173
+ timeout = @config['timeout']
174
+ timeout = timeout.nil? ? 300 : timeout.to_i
175
+ end
176
+ bind_address = '127.0.0.1' if bind_address.nil?
177
+ port = 3001 if (port.nil? || port <= 0 || port > 65535)
178
+
179
+ super do
180
+ @pikelet_class.start if @pikelet_class.respond_to?(:start)
181
+ @server = ::Puma::Server.new(@pikelet_class)
182
+ @server.binder.add_tcp_listener(bind_address, port)
183
+ yield @server if block_given?
184
+ @server.run(false) # no background run, use current thread
178
185
  end
179
- @bind_address = '0.0.0.0' if @bind_address.nil?
180
- @port = 3001 if (@port.nil? || @port <= 0 || @port > 65535)
181
-
182
- @server = ::Thin::Server.new(@bind_address, @port,
183
- @klass, :signals => false)
184
- @server.timeout = @timeout
185
- end
186
-
187
- def start
188
- super
189
- @klass.start if @klass.respond_to?(:start)
190
- @server.start
191
186
  end
192
187
 
193
188
  # this should only reload if all changes can be applied -- will
194
189
  # return false to log warning otherwise
195
190
  def reload(cfg)
196
- # TODO fail if port changes
197
- @klass.respond_to?(:reload) ?
198
- (@klass.reload(cfg) && super(cfg)) : super(cfg)
191
+ # TODO handle bind_address/port changes by changing listeners?
192
+ return false unless @pikelet_class.respond_to?(:reload)
193
+ super(cfg) { @pikelet_class.reload(cfg) }
199
194
  end
200
195
 
201
196
  def stop
202
- @server.stop!
203
- @klass.stop if @klass.respond_to?(:stop)
204
- super
197
+ super do |thread|
198
+ unless @server.nil?
199
+ Flapjack.logger.info "shutting down server"
200
+ @server.stop(true) # no background stop, wait for requests to finish
201
+ Flapjack.logger.info "shut down server"
202
+ end
203
+ @pikelet_class.stop(thread) if @pikelet_class.respond_to?(:stop)
204
+ end
205
205
  end
206
+ end
206
207
 
207
- def update_status
208
- return @status unless 'stopping'.eql?(@status)
209
- @status = 'stopped' if (@server.backend.size <= 0)
210
- end
208
+ WRAPPERS = [Flapjack::Pikelet::Generic, Flapjack::Pikelet::HTTP]
209
+
210
+ TYPES = {'jsonapi' => [Flapjack::Gateways::JSONAPI],
211
+ 'email' => [Flapjack::Gateways::Email],
212
+ 'notifier' => [Flapjack::Notifier],
213
+ 'processor' => [Flapjack::Processor],
214
+ 'jabber' => [Flapjack::Gateways::Jabber::Bot,
215
+ Flapjack::Gateways::Jabber::Notifier,
216
+ Flapjack::Gateways::Jabber::Interpreter],
217
+ 'oobetet' => [Flapjack::Gateways::Oobetet::Bot,
218
+ Flapjack::Gateways::Oobetet::Notifier],
219
+ 'pagerduty' => [Flapjack::Gateways::PagerDuty::Notifier,
220
+ Flapjack::Gateways::PagerDuty::AckFinder],
221
+ 'slack' => [Flapjack::Gateways::Slack],
222
+ 'sms' => [Flapjack::Gateways::SmsMessagenet],
223
+ 'sms_nexmo' => [Flapjack::Gateways::SmsNexmo],
224
+ 'sms_twilio' => [Flapjack::Gateways::SmsTwilio],
225
+ 'sms_aspsms' => [Flapjack::Gateways::SmsAspsms],
226
+ 'aws_sns' => [Flapjack::Gateways::AwsSns],
227
+ 'web' => [Flapjack::Gateways::Web],
228
+ }
229
+
230
+ def self.is_pikelet?(type)
231
+ TYPES.has_key?(type)
232
+ end
233
+
234
+ def self.create(type, shutdown, opts = {})
235
+ config = opts[:config] || {}
236
+
237
+ types = TYPES[type]
238
+
239
+ return [] if types.nil?
240
+
241
+ created = types.collect {|pikelet_class|
242
+ wrapper = WRAPPERS.detect {|wrap| wrap::TYPES.include?(type) }
243
+ logger_name = if TYPES[type].size == 1
244
+ "flapjack-#{type}"
245
+ else
246
+ "flapjack-#{type}-#{pikelet_class.name.demodulize.underscore}"
247
+ end
248
+ wrapper.new(pikelet_class, shutdown, :logger_name => logger_name,
249
+ :config => config, :boot_time => opts[:boot_time])
250
+ }
251
+ created.each {|c| c.siblings = created - [c] }
252
+ created
211
253
  end
212
254
 
213
255
  end