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.
- 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
data/lib/flapjack/data/event.rb
CHANGED
|
@@ -1,35 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
require 'flapjack'
|
|
4
|
-
|
|
5
|
-
require 'flapjack/data/migration'
|
|
3
|
+
require 'flapjack/redis_proxy'
|
|
6
4
|
|
|
7
5
|
module Flapjack
|
|
8
6
|
module Data
|
|
9
7
|
class Event
|
|
10
8
|
|
|
11
|
-
attr_accessor :counter, :id_hash
|
|
9
|
+
attr_accessor :counter, :id_hash
|
|
12
10
|
|
|
13
|
-
attr_reader :
|
|
14
|
-
:initial_failure_delay, :repeat_failure_delay
|
|
11
|
+
attr_reader :id, :summary, :details, :acknowledgement_id, :perfdata
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
# type was a required key in v1, but is superfluous
|
|
14
|
+
# tags are now ignored, tags on the checks are used for rule matching
|
|
15
|
+
REQUIRED_KEYS = %w(state check)
|
|
16
|
+
OPTIONAL_KEYS = %w(entity time initial_failure_delay
|
|
17
|
+
repeat_failure_delay summary details acknowledgement_id duration tags
|
|
18
|
+
perfdata type)
|
|
20
19
|
|
|
21
20
|
VALIDATIONS = {
|
|
22
|
-
proc {|e| e['type'].is_a?(String) &&
|
|
23
|
-
['service', 'action'].include?(e['type'].downcase) } =>
|
|
24
|
-
"type must be either 'service' or 'action'",
|
|
25
|
-
|
|
26
21
|
proc {|e| e['state'].is_a?(String) &&
|
|
27
22
|
['ok', 'warning', 'critical', 'unknown', 'acknowledgement',
|
|
28
|
-
'test_notifications'].include?(e['state'].downcase)
|
|
23
|
+
'test_notifications'].include?(e['state'].downcase) ||
|
|
24
|
+
!(e['state'] =~ /\Atest_notifications(?:\s+#{Flapjack::Data::Condition.unhealthy.keys.join('|')})?\z/).nil? } =>
|
|
29
25
|
"state must be one of 'ok', 'warning', 'critical', 'unknown', " +
|
|
30
|
-
"'acknowledgement' or 'test_notifications'",
|
|
26
|
+
"'acknowledgement', 'test_notifications', or 'test_notifications [problem]' ",
|
|
31
27
|
|
|
32
|
-
proc {|e| e['entity'].is_a?(String) } =>
|
|
28
|
+
proc {|e| e['entity'].nil? || e['entity'].is_a?(String) } =>
|
|
33
29
|
"entity must be a string",
|
|
34
30
|
|
|
35
31
|
proc {|e| e['check'].is_a?(String) } =>
|
|
@@ -70,93 +66,25 @@ module Flapjack
|
|
|
70
66
|
"duration must be a positive integer, or a string castable to one",
|
|
71
67
|
|
|
72
68
|
proc {|e| e['tags'].nil? ||
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
(e['tags'].is_a?(Array) &&
|
|
70
|
+
e['tags'].all? {|tag| tag.is_a?(String)}) } =>
|
|
75
71
|
"tags must be an array of strings",
|
|
76
72
|
}
|
|
77
73
|
|
|
78
|
-
# Helper method for getting the next event.
|
|
79
|
-
#
|
|
80
|
-
# Has a blocking and non-blocking method signature.
|
|
81
|
-
#
|
|
82
|
-
# Calling next with :block => true, we wait indefinitely for events coming
|
|
83
|
-
# from other systems. This is the default behaviour.
|
|
84
|
-
#
|
|
85
|
-
# Calling next with :block => false, will return a nil if there are no
|
|
86
|
-
# events on the queue.
|
|
87
|
-
def self.next(queue, opts = {})
|
|
88
|
-
raise "Redis connection not set" unless redis = opts[:redis]
|
|
89
|
-
|
|
90
|
-
defaults = { :block => true,
|
|
91
|
-
:archive_events => false,
|
|
92
|
-
:events_archive_maxage => (3 * 60 * 60) }
|
|
93
|
-
options = defaults.merge(opts)
|
|
94
|
-
|
|
95
|
-
archive_dest = nil
|
|
96
|
-
base_time_str = Time.now.utc.strftime("%Y%m%d%H")
|
|
97
|
-
|
|
98
|
-
if options[:archive_events]
|
|
99
|
-
archive_dest = "events_archive:#{base_time_str}"
|
|
100
|
-
unless @previous_base_time_str == base_time_str
|
|
101
|
-
Flapjack::Data::Migration.purge_expired_archive_index(:redis => redis)
|
|
102
|
-
end
|
|
103
|
-
@previous_base_time_str = base_time_str
|
|
104
|
-
if options[:block]
|
|
105
|
-
raw = redis.brpoplpush(queue, archive_dest, 0)
|
|
106
|
-
else
|
|
107
|
-
raw = redis.rpoplpush(queue, archive_dest)
|
|
108
|
-
return unless raw
|
|
109
|
-
end
|
|
110
|
-
redis.sadd("known_events_archive_keys", archive_dest)
|
|
111
|
-
elsif options[:block]
|
|
112
|
-
raw = redis.brpop(queue, 0)[1]
|
|
113
|
-
else
|
|
114
|
-
raw = redis.rpop(queue)
|
|
115
|
-
return unless raw
|
|
116
|
-
end
|
|
117
|
-
parsed = parse_and_validate(raw, :logger => options[:logger])
|
|
118
|
-
if parsed.nil?
|
|
119
|
-
# either bad json or invalid data -- in either case we'll
|
|
120
|
-
# store the raw data in a rejected list
|
|
121
|
-
rejected_dest = "events_rejected:#{base_time_str}"
|
|
122
|
-
if options[:archive_events]
|
|
123
|
-
redis.multi do |multi|
|
|
124
|
-
multi.lrem(archive_dest, 1, raw)
|
|
125
|
-
multi.lpush(rejected_dest, raw)
|
|
126
|
-
end
|
|
127
|
-
redis.expire(archive_dest, options[:events_archive_maxage])
|
|
128
|
-
else
|
|
129
|
-
redis.lpush(rejected_dest, raw)
|
|
130
|
-
end
|
|
131
|
-
return
|
|
132
|
-
elsif options[:archive_events]
|
|
133
|
-
redis.expire(archive_dest, options[:events_archive_maxage])
|
|
134
|
-
end
|
|
135
|
-
self.new(parsed)
|
|
136
|
-
end
|
|
137
|
-
|
|
138
74
|
def self.parse_and_validate(raw, opts = {})
|
|
139
75
|
errors = []
|
|
140
|
-
if parsed =
|
|
141
|
-
return if 'noop'.eql?(parsed['type'])
|
|
76
|
+
if parsed = Flapjack.load_json(raw)
|
|
142
77
|
if parsed.is_a?(Hash)
|
|
143
78
|
errors = validation_errors_for_hash(parsed, opts)
|
|
144
79
|
else
|
|
145
80
|
errors << "Event must be a JSON hash, see http://flapjack.io/docs/1.0/development/DATA_STRUCTURES#event-queue"
|
|
146
81
|
end
|
|
147
|
-
return parsed
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
if opts[:logger]
|
|
151
|
-
error_str = errors.nil? ? '' : errors.join(', ')
|
|
152
|
-
opts[:logger].error("Invalid event data received, #{error_str} #{parsed.inspect}")
|
|
82
|
+
return [parsed, errors]
|
|
153
83
|
end
|
|
154
|
-
nil
|
|
155
|
-
rescue
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
end
|
|
159
|
-
nil
|
|
84
|
+
[nil, errors]
|
|
85
|
+
rescue JSON::JSONError => e
|
|
86
|
+
errors << "Error deserialising event json: #{e}, raw json: #{raw.inspect}"
|
|
87
|
+
[nil, errors]
|
|
160
88
|
end
|
|
161
89
|
|
|
162
90
|
def self.validation_errors_for_hash(hash, opts = {})
|
|
@@ -185,67 +113,84 @@ module Flapjack
|
|
|
185
113
|
# creates, or modifies, an event object and adds it to the events list in redis
|
|
186
114
|
# 'entity' => entity,
|
|
187
115
|
# 'check' => check,
|
|
116
|
+
# 'time' => timestamp,
|
|
117
|
+
# 'initial_failure_delay' => initial_failure_delay,
|
|
118
|
+
# 'repeat_failure_delay' => repeat_failure_delay
|
|
188
119
|
# 'type' => 'service',
|
|
189
120
|
# 'state' => state,
|
|
190
121
|
# 'summary' => check_output,
|
|
191
122
|
# 'details' => check_long_output,
|
|
192
|
-
# 'perfdata' => perf_data
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
123
|
+
# 'perfdata' => perf_data
|
|
124
|
+
def self.push(queue, event)
|
|
125
|
+
event['time'] = Time.now.to_i if event['time'].nil?
|
|
126
|
+
|
|
127
|
+
begin
|
|
128
|
+
event_json = Flapjack.dump_json(event)
|
|
129
|
+
rescue JSON::JSONError => e
|
|
130
|
+
Flapjack.logger.warn("Error serialising event json: #{e}, event: #{event.inspect}")
|
|
131
|
+
event_json = nil
|
|
132
|
+
end
|
|
198
133
|
|
|
199
|
-
|
|
200
|
-
|
|
134
|
+
if event_json
|
|
135
|
+
Flapjack.redis.multi do
|
|
136
|
+
Flapjack.redis.lpush(queue, event_json)
|
|
137
|
+
Flapjack.redis.lpush("#{queue}_actions", "+")
|
|
138
|
+
end
|
|
139
|
+
end
|
|
201
140
|
end
|
|
202
141
|
|
|
203
142
|
# Provide a count of the number of events on the queue to be processed.
|
|
204
|
-
def self.pending_count(queue
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
'acknowledgement_id' => opts[:acknowledgement_id]
|
|
218
|
-
}
|
|
219
|
-
add(data, :redis => opts[:redis])
|
|
143
|
+
def self.pending_count(queue)
|
|
144
|
+
Flapjack.redis.llen(queue)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def self.create_acknowledgements(queue, checks, opts = {})
|
|
148
|
+
raise "Check(s) must be provided" if checks.nil?
|
|
149
|
+
checks.each do |check|
|
|
150
|
+
self.push(queue, 'state' => 'acknowledgement',
|
|
151
|
+
'check' => check.name,
|
|
152
|
+
'summary' => opts[:summary],
|
|
153
|
+
'duration' => opts[:duration],
|
|
154
|
+
'acknowledgement_id' => opts[:acknowledgement_id])
|
|
155
|
+
end
|
|
220
156
|
end
|
|
221
157
|
|
|
222
|
-
def self.test_notifications(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
158
|
+
def self.test_notifications(queue, checks, opts = {})
|
|
159
|
+
raise "Check(s) must be provided" if checks.nil?
|
|
160
|
+
condition = opts[:condition] || 'critical'
|
|
161
|
+
unless Flapjack::Data::Condition.unhealthy.keys.include?(condition)
|
|
162
|
+
raise "Condition must be a problem"
|
|
163
|
+
end
|
|
164
|
+
checks.each do |check|
|
|
165
|
+
self.push(queue, 'state' => "test_notifications #{condition}",
|
|
166
|
+
'check' => check.name,
|
|
167
|
+
'summary' => opts[:summary],
|
|
168
|
+
'details' => opts[:details])
|
|
169
|
+
end
|
|
231
170
|
end
|
|
232
171
|
|
|
233
172
|
def initialize(attrs = {})
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
173
|
+
@id = if attrs['entity'].nil?
|
|
174
|
+
attrs['check']
|
|
175
|
+
else
|
|
176
|
+
"#{attrs['entity']}:#{attrs['check']}"
|
|
177
|
+
end
|
|
178
|
+
[:state, :time, :initial_failure_delay, :repeat_failure_delay,
|
|
179
|
+
:summary, :details, :perfdata, :acknowledgement_id,
|
|
180
|
+
:duration].each do |key|
|
|
237
181
|
|
|
238
|
-
instance_variable_set("@#{key}",
|
|
182
|
+
instance_variable_set("@#{key.to_s}", attrs[key.to_s])
|
|
239
183
|
end
|
|
240
|
-
# summary
|
|
241
|
-
@summary
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
184
|
+
# summary, details and perfdata are optional. set to nil if they only contain whitespace
|
|
185
|
+
['@summary', '@details', '@perfdata'].each do |inst|
|
|
186
|
+
value = instance_variable_get(inst)
|
|
187
|
+
v = if value.is_a?(String)
|
|
188
|
+
vs = value.strip
|
|
189
|
+
vs.empty? ? nil : vs
|
|
190
|
+
else
|
|
191
|
+
nil
|
|
192
|
+
end
|
|
193
|
+
instance_variable_set(inst, v)
|
|
249
194
|
end
|
|
250
195
|
end
|
|
251
196
|
|
|
@@ -254,54 +199,21 @@ module Flapjack
|
|
|
254
199
|
@state.downcase
|
|
255
200
|
end
|
|
256
201
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
return unless @duration
|
|
264
|
-
@duration.to_i
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def time
|
|
268
|
-
return unless @time
|
|
269
|
-
@time.to_i
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
def id
|
|
273
|
-
(entity || '-') + ':' + (check || '-')
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
def type
|
|
277
|
-
return unless @type
|
|
278
|
-
@type.downcase
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
def service?
|
|
282
|
-
type == 'service'
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
def acknowledgement?
|
|
286
|
-
(type == 'action') && (state == 'acknowledgement')
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
def test_notifications?
|
|
290
|
-
(type == 'action') && (state == 'test_notifications')
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
def ok?
|
|
294
|
-
(state == 'ok') || (state == 'up')
|
|
202
|
+
[:time, :initial_failure_delay, :repeat_failure_delay, :duration].each do |num_prop|
|
|
203
|
+
define_method(num_prop) do
|
|
204
|
+
prop = instance_variable_get("@#{num_prop}")
|
|
205
|
+
return if prop.nil?
|
|
206
|
+
prop.to_i
|
|
207
|
+
end
|
|
295
208
|
end
|
|
296
209
|
|
|
297
|
-
def
|
|
298
|
-
|
|
210
|
+
def dump
|
|
211
|
+
return @dump unless @dump.nil?
|
|
212
|
+
@dump = "#{id}, #{state}"
|
|
213
|
+
@dump << ", #{summary}" unless summary.nil?
|
|
214
|
+
@dump << ", #{Time.at(time).to_s}" unless time.nil?
|
|
299
215
|
end
|
|
300
|
-
|
|
301
|
-
# # Not used anywhere
|
|
302
|
-
# def unreachable?
|
|
303
|
-
# state == 'unreachable'
|
|
304
|
-
# end
|
|
305
216
|
end
|
|
306
217
|
end
|
|
307
218
|
end
|
|
219
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'active_support/concern'
|
|
4
|
+
require 'active_support/inflector'
|
|
5
|
+
require 'active_support/core_ext/hash/slice'
|
|
6
|
+
|
|
7
|
+
require 'sinatra/base'
|
|
8
|
+
|
|
9
|
+
require 'flapjack/gateways/jsonapi/data/join_descriptor'
|
|
10
|
+
require 'flapjack/gateways/jsonapi/data/method_descriptor'
|
|
11
|
+
|
|
12
|
+
module Flapjack
|
|
13
|
+
module Data
|
|
14
|
+
module Extensions
|
|
15
|
+
module Associations
|
|
16
|
+
|
|
17
|
+
extend ActiveSupport::Concern
|
|
18
|
+
|
|
19
|
+
module ClassMethods
|
|
20
|
+
|
|
21
|
+
def jsonapi_lock_method(http_method, locks = nil, &block)
|
|
22
|
+
locks ||= []
|
|
23
|
+
|
|
24
|
+
if :delete.eql?(http_method)
|
|
25
|
+
# all associations, not just the ones exposed via JSONAPI
|
|
26
|
+
self.send(:with_association_data) do |assoc_data|
|
|
27
|
+
assoc_data.each_pair do |name, data|
|
|
28
|
+
locks |= [data.data_klass] + data.related_klasses
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
locks |= jsonapi_associations.values.select {|a|
|
|
33
|
+
!a.type.nil?
|
|
34
|
+
}.map(&:lock_klasses).reduce([], :|)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if locks.empty?
|
|
38
|
+
self.lock(&block)
|
|
39
|
+
else
|
|
40
|
+
locks.sort_by!(&:name)
|
|
41
|
+
self.lock(*locks, &block)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def populate_association_data(jsonapi_assoc)
|
|
46
|
+
# SMELL mucking about with a zermelo protected method...
|
|
47
|
+
self.send(:with_association_data) do |assoc_data|
|
|
48
|
+
assoc_data.each_pair do |name, data|
|
|
49
|
+
ja = jsonapi_assoc[name.to_sym]
|
|
50
|
+
next if ja.nil?
|
|
51
|
+
ja.association_data = data
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
require 'active_support/concern'
|
|
6
|
+
|
|
7
|
+
require 'swagger/blocks'
|
|
8
|
+
|
|
9
|
+
module Flapjack
|
|
10
|
+
module Data
|
|
11
|
+
module Extensions
|
|
12
|
+
module ShortName
|
|
13
|
+
extend ActiveSupport::Concern
|
|
14
|
+
|
|
15
|
+
module ClassMethods
|
|
16
|
+
|
|
17
|
+
def short_model_name
|
|
18
|
+
ActiveModel::Name.new(self, Flapjack::Data, self.name.demodulize)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'swagger/blocks'
|
|
4
|
+
|
|
5
|
+
require 'zermelo/records/redis'
|
|
6
|
+
|
|
7
|
+
require 'flapjack/data/alert'
|
|
8
|
+
require 'flapjack/data/check'
|
|
9
|
+
require 'flapjack/data/contact'
|
|
10
|
+
require 'flapjack/data/rule'
|
|
11
|
+
require 'flapjack/data/scheduled_maintenance'
|
|
12
|
+
require 'flapjack/data/unscheduled_maintenance'
|
|
13
|
+
|
|
14
|
+
require 'flapjack/data/extensions/associations'
|
|
15
|
+
require 'flapjack/data/extensions/short_name'
|
|
16
|
+
require 'flapjack/data/validators/id_validator'
|
|
17
|
+
|
|
18
|
+
require 'flapjack/gateways/jsonapi/data/join_descriptor'
|
|
19
|
+
require 'flapjack/gateways/jsonapi/data/method_descriptor'
|
|
20
|
+
|
|
21
|
+
module Flapjack
|
|
22
|
+
|
|
23
|
+
module Data
|
|
24
|
+
|
|
25
|
+
class Medium
|
|
26
|
+
|
|
27
|
+
include Zermelo::Records::RedisSet
|
|
28
|
+
include ActiveModel::Serializers::JSON
|
|
29
|
+
self.include_root_in_json = false
|
|
30
|
+
include Swagger::Blocks
|
|
31
|
+
|
|
32
|
+
include Flapjack::Data::Extensions::Associations
|
|
33
|
+
include Flapjack::Data::Extensions::ShortName
|
|
34
|
+
|
|
35
|
+
TRANSPORTS = [
|
|
36
|
+
'email',
|
|
37
|
+
'jabber',
|
|
38
|
+
'pagerduty',
|
|
39
|
+
'sms',
|
|
40
|
+
'slack',
|
|
41
|
+
'sms_twilio',
|
|
42
|
+
'sms_nexmo',
|
|
43
|
+
'sms_aspsms',
|
|
44
|
+
'sns'
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
define_attributes :transport => :string,
|
|
48
|
+
:address => :string,
|
|
49
|
+
:interval => :integer,
|
|
50
|
+
:rollup_threshold => :integer,
|
|
51
|
+
:pagerduty_subdomain => :string,
|
|
52
|
+
:pagerduty_token => :string,
|
|
53
|
+
:pagerduty_ack_duration => :integer,
|
|
54
|
+
:last_rollup_type => :string
|
|
55
|
+
|
|
56
|
+
belongs_to :contact, :class_name => 'Flapjack::Data::Contact',
|
|
57
|
+
:inverse_of => :media
|
|
58
|
+
|
|
59
|
+
has_and_belongs_to_many :rules, :class_name => 'Flapjack::Data::Rule',
|
|
60
|
+
:inverse_of => :media
|
|
61
|
+
|
|
62
|
+
# this can be called from the API (with no args) or from notifier.rb
|
|
63
|
+
# (which will pass an effective time)
|
|
64
|
+
def alerting_checks(opts = {})
|
|
65
|
+
time = opts[:time] || Time.now
|
|
66
|
+
init_scope = Flapjack::Data::Check.intersect(:enabled => true, :alertable => true)
|
|
67
|
+
ret = checks(:initial_scope => init_scope,
|
|
68
|
+
:time => Time.now)
|
|
69
|
+
|
|
70
|
+
return Flapjack::Data::Check.empty if ret.empty?
|
|
71
|
+
|
|
72
|
+
start_range = Zermelo::Filters::IndexRange.new(nil, time, :by_score => true)
|
|
73
|
+
end_range = Zermelo::Filters::IndexRange.new(time, nil, :by_score => true)
|
|
74
|
+
|
|
75
|
+
sched_maint_check_ids = Flapjack::Data::ScheduledMaintenance.
|
|
76
|
+
intersect(:start_time => start_range, :end_time => end_range).
|
|
77
|
+
associated_ids_for(:check).values
|
|
78
|
+
|
|
79
|
+
ret = ret.diff(:id => sched_maint_check_ids) unless sched_maint_check_ids.empty?
|
|
80
|
+
|
|
81
|
+
unsched_maint_check_ids = Flapjack::Data::UnscheduledMaintenance.
|
|
82
|
+
intersect(:start_time => start_range, :end_time => end_range).
|
|
83
|
+
associated_ids_for(:check).values
|
|
84
|
+
|
|
85
|
+
ret = ret.diff(:id => unsched_maint_check_ids) unless unsched_maint_check_ids.empty?
|
|
86
|
+
ret
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def checks(opts = {})
|
|
90
|
+
time_zone = self.contact.time_zone
|
|
91
|
+
time = opts[:time] || Time.now
|
|
92
|
+
init_scope = opts[:initial_scope] || Flapjack::Data::Check.intersect(:enabled => true)
|
|
93
|
+
|
|
94
|
+
# TODO maybe fold time validation into 'matching_checks'
|
|
95
|
+
global_rejector_ids = self.rules.intersect(:enabled => true, :blackhole => true,
|
|
96
|
+
:strategy => 'global').select {|rejector|
|
|
97
|
+
|
|
98
|
+
rejector.is_occurring_at?(time, time_zone)
|
|
99
|
+
}.map(&:id)
|
|
100
|
+
|
|
101
|
+
unless global_rejector_ids.empty?
|
|
102
|
+
# global blackhole
|
|
103
|
+
return Flapjack::Data::Check.empty
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
rejector_ids = self.rules.intersect(:enabled => true, :blackhole => true,
|
|
107
|
+
:strategy => ['all_tags', 'any_tag', 'no_tag']).select {|rejector|
|
|
108
|
+
|
|
109
|
+
rejector.is_occurring_at?(time, time_zone)
|
|
110
|
+
}.map(&:id)
|
|
111
|
+
|
|
112
|
+
acceptors = self.rules.intersect(:enabled => true, :blackhole => false).select {|acceptor|
|
|
113
|
+
acceptor.is_occurring_at?(time, time_zone)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
# no positives
|
|
117
|
+
return Flapjack::Data::Check.empty if acceptors.empty?
|
|
118
|
+
|
|
119
|
+
ret = init_scope
|
|
120
|
+
|
|
121
|
+
if acceptors.none? {|a| 'global'.eql?(a.strategy) }
|
|
122
|
+
# if no global acceptor, scope by tags for acceptors
|
|
123
|
+
acceptor_checks = Flapjack::Data::Rule.matching_checks(acceptors.map(&:id))
|
|
124
|
+
ret = ret.intersect(:id => acceptor_checks)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# then exclude by checks with tags matching rejector, if any
|
|
128
|
+
rejector_checks = Flapjack::Data::Rule.matching_checks(rejector_ids)
|
|
129
|
+
unless rejector_checks.empty?
|
|
130
|
+
ret = ret.diff(:id => rejector_checks)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
ret
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
has_many :alerts, :class_name => 'Flapjack::Data::Alert', :inverse_of => :medium
|
|
137
|
+
|
|
138
|
+
belongs_to :last_state, :class_name => 'Flapjack::Data::State',
|
|
139
|
+
:inverse_of => :latest_media, :after_clear => :destroy_state
|
|
140
|
+
|
|
141
|
+
def self.destroy_state(medium_id, st_id)
|
|
142
|
+
# won't be deleted if still referenced elsewhere -- see the State
|
|
143
|
+
# before_destroy callback
|
|
144
|
+
Flapjack::Data::State.intersect(:id => st_id).destroy_all
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
index_by :transport
|
|
148
|
+
|
|
149
|
+
validates :transport, :presence => true,
|
|
150
|
+
:inclusion => {:in => Flapjack::Data::Medium::TRANSPORTS }
|
|
151
|
+
|
|
152
|
+
validates :address, :presence => true
|
|
153
|
+
|
|
154
|
+
validates :interval, :presence => true,
|
|
155
|
+
:numericality => {:greater_than_or_equal_to => 0, :only_integer => true},
|
|
156
|
+
:unless => proc {|m| 'pagerduty'.eql?(m.transport) }
|
|
157
|
+
|
|
158
|
+
validates :rollup_threshold, :allow_nil => true,
|
|
159
|
+
:numericality => {:greater_than => 0, :only_integer => true},
|
|
160
|
+
:unless => proc {|m| 'pagerduty'.eql?(m.transport) }
|
|
161
|
+
|
|
162
|
+
validates_each :interval, :rollup_threshold,
|
|
163
|
+
:if => proc {|m| 'pagerduty'.eql?(m.transport) } do |record, att, value|
|
|
164
|
+
|
|
165
|
+
record.errors.add(att, 'must be nil') unless value.nil?
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
validates :pagerduty_subdomain, :presence => true,
|
|
169
|
+
:if => proc {|m| 'pagerduty'.eql?(m.transport) }
|
|
170
|
+
|
|
171
|
+
validates :pagerduty_token, :presence => true,
|
|
172
|
+
:if => proc {|m| 'pagerduty'.eql?(m.transport) }
|
|
173
|
+
|
|
174
|
+
validates :pagerduty_ack_duration, :allow_nil => true,
|
|
175
|
+
:numericality => {:greater_than => 0, :only_integer => true},
|
|
176
|
+
:if => proc {|m| 'pagerduty'.eql?(m.transport) }
|
|
177
|
+
|
|
178
|
+
validates_each :pagerduty_subdomain, :pagerduty_token,
|
|
179
|
+
:pagerduty_ack_duration,
|
|
180
|
+
:unless => proc {|m| 'pagerduty'.eql?(m.transport) } do |record, att, value|
|
|
181
|
+
record.errors.add(att, 'must be nil') unless value.nil?
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
validates_with Flapjack::Data::Validators::IdValidator
|
|
185
|
+
|
|
186
|
+
swagger_schema :Medium do
|
|
187
|
+
key :required, [:id, :type, :transport]
|
|
188
|
+
|
|
189
|
+
property :id do
|
|
190
|
+
key :type, :string
|
|
191
|
+
key :format, :uuid
|
|
192
|
+
end
|
|
193
|
+
property :type do
|
|
194
|
+
key :type, :string
|
|
195
|
+
key :enum, [Flapjack::Data::Medium.short_model_name.singular]
|
|
196
|
+
end
|
|
197
|
+
property :transport do
|
|
198
|
+
key :type, :string
|
|
199
|
+
key :enum, Flapjack::Data::Medium::TRANSPORTS.map(&:to_sym)
|
|
200
|
+
end
|
|
201
|
+
property :address do
|
|
202
|
+
key :type, :string
|
|
203
|
+
end
|
|
204
|
+
property :interval do
|
|
205
|
+
key :type, :integer
|
|
206
|
+
key :minimum, 0
|
|
207
|
+
end
|
|
208
|
+
property :rollup_threshold do
|
|
209
|
+
key :type, :integer
|
|
210
|
+
key :minimum, 1
|
|
211
|
+
end
|
|
212
|
+
property :pagerduty_subdomain do
|
|
213
|
+
key :type, :string
|
|
214
|
+
end
|
|
215
|
+
property :pagerduty_token do
|
|
216
|
+
key :type, :string
|
|
217
|
+
end
|
|
218
|
+
property :pagerduty_ack_duration do
|
|
219
|
+
key :type, :integer
|
|
220
|
+
key :minimum, 1
|
|
221
|
+
end
|
|
222
|
+
property :relationships do
|
|
223
|
+
key :"$ref", :MediumLinks
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
swagger_schema :MediumLinks do
|
|
228
|
+
key :required, [:contact, :rules]
|
|
229
|
+
property :contact do
|
|
230
|
+
key :"$ref", :ContactLinkage
|
|
231
|
+
end
|
|
232
|
+
property :rules do
|
|
233
|
+
key :"$ref", :RulesLinkage
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
swagger_schema :MediumCreate do
|
|
238
|
+
key :required, [:type, :address, :transport]
|
|
239
|
+
property :id do
|
|
240
|
+
key :type, :string
|
|
241
|
+
key :format, :uuid
|
|
242
|
+
end
|
|
243
|
+
property :type do
|
|
244
|
+
key :type, :string
|
|
245
|
+
key :enum, [Flapjack::Data::Medium.short_model_name.singular]
|
|
246
|
+
end
|
|
247
|
+
property :transport do
|
|
248
|
+
key :type, :string
|
|
249
|
+
key :enum, Flapjack::Data::Medium::TRANSPORTS.map(&:to_sym)
|
|
250
|
+
end
|
|
251
|
+
property :address do
|
|
252
|
+
key :type, :string
|
|
253
|
+
end
|
|
254
|
+
property :interval do
|
|
255
|
+
key :type, :integer
|
|
256
|
+
key :minimum, 0
|
|
257
|
+
end
|
|
258
|
+
property :rollup_threshold do
|
|
259
|
+
key :type, :integer
|
|
260
|
+
key :minimum, 1
|
|
261
|
+
end
|
|
262
|
+
property :pagerduty_subdomain do
|
|
263
|
+
key :type, :string
|
|
264
|
+
end
|
|
265
|
+
property :pagerduty_token do
|
|
266
|
+
key :type, :string
|
|
267
|
+
end
|
|
268
|
+
property :pagerduty_ack_duration do
|
|
269
|
+
key :type, :integer
|
|
270
|
+
key :minimum, 1
|
|
271
|
+
end
|
|
272
|
+
property :relationships do
|
|
273
|
+
key :"$ref", :MediumCreateLinks
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
swagger_schema :MediumCreateLinks do
|
|
278
|
+
key :required, [:contact]
|
|
279
|
+
property :contact do
|
|
280
|
+
key :"$ref", :data_ContactReference
|
|
281
|
+
end
|
|
282
|
+
property :rules do
|
|
283
|
+
key :"$ref", :data_RulesReference
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
swagger_schema :MediumUpdate do
|
|
288
|
+
key :required, [:id, :type]
|
|
289
|
+
property :id do
|
|
290
|
+
key :type, :string
|
|
291
|
+
key :format, :uuid
|
|
292
|
+
end
|
|
293
|
+
property :type do
|
|
294
|
+
key :type, :string
|
|
295
|
+
key :enum, [Flapjack::Data::Medium.short_model_name.singular]
|
|
296
|
+
end
|
|
297
|
+
property :transport do
|
|
298
|
+
key :type, :string
|
|
299
|
+
key :enum, Flapjack::Data::Medium::TRANSPORTS.map(&:to_sym)
|
|
300
|
+
end
|
|
301
|
+
property :address do
|
|
302
|
+
key :type, :string
|
|
303
|
+
end
|
|
304
|
+
property :interval do
|
|
305
|
+
key :type, :integer
|
|
306
|
+
key :minimum, 0
|
|
307
|
+
end
|
|
308
|
+
property :rollup_threshold do
|
|
309
|
+
key :type, :integer
|
|
310
|
+
key :minimum, 1
|
|
311
|
+
end
|
|
312
|
+
property :pagerduty_subdomain do
|
|
313
|
+
key :type, :string
|
|
314
|
+
end
|
|
315
|
+
property :pagerduty_token do
|
|
316
|
+
key :type, :string
|
|
317
|
+
end
|
|
318
|
+
property :pagerduty_ack_duration do
|
|
319
|
+
key :type, :integer
|
|
320
|
+
key :minimum, 1
|
|
321
|
+
end
|
|
322
|
+
property :relationships do
|
|
323
|
+
key :"$ref", :MediumUpdateLinks
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
swagger_schema :MediumUpdateLinks do
|
|
328
|
+
property :rules do
|
|
329
|
+
key :"$ref", :data_RulesReference
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def self.swagger_included_classes
|
|
334
|
+
# hack -- hardcoding for now
|
|
335
|
+
[
|
|
336
|
+
Flapjack::Data::Check,
|
|
337
|
+
Flapjack::Data::Contact,
|
|
338
|
+
Flapjack::Data::Medium,
|
|
339
|
+
Flapjack::Data::Rule,
|
|
340
|
+
Flapjack::Data::ScheduledMaintenance,
|
|
341
|
+
Flapjack::Data::State,
|
|
342
|
+
Flapjack::Data::Tag,
|
|
343
|
+
Flapjack::Data::UnscheduledMaintenance
|
|
344
|
+
]
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
def self.jsonapi_methods
|
|
348
|
+
@jsonapi_methods ||= {
|
|
349
|
+
:post => Flapjack::Gateways::JSONAPI::Data::MethodDescriptor.new(
|
|
350
|
+
:attributes => [:transport, :address, :interval, :rollup_threshold,
|
|
351
|
+
:pagerduty_subdomain, :pagerduty_token,
|
|
352
|
+
:pagerduty_ack_duration],
|
|
353
|
+
:descriptions => {
|
|
354
|
+
:singular => "Create a media record.",
|
|
355
|
+
:multiple => "Create media records."
|
|
356
|
+
}
|
|
357
|
+
),
|
|
358
|
+
:get => Flapjack::Gateways::JSONAPI::Data::MethodDescriptor.new(
|
|
359
|
+
:attributes => [:transport, :address, :interval, :rollup_threshold,
|
|
360
|
+
:pagerduty_subdomain, :pagerduty_token,
|
|
361
|
+
:pagerduty_ack_duration],
|
|
362
|
+
:descriptions => {
|
|
363
|
+
:singular => "Returns data for a media record.",
|
|
364
|
+
:multiple => "Returns data for media records."
|
|
365
|
+
}
|
|
366
|
+
),
|
|
367
|
+
:patch => Flapjack::Gateways::JSONAPI::Data::MethodDescriptor.new(
|
|
368
|
+
:attributes => [:transport, :address, :interval, :rollup_threshold,
|
|
369
|
+
:pagerduty_subdomain, :pagerduty_token,
|
|
370
|
+
:pagerduty_ack_duration],
|
|
371
|
+
:descriptions => {
|
|
372
|
+
:singular => "Update a media record.",
|
|
373
|
+
:multiple => "Update media records."
|
|
374
|
+
}
|
|
375
|
+
),
|
|
376
|
+
:delete => Flapjack::Gateways::JSONAPI::Data::MethodDescriptor.new(
|
|
377
|
+
:descriptions => {
|
|
378
|
+
:singular => "Delete a media record.",
|
|
379
|
+
:multiple => "Delete media records."
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
}
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def self.jsonapi_associations
|
|
386
|
+
unless instance_variable_defined?('@jsonapi_associations')
|
|
387
|
+
@jsonapi_associations = {
|
|
388
|
+
:alerting_checks => Flapjack::Gateways::JSONAPI::Data::JoinDescriptor.new(
|
|
389
|
+
:get => true,
|
|
390
|
+
:number => :multiple, :link => true, :includable => true,
|
|
391
|
+
:type => 'check',
|
|
392
|
+
:klass => Flapjack::Data::Check,
|
|
393
|
+
:callback_classes => [
|
|
394
|
+
Flapjack::Data::Contact,
|
|
395
|
+
Flapjack::Data::Rule,
|
|
396
|
+
Flapjack::Data::ScheduledMaintenance
|
|
397
|
+
],
|
|
398
|
+
:descriptions => {
|
|
399
|
+
:get => "Returns all checks that have alerted through a medium (that are still failing."
|
|
400
|
+
}
|
|
401
|
+
),
|
|
402
|
+
:contact => Flapjack::Gateways::JSONAPI::Data::JoinDescriptor.new(
|
|
403
|
+
:post => true, :get => true,
|
|
404
|
+
:number => :singular, :link => true, :includable => true,
|
|
405
|
+
:descriptions => {
|
|
406
|
+
:post => "Set a contact for a medium during medium creation (required).",
|
|
407
|
+
:get => "Get the contact a medium belongs to."
|
|
408
|
+
}
|
|
409
|
+
),
|
|
410
|
+
:rules => Flapjack::Gateways::JSONAPI::Data::JoinDescriptor.new(
|
|
411
|
+
:post => true, :get => true, :patch => true, :delete => true,
|
|
412
|
+
:number => :multiple, :link => true, :includable => true,
|
|
413
|
+
:descriptions => {
|
|
414
|
+
:post => "Associate this medium with rules on medium creation.",
|
|
415
|
+
:get => "Get the rules this medium is associated with.",
|
|
416
|
+
:patch => "Update the rules this medium is associated with.",
|
|
417
|
+
:delete => "Delete associations between this medium and rules."
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
)
|
|
421
|
+
}
|
|
422
|
+
populate_association_data(@jsonapi_associations)
|
|
423
|
+
end
|
|
424
|
+
@jsonapi_associations
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
end
|