interferon 0.2.2 → 0.2.4
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/.travis.yml +3 -0
- data/config.example.yaml +1 -0
- data/lib/interferon/alert.rb +0 -6
- data/lib/interferon/alert_dsl.rb +4 -0
- data/lib/interferon/destinations/datadog.rb +15 -2
- data/lib/interferon/version.rb +1 -1
- data/lib/interferon.rb +1 -1
- data/spec/lib/interferon/destinations/datadog_spec.rb +36 -8
- data/spec/lib/interferon_spec.rb +79 -32
- data/spec/spec_helper.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e832b3eccfa9cec75b1e26dba0384209817c3e7e
|
4
|
+
data.tar.gz: 7d3673b1f98c3109f5a2b389c20cf91f6d5ddfe5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84ad9260f477f30a7711a7807f3f09df804a43c77493d931febbc9eb98d888441370046f3a7093c78b863b22ec625bd4eeec1c8241376710828fb7c85df591ea
|
7
|
+
data.tar.gz: 3fd09fa405794191e7398297511ae86e7f5d63255adf9828088351955aa339a058780801cdb3108672fed97dbb8ebf936b5db7e7866b9d3e636404cb88841330
|
data/.travis.yml
CHANGED
data/config.example.yaml
CHANGED
data/lib/interferon/alert.rb
CHANGED
data/lib/interferon/alert_dsl.rb
CHANGED
@@ -37,6 +37,7 @@ module Interferon::Destinations
|
|
37
37
|
@dog = Dogapi::Client.new(*args)
|
38
38
|
|
39
39
|
@existing_alerts = nil
|
40
|
+
@max_mute_minutes = options['max_mute_minutes']
|
40
41
|
@dry_run = options['dry_run']
|
41
42
|
|
42
43
|
# Datadog communication threads
|
@@ -154,6 +155,10 @@ module Interferon::Destinations
|
|
154
155
|
timeout_h: alert['timeout_h'],
|
155
156
|
}
|
156
157
|
|
158
|
+
unless alert['notify']['include_tags'].nil?
|
159
|
+
alert_options[:include_tags] = alert['notify']['include_tags']
|
160
|
+
end
|
161
|
+
|
157
162
|
unless alert['evaluation_delay'].nil?
|
158
163
|
alert_options[:evaluation_delay] = alert['evaluation_delay']
|
159
164
|
end
|
@@ -271,9 +276,15 @@ EOM
|
|
271
276
|
monitor_options
|
272
277
|
)
|
273
278
|
|
274
|
-
# Unmute existing alerts that
|
279
|
+
# Unmute existing alerts that exceed the max silenced time
|
275
280
|
# Datadog does not allow updates to silencing via the update_alert API call.
|
276
|
-
|
281
|
+
silenced = existing_alert['options']['silenced']
|
282
|
+
if !@max_mute_minutes.nil?
|
283
|
+
silenced = silenced.values.reject do |t|
|
284
|
+
t.nil? || t == '*' || t > Time.now.to_i + @max_mute_minutes * 60
|
285
|
+
end
|
286
|
+
@dog.unmute_monitor(id) if alert_options[:silenced].empty? && silenced.empty?
|
287
|
+
elsif alert_options[:silenced].empty? && !silenced.empty?
|
277
288
|
@dog.unmute_monitor(id)
|
278
289
|
end
|
279
290
|
else
|
@@ -338,6 +349,7 @@ EOM
|
|
338
349
|
query: alert_api_json['query'].strip,
|
339
350
|
message: alert_api_json['message'].strip,
|
340
351
|
evaluation_delay: alert_api_json['options']['evaluation_delay'],
|
352
|
+
include_tags: alert_api_json['options']['include_tags'],
|
341
353
|
notify_no_data: alert_api_json['options']['notify_no_data'],
|
342
354
|
notify_audit: alert_api_json['options']['notify_audit'],
|
343
355
|
no_data_timeframe: alert_api_json['options']['no_data_timeframe'],
|
@@ -355,6 +367,7 @@ EOM
|
|
355
367
|
notify_recovery: alert['notify']['recovery']
|
356
368
|
).strip,
|
357
369
|
evaluation_delay: alert['evaluation_delay'],
|
370
|
+
include_tags: alert['notify']['include_tags'],
|
358
371
|
notify_no_data: alert['notify_no_data'],
|
359
372
|
notify_audit: alert['notify']['audit'],
|
360
373
|
no_data_timeframe: alert['no_data_timeframe'],
|
data/lib/interferon/version.rb
CHANGED
data/lib/interferon.rb
CHANGED
@@ -148,7 +148,7 @@ module Interferon
|
|
148
148
|
def update_alerts(destinations, hosts, alerts, groups)
|
149
149
|
alerts_queue, alert_errors = build_alerts_queue(hosts, alerts, groups)
|
150
150
|
if @dry_run && !alert_errors.empty?
|
151
|
-
erroneous_alert_files =
|
151
|
+
erroneous_alert_files = alert_errors.map(&:to_s).join(', ')
|
152
152
|
raise "Alerts failed to apply or evaluate for all hosts: #{erroneous_alert_files}"
|
153
153
|
end
|
154
154
|
|
@@ -3,19 +3,27 @@ require 'interferon/destinations/datadog'
|
|
3
3
|
|
4
4
|
describe Interferon::Destinations::Datadog do
|
5
5
|
let(:retries) { 3 }
|
6
|
-
let(:
|
7
|
-
|
6
|
+
let(:max_mute_minutes) { 60 }
|
7
|
+
let(:base_datadog_config) do
|
8
|
+
{
|
8
9
|
'api_key' => 'TEST_API_KEY',
|
9
10
|
'app_key' => 'TEST_APP_KEY',
|
10
|
-
'retries' => retries
|
11
|
+
'retries' => retries,
|
12
|
+
}
|
13
|
+
end
|
14
|
+
let(:datadog) do
|
15
|
+
Interferon::Destinations::Datadog.new(
|
16
|
+
base_datadog_config
|
11
17
|
)
|
12
18
|
end
|
13
19
|
let(:datadog_dry_run) do
|
14
20
|
Interferon::Destinations::Datadog.new(
|
15
|
-
'
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
base_datadog_config.merge('dry_run' => true)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
let(:datadog_max_mute) do
|
25
|
+
Interferon::Destinations::Datadog.new(
|
26
|
+
base_datadog_config.merge('max_mute_minutes' => max_mute_minutes)
|
19
27
|
)
|
20
28
|
end
|
21
29
|
let(:mock_alert_id) { 123 }
|
@@ -80,7 +88,7 @@ describe Interferon::Destinations::Datadog do
|
|
80
88
|
datadog.create_alert(mock_alert, mock_people)
|
81
89
|
end
|
82
90
|
|
83
|
-
it 'calls dogapi to unmute when
|
91
|
+
it 'calls dogapi to unmute when existing alert is muted' do
|
84
92
|
expect_any_instance_of(Dogapi::Client).to receive(:update_monitor).and_return([200, ''])
|
85
93
|
expect_any_instance_of(Dogapi::Client).to receive(:unmute_monitor).and_return([200, ''])
|
86
94
|
mock_response['Test Alert']['options']['silenced'] = { '*' => nil }
|
@@ -88,6 +96,26 @@ describe Interferon::Destinations::Datadog do
|
|
88
96
|
datadog.create_alert(mock_alert, mock_people)
|
89
97
|
end
|
90
98
|
|
99
|
+
it 'calls dogapi to unmute when existing mute exceed max_mute_minutes' do
|
100
|
+
expect_any_instance_of(Dogapi::Client).to receive(:update_monitor).and_return([200, ''])
|
101
|
+
expect_any_instance_of(Dogapi::Client).to receive(:unmute_monitor).and_return([200, ''])
|
102
|
+
mock_response['Test Alert']['options']['silenced'] = {
|
103
|
+
'*' => Time.now.to_i + max_mute_minutes * 60 + 10,
|
104
|
+
}
|
105
|
+
expect(datadog_max_mute).to receive(:existing_alerts).and_return(mock_response)
|
106
|
+
datadog_max_mute.create_alert(mock_alert, mock_people)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'calls dogapi to keep mute when existing mute does not exceed max_mute_minutes' do
|
110
|
+
expect_any_instance_of(Dogapi::Client).to receive(:update_monitor).and_return([200, ''])
|
111
|
+
expect_any_instance_of(Dogapi::Client).not_to receive(:unmute_monitor)
|
112
|
+
mock_response['Test Alert']['options']['silenced'] = {
|
113
|
+
'*' => Time.now.to_i + max_mute_minutes * 60 - 10,
|
114
|
+
}
|
115
|
+
expect(datadog_max_mute).to receive(:existing_alerts).and_return(mock_response)
|
116
|
+
datadog_max_mute.create_alert(mock_alert, mock_people)
|
117
|
+
end
|
118
|
+
|
91
119
|
it 'calls validate monitor in dry-run' do
|
92
120
|
expect_any_instance_of(Dogapi::Client).to receive(:validate_monitor).and_return([200, ''])
|
93
121
|
expect(datadog_dry_run).to receive(:existing_alerts).and_return(mock_response)
|
data/spec/lib/interferon_spec.rb
CHANGED
@@ -8,62 +8,107 @@ describe Interferon::Destinations::Datadog do
|
|
8
8
|
let(:the_existing_alerts) { mock_existing_alerts }
|
9
9
|
let(:dest) { MockDest.new(the_existing_alerts) }
|
10
10
|
|
11
|
-
|
11
|
+
shared_examples_for 'alert_option' do |alert_option, same_value, different_value, alert_dsl|
|
12
|
+
let(:json_message) { 'message' + "\n#{Interferon::Destinations::Datadog::ALERT_KEY}" }
|
13
|
+
let(:alert) do
|
14
|
+
alert_dsl_path = alert_dsl.nil? ? alert_option : alert_dsl
|
15
|
+
create_test_alert('name1', 'testquery', 'message', alert_dsl_path => same_value)
|
16
|
+
end
|
17
|
+
let(:alert_same) do
|
18
|
+
mock_alert_json(
|
19
|
+
'name2', 'testquery', json_message, 'metric alert', [1], alert_option => same_value
|
20
|
+
)
|
21
|
+
end
|
22
|
+
let(:alert_diff) do
|
23
|
+
mock_alert_json(
|
24
|
+
'name2', 'testquery', json_message, 'metric_alert', [1], alert_option => different_value
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when the options are the same' do
|
29
|
+
it 'should return true' do
|
30
|
+
expect(Interferon::Destinations::Datadog.same_alerts(alert, [], alert_same)).to be true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when the options are the different' do
|
35
|
+
it 'should return false' do
|
36
|
+
expect(Interferon::Destinations::Datadog.same_alerts(alert, [], alert_diff)).to be false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#same_alerts' do
|
42
|
+
let(:json_message) { 'message' + "\n#{Interferon::Destinations::Datadog::ALERT_KEY}" }
|
43
|
+
|
44
|
+
it 'detects a no change if alert message is the same' do
|
45
|
+
alert1 = create_test_alert('name1', 'testquery', 'message')
|
46
|
+
alert2 = mock_alert_json('name2', 'testquery', json_message)
|
47
|
+
|
48
|
+
expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be true
|
49
|
+
end
|
50
|
+
|
12
51
|
it 'detects a change if alert message is different' do
|
13
|
-
alert1 = create_test_alert('name1', 'testquery', '
|
14
|
-
alert2 = mock_alert_json('name2', 'testquery',
|
52
|
+
alert1 = create_test_alert('name1', 'testquery', 'message2')
|
53
|
+
alert2 = mock_alert_json('name2', 'testquery', json_message)
|
15
54
|
|
16
55
|
expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be false
|
17
56
|
end
|
18
57
|
|
19
|
-
it 'detects
|
20
|
-
alert1 = create_test_alert('name1', '
|
21
|
-
alert2 = mock_alert_json('name2', '
|
58
|
+
it 'detects no change if datadog query is the same' do
|
59
|
+
alert1 = create_test_alert('name1', 'testquery', 'message')
|
60
|
+
alert2 = mock_alert_json('name2', 'testquery', json_message)
|
22
61
|
|
23
|
-
expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be
|
62
|
+
expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be true
|
24
63
|
end
|
25
64
|
|
26
|
-
it 'detects a change if
|
27
|
-
alert1 = create_test_alert('name1', 'testquery1', '
|
28
|
-
alert2 = mock_alert_json('name2', 'testquery2',
|
65
|
+
it 'detects a change if datadog query is different' do
|
66
|
+
alert1 = create_test_alert('name1', 'testquery1', 'message')
|
67
|
+
alert2 = mock_alert_json('name2', 'testquery2', json_message)
|
29
68
|
|
30
69
|
expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be false
|
31
70
|
end
|
32
71
|
|
33
|
-
|
34
|
-
|
35
|
-
|
72
|
+
context 'notify_no_data option' do
|
73
|
+
it_behaves_like('alert_option', 'notify_no_data', true, false)
|
74
|
+
end
|
36
75
|
|
37
|
-
|
76
|
+
context 'silenced option' do
|
77
|
+
it_behaves_like('alert_option', 'silenced', { 'silenced' => '*' }, false)
|
38
78
|
end
|
39
79
|
|
40
|
-
|
41
|
-
|
42
|
-
|
80
|
+
context 'no_data_timeframe option' do
|
81
|
+
it_behaves_like('alert_option', 'no_data_timeframe', nil, 60)
|
82
|
+
end
|
43
83
|
|
44
|
-
|
84
|
+
context 'require_full_window option' do
|
85
|
+
it_behaves_like('alert_option', 'require_full_window', false, true)
|
45
86
|
end
|
46
87
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
'name2', 'testquery2', 'message2', nil, [1], require_full_window: true
|
51
|
-
)
|
88
|
+
context 'evaluation_delay option' do
|
89
|
+
it_behaves_like('alert_option', 'evaluation_delay', nil, 300)
|
90
|
+
end
|
52
91
|
|
53
|
-
|
92
|
+
context 'thresholds option' do
|
93
|
+
it_behaves_like('alert_option', 'thresholds', nil, 'critical' => 1)
|
54
94
|
end
|
55
95
|
|
56
|
-
|
57
|
-
|
58
|
-
|
96
|
+
context 'timeout_h option' do
|
97
|
+
it_behaves_like('alert_option', 'timeout_h', nil, 300)
|
98
|
+
end
|
59
99
|
|
60
|
-
|
100
|
+
context 'include_tags option' do
|
101
|
+
it_behaves_like('alert_option', 'include_tags', true, false, 'notify' => 'include_tags')
|
61
102
|
end
|
62
103
|
|
63
|
-
|
64
|
-
|
104
|
+
context 'notify_audit option' do
|
105
|
+
it_behaves_like('alert_option', 'notify_audit', true, false, 'notify' => 'audit')
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'detects no change if alert silenced is true compared to wildcard hash' do
|
109
|
+
alert1 = create_test_alert('name1', 'testquery', 'message', 'silenced' => true)
|
65
110
|
alert2 = mock_alert_json(
|
66
|
-
'
|
111
|
+
'name2', 'testquery', json_message, 'metric alert', [1], 'silenced' => { '*' => nil }
|
67
112
|
)
|
68
113
|
|
69
114
|
expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be true
|
@@ -271,7 +316,6 @@ describe Interferon::Destinations::Datadog do
|
|
271
316
|
|
272
317
|
def mock_alert_json(name, datadog_query, message, type = 'metric alert', id = nil, options = {})
|
273
318
|
options = DEFAULT_OPTIONS.merge(options)
|
274
|
-
|
275
319
|
{
|
276
320
|
'name' => name,
|
277
321
|
'query' => datadog_query,
|
@@ -302,6 +346,9 @@ describe Interferon::Destinations::Datadog do
|
|
302
346
|
|
303
347
|
notify_dsl = NotifyDSL.new({})
|
304
348
|
notify_dsl.groups(['a'])
|
349
|
+
notify_dsl.audit(options['notify' => 'audit'])
|
350
|
+
notify_dsl.include_tags(options['notify' => 'include_tags'])
|
351
|
+
|
305
352
|
alert_dsl.instance_variable_set(:@notify, notify_dsl)
|
306
353
|
|
307
354
|
alert_dsl.name(name)
|
data/spec/spec_helper.rb
CHANGED
@@ -35,7 +35,7 @@ RSpec.configure do |config|
|
|
35
35
|
|
36
36
|
# This setting enables warnings. It's recommended, but in some cases may
|
37
37
|
# be too noisy due to issues in dependencies.
|
38
|
-
config.warnings =
|
38
|
+
config.warnings = false
|
39
39
|
|
40
40
|
# Many RSpec users commonly either run the entire suite or an individual
|
41
41
|
# file, and it's useful to allow more verbose output when running an
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: interferon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Serebryany
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-09-
|
12
|
+
date: 2017-09-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dogapi
|