interferon 0.0.7 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cf3a434f94d6e961434e2d3011613ff875c07e83
4
- data.tar.gz: 56ed577469d6d97ea2a7798e12e7d0ab3f4e59a8
3
+ metadata.gz: 35b5382f5aabd274b548257bcc5f227faf1b951e
4
+ data.tar.gz: abacd2609b40bf28b2783bbd21b24c384f991188
5
5
  SHA512:
6
- metadata.gz: eb304b434ad6417a9d8184bea6292bbbb80cf45edba557f34df78f7a6376bc58079257fcaa1f3d04f4826dadf991a608fed508f514a7a68d49b41295be5c46b5
7
- data.tar.gz: dcd28c67b74e92a5c2a43f470ed4845a292a1d2915eeb2d7d3710e5868a17f858eeb298b42139f85c41b14408ee2882039d51d5270f011bc2b35c9d57e0e5ab0
6
+ metadata.gz: b215a4e355f66daa582d65b521fe0eef5842eb795551df1998844d82cb1892a64b7a95e3b60fff1ec2992eb2e88de2f584c274c9bd5570b6f0ae4026b05eeb5a
7
+ data.tar.gz: 2bb6ee4093fe2bbe46d811a3cb79a357066073727a699d773b306a5355fd8f7b9d06a4f2bdb51082ac6570a3166820ce7f1b88d63f9fb76d6d032fc8b97073b0
data/config.example.yaml CHANGED
@@ -35,3 +35,4 @@ destinations:
35
35
  options:
36
36
  app_key: "fillmein"
37
37
  api_key: "alsomissing"
38
+ api_timeout: 15
@@ -22,6 +22,14 @@ module Interferon
22
22
  self
23
23
  end
24
24
 
25
+ def change_name(name)
26
+ unless @dsl
27
+ raise "This alert has not yet been evaluated"
28
+ end
29
+
30
+ @dsl.name(name)
31
+ end
32
+
25
33
  def [](attr)
26
34
  unless @dsl
27
35
  raise "This alert has not yet been evaluated"
@@ -15,8 +15,22 @@ module Interferon::Destinations
15
15
  end
16
16
  end
17
17
 
18
- @dog = Dogapi::Client.new(options['api_key'], options['app_key'])
19
- @dry_run = !!options['dry_run']
18
+ # Set dogapi timeout explicitly
19
+ api_timeout = options['api_timeout'] || 15
20
+
21
+ # Default parameters of Dogapi Client initialize() can be referenced from link below:
22
+ # (as of this writing)
23
+ # https://github.com/DataDog/dogapi-rb/blob/master/lib/dogapi/facade.rb#L14
24
+ args = [
25
+ options['api_key'],
26
+ options['app_key'],
27
+ nil, # host to talk to
28
+ nil, # device
29
+ true, # silent?
30
+ api_timeout, # API timeout
31
+ ]
32
+ @dog = Dogapi::Client.new(*args)
33
+
20
34
  @existing_alerts = nil
21
35
 
22
36
  # create datadog alerts 10 at a time
@@ -34,9 +48,19 @@ module Interferon::Destinations
34
48
  }
35
49
  end
36
50
 
51
+ def api_errors
52
+ @api_errors ||= []
53
+ end
54
+
37
55
  def existing_alerts
38
56
  unless @existing_alerts
39
57
  resp = @dog.get_all_alerts()
58
+
59
+ code = resp[0].to_i
60
+ if code != 200
61
+ raise "Failed to retrieve existing alerts from datadog. #{code.to_s}: #{resp[1].inspect}"
62
+ end
63
+
40
64
  alerts = resp[1]['alerts']
41
65
 
42
66
  # key alerts by name
@@ -87,7 +111,7 @@ module Interferon::Destinations
87
111
  resp = @dog.alert(
88
112
  alert['metric']['datadog_query'].strip,
89
113
  alert_opts,
90
- ) unless @dry_run
114
+ )
91
115
 
92
116
  # existing alert, modify it
93
117
  else
@@ -99,11 +123,14 @@ module Interferon::Destinations
99
123
  id,
