flapjack 1.6.0 → 2.0.0b1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -6
- data/.gitmodules +1 -1
- data/.rspec +1 -1
- data/.ruby-version +1 -1
- data/.travis.yml +12 -13
- data/CHANGELOG.md +2 -9
- data/CONTRIBUTING.md +7 -2
- data/Gemfile +4 -13
- data/LICENCE +1 -0
- data/README.md +8 -2
- data/Rakefile +2 -2
- data/bin/flapjack +3 -12
- data/build.sh +4 -2
- data/etc/flapjack_config.toml.example +273 -0
- data/features/ack_after_sched_maint.feature +18 -21
- data/features/cli.feature +11 -71
- data/features/cli_flapjack-feed-events.feature +14 -15
- data/features/cli_flapjack-nagios-receiver.feature +12 -41
- data/features/cli_flapper.feature +12 -41
- data/features/cli_purge.feature +5 -6
- data/features/cli_receive-events.feature +6 -7
- data/features/cli_simulate-failed-check.feature +5 -6
- data/features/events.feature +206 -181
- data/features/events_check_names.feature +4 -7
- data/features/notification_rules.feature +144 -223
- data/features/notifications.feature +65 -57
- data/features/rollup.feature +45 -47
- data/features/steps/cli_steps.rb +4 -5
- data/features/steps/events_steps.rb +163 -373
- data/features/steps/notifications_steps.rb +408 -264
- data/features/steps/packaging-lintian_steps.rb +0 -4
- data/features/steps/time_travel_steps.rb +0 -26
- data/features/support/daemons.rb +6 -31
- data/features/support/env.rb +65 -74
- data/flapjack.gemspec +22 -24
- data/lib/flapjack.rb +14 -7
- data/lib/flapjack/cli/flapper.rb +74 -173
- data/lib/flapjack/cli/maintenance.rb +278 -109
- data/lib/flapjack/cli/migrate.rb +950 -0
- data/lib/flapjack/cli/purge.rb +19 -22
- data/lib/flapjack/cli/receiver.rb +150 -326
- data/lib/flapjack/cli/server.rb +8 -235
- data/lib/flapjack/cli/simulate.rb +42 -57
- data/lib/flapjack/configuration.rb +51 -37
- data/lib/flapjack/coordinator.rb +138 -129
- data/lib/flapjack/data/acknowledgement.rb +177 -0
- data/lib/flapjack/data/alert.rb +97 -158
- data/lib/flapjack/data/check.rb +611 -0
- data/lib/flapjack/data/condition.rb +70 -0
- data/lib/flapjack/data/contact.rb +226 -456
- data/lib/flapjack/data/event.rb +96 -184
- data/lib/flapjack/data/extensions/associations.rb +59 -0
- data/lib/flapjack/data/extensions/short_name.rb +25 -0
- data/lib/flapjack/data/medium.rb +428 -0
- data/lib/flapjack/data/metrics.rb +194 -0
- data/lib/flapjack/data/notification.rb +22 -281
- data/lib/flapjack/data/rule.rb +473 -0
- data/lib/flapjack/data/scheduled_maintenance.rb +244 -0
- data/lib/flapjack/data/state.rb +221 -0
- data/lib/flapjack/data/statistic.rb +112 -0
- data/lib/flapjack/data/tag.rb +277 -0
- data/lib/flapjack/data/test_notification.rb +182 -0
- data/lib/flapjack/data/unscheduled_maintenance.rb +159 -0
- data/lib/flapjack/data/validators/id_validator.rb +20 -0
- data/lib/flapjack/exceptions.rb +6 -0
- data/lib/flapjack/filters/acknowledgement.rb +23 -16
- data/lib/flapjack/filters/base.rb +0 -5
- data/lib/flapjack/filters/delays.rb +53 -43
- data/lib/flapjack/filters/ok.rb +23 -14
- data/lib/flapjack/filters/scheduled_maintenance.rb +3 -3
- data/lib/flapjack/filters/unscheduled_maintenance.rb +12 -3
- data/lib/flapjack/gateways/aws_sns.rb +65 -49
- data/lib/flapjack/gateways/aws_sns/alert.text.erb +2 -2
- data/lib/flapjack/gateways/aws_sns/alert_subject.text.erb +2 -2
- data/lib/flapjack/gateways/aws_sns/rollup_subject.text.erb +1 -1
- data/lib/flapjack/gateways/email.rb +107 -90
- data/lib/flapjack/gateways/email/alert.html.erb +19 -18
- data/lib/flapjack/gateways/email/alert.text.erb +20 -14
- data/lib/flapjack/gateways/email/alert_subject.text.erb +2 -1
- data/lib/flapjack/gateways/email/rollup.html.erb +14 -13
- data/lib/flapjack/gateways/email/rollup.text.erb +13 -10
- data/lib/flapjack/gateways/jabber.rb +679 -671
- data/lib/flapjack/gateways/jabber/alert.text.erb +9 -6
- data/lib/flapjack/gateways/jsonapi.rb +164 -350
- data/lib/flapjack/gateways/jsonapi/data/join_descriptor.rb +44 -0
- data/lib/flapjack/gateways/jsonapi/data/method_descriptor.rb +21 -0
- data/lib/flapjack/gateways/jsonapi/helpers/headers.rb +63 -0
- data/lib/flapjack/gateways/jsonapi/helpers/miscellaneous.rb +136 -0
- data/lib/flapjack/gateways/jsonapi/helpers/resources.rb +227 -0
- data/lib/flapjack/gateways/jsonapi/helpers/serialiser.rb +313 -0
- data/lib/flapjack/gateways/jsonapi/helpers/swagger_docs.rb +322 -0
- data/lib/flapjack/gateways/jsonapi/methods/association_delete.rb +115 -0
- data/lib/flapjack/gateways/jsonapi/methods/association_get.rb +288 -0
- data/lib/flapjack/gateways/jsonapi/methods/association_patch.rb +178 -0
- data/lib/flapjack/gateways/jsonapi/methods/association_post.rb +116 -0
- data/lib/flapjack/gateways/jsonapi/methods/metrics.rb +71 -0
- data/lib/flapjack/gateways/jsonapi/methods/resource_delete.rb +119 -0
- data/lib/flapjack/gateways/jsonapi/methods/resource_get.rb +186 -0
- data/lib/flapjack/gateways/jsonapi/methods/resource_patch.rb +239 -0
- data/lib/flapjack/gateways/jsonapi/methods/resource_post.rb +197 -0
- data/lib/flapjack/gateways/jsonapi/middleware/array_param_fixer.rb +27 -0
- data/lib/flapjack/gateways/jsonapi/{rack → middleware}/json_params_parser.rb +7 -6
- data/lib/flapjack/gateways/jsonapi/middleware/request_timestamp.rb +18 -0
- data/lib/flapjack/gateways/oobetet.rb +222 -170
- data/lib/flapjack/gateways/pager_duty.rb +388 -0
- data/lib/flapjack/gateways/pager_duty/alert.text.erb +13 -0
- data/lib/flapjack/gateways/slack.rb +56 -48
- data/lib/flapjack/gateways/slack/alert.text.erb +1 -1
- data/lib/flapjack/gateways/slack/rollup.text.erb +1 -1
- data/lib/flapjack/gateways/sms_aspsms.rb +155 -0
- data/lib/flapjack/gateways/sms_aspsms/alert.text.erb +7 -0
- data/lib/flapjack/gateways/sms_aspsms/rollup.text.erb +2 -0
- data/lib/flapjack/gateways/sms_messagenet.rb +77 -57
- data/lib/flapjack/gateways/sms_messagenet/alert.text.erb +3 -2
- data/lib/flapjack/gateways/sms_nexmo.rb +53 -51
- data/lib/flapjack/gateways/sms_nexmo/alert.text.erb +2 -2
- data/lib/flapjack/gateways/sms_nexmo/rollup.text.erb +1 -1
- data/lib/flapjack/gateways/sms_twilio.rb +79 -62
- data/lib/flapjack/gateways/sms_twilio/alert.text.erb +3 -2
- data/lib/flapjack/gateways/web.rb +437 -345
- data/lib/flapjack/gateways/web/middleware/request_timestamp.rb +18 -0
- data/lib/flapjack/gateways/web/public/css/bootstrap.css +3793 -4340
- data/lib/flapjack/gateways/web/public/css/bootstrap.css.map +1 -0
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.eot +0 -0
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.svg +273 -214
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.woff +0 -0
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/lib/flapjack/gateways/web/public/js/bootstrap.js +1637 -1607
- data/lib/flapjack/gateways/web/public/js/self_stats.js +1 -2
- data/lib/flapjack/gateways/web/views/_pagination.html.erb +19 -0
- data/lib/flapjack/gateways/web/views/check.html.erb +159 -121
- data/lib/flapjack/gateways/web/views/checks.html.erb +82 -41
- data/lib/flapjack/gateways/web/views/contact.html.erb +59 -71
- data/lib/flapjack/gateways/web/views/contacts.html.erb +32 -8
- data/lib/flapjack/gateways/web/views/index.html.erb +2 -2
- data/lib/flapjack/gateways/web/views/{layout.erb → layout.html.erb} +7 -23
- data/lib/flapjack/gateways/web/views/self_stats.html.erb +32 -33
- data/lib/flapjack/gateways/web/views/tag.html.erb +32 -0
- data/lib/flapjack/gateways/web/views/tags.html.erb +51 -0
- data/lib/flapjack/logger.rb +34 -3
- data/lib/flapjack/notifier.rb +180 -112
- data/lib/flapjack/patches.rb +8 -63
- data/lib/flapjack/pikelet.rb +185 -143
- data/lib/flapjack/processor.rb +323 -191
- data/lib/flapjack/record_queue.rb +33 -0
- data/lib/flapjack/redis_proxy.rb +66 -0
- data/lib/flapjack/utility.rb +21 -15
- data/lib/flapjack/version.rb +2 -1
- data/libexec/httpbroker.go +218 -14
- data/libexec/oneoff.go +13 -10
- data/spec/lib/flapjack/configuration_spec.rb +286 -0
- data/spec/lib/flapjack/coordinator_spec.rb +103 -157
- data/spec/lib/flapjack/data/check_spec.rb +175 -0
- data/spec/lib/flapjack/data/contact_spec.rb +26 -349
- data/spec/lib/flapjack/data/event_spec.rb +76 -291
- data/spec/lib/flapjack/data/medium_spec.rb +19 -0
- data/spec/lib/flapjack/data/rule_spec.rb +43 -0
- data/spec/lib/flapjack/data/scheduled_maintenance_spec.rb +976 -0
- data/spec/lib/flapjack/data/unscheduled_maintenance_spec.rb +34 -0
- data/spec/lib/flapjack/gateways/aws_sns_spec.rb +111 -60
- data/spec/lib/flapjack/gateways/email_spec.rb +194 -161
- data/spec/lib/flapjack/gateways/jabber_spec.rb +961 -162
- data/spec/lib/flapjack/gateways/jsonapi/methods/check_links_spec.rb +155 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/checks_spec.rb +426 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/contact_links_spec.rb +217 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/contacts_spec.rb +425 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/events_spec.rb +271 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/media_spec.rb +257 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/medium_links_spec.rb +163 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/metrics_spec.rb +8 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/rule_links_spec.rb +212 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/rules_spec.rb +289 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/scheduled_maintenance_links_spec.rb +49 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/scheduled_maintenances_spec.rb +242 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/tag_links_spec.rb +274 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/tags_spec.rb +302 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/unscheduled_maintenance_links_spec.rb +49 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/unscheduled_maintenances_spec.rb +339 -0
- data/spec/lib/flapjack/gateways/jsonapi_spec.rb +1 -1
- data/spec/lib/flapjack/gateways/oobetet_spec.rb +151 -79
- data/spec/lib/flapjack/gateways/pager_duty_spec.rb +353 -0
- data/spec/lib/flapjack/gateways/slack_spec.rb +53 -53
- data/spec/lib/flapjack/gateways/sms_aspsms_spec.rb +106 -0
- data/spec/lib/flapjack/gateways/sms_messagenet_spec.rb +111 -54
- data/spec/lib/flapjack/gateways/sms_nexmo_spec.rb +50 -51
- data/spec/lib/flapjack/gateways/sms_twilio_spec.rb +108 -48
- data/spec/lib/flapjack/gateways/web_spec.rb +144 -216
- data/spec/lib/flapjack/notifier_spec.rb +132 -1
- data/spec/lib/flapjack/pikelet_spec.rb +111 -50
- data/spec/lib/flapjack/processor_spec.rb +210 -40
- data/spec/lib/flapjack/redis_proxy_spec.rb +45 -0
- data/spec/lib/flapjack/utility_spec.rb +11 -15
- data/spec/service_consumers/fixture_data.rb +547 -0
- data/spec/service_consumers/pact_helper.rb +21 -32
- data/spec/service_consumers/pacts/flapjack-diner_v2.0.json +4652 -0
- data/spec/service_consumers/provider_states_for_flapjack-diner.rb +279 -322
- data/spec/service_consumers/provider_support.rb +8 -0
- data/spec/spec_helper.rb +34 -44
- data/spec/support/erb_view_helper.rb +1 -1
- data/spec/support/factories.rb +58 -0
- data/spec/support/jsonapi_helper.rb +15 -26
- data/spec/support/mock_logger.rb +43 -0
- data/spec/support/xmpp_comparable.rb +24 -0
- data/src/flapjack/transport_test.go +30 -1
- data/tasks/dump_keys.rake +82 -0
- data/tasks/events.rake +7 -7
- data/tasks/support/flapjack_config_benchmark.toml +28 -0
- data/tasks/support/flapjack_config_benchmark.yaml +0 -2
- metadata +175 -222
- data/Guardfile +0 -14
- data/etc/flapjack_config.yaml.example +0 -477
- data/features/cli_flapjack-populator.feature +0 -90
- data/features/support/silent_system.rb +0 -4
- data/lib/flapjack/cli/import.rb +0 -108
- data/lib/flapjack/data/entity.rb +0 -652
- data/lib/flapjack/data/entity_check.rb +0 -1044
- data/lib/flapjack/data/message.rb +0 -56
- data/lib/flapjack/data/migration.rb +0 -234
- data/lib/flapjack/data/notification_rule.rb +0 -425
- data/lib/flapjack/data/semaphore.rb +0 -44
- data/lib/flapjack/data/tagged.rb +0 -48
- data/lib/flapjack/gateways/jsonapi/check_methods.rb +0 -206
- data/lib/flapjack/gateways/jsonapi/check_presenter.rb +0 -221
- data/lib/flapjack/gateways/jsonapi/contact_methods.rb +0 -186
- data/lib/flapjack/gateways/jsonapi/entity_methods.rb +0 -223
- data/lib/flapjack/gateways/jsonapi/medium_methods.rb +0 -185
- data/lib/flapjack/gateways/jsonapi/metrics_methods.rb +0 -132
- data/lib/flapjack/gateways/jsonapi/notification_rule_methods.rb +0 -141
- data/lib/flapjack/gateways/jsonapi/pagerduty_credential_methods.rb +0 -139
- data/lib/flapjack/gateways/jsonapi/report_methods.rb +0 -146
- data/lib/flapjack/gateways/pagerduty.rb +0 -318
- data/lib/flapjack/gateways/pagerduty/alert.text.erb +0 -10
- data/lib/flapjack/gateways/web/public/css/select2-bootstrap.css +0 -87
- data/lib/flapjack/gateways/web/public/css/select2.css +0 -615
- data/lib/flapjack/gateways/web/public/css/tablesort.css +0 -67
- data/lib/flapjack/gateways/web/public/img/select2-spinner.gif +0 -0
- data/lib/flapjack/gateways/web/public/img/select2.png +0 -0
- data/lib/flapjack/gateways/web/public/img/select2x2.png +0 -0
- data/lib/flapjack/gateways/web/public/js/backbone.js +0 -1581
- data/lib/flapjack/gateways/web/public/js/backbone.jsonapi.js +0 -322
- data/lib/flapjack/gateways/web/public/js/flapjack.js +0 -82
- data/lib/flapjack/gateways/web/public/js/jquery.tablesorter.js +0 -1640
- data/lib/flapjack/gateways/web/public/js/jquery.tablesorter.widgets.js +0 -1390
- data/lib/flapjack/gateways/web/public/js/modules/contact.js +0 -520
- data/lib/flapjack/gateways/web/public/js/modules/entity.js +0 -28
- data/lib/flapjack/gateways/web/public/js/modules/medium.js +0 -40
- data/lib/flapjack/gateways/web/public/js/select2.js +0 -3397
- data/lib/flapjack/gateways/web/public/js/tablesort.js +0 -44
- data/lib/flapjack/gateways/web/public/js/underscore.js +0 -1276
- data/lib/flapjack/gateways/web/views/edit_contacts.html.erb +0 -173
- data/lib/flapjack/gateways/web/views/entities.html.erb +0 -30
- data/lib/flapjack/gateways/web/views/entity.html.erb +0 -51
- data/lib/flapjack/rack_logger.rb +0 -47
- data/lib/flapjack/redis_pool.rb +0 -42
- data/spec/lib/flapjack/data/entity_check_spec.rb +0 -1418
- data/spec/lib/flapjack/data/entity_spec.rb +0 -872
- data/spec/lib/flapjack/data/message_spec.rb +0 -30
- data/spec/lib/flapjack/data/migration_spec.rb +0 -104
- data/spec/lib/flapjack/data/notification_rule_spec.rb +0 -232
- data/spec/lib/flapjack/data/notification_spec.rb +0 -53
- data/spec/lib/flapjack/data/semaphore_spec.rb +0 -24
- data/spec/lib/flapjack/filters/acknowledgement_spec.rb +0 -6
- data/spec/lib/flapjack/filters/delays_spec.rb +0 -6
- data/spec/lib/flapjack/filters/ok_spec.rb +0 -6
- data/spec/lib/flapjack/filters/scheduled_maintenance_spec.rb +0 -6
- data/spec/lib/flapjack/filters/unscheduled_maintenance_spec.rb +0 -6
- data/spec/lib/flapjack/gateways/jsonapi/check_methods_spec.rb +0 -315
- data/spec/lib/flapjack/gateways/jsonapi/check_presenter_spec.rb +0 -223
- data/spec/lib/flapjack/gateways/jsonapi/contact_methods_spec.rb +0 -131
- data/spec/lib/flapjack/gateways/jsonapi/entity_methods_spec.rb +0 -389
- data/spec/lib/flapjack/gateways/jsonapi/medium_methods_spec.rb +0 -231
- data/spec/lib/flapjack/gateways/jsonapi/notification_rule_methods_spec.rb +0 -169
- data/spec/lib/flapjack/gateways/jsonapi/pagerduty_credential_methods_spec.rb +0 -114
- data/spec/lib/flapjack/gateways/jsonapi/report_methods_spec.rb +0 -590
- data/spec/lib/flapjack/gateways/pagerduty_spec.rb +0 -249
- data/spec/lib/flapjack/gateways/web/views/check.html.erb_spec.rb +0 -21
- data/spec/lib/flapjack/gateways/web/views/contact.html.erb_spec.rb +0 -24
- data/spec/lib/flapjack/gateways/web/views/index.html.erb_spec.rb +0 -16
- data/spec/lib/flapjack/redis_pool_spec.rb +0 -29
- data/spec/service_consumers/pacts/flapjack-diner_v1.0.json +0 -4702
- data/tasks/entities.rake +0 -151
- data/tasks/profile.rake +0 -282
- data/tmp/acknowledge.rb +0 -13
- data/tmp/create_config_yaml.rb +0 -16
- data/tmp/create_event_ok.rb +0 -30
- data/tmp/create_event_unknown.rb +0 -30
- data/tmp/create_events_failure.rb +0 -34
- data/tmp/create_events_ok.rb +0 -32
- data/tmp/create_events_ok_fail_ack_ok.rb +0 -53
- data/tmp/create_events_ok_failure.rb +0 -41
- data/tmp/create_events_ok_failure_ack.rb +0 -53
- data/tmp/dummy_contacts.json +0 -43
- data/tmp/dummy_entities.json +0 -37
- data/tmp/generate_nagios_test_hosts.rb +0 -16
- data/tmp/notification_rules.rb +0 -73
- data/tmp/parse_config_yaml.rb +0 -7
- data/tmp/redis_find_spurious_unknown_states.rb +0 -52
- data/tmp/test_json_post.rb +0 -19
- 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
|
-
|
data/lib/flapjack/data/tagged.rb
DELETED
@@ -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
|