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
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'zermelo/records/redis'
|
|
4
|
+
|
|
5
|
+
module Flapjack
|
|
6
|
+
module Data
|
|
7
|
+
class Condition
|
|
8
|
+
|
|
9
|
+
include Comparable
|
|
10
|
+
|
|
11
|
+
def <=>(cond)
|
|
12
|
+
return nil unless cond.is_a?(Flapjack::Data::Condition)
|
|
13
|
+
self.priority <=> cond.priority
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# class methods rather than constants, as these may come from config
|
|
17
|
+
# data in the future; name => priority
|
|
18
|
+
def self.healthy
|
|
19
|
+
{
|
|
20
|
+
'ok' => 1
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.unhealthy
|
|
25
|
+
{
|
|
26
|
+
'critical' => -3,
|
|
27
|
+
'warning' => -2,
|
|
28
|
+
'unknown' => -1
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# NB: not actually persisted; we probably want a non-persisted record type
|
|
33
|
+
# for this case
|
|
34
|
+
include Zermelo::Records::RedisSet
|
|
35
|
+
|
|
36
|
+
define_attributes :name => :string,
|
|
37
|
+
:priority => :integer
|
|
38
|
+
|
|
39
|
+
validates :name, :presence => true,
|
|
40
|
+
:inclusion => { :in => Flapjack::Data::Condition.healthy.keys +
|
|
41
|
+
Flapjack::Data::Condition.unhealthy.keys }
|
|
42
|
+
|
|
43
|
+
validates :priority, :presence => true,
|
|
44
|
+
:numericality => {:only_integer => true},
|
|
45
|
+
:inclusion => { :in => Flapjack::Data::Condition.healthy.values |
|
|
46
|
+
Flapjack::Data::Condition.unhealthy.values }
|
|
47
|
+
|
|
48
|
+
before_create :save_allowed?
|
|
49
|
+
before_update :save_allowed?
|
|
50
|
+
def save_allowed?
|
|
51
|
+
false
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.healthy?(c)
|
|
55
|
+
self.healthy.keys.include?(c)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.most_unhealthy
|
|
59
|
+
self.unhealthy.min_by {|_, pri| pri }.first
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.for_name(n)
|
|
63
|
+
c = Flapjack::Data::Condition.new(:name => n,
|
|
64
|
+
:priority => self.healthy[n.to_s] || self.unhealthy[n.to_s] )
|
|
65
|
+
c.valid? ? c : nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
# NB: use of redis.keys probably indicates we should maintain a data
|
|
4
|
-
# structure to avoid the need for this type of query
|
|
5
|
-
|
|
6
3
|
require 'securerandom'
|
|
7
4
|
require 'set'
|
|
8
5
|
|
|
9
6
|
require 'ice_cube'
|
|
7
|
+
require 'swagger/blocks'
|
|
8
|
+
|
|
9
|
+
require 'zermelo/records/redis'
|
|
10
10
|
|
|
11
|
-
require 'flapjack/data/
|
|
12
|
-
require 'flapjack/data/
|
|
13
|
-
|
|
11
|
+
require 'flapjack/data/extensions/short_name'
|
|
12
|
+
require 'flapjack/data/validators/id_validator'
|
|
13
|
+
|
|
14
|
+
require 'flapjack/data/extensions/associations'
|
|
15
|
+
require 'flapjack/gateways/jsonapi/data/join_descriptor'
|
|
16
|
+
require 'flapjack/gateways/jsonapi/data/method_descriptor'
|
|
14
17
|
|
|
15
18
|
module Flapjack
|
|
16
19
|
|
|
@@ -18,515 +21,282 @@ module Flapjack
|
|
|
18
21
|
|
|
19
22
|
class Contact
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
'email',
|
|
26
|
-
'sms',
|
|
27
|
-
'slack',
|
|
28
|
-
'sms_twilio',
|
|
29
|
-
'sms_nexmo',
|
|
30
|
-
'jabber',
|
|
31
|
-
'pagerduty',
|
|
32
|
-
'sns'
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
def self.all(options = {})
|
|
36
|
-
raise "Redis connection not set" unless redis = options[:redis]
|
|
37
|
-
|
|
38
|
-
redis.keys('contact:*').inject([]) {|ret, k|
|
|
39
|
-
k =~ /^contact:(.*)$/
|
|
40
|
-
id = $1
|
|
41
|
-
contact = self.find_by_id(id, :redis => redis)
|
|
42
|
-
ret << contact unless contact.nil?
|
|
43
|
-
ret
|
|
44
|
-
}.sort_by {|c| [c.last_name, c.first_name]}
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def self.find_by_id(contact_id, options = {})
|
|
48
|
-
raise "Redis connection not set" unless redis = options[:redis]
|
|
49
|
-
raise "No id value passed" unless contact_id
|
|
50
|
-
logger = options[:logger]
|
|
51
|
-
|
|
52
|
-
# sanity check
|
|
53
|
-
return unless redis.hexists("contact:#{contact_id}", 'first_name')
|
|
54
|
-
|
|
55
|
-
contact = self.new(:id => contact_id, :redis => redis, :logger => logger)
|
|
56
|
-
contact.refresh
|
|
57
|
-
contact
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def self.find_by_ids(contact_ids, options = {})
|
|
61
|
-
raise "Redis connection not set" unless redis = options[:redis]
|
|
62
|
-
logger = options[:logger]
|
|
63
|
-
|
|
64
|
-
contact_ids.map do |id|
|
|
65
|
-
self.find_by_id(id, options)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def self.exists_with_id?(contact_id, options = {})
|
|
70
|
-
raise "Redis connection not set" unless redis = options[:redis]
|
|
71
|
-
raise "No id value passed" unless contact_id
|
|
24
|
+
include Zermelo::Records::RedisSet
|
|
25
|
+
include ActiveModel::Serializers::JSON
|
|
26
|
+
self.include_root_in_json = false
|
|
27
|
+
include Swagger::Blocks
|
|
72
28
|
|
|
73
|
-
|
|
74
|
-
|
|
29
|
+
include Flapjack::Data::Extensions::Associations
|
|
30
|
+
include Flapjack::Data::Extensions::ShortName
|
|
75
31
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
contact_id = contact_data['id']
|
|
79
|
-
raise "Contact id value not provided" if contact_id.nil?
|
|
32
|
+
define_attributes :name => :string,
|
|
33
|
+
:timezone => :string
|
|
80
34
|
|
|
81
|
-
|
|
82
|
-
contact.delete!
|
|
83
|
-
end
|
|
35
|
+
index_by :name
|
|
84
36
|
|
|
85
|
-
|
|
86
|
-
|
|
37
|
+
has_many :rules, :class_name => 'Flapjack::Data::Rule',
|
|
38
|
+
:inverse_of => :contact
|
|
87
39
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
end
|
|
40
|
+
has_many :media, :class_name => 'Flapjack::Data::Medium',
|
|
41
|
+
:inverse_of => :contact
|
|
91
42
|
|
|
92
|
-
|
|
93
|
-
|
|
43
|
+
has_and_belongs_to_many :tags, :class_name => 'Flapjack::Data::Tag',
|
|
44
|
+
:inverse_of => :contacts
|
|
94
45
|
|
|
95
|
-
|
|
96
|
-
raise "Redis connection not set" unless redis = options[:redis]
|
|
46
|
+
validates_with Flapjack::Data::Validators::IdValidator
|
|
97
47
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
end
|
|
48
|
+
validates_each :timezone, :allow_nil => true do |record, att, value|
|
|
49
|
+
record.errors.add(att, 'must be a valid time zone string') if ActiveSupport::TimeZone[value].nil?
|
|
101
50
|
end
|
|
102
51
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
fn, ln, em = @redis.hmget("contact:#{@id}", 'first_name', 'last_name', 'email')
|
|
108
|
-
self.first_name = Flapjack.sanitize(fn)
|
|
109
|
-
self.last_name = Flapjack.sanitize(ln)
|
|
110
|
-
self.email = Flapjack.sanitize(em)
|
|
111
|
-
self.media = @redis.hgetall("contact_media:#{@id}")
|
|
112
|
-
self.media_intervals = @redis.hgetall("contact_media_intervals:#{self.id}")
|
|
113
|
-
self.media_rollup_thresholds = @redis.hgetall("contact_media_rollup_thresholds:#{self.id}")
|
|
114
|
-
|
|
115
|
-
# similar to code in instance method pagerduty_credentials
|
|
116
|
-
if service_key = @redis.hget("contact_media:#{@id}", 'pagerduty')
|
|
117
|
-
self.pagerduty_credentials =
|
|
118
|
-
@redis.hgetall("contact_pagerduty:#{@id}").merge('service_key' => service_key)
|
|
119
|
-
end
|
|
52
|
+
before_destroy :remove_child_records
|
|
53
|
+
def remove_child_records
|
|
54
|
+
self.media.each {|medium| medium.destroy }
|
|
55
|
+
self.rules.each {|rule| rule.destroy }
|
|
120
56
|
end
|
|
121
57
|
|
|
122
|
-
def
|
|
123
|
-
self.
|
|
124
|
-
self.
|
|
58
|
+
def time_zone
|
|
59
|
+
return nil if self.timezone.nil?
|
|
60
|
+
ActiveSupport::TimeZone[self.timezone]
|
|
125
61
|
end
|
|
126
62
|
|
|
127
|
-
def
|
|
128
|
-
|
|
129
|
-
# rather than check if the key is present we'll just request its
|
|
130
|
-
# deletion anyway, fewer round-trips
|
|
131
|
-
@redis.keys('contacts_for:*').each do |cfk|
|
|
132
|
-
@redis.srem(cfk, self.id)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
@redis.del("drop_alerts_for_contact:#{self.id}")
|
|
136
|
-
dafc = @redis.keys("drop_alerts_for_contact:#{self.id}:*")
|
|
137
|
-
@redis.del(*dafc) unless dafc.empty?
|
|
138
|
-
|
|
139
|
-
# TODO if implemented, alerts_by_contact & alerts_by_check:
|
|
140
|
-
# list all alerts from all matched keys, remove them from
|
|
141
|
-
# the main alerts sorted set, remove all alerts_by sorted sets
|
|
142
|
-
# for the contact
|
|
143
|
-
|
|
144
|
-
# remove all associated notification rules
|
|
145
|
-
self.notification_rules.each do |nr|
|
|
146
|
-
self.delete_notification_rule(nr)
|
|
147
|
-
end
|
|
63
|
+
def checks
|
|
64
|
+
time = Time.now
|
|
148
65
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
"contact_media_rollup_thresholds:#{self.id}",
|
|
152
|
-
"contact_tz:#{self.id}", "contact_pagerduty:#{self.id}")
|
|
153
|
-
end
|
|
66
|
+
global_acceptors = self.rules.intersect(:enabled => true,
|
|
67
|
+
:blackhole => false, :strategy => 'global')
|
|
154
68
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
@redis.hgetall("contact_pagerduty:#{self.id}").
|
|
158
|
-
merge('service_key' => service_key)
|
|
159
|
-
end
|
|
69
|
+
global_rejector_ids = self.rules.intersect(:enabled => true,
|
|
70
|
+
:blackhole => true, :strategy => 'global').select {|rejector|
|
|
160
71
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
@redis.hmset("contact_pagerduty:#{self.id}",
|
|
164
|
-
*['subdomain', 'token', 'username', 'password'].collect {|f| [f, details[f]]})
|
|
165
|
-
end
|
|
72
|
+
rejector.is_occurring_at?(time, timezone)
|
|
73
|
+
}.map(&:id)
|
|
166
74
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
@redis.del("contact_pagerduty:#{self.id}")
|
|
170
|
-
end
|
|
75
|
+
# global blackhole
|
|
76
|
+
return Flapjack::Data::Check.empty unless global_rejector_ids.empty?
|
|
171
77
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
key = "contacts_for:#{entity.id}"
|
|
175
|
-
@redis.sadd(key, self.id)
|
|
176
|
-
end
|
|
78
|
+
tag_rejector_ids = self.rules.intersect(:enabled => true,
|
|
79
|
+
:blackhole => true, :strategy => ['any_tag', 'all_tags', 'no_tag']).select {|rejector|
|
|
177
80
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
key = "contacts_for:#{entity.id}"
|
|
181
|
-
@redis.srem(key, self.id)
|
|
182
|
-
end
|
|
81
|
+
rejector.is_occurring_at?(time, timezone)
|
|
82
|
+
}.map(&:id)
|
|
183
83
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
def entities(options = {})
|
|
187
|
-
@redis.keys('contacts_for:*').inject({}) {|ret, k|
|
|
188
|
-
if @redis.sismember(k, self.id)
|
|
189
|
-
if k =~ /^contacts_for:([a-zA-Z0-9][a-zA-Z0-9\.\-]*[a-zA-Z0-9])(?::(\w+))?$/
|
|
190
|
-
entity_id = $1
|
|
191
|
-
check = $2
|
|
192
|
-
|
|
193
|
-
entity = nil
|
|
194
|
-
|
|
195
|
-
if ret.has_key?(entity_id)
|
|
196
|
-
entity = ret[entity_id][:entity]
|
|
197
|
-
else
|
|
198
|
-
entity = Flapjack::Data::Entity.find_by_id(entity_id, :redis => @redis)
|
|
199
|
-
ret[entity_id] = {
|
|
200
|
-
:entity => entity
|
|
201
|
-
}
|
|
202
|
-
# using a set to ensure unique check values
|
|
203
|
-
ret[entity_id][:checks] = Set.new if options[:checks]
|
|
204
|
-
ret[entity_id][:tags] = entity.tags if entity && options[:tags]
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
if options[:checks]
|
|
208
|
-
# if not registered for the check, then was registered for
|
|
209
|
-
# the entity, so add all checks
|
|
210
|
-
ret[entity_id][:checks] |= (check || (entity ? entity.check_list : []))
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
ret
|
|
215
|
-
}.values
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
def self.entity_ids_for(contact_ids, options = {})
|
|
219
|
-
raise "Redis connection not set" unless redis = options[:redis]
|
|
84
|
+
tag_acceptors = self.rules.intersect(:enabled => true, :blackhole => false,
|
|
85
|
+
:strategy => ['any_tag', 'all_tags', 'no_tag']).select {|acceptor|
|
|
220
86
|
|
|
221
|
-
|
|
87
|
+
acceptor.is_occurring_at?(time, timezone)
|
|
88
|
+
}
|
|
222
89
|
|
|
223
|
-
|
|
224
|
-
|
|
90
|
+
# no positives
|
|
91
|
+
return Flapjack::Data::Check.empty if tag_acceptors.empty?
|
|
225
92
|
|
|
226
|
-
redis.keys('contacts_for:*').each do |k|
|
|
227
|
-
contact_ids = redis.sinter(k, temp_set)
|
|
228
|
-
next if contact_ids.empty?
|
|
229
|
-
next unless k =~ /^contacts_for:([a-zA-Z0-9][a-zA-Z0-9\.\-]*[a-zA-Z0-9])(?::(\w+))?$/
|
|
230
93
|
|
|
231
|
-
|
|
232
|
-
|
|
94
|
+
# initial scope is all enabled
|
|
95
|
+
linked_checks = Flapjack::Data::Check.intersect(:enabled => true)
|
|
233
96
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
97
|
+
if global_acceptors.empty?
|
|
98
|
+
# if no global acceptor, scope by matching tags
|
|
99
|
+
tag_acceptor_checks = Flapjack::Data::Rule.matching_checks(tag_acceptors.map(&:id))
|
|
100
|
+
linked_checks = linked_checks.intersect(:id => tag_acceptor_checks)
|
|
238
101
|
end
|
|
239
102
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
def name
|
|
246
|
-
[(self.first_name || ''), (self.last_name || '')].join(" ").strip
|
|
247
|
-
end
|
|
103
|
+
# then exclude by checks with tags matching rejector, if any
|
|
104
|
+
tag_rejector_checks = Flapjack::Data::Rule.matching_checks(tag_rejector_ids)
|
|
105
|
+
unless tag_rejector_checks.empty?
|
|
106
|
+
linked_checks = linked_checks.diff(:id => tag_rejector_checks)
|
|
107
|
+
end
|
|
248
108
|
|
|
249
|
-
|
|
250
|
-
@redis.smembers("contact_notification_rules:#{self.id}")
|
|
109
|
+
linked_checks
|
|
251
110
|
end
|
|
252
111
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
end
|
|
259
|
-
ret
|
|
112
|
+
swagger_schema :Contact do
|
|
113
|
+
key :required, [:id, :type, :name]
|
|
114
|
+
property :id do
|
|
115
|
+
key :type, :string
|
|
116
|
+
key :format, :uuid
|
|
260
117
|
end
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
:regex_entities => [],
|
|
265
|
-
:tags => Set.new([]),
|
|
266
|
-
:regex_tags => Set.new([]),
|
|
267
|
-
:time_restrictions => [],
|
|
268
|
-
:warning_media => ALL_MEDIA,
|
|
269
|
-
:critical_media => ALL_MEDIA,
|
|
270
|
-
:warning_blackhole => false,
|
|
271
|
-
:critical_blackhole => false,
|
|
272
|
-
}, :logger => opts[:logger])
|
|
273
|
-
rules.unshift(rule)
|
|
118
|
+
property :type do
|
|
119
|
+
key :type, :string
|
|
120
|
+
key :enum, [Flapjack::Data::Contact.short_model_name.singular]
|
|
274
121
|
end
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
def add_notification_rule(rule_data, opts = {})
|
|
279
|
-
if logger = opts[:logger]
|
|
280
|
-
logger.debug("add_notification_rule: contact_id: #{self.id} (#{self.id.class})")
|
|
122
|
+
property :name do
|
|
123
|
+
key :type, :string
|
|
281
124
|
end
|
|
282
|
-
|
|
283
|
-
:
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
# move an existing notification rule from another contact to this one
|
|
287
|
-
def grab_notification_rule(rule)
|
|
288
|
-
@redis.srem("contact_notification_rules:#{rule.contact.id}", rule.id)
|
|
289
|
-
rule.contact_id = self.id
|
|
290
|
-
rule.update({})
|
|
291
|
-
@redis.sadd("contact_notification_rules:#{self.id}", rule.id)
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
def delete_notification_rule(rule)
|
|
295
|
-
@redis.srem("contact_notification_rules:#{self.id}", rule.id)
|
|
296
|
-
@redis.del("notification_rule:#{rule.id}")
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
# how often to notify this contact on the given media
|
|
300
|
-
# return 15 mins if no value is set
|
|
301
|
-
def interval_for_media(media)
|
|
302
|
-
interval = @redis.hget("contact_media_intervals:#{self.id}", media)
|
|
303
|
-
(interval.nil? || (interval.to_i <= 0)) ? (15 * 60) : interval.to_i
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
def set_interval_for_media(media, interval)
|
|
307
|
-
return if 'pagerduty'.eql?(media)
|
|
308
|
-
if interval.nil?
|
|
309
|
-
@redis.hdel("contact_media_intervals:#{self.id}", media)
|
|
310
|
-
return
|
|
125
|
+
property :timezone do
|
|
126
|
+
key :type, :string
|
|
127
|
+
key :format, :tzinfo
|
|
311
128
|
end
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
def rollup_threshold_for_media(media)
|
|
317
|
-
threshold = @redis.hget("contact_media_rollup_thresholds:#{self.id}", media)
|
|
318
|
-
(threshold.nil? || (threshold.to_i <= 0 )) ? nil : threshold.to_i
|
|
319
|
-
end
|
|
320
|
-
|
|
321
|
-
def set_rollup_threshold_for_media(media, threshold)
|
|
322
|
-
return if 'pagerduty'.eql?(media)
|
|
323
|
-
if threshold.nil?
|
|
324
|
-
@redis.hdel("contact_media_rollup_thresholds:#{self.id}", media)
|
|
325
|
-
return
|
|
129
|
+
property :relationships do
|
|
130
|
+
key :"$ref", :ContactLinks
|
|
326
131
|
end
|
|
327
|
-
@redis.hset("contact_media_rollup_thresholds:#{self.id}", media, threshold)
|
|
328
|
-
self.media_rollup_thresholds = @redis.hgetall("contact_media_rollup_thresholds:#{self.id}")
|
|
329
132
|
end
|
|
330
133
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
def remove_media(media)
|
|
338
|
-
@redis.hdel("contact_media:#{self.id}", media)
|
|
339
|
-
@redis.hdel("contact_media_intervals:#{self.id}", media)
|
|
340
|
-
@redis.hdel("contact_media_rollup_thresholds:#{self.id}", media)
|
|
341
|
-
if media == 'pagerduty'
|
|
342
|
-
@redis.del("contact_pagerduty:#{self.id}")
|
|
134
|
+
swagger_schema :ContactLinks do
|
|
135
|
+
key :required, [:checks, :media, :rules]
|
|
136
|
+
property :checks do
|
|
137
|
+
key :"$ref", :ChecksLinkage
|
|
343
138
|
end
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
# drop notifications for
|
|
347
|
-
def drop_notifications?(opts = {})
|
|
348
|
-
media = opts[:media]
|
|
349
|
-
check = opts[:check]
|
|
350
|
-
state = opts[:state]
|
|
351
|
-
|
|
352
|
-
# build it and they will come
|
|
353
|
-
@redis.exists("drop_alerts_for_contact:#{self.id}") ||
|
|
354
|
-
(media && @redis.exists("drop_alerts_for_contact:#{self.id}:#{media}")) ||
|
|
355
|
-
(media && check &&
|
|
356
|
-
@redis.exists("drop_alerts_for_contact:#{self.id}:#{media}:#{check}")) ||
|
|
357
|
-
(media && check && state &&
|
|
358
|
-
@redis.exists("drop_alerts_for_contact:#{self.id}:#{media}:#{check}:#{state}"))
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
def update_sent_alert_keys(opts = {})
|
|
362
|
-
media = opts[:media]
|
|
363
|
-
check = opts[:check]
|
|
364
|
-
state = opts[:state]
|
|
365
|
-
delete = !! opts[:delete]
|
|
366
|
-
key = "drop_alerts_for_contact:#{self.id}:#{media}:#{check}:#{state}"
|
|
367
|
-
if delete
|
|
368
|
-
@redis.del(key)
|
|
369
|
-
else
|
|
370
|
-
@redis.set(key, 'd')
|
|
371
|
-
@redis.expire(key, self.interval_for_media(media))
|
|
372
|
-
# TODO: #182 - update the alert history keys
|
|
139
|
+
property :media do
|
|
140
|
+
key :"$ref", :MediaLinkage
|
|
373
141
|
end
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
def drop_rollup_notifications_for_media?(media)
|
|
377
|
-
@redis.exists("drop_rollup_alerts_for_contact:#{self.id}:#{media}")
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
def update_sent_rollup_alert_keys_for_media(media, opts = {})
|
|
381
|
-
delete = !! opts[:delete]
|
|
382
|
-
key = "drop_rollup_alerts_for_contact:#{self.id}:#{media}"
|
|
383
|
-
if delete
|
|
384
|
-
@redis.del(key)
|
|
385
|
-
else
|
|
386
|
-
@redis.set(key, 'd')
|
|
387
|
-
@redis.expire(key, self.interval_for_media(media))
|
|
142
|
+
property :rules do
|
|
143
|
+
key :"$ref", :RulesLinkage
|
|
388
144
|
end
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
def add_alerting_check_for_media(media, event_id)
|
|
392
|
-
@redis.zadd("contact_alerting_checks:#{self.id}:media:#{media}", Time.now.to_i, event_id)
|
|
393
|
-
end
|
|
394
|
-
|
|
395
|
-
def remove_alerting_check_for_media(media, event_id)
|
|
396
|
-
@redis.zrem("contact_alerting_checks:#{self.id}:media:#{media}", event_id)
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
# removes any checks that are in ok, scheduled or unscheduled maintenance,
|
|
400
|
-
# or are disabled from the alerting checks set for the given media;
|
|
401
|
-
# returns whether this cleaning moved the medium from rollup to recovery
|
|
402
|
-
def clean_alerting_checks_for_media(media)
|
|
403
|
-
cleaned = 0
|
|
404
|
-
|
|
405
|
-
alerting_checks = alerting_checks_for_media(media)
|
|
406
|
-
rollup_threshold = rollup_threshold_for_media(media)
|
|
407
|
-
|
|
408
|
-
alerting_checks.each do |check|
|
|
409
|
-
entity_check = Flapjack::Data::EntityCheck.for_event_id(check, :redis => @redis)
|
|
410
|
-
next unless Flapjack::Data::EntityCheck.state_for_event_id?(check, :redis => @redis) == 'ok' ||
|
|
411
|
-
Flapjack::Data::EntityCheck.in_unscheduled_maintenance_for_event_id?(check, :redis => @redis) ||
|
|
412
|
-
Flapjack::Data::EntityCheck.in_scheduled_maintenance_for_event_id?(check, :redis => @redis) ||
|
|
413
|
-
!entity_check.enabled? ||
|
|
414
|
-
!entity_check.contacts.map {|c| c.id}.include?(self.id)
|
|
415
|
-
|
|
416
|
-
# FIXME: why can't i get this logging when called from notifier (notification.rb)?
|
|
417
|
-
@logger.debug("removing from alerting checks for #{self.id}/#{media}: #{check}") if @logger
|
|
418
|
-
remove_alerting_check_for_media(media, check)
|
|
419
|
-
cleaned += 1
|
|
145
|
+
property :tags do
|
|
146
|
+
key :"$ref", :TagsLinkage
|
|
420
147
|
end
|
|
421
|
-
|
|
422
|
-
return false if rollup_threshold.nil? || (rollup_threshold <= 0) ||
|
|
423
|
-
(alerting_checks.size < rollup_threshold)
|
|
424
|
-
|
|
425
|
-
return(cleaned > (alerting_checks.size - rollup_threshold))
|
|
426
|
-
end
|
|
427
|
-
|
|
428
|
-
def alerting_checks_for_media(media)
|
|
429
|
-
@redis.zrange("contact_alerting_checks:#{self.id}:media:#{media}", 0, -1)
|
|
430
148
|
end
|
|
431
149
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
150
|
+
swagger_schema :ContactCreate do
|
|
151
|
+
key :required, [:type, :name]
|
|
152
|
+
property :id do
|
|
153
|
+
key :type, :string
|
|
154
|
+
key :format, :uuid
|
|
155
|
+
end
|
|
156
|
+
property :type do
|
|
157
|
+
key :type, :string
|
|
158
|
+
key :enum, [Flapjack::Data::Contact.short_model_name.singular]
|
|
159
|
+
end
|
|
160
|
+
property :name do
|
|
161
|
+
key :type, :string
|
|
162
|
+
end
|
|
163
|
+
property :timezone do
|
|
164
|
+
key :type, :string
|
|
165
|
+
key :format, :tzinfo
|
|
166
|
+
end
|
|
167
|
+
property :relationships do
|
|
168
|
+
key :"$ref", :ContactCreateLinks
|
|
169
|
+
end
|
|
444
170
|
end
|
|
445
171
|
|
|
446
|
-
|
|
447
|
-
|
|
172
|
+
swagger_schema :ContactCreateLinks do
|
|
173
|
+
property :tags do
|
|
174
|
+
key :"$ref", :data_TagsReference
|
|
175
|
+
end
|
|
448
176
|
end
|
|
449
177
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
178
|
+
swagger_schema :ContactUpdate do
|
|
179
|
+
key :required, [:id, :type]
|
|
180
|
+
property :id do
|
|
181
|
+
key :type, :string
|
|
182
|
+
key :format, :uuid
|
|
183
|
+
end
|
|
184
|
+
property :type do
|
|
185
|
+
key :type, :string
|
|
186
|
+
key :enum, [Flapjack::Data::Contact.short_model_name.singular]
|
|
187
|
+
end
|
|
188
|
+
property :name do
|
|
189
|
+
key :type, :string
|
|
190
|
+
end
|
|
191
|
+
property :timezone do
|
|
192
|
+
key :type, :string
|
|
193
|
+
key :format, :tzinfo
|
|
194
|
+
end
|
|
195
|
+
property :relationships do
|
|
196
|
+
key :"$ref", :ContactUpdateLinks
|
|
455
197
|
end
|
|
456
198
|
end
|
|
457
199
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
200
|
+
swagger_schema :ContactUpdateLinks do
|
|
201
|
+
property :media do
|
|
202
|
+
key :"$ref", :data_MediaReference
|
|
203
|
+
end
|
|
204
|
+
property :rules do
|
|
205
|
+
key :"$ref", :data_RulesReference
|
|
206
|
+
end
|
|
207
|
+
property :tags do
|
|
208
|
+
key :"$ref", :data_TagsReference
|
|
209
|
+
end
|
|
461
210
|
end
|
|
462
211
|
|
|
463
|
-
def
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
212
|
+
def self.swagger_included_classes
|
|
213
|
+
# hack -- hardcoding for now
|
|
214
|
+
[
|
|
215
|
+
Flapjack::Data::Check,
|
|
216
|
+
Flapjack::Data::Contact,
|
|
217
|
+
Flapjack::Data::Medium,
|
|
218
|
+
Flapjack::Data::Rule,
|
|
219
|
+
Flapjack::Data::ScheduledMaintenance,
|
|
220
|
+
Flapjack::Data::State,
|
|
221
|
+
Flapjack::Data::Tag,
|
|
222
|
+
Flapjack::Data::UnscheduledMaintenance
|
|
223
|
+
]
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def self.jsonapi_methods
|
|
227
|
+
@jsonapi_methods ||= {
|
|
228
|
+
:post => Flapjack::Gateways::JSONAPI::Data::MethodDescriptor.new(
|
|
229
|
+
:attributes => [:name, :timezone],
|
|
230
|
+
:descriptions => {
|
|
231
|
+
:singular => "Create a contact.",
|
|
232
|
+
:multiple => "Create contacts."
|
|
233
|
+
}
|
|
234
|
+
),
|
|
235
|
+
:get => Flapjack::Gateways::JSONAPI::Data::MethodDescriptor.new(
|
|
236
|
+
:attributes => [:name, :timezone],
|
|
237
|
+
:descriptions => {
|
|
238
|
+
:singular => "Get data for a contact.",
|
|
239
|
+
:multiple => "Get data for multiple contacts."
|
|
240
|
+
}
|
|
241
|
+
),
|
|
242
|
+
:patch => Flapjack::Gateways::JSONAPI::Data::MethodDescriptor.new(
|
|
243
|
+
:attributes => [:name, :timezone],
|
|
244
|
+
:descriptions => {
|
|
245
|
+
:singular => "Update a contact record.",
|
|
246
|
+
:multiple => "Update contact records."
|
|
247
|
+
}
|
|
248
|
+
),
|
|
249
|
+
:delete => Flapjack::Gateways::JSONAPI::Data::MethodDescriptor.new(
|
|
250
|
+
:descriptions => {
|
|
251
|
+
:singular => "Delete a contact.",
|
|
252
|
+
:multiple => "Delete contacts."
|
|
253
|
+
}
|
|
254
|
+
),
|
|
475
255
|
}
|
|
476
|
-
Flapjack.dump_json(json_data)
|
|
477
|
-
end
|
|
478
|
-
|
|
479
|
-
private
|
|
480
|
-
|
|
481
|
-
def initialize(options = {})
|
|
482
|
-
raise "Redis connection not set" unless @redis = options[:redis]
|
|
483
|
-
@id = options[:id]
|
|
484
|
-
@logger = options[:logger]
|
|
485
256
|
end
|
|
486
257
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
258
|
+
def self.jsonapi_associations
|
|
259
|
+
unless instance_variable_defined?('@jsonapi_associations')
|
|
260
|
+
@jsonapi_associations = {
|
|
261
|
+
:checks => Flapjack::Gateways::JSONAPI::Data::JoinDescriptor.new(
|
|
262
|
+
:get => true,
|
|
263
|
+
:number => :multiple, :link => true, :includable => true,
|
|
264
|
+
:type => 'check',
|
|
265
|
+
:klass => Flapjack::Data::Check,
|
|
266
|
+
:descriptions => {
|
|
267
|
+
:get => "Returns checks which this contact's notification " \
|
|
268
|
+
"rules allow it to receive notifications."
|
|
269
|
+
}
|
|
270
|
+
),
|
|
271
|
+
:media => Flapjack::Gateways::JSONAPI::Data::JoinDescriptor.new(
|
|
272
|
+
:get => true,
|
|
273
|
+
:number => :multiple, :link => true, :includable => true,
|
|
274
|
+
:descriptions => {
|
|
275
|
+
:get => "Returns media belonging to the contact."
|
|
276
|
+
}
|
|
277
|
+
),
|
|
278
|
+
:rules => Flapjack::Gateways::JSONAPI::Data::JoinDescriptor.new(
|
|
279
|
+
:get => true,
|
|
280
|
+
:number => :multiple, :link => true, :includable => true,
|
|
281
|
+
:descriptions => {
|
|
282
|
+
:get => "Returns rules belonging to the contact."
|
|
283
|
+
}
|
|
284
|
+
),
|
|
285
|
+
:tags => Flapjack::Gateways::JSONAPI::Data::JoinDescriptor.new(
|
|
286
|
+
:post => true, :get => true, :patch => true, :delete => true,
|
|
287
|
+
:number => :multiple, :link => true, :includable => true,
|
|
288
|
+
:descriptions => {
|
|
289
|
+
:post => "Associate tags with this contact.",
|
|
290
|
+
:get => "Returns all tags linked to this contact.",
|
|
291
|
+
:patch => "Update the tags associated with this contact.",
|
|
292
|
+
:delete => "Delete associations between tags and this contact."
|
|
293
|
+
}
|
|
294
|
+
)
|
|
516
295
|
}
|
|
296
|
+
populate_association_data(@jsonapi_associations)
|
|
517
297
|
end
|
|
518
|
-
|
|
519
|
-
tz = contact_data['timezone']
|
|
520
|
-
if tz.nil?
|
|
521
|
-
redis.del("contact_tz:#{contact_id}")
|
|
522
|
-
elsif tz.is_a?(String) && !ActiveSupport::TimeZone[tz].nil?
|
|
523
|
-
redis.set("contact_tz:#{contact_id}", tz )
|
|
524
|
-
end
|
|
525
|
-
end
|
|
298
|
+
@jsonapi_associations
|
|
526
299
|
end
|
|
527
|
-
|
|
528
300
|
end
|
|
529
|
-
|
|
530
301
|
end
|
|
531
|
-
|
|
532
302
|
end
|