100
124
  alert['metric']['datadog_query'].strip,
101
125
  alert_opts
102
- ) unless @dry_run
126
+ )
103
127
  end
104
128
 
105
129
  # log whenever we've encountered errors
106
- code = @dry_run ? 200 : resp[0].to_i
130
+ code = resp[0].to_i
131
+ if code != 200
132
+ api_errors << "#{code.to_s} on alert #{alert['name']}"
133
+ end
107
134
 
108
135
  # client error
109
136
  if code == 400
@@ -113,7 +140,8 @@ module Interferon::Destinations
113
140
 
114
141
  @stats[:api_client_errors] += 1
115
142
  log.error("client error while #{action} alert '#{alert['name']}';" \
116
- " query was '#{alert['metric']['datadog_query'].strip}'")
143
+ " query was '#{alert['metric']['datadog_query'].strip}'" \
144
+ " response was #{resp[0]}:'#{resp[1].inspect}'")
117
145
 
118
146
  # unknown (prob. datadog) error:
119
147
  elsif code >= 400 || code == -1
@@ -138,14 +166,15 @@ module Interferon::Destinations
138
166
  @stats[:alerts_silenced] += 1 if alert_opts[:silenced]
139
167
  end
140
168
 
169
+ id = resp[1].nil? ? nil : resp[1]['id']
141
170
  # lets key alerts by their name
142
- return alert['name']
171
+ return [alert['name'], id]
143
172
  end
144
173
 
145
174
  def remove_alert(alert)
146
175
  if alert['message'].include?(ALERT_KEY)
147
176
  log.debug("deleting alert #{alert['id']} (#{alert['name']})")
148
- @dog.delete_alert(alert['id']) unless @dry_run
177
+ @dog.delete_alert(alert['id'])
149
178
  @stats[:alerts_deleted] += 1
150
179
  else
151
180
  log.warn("not deleting manually-created alert #{alert['id']} (#{alert['name']})")
@@ -163,5 +192,11 @@ module Interferon::Destinations
163
192
  @stats[:alerts_deleted],
164
193
  ]
165
194
  end
195
+
196
+ def remove_alert_by_id(alert_id)
197
+ log.debug("deleting alert, id: #{alert_id}")
198
+ @dog.delete_alert(alert_id)
199
+ @stats[:alerts_deleted] += 1
200
+ end
166
201
  end
167
202
  end
@@ -1,3 +1,3 @@
1
1
  module Interferon
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.12"
3
3
  end
data/lib/interferon.rb CHANGED
@@ -18,6 +18,8 @@ module Interferon
18
18
  include Logging
19
19
  attr_accessor :host_sources, :destinations, :host_info
20
20
 
21
+ DRY_RUN_ALERTS_NAME_PREFIX = '[-dry-run-]'
22
+
21
23
  # groups_sources is a hash from type => options for each group source
22
24
  # host_sources is a hash from type => options for each host source
23
25
  # destinations is a similiar hash from type => options for each alerter
@@ -41,13 +43,11 @@ module Interferon
41
43
  groups = read_groups(@groups_sources)
42
44
  hosts = read_hosts(@host_sources)
43
45
 
44
- # make sure destinations know if it's a dry run
45
46
  @destinations.each do |dest|
46
47
  dest['options'] ||= {}
47
- dest['options']['dry_run'] = dry_run
48
48
  end
49
49
 
50
- update_alerts(@destinations, hosts, alerts, groups)
50
+ update_alerts(@destinations, hosts, alerts, groups, dry_run)
51
51
 
52
52
  if @request_shutdown
53
53
  log.info "interferon #{run_desc} shut down by SIGTERM"
@@ -133,132 +133,198 @@ module Interferon
133
133
  return hosts
134
134
  end
135
135
 
136
- def update_alerts(destinations, hosts, alerts, groups)
136
+ def update_alerts(destinations, hosts, alerts, groups, dry_run)
137
137
  loader = DestinationsLoader.new([@alerts_repo_path])
138
138
  loader.get_all(destinations).each do |dest|
139
139
  break if @request_shutdown
140
140
  log.info "updating alerts on #{dest.class.name}"
141
+ update_alerts_on_destination(dest, hosts, alerts, groups, dry_run)
142
+ end
143
+ end
141
144
 
142
- # track some counters/stats per destination
143
- start_time = Time.new.to_f
144
-
145
- # get already-defined alerts
146
- existing_alerts = dest.existing_alerts.dup
147
- existing_alerts.each{ |key, existing_alert| existing_alert['still_exists'] = false }
148
-
149
- # create or update alerts; mark when we've done that
150
- alerts_queue = Hash.new
151
- alerts.each do |alert|
152
- break if @request_shutdown
153
- counters = {
154
- :errors => 0,
155
- :evals => 0,
156
- :applies => 0,
157
- :hosts => hosts.length
158
- }
159
- last_eval_error = nil
160
-
161
- hosts.each do |hostinfo|
162
- begin
163
- alert.evaluate(hostinfo)
164
- counters[:evals] += 1
165
- rescue StandardError => e
166
- log.debug "Evaluation of alert #{alert} failed in the context of host #{hostinfo}"
167
- counters[:errors] += 1
168
- last_eval_error = e
169
- next
170
- end
145
+ def update_alerts_on_destination(dest, hosts, alerts, groups, dry_run)
146
+ # track some counters/stats per destination
147
+ start_time = Time.new.to_f
171
148
 
172
- # don't define an alert that doesn't apply to this hostinfo
173
- unless alert[:applies]
174
- log.debug "alert #{alert[:name]} doesn't apply to #{hostinfo.inspect}"
175
- next
176
- end
149
+ # get already-defined alerts
150
+ existing_alerts = dest.existing_alerts.dup
177
151
 
178
- counters[:applies] += 1
152
+ if dry_run
153
+ do_dry_run_update(dest, hosts, alerts, existing_alerts, groups)
154
+ else
155
+ do_regular_update(dest, hosts, alerts, existing_alerts, groups)
156
+ end
179
157
 
180
- # don't define alerts twice
181
- next if alerts_queue.key?(alert[:name])
158
+ unless @request_shutdown
159
+ # run time summary
160
+ run_time = Time.new.to_f - start_time
161
+ statsd.histogram(
162
+ dry_run ? 'destinations.run_time.dry_run' : 'destinations.run_time',
163
+ run_time,
164
+ :tags => ["destination:#{dest.class.name}"])
165
+ log.info "#{dest.class.name} : run completed in %.2f seconds" % (run_time)
166
+
167
+ # report destination stats
168
+ dest.report_stats
169
+ end
182
170
 
183
- # figure out who to notify
184
- people = Set.new(alert[:notify][:people])
185
- alert[:notify][:groups].each do |g|
186
- people += (groups[g] || [])
187
- end
171
+ if dry_run && !dest.api_errors.empty?
172
+ raise dest.api_errors.to_s
173
+ end
174
+ end
188
175
 
189
- # queue the alert up for creation; we clone the alert to save the current state
190
- alerts_queue[alert[:name]] ||= [alert.clone, people]
191
- end
176
+ def do_dry_run_update(dest, hosts, alerts, existing_alerts, groups)
177
+ to_remove = existing_alerts.reject{|key, a| !key.start_with?(DRY_RUN_ALERTS_NAME_PREFIX)}
178
+ alerts_queue = build_alerts_queue(hosts, alerts, groups)
179
+ alerts_queue.reject!{|name, pair| !Interferon::need_dry_run(pair[0], existing_alerts)}
180
+ alerts_queue.each do |name, pair|
181
+ alert = pair[0]
182
+ alert.change_name(DRY_RUN_ALERTS_NAME_PREFIX + alert['name'])
183
+ end
192
184
 
193
- # log some of the counters
194
- statsd.gauge('alerts.evaluate.errors', counters[:errors], :tags => ["alert:#{alert}"])
195
- statsd.gauge('alerts.evaluate.applies', counters[:applies], :tags => ["alert:#{alert}"])
185
+ # flush queue
186
+ created_alerts_key_ids = create_alerts(dest, alerts_queue)
187
+ created_alerts_ids = created_alerts_key_ids.map{|a| a[1]}
188
+ to_remove_ids = to_remove.empty? ? [] : to_remove.map{|a| a['id']}
189
+ # remove existing alerts that shouldn't exist
190
+ (created_alerts_ids + to_remove_ids).each do |id|
191
+ break if @request_shutdown
192
+ dest.remove_alert_by_id(id) unless id.nil?
193
+ end
194
+ end
196
195
 
197
- if counters[:applies] > 0
198
- log.info "alert #{alert} applies to #{counters[:applies]} of #{counters[:hosts]} hosts"
199
- end
196
+ def do_regular_update(dest, hosts, alerts, existing_alerts, groups)
197
+ existing_alerts.each{ |key, existing_alert| existing_alert['still_exists'] = false }
200
198
 
201
- # did the alert fail to evaluate on all hosts?
202
- if counters[:errors] == counters[:hosts]
203
- log.error "alert #{alert} failed to evaluate in the context of all hosts!"
204
- log.error "last error on alert #{alert}: #{last_eval_error}"
199
+ alerts_queue = build_alerts_queue(hosts, alerts, groups)
205
200
 
206
- statsd.gauge('alerts.evaluate.failed_on_all', 1, :tags => ["alert:#{alert}"])
207
- log.debug "alert #{alert}: error #{last_eval_error}\n#{last_eval_error.backtrace.join("\n")}"
208
- else
209
- statsd.gauge('alerts.evaluate.failed_on_all', 0, :tags => ["alert:#{alert}"])
210
- end
201
+ # flush queue
202
+ created_alerts_keys = create_alerts(dest, alerts_queue).map{|a| a[0]}
203
+ created_alerts_keys.each do |alert_key|
204
+ # don't delete alerts we still have defined
205
+ existing_alerts[alert_key]['still_exists'] = true if existing_alerts.include?(alert_key)
206
+ end
207
+
208
+ # remove existing alerts that shouldn't exist
209
+ to_delete = existing_alerts.reject{ |key, existing_alert| existing_alert['still_exists'] }
210
+ to_delete.each do |key, alert|
211
+ break if @request_shutdown
212
+ dest.remove_alert(alert)
213
+ end
214
+ end
211
215
 
212
- # did the alert apply to any hosts?
213
- if counters[:applies] == 0
214
- statsd.gauge('alerts.evaluate.never_applies', 1, :tags => ["alert:#{alert}"])
215
- log.warn "alert #{alert} did not apply to any hosts"
216
- else
217
- statsd.gauge('alerts.evaluate.never_applies', 0, :tags => ["alert:#{alert}"])
216
+ def create_alerts(dest, alerts_queue)
217
+ alert_key_ids = []
218
+ alerts_to_create = alerts_queue.keys
219
+ concurrency = dest.concurrency || 10
220
+ unless @request_shutdown
221
+ threads = concurrency.times.map do |i|
222
+ log.info "thread #{i} created"
223
+ t = Thread.new do
224
+ while name = alerts_to_create.shift
225
+ break if @request_shutdown
226
+ cur_alert, people = alerts_queue[name]
227
+ log.debug "creating alert for #{cur_alert[:name]}"
228
+ alert_key_ids << dest.create_alert(cur_alert, people)
229
+ end
218
230
  end
231
+ t.abort_on_exception = true
232
+ t
219
233
  end
234
+ threads.map(&:join)
235
+ end
236
+ alert_key_ids
237
+ end
220
238
 
221
- # flush queue
222
- alerts_to_create = alerts_queue.keys
223
- concurrency = dest.concurrency || 10
224
- unless @request_shutdown
225
- threads = concurrency.times.map do |i|
226
- log.info "thread #{i} created"
227
- t = Thread.new do
228
- while name = alerts_to_create.shift
229
- break if @request_shutdown
230
- cur_alert, people = alerts_queue[name]
231
-
232
- log.debug "creating alert for #{cur_alert[:name]}"
233
- alert_key = dest.create_alert(cur_alert, people)
234
-
235
- # don't delete alerts we still have defined
236
- existing_alerts[alert_key]['still_exists'] = true if existing_alerts.include?(alert_key)
237
- end
238
- end
239
- t.abort_on_exception = true
240
- t
239
+ def build_alerts_queue(hosts, alerts, groups)
240
+ # create or update alerts; mark when we've done that
241
+ alerts_queue = Hash.new
242
+ alerts.each do |alert|
243
+ break if @request_shutdown
244
+ counters = {
245
+ :errors => 0,
246
+ :evals => 0,
247
+ :applies => 0,
248
+ :hosts => hosts.length
249
+ }
250
+ last_eval_error = nil
251
+
252
+ hosts.each do |hostinfo|
253
+ begin
254
+ alert.evaluate(hostinfo)
255
+ counters[:evals] += 1
256
+ rescue StandardError => e
257
+ log.debug "Evaluation of alert #{alert} failed in the context of host #{hostinfo}"
258
+ counters[:errors] += 1
259
+ last_eval_error = e
260
+ next
241
261
  end
242
- threads.map(&:join)
262
+
263
+ # don't define an alert that doesn't apply to this hostinfo
264
+ unless alert[:applies]
265
+ log.debug "alert #{alert[:name]} doesn't apply to #{hostinfo.inspect}"
266
+ next
267
+ end
268
+
269
+ counters[:applies] += 1
270
+ # don't define alerts twice
271
+ next if alerts_queue.key?(alert[:name])
272
+
273
+ # figure out who to notify
274
+ people = Set.new(alert[:notify][:people])
275
+ alert[:notify][:groups].each do |g|
276
+ people += (groups[g] || [])
277
+ end
278
+
279
+ # queue the alert up for creation; we clone the alert to save the current state
280
+ alerts_queue[alert[:name]] ||= [alert.clone, people]
243
281
  end
244
282
 
245
- # remove existing alerts that shouldn't exist
246
- to_delete = existing_alerts.reject{ |key, existing_alert| existing_alert['still_exists'] }
247
- to_delete.each do |key, alert|
248
- break if @request_shutdown
249
- dest.remove_alert(alert)
283
+ # log some of the counters
284
+ statsd.gauge('alerts.evaluate.errors', counters[:errors], :tags => ["alert:#{alert}"])
285
+ statsd.gauge('alerts.evaluate.applies', counters[:applies], :tags => ["alert:#{alert}"])
286
+
287
+ if counters[:applies] > 0
288
+ log.info "alert #{alert} applies to #{counters[:applies]} of #{counters[:hosts]} hosts"
250
289
  end
251
290
 
252
- unless @request_shutdown
253
- # run time summary
254
- run_time = Time.new.to_f - start_time
255
- statsd.histogram('destinations.run_time', run_time, :tags => ["destination:#{dest.class.name}"])
256
- log.info "#{dest.class.name} : run completed in %.2f seconds" % (run_time)
291
+ # did the alert fail to evaluate on all hosts?
292
+ if counters[:errors] == counters[:hosts]
293
+ log.error "alert #{alert} failed to evaluate in the context of all hosts!"
294
+ log.error "last error on alert #{alert}: #{last_eval_error}"
295
+
296
+ statsd.gauge('alerts.evaluate.failed_on_all', 1, :tags => ["alert:#{alert}"])
297
+ log.debug "alert #{alert}: error #{last_eval_error}\n#{last_eval_error.backtrace.join("\n")}"
298
+ else
299
+ statsd.gauge('alerts.evaluate.failed_on_all', 0, :tags => ["alert:#{alert}"])
300
+ end
257
301
 
258
- # report destination stats
259
- dest.report_stats
302
+ # did the alert apply to any hosts?
303
+ if counters[:applies] == 0
304
+ statsd.gauge('alerts.evaluate.never_applies', 1, :tags => ["alert:#{alert}"])
305
+ log.warn "alert #{alert} did not apply to any hosts"
306
+ else
307
+ statsd.gauge('alerts.evaluate.never_applies', 0, :tags => ["alert:#{alert}"])
260
308
  end
261
309
  end
310
+ alerts_queue
311
+ end
312
+
313
+ def self.need_dry_run(alert, existing_alerts_from_api)
314
+ existing = existing_alerts_from_api[alert['name']]
315
+ if existing.nil?
316
+ true
317
+ else
318
+ !same_alerts_for_dry_run_purpose(alert, existing)
319
+ end
320
+ end
321
+
322
+ def self.same_alerts_for_dry_run_purpose(alert, alert_api_json)
323
+ query1 = alert['metric']['datadog_query']
324
+ query2 = alert_api_json['query']
325
+ query1.strip!
326
+ query2.strip!
327
+ query1 == query2
262
328
  end
263
329
  end
264
330
  end
@@ -0,0 +1,39 @@
1
+ module Interferon
2
+ module MockDSLMixin
3
+ def initialize
4
+ end
5
+
6
+ def get_or_set(field, val, block, default)
7
+ @hash ||= Hash.new
8
+ if val.nil?
9
+ return @hash[field]
10
+ else
11
+ @hash[field] = val
12
+ end
13
+ end
14
+ end
15
+
16
+ class MockAlertDSL < AlertDSL
17
+ include MockDSLMixin
18
+
19
+ def notify(v = nil)
20
+ get_or_set(:notify, v, nil, nil)
21
+ end
22
+
23
+ def metric(v = nil)
24
+ get_or_set(:metric, v, nil, nil)
25
+ end
26
+
27
+ def id(v = nil, &block)
28
+ get_or_set(:@id, v, block, '')
29
+ end
30
+ end
31
+
32
+ class MockNotifyDSL < NotifyDSL
33
+ include MockDSLMixin
34
+ end
35
+
36
+ class MockMetricDSL < MetricDSL
37
+ include MockDSLMixin
38
+ end
39
+ end
@@ -0,0 +1,11 @@
1
+ module Interferon
2
+ class MockAlert < Alert
3
+ def initialize(dsl)
4
+ @dsl = dsl
5
+ end
6
+
7
+ def []=(key, val)
8
+ @dsl.get_or_set(("@"+ key).to_sym, val, nil, nil)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+ require 'helpers/mock_alert'
3
+ require 'helpers/dsl_helper'
4
+ require 'interferon/destinations/datadog'
5
+
6
+ include Interferon
7
+
8
+ describe Interferon::Interferon do
9
+ it "would not be dry run if only alert message changed" do
10
+ alert1 = create_test_alert('name1', 'testquery', 'message1')
11
+ alert2 = mock_alert_json('name2', 'testquery', 'message2')
12
+
13
+ expect(Interferon::Interferon.same_alerts_for_dry_run_purpose(alert1, alert2)).to be true
14
+ end
15
+
16
+ it "would be dry run if alert datadog query changed" do
17
+ alert1 = create_test_alert('name1', 'testquery1', 'message1')
18
+ alert2 = mock_alert_json('name2', 'testquery2', 'message2')
19
+
20
+ expect(Interferon::Interferon.same_alerts_for_dry_run_purpose(alert1, alert2)).to be false
21
+ end
22
+
23
+ context "dry_run_update_alerts_on_destination" do
24
+ let(:the_existing_alerts) {mock_existing_alerts}
25
+ let(:dest) {MockDest.new(the_existing_alerts)}
26
+ before do
27
+ allow_any_instance_of(MockAlert).to receive(:evaluate)
28
+ allow(dest).to receive(:remove_alert_by_id)
29
+ allow(dest).to receive(:report_stats)
30
+ end
31
+
32
+ it 'dry run does not re-run existing alerts' do
33
+ alerts = mock_existing_alerts
34
+ interferon = Interferon::Interferon.new(nil,nil,nil,nil)
35
+ expect(dest).not_to receive(:create_alert)
36
+ expect(dest).not_to receive(:remove_alert_by_id)
37
+
38
+ interferon.update_alerts_on_destination(dest, ['host'], [alerts['name1'], alerts['name2']], {}, true)
39
+ end
40
+
41
+ it 'dry run runs added alerts' do
42
+ alerts = mock_existing_alerts
43
+ interferon = Interferon::Interferon.new(nil,nil,nil,nil)
44
+ added = create_test_alert('name3', 'testquery3', '')
45
+ expect(dest).to receive(:create_alert).once.and_call_original
46
+ expect(dest).to receive(:remove_alert_by_id).with('[-dry-run-]name3').once
47
+
48
+ interferon.update_alerts_on_destination(dest, ['host'], [alerts['name1'], alerts['name2'], added], {}, true)
49
+ end
50
+
51
+ it 'dry run runs updated alerts' do
52
+ alerts = mock_existing_alerts
53
+ interferon = Interferon::Interferon.new(nil,nil,nil,nil)
54
+ added = create_test_alert('name1', 'testquery3', '')
55
+ expect(dest).to receive(:create_alert).once.and_call_original
56
+ expect(dest).to receive(:remove_alert_by_id).with('[-dry-run-]name1').once
57
+
58
+ interferon.update_alerts_on_destination(dest, ['host'], [added], {}, true)
59
+ end
60
+
61
+ def mock_existing_alerts
62
+ alert1 = mock_alert_json('name1', 'testquery1', '')
63
+ alert2 = mock_alert_json('name2', 'testquery2', '')
64
+ {'name1'=>alert1, 'name2'=>alert2}
65
+ end
66
+
67
+ class MockDest < Interferon::Destinations::Datadog
68
+ @existing_alerts
69
+
70
+ def initialize(the_existing_alerts)
71
+ @existing_alerts = the_existing_alerts
72
+ end
73
+
74
+ def create_alert(alert, people)
75
+ name = alert['name']
76
+ [name, name]
77
+ end
78
+
79
+ def existing_alerts
80
+ @existing_alerts
81
+ end
82
+ end
83
+ end
84
+
85
+ def mock_alert_json(name, datadog_query, message)
86
+ {'name'=> name,'query'=> datadog_query,'message'=> message}
87
+ end
88
+
89
+ def create_test_alert(name, datadog_query, message)
90
+ alert_dsl = MockAlertDSL.new
91
+ metric_dsl = MockMetricDSL.new
92
+ metric_dsl.datadog_query(datadog_query)
93
+ alert_dsl.metric(metric_dsl)
94
+ alert_dsl.name(name)
95
+ alert_dsl.applies(true)
96
+ alert_dsl.message(message)
97
+ notify_dsl = MockNotifyDSL.new
98
+ notify_dsl.groups(['a'])
99
+ alert_dsl.notify(notify_dsl)
100
+ MockAlert.new(alert_dsl)
101
+ end
102
+ end
metadata CHANGED
@@ -1,104 +1,104 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interferon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Serebryany
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-28 00:00:00.000000000 Z
11
+ date: 2016-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dogapi
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.11'
20
- - - '>='
20
+ - - ">="
21
21
  - !ruby/object:Gem::Version
22
22
  version: 1.11.1
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
29
  version: '1.11'
30
- - - '>='
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.11.1
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: aws-sdk
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ~>
37
+ - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '1.35'
40
- - - '>='
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: 1.35.1
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ~>
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
49
  version: '1.35'
50
- - - '>='
50
+ - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 1.35.1
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: dogstatsd-ruby
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - ~>
57
+ - - "~>"
58
58
  - !ruby/object:Gem::Version
59
59
  version: '1.4'
60
- - - '>='
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: 1.4.1
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ~>
67
+ - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '1.4'
70
- - - '>='
70
+ - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: 1.4.1
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: rspec
75
75
  requirement: !ruby/object:Gem::Requirement
76
76
  requirements:
77
- - - ~>
77
+ - - "~>"
78
78
  - !ruby/object:Gem::Version
79
79
  version: '3.2'
80
80
  type: :development
81
81
  prerelease: false
82
82
  version_requirements: !ruby/object:Gem::Requirement
83
83
  requirements:
84
- - - ~>
84
+ - - "~>"
85
85
  - !ruby/object:Gem::Version
86
86
  version: '3.2'
87
87
  - !ruby/object:Gem::Dependency
88
88
  name: pry
89
89
  requirement: !ruby/object:Gem::Requirement
90
90
  requirements:
91
- - - ~>
91
+ - - "~>"
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0.10'
94
94
  type: :development
95
95
  prerelease: false
96
96
  version_requirements: !ruby/object:Gem::Requirement
97
97
  requirements:
98
- - - ~>
98
+ - - "~>"
99
99
  - !ruby/object:Gem::Version
100
100
  version: '0.10'
101
- description: ': Store metrics alerts in code!'
101
+ description: ": Store metrics alerts in code!"
102
102
  email:
103
103
  - igor.serebryany@airbnb.com
104
104
  executables:
@@ -106,8 +106,8 @@ executables:
106
106
  extensions: []
107
107
  extra_rdoc_files: []
108
108
  files:
109
- - .gitignore
110
- - .travis.yml
109
+ - ".gitignore"
110
+ - ".travis.yml"
111
111
  - Gemfile
112
112
  - LICENSE
113
113
  - README.md
@@ -135,12 +135,15 @@ files:
135
135
  - spec/fixtures/loaders2/test_sources/order_test_source.rb
136
136
  - spec/fixtures/loaders2/test_sources/secondary_source.rb
137
137
  - spec/fixtures/loaders2/test_sources/test_source.rb
138
+ - spec/helpers/dsl_helper.rb
138
139
  - spec/helpers/loader_helper.rb
139
140
  - spec/helpers/logging_helper.rb
141
+ - spec/helpers/mock_alert.rb
140
142
  - spec/helpers/optica_helper.rb
141
143
  - spec/lib/interferon/host_sources/optica_services_spec.rb
142
144
  - spec/lib/interferon/host_sources/optica_spec.rb
143
145
  - spec/lib/interferon/loaders_spec.rb
146
+ - spec/lib/interferon_spec.rb
144
147
  - spec/spec_helper.rb
145
148
  homepage: https://www.github.com/airbnb/interferon
146
149
  licenses:
@@ -152,20 +155,20 @@ require_paths:
152
155
  - lib
153
156
  required_ruby_version: !ruby/object:Gem::Requirement
154
157
  requirements:
155
- - - '>='
158
+ - - ">="
156
159
  - !ruby/object:Gem::Version
157
160
  version: '0'
158
161
  required_rubygems_version: !ruby/object:Gem::Requirement
159
162
  requirements:
160
- - - '>='
163
+ - - ">="
161
164
  - !ruby/object:Gem::Version
162
165
  version: '0'
163
166
  requirements: []
164
167
  rubyforge_project:
165
- rubygems_version: 2.0.14
168
+ rubygems_version: 2.4.5.1
166
169
  signing_key:
167
170
  specification_version: 4
168
- summary: ': Store metrics alerts in code!'
171
+ summary: ": Store metrics alerts in code!"
169
172
  test_files:
170
173
  - spec/fixtures/loaders/host_sources/test_host_source.rb
171
174
  - spec/fixtures/loaders/test_sources/order_test_source.rb
@@ -173,10 +176,13 @@ test_files:
173
176
  - spec/fixtures/loaders2/test_sources/order_test_source.rb
174
177
  - spec/fixtures/loaders2/test_sources/secondary_source.rb
175
178
  - spec/fixtures/loaders2/test_sources/test_source.rb
179
+ - spec/helpers/dsl_helper.rb
176
180
  - spec/helpers/loader_helper.rb
177
181
  - spec/helpers/logging_helper.rb
182
+ - spec/helpers/mock_alert.rb
178
183
  - spec/helpers/optica_helper.rb
179
184
  - spec/lib/interferon/host_sources/optica_services_spec.rb
180
185
  - spec/lib/interferon/host_sources/optica_spec.rb
181
186
  - spec/lib/interferon/loaders_spec.rb
187
+ - spec/lib/interferon_spec.rb
182
188
  - spec/spec_helper.rb