chef-handler-datadog 0.12.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +158 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +35 -1
- data/CONTRIBUTING.md +14 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +296 -0
- data/README.md +1 -3
- data/chef-handler-datadog.gemspec +10 -10
- data/lib/chef/handler/datadog.rb +5 -5
- data/lib/chef/handler/datadog_chef_events.rb +3 -0
- data/lib/chef/handler/datadog_chef_metrics.rb +1 -1
- data/lib/chef/handler/datadog_chef_tags.rb +2 -1
- data/lib/chef_handler_datadog.rb +1 -1
- data/spec/datadog_spec.rb +198 -166
- data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_alert_handles_when_specified.yml +239 -181
- data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_event_title_correctly.yml +119 -90
- data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_priority_correctly.yml +119 -90
- data/spec/support/cassettes/Chef_Handler_Datadog/hostname/uses_the_node_name_when_no_config_specified.yml +119 -89
- data/spec/support/cassettes/Chef_Handler_Datadog/hostname/uses_the_specified_hostname_when_provided.yml +119 -89
- data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/does_not_use_the_instance_id_when_config_specified_to_false.yml +119 -89
- data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/uses_the_instance_id_when_config_is_specified.yml +119 -89
- data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/uses_the_instance_id_when_no_config_specified.yml +119 -89
- data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_events/posts_an_event.yml +119 -89
- data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_events/sets_priority_correctly.yml +119 -89
- data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_metrics/reports_metrics.yml +119 -89
- data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/sets_tags/puts_the_tags_for_the_current_node.yml +119 -89
- data/spec/support/cassettes/Chef_Handler_Datadog/resources/failure_during_compile_phase/only_emits_the_run_status_metrics.yml +74 -56
- data/spec/support/cassettes/Chef_Handler_Datadog/resources/failure_during_compile_phase/posts_an_event.yml +74 -56
- data/spec/support/cassettes/Chef_Handler_Datadog/resources/failure_during_compile_phase_with_an_elapsed_time_and_incomplete_resource_collection/only_emits_the_run_status_metrics.yml +73 -55
- data/spec/support/cassettes/Chef_Handler_Datadog/resources/failure_during_compile_phase_with_an_elapsed_time_and_incomplete_resource_collection/posts_an_event.yml +73 -55
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_policy_tags_are_enabled/sets_the_policy_name_and_policy_group_tags.yml +120 -90
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_policy_tags_are_not_enabled/does_not_set_the_policy_name_and_policy_group_tags.yml +111 -81
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_specified/allows_for_empty_scope_prefix.yml +119 -90
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_specified/allows_for_empty_tag_prefix.yml +117 -127
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_specified/allows_for_user-specified_scope_prefix.yml +119 -90
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_specified/allows_for_user-specified_tag_prefix.yml +121 -92
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_specified/sets_the_role_and_env_and_tags.yml +119 -90
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_tag_blacklist_is_specified/does_not_include_the_tag_s_specified.yml +118 -88
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_tag_blacklist_is_unspecified/should_include_all_of_the_tag_s_.yml +118 -88
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_unspecified/sets_role_env_and_nothing_else.yml +119 -90
- data/spec/support/cassettes/Chef_Handler_Datadog/tags_submission_retries/when_not_specified/does_not_retry_after_a_failed_submission.yml +112 -124
- data/spec/support/cassettes/Chef_Handler_Datadog/tags_submission_retries/when_specified_as_2_retries/retries_no_more_than_twice.yml +108 -210
- data/spec/support/cassettes/Chef_Handler_Datadog/tags_submission_retries/when_specified_as_2_retries/stops_retrying_once_submission_is_successful.yml +110 -168
- data/spec/support/cassettes/Chef_Handler_Datadog/updated_resources/posts_an_event.yml +119 -89
- metadata +9 -21
- data/.travis.yml +0 -34
- data/gemfiles/chef_12.7.gemfile +0 -16
- data/gemfiles/chef_12.gemfile +0 -16
- data/gemfiles/chef_13.gemfile +0 -16
- data/gemfiles/chef_14.gemfile +0 -16
- data/spec/support/cassettes/Chef_Handler_Datadog/handles_no_application_key/fails_when_no_application_key_is_provided.yml +0 -143
- data/spec/support/cassettes/Chef_Handler_Datadog/when_reporting_to_multiple_endpoints/emits_events/posts_an_event.yml +0 -575
- data/spec/support/cassettes/Chef_Handler_Datadog/when_reporting_to_multiple_endpoints/emits_metrics/reports_metrics.yml +0 -575
- data/spec/support/cassettes/Chef_Handler_Datadog/when_reporting_to_multiple_endpoints/sets_tags/puts_the_tags_for_the_current_node.yml +0 -575
data/README.md
CHANGED
@@ -3,9 +3,7 @@
|
|
3
3
|
An Exception and Report Handler for Chef.
|
4
4
|
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/chef-handler-datadog.svg)](http://badge.fury.io/rb/chef-handler-datadog)
|
6
|
-
[![Build Status](https://
|
7
|
-
[![Code Climate](https://codeclimate.com/github/DataDog/chef-handler-datadog/badges/gpa.svg)](https://codeclimate.com/github/DataDog/chef-handler-datadog)
|
8
|
-
[![Dependency Status](https://gemnasium.com/DataDog/chef-handler-datadog.svg)](https://gemnasium.com/DataDog/chef-handler-datadog)
|
6
|
+
[![Build Status](https://img.shields.io/circleci/build/gh/DataDog/chef-handler-datadog.svg)](https://circleci.com/gh/DataDog/chef-handler-datadog)
|
9
7
|
|
10
8
|
## Using chef-handler-datadog
|
11
9
|
|
@@ -3,19 +3,19 @@
|
|
3
3
|
require File.expand_path('lib/chef_handler_datadog', __dir__)
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
|
-
gem.name
|
7
|
-
gem.summary
|
8
|
-
gem.description
|
9
|
-
gem.license
|
10
|
-
gem.version
|
6
|
+
gem.name = 'chef-handler-datadog'
|
7
|
+
gem.summary = 'Chef Handler reports events and metrics to Datadog'
|
8
|
+
gem.description = 'This Handler will report the events and metrics for a chef-client run to Datadog.'
|
9
|
+
gem.license = 'BSD'
|
10
|
+
gem.version = ChefHandlerDatadog::VERSION
|
11
11
|
|
12
|
-
gem.files
|
13
|
-
gem.executables
|
14
|
-
gem.test_files
|
15
|
-
gem.require_paths
|
12
|
+
gem.files = `git ls-files`.split($\) # rubocop:disable Style/SpecialGlobalVars
|
13
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
+
gem.require_paths = ['lib']
|
16
16
|
gem.extra_rdoc_files = ['README.md', 'LICENSE.txt']
|
17
17
|
|
18
|
-
gem.add_dependency 'dogapi', '
|
18
|
+
gem.add_dependency 'dogapi', '~> 1.42.0'
|
19
19
|
|
20
20
|
gem.add_development_dependency 'appraisal', '~> 2.0.1'
|
21
21
|
gem.add_development_dependency 'bundler'
|
data/lib/chef/handler/datadog.rb
CHANGED
@@ -78,9 +78,9 @@ class Chef
|
|
78
78
|
@metrics.emit_to_datadog dog
|
79
79
|
@event.emit_to_datadog dog
|
80
80
|
@tags.send_update_to_datadog dog
|
81
|
-
rescue
|
82
|
-
Chef::Log.error("Could not
|
83
|
-
Chef::Log.error('
|
81
|
+
rescue => e
|
82
|
+
Chef::Log.error("Could not send/emit to Datadog:\n" + e.to_s)
|
83
|
+
Chef::Log.error('Event data to be submitted was:')
|
84
84
|
Chef::Log.error(@event.event_title)
|
85
85
|
Chef::Log.error(@event.event_body)
|
86
86
|
Chef::Log.error('Tags to be set for this run:')
|
@@ -134,7 +134,7 @@ class Chef
|
|
134
134
|
app_key,
|
135
135
|
nil, # host
|
136
136
|
nil, # device
|
137
|
-
|
137
|
+
false, # silent
|
138
138
|
nil, # timeout
|
139
139
|
url
|
140
140
|
))
|
@@ -159,7 +159,7 @@ class Chef
|
|
159
159
|
# then add extra endpoints
|
160
160
|
extra_endpoints = @config[:extra_endpoints] || []
|
161
161
|
extra_endpoints.each do |endpoint|
|
162
|
-
url = endpoint[:url] || config_url()
|
162
|
+
url = endpoint[:api_url] || endpoint[:url] || config_url()
|
163
163
|
api_key = endpoint[:api_key]
|
164
164
|
app_key = endpoint[:application_key]
|
165
165
|
endpoints << [url, api_key, app_key] if validate_keys(api_key, app_key, false)
|
@@ -50,6 +50,6 @@ class DatadogChefMetrics
|
|
50
50
|
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT => e
|
51
51
|
Chef::Log.warn("Could not send metrics to Datadog. Connection error:\n" + e)
|
52
52
|
rescue StandardError => e
|
53
|
-
Chef::Log.warn("Could not determine whether chef run metrics were successfully submitted to Datadog
|
53
|
+
Chef::Log.warn("Could not determine whether chef run metrics were successfully submitted to Datadog. Error:\n#{e}")
|
54
54
|
end
|
55
55
|
end # end class DatadogChefMetrics
|
@@ -92,6 +92,7 @@ class DatadogChefTags
|
|
92
92
|
def send_update_to_datadog(dog)
|
93
93
|
tags = combined_host_tags
|
94
94
|
retries = @retries
|
95
|
+
rc = []
|
95
96
|
begin
|
96
97
|
loop do
|
97
98
|
should_retry = false
|
@@ -114,7 +115,7 @@ class DatadogChefTags
|
|
114
115
|
break unless should_retry
|
115
116
|
end
|
116
117
|
rescue StandardError => e
|
117
|
-
Chef::Log.warn("Could not determine whether #{@hostname}'s tags were successfully submitted to Datadog: #{rc}. Error:\n#{e}")
|
118
|
+
Chef::Log.warn("Could not determine whether #{@hostname}'s tags were successfully submitted to Datadog: #{rc.inspect}. Error:\n#{e}")
|
118
119
|
end
|
119
120
|
end
|
120
121
|
|
data/lib/chef_handler_datadog.rb
CHANGED
data/spec/datadog_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
describe Chef::Handler::Datadog, :
|
4
|
+
describe Chef::Handler::Datadog, vcr: :new_episodes do
|
5
5
|
# The #report method currently long and clunky, and we need to simulate a
|
6
6
|
# Chef run to test all aspects of this, as well as push values into the test.
|
7
7
|
before(:all) do
|
@@ -18,22 +18,31 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
18
18
|
|
19
19
|
before(:each) do
|
20
20
|
@handler = Chef::Handler::Datadog.new(
|
21
|
-
:
|
22
|
-
:
|
21
|
+
api_key: API_KEY,
|
22
|
+
application_key: APPLICATION_KEY,
|
23
23
|
)
|
24
24
|
end
|
25
25
|
|
26
26
|
describe 'initialize' do
|
27
27
|
it 'should allow config hash to have string keys' do
|
28
28
|
Chef::Handler::Datadog.new(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
api_key: API_KEY,
|
30
|
+
application_key: APPLICATION_KEY,
|
31
|
+
tag_prefix: 'tag',
|
32
|
+
scope_prefix: nil
|
33
33
|
)
|
34
34
|
end
|
35
|
+
|
36
|
+
it 'should create a Dogapi client for the endpoint' do
|
37
|
+
dogs = @handler.instance_variable_get(:@dogs)
|
38
|
+
|
39
|
+
# Check that we do have a Dogapi client
|
40
|
+
expect(dogs.length).to eq(1)
|
41
|
+
end
|
35
42
|
end
|
36
43
|
|
44
|
+
|
45
|
+
|
37
46
|
describe 'reports metrics event and sets tags' do
|
38
47
|
# Construct a good run_status
|
39
48
|
before(:each) do
|
@@ -57,7 +66,7 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
57
66
|
context 'emits metrics' do
|
58
67
|
it 'reports metrics' do
|
59
68
|
expect(a_request(:post, METRICS_ENDPOINT).with(
|
60
|
-
:
|
69
|
+
query: { api_key: @handler.config[:api_key] }
|
61
70
|
)).to have_been_made.times(5)
|
62
71
|
end
|
63
72
|
end
|
@@ -65,17 +74,18 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
65
74
|
context 'emits events' do
|
66
75
|
it 'posts an event' do
|
67
76
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
68
|
-
:
|
69
|
-
:
|
70
|
-
|
71
|
-
|
77
|
+
query: { api_key: @handler.config[:api_key] },
|
78
|
+
body: hash_including(msg_text: 'Chef updated 0 resources out of 0 resources total.',
|
79
|
+
msg_title: "Chef completed in 5 seconds on #{@node.name} ",
|
80
|
+
tags: ['env:testing']),
|
72
81
|
)).to have_been_made.times(1)
|
73
82
|
end
|
74
83
|
|
75
84
|
it 'sets priority correctly' do
|
76
85
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
77
|
-
:
|
78
|
-
:
|
86
|
+
query: { api_key: @handler.config[:api_key] },
|
87
|
+
body: hash_including(alert_type: 'success',
|
88
|
+
priority: 'low'),
|
79
89
|
)).to have_been_made.times(1)
|
80
90
|
end
|
81
91
|
end
|
@@ -85,15 +95,15 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
85
95
|
# We no longer need to query the tag api for current tags,
|
86
96
|
# rather udpate only the tags for the designated source type
|
87
97
|
expect(a_request(:get, HOST_TAG_ENDPOINT + @node.name).with(
|
88
|
-
:
|
89
|
-
|
98
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
99
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
90
100
|
)).to have_been_made.times(0)
|
91
101
|
|
92
102
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
93
|
-
:
|
94
|
-
|
95
|
-
|
96
|
-
:
|
103
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
104
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
105
|
+
query: { source: 'chef' },
|
106
|
+
body: { tags: ['env:testing'] },
|
97
107
|
)).to have_been_made.times(1)
|
98
108
|
end
|
99
109
|
end
|
@@ -104,7 +114,7 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
104
114
|
@node = Chef::Node.build('chef.handler.datadog.test-ec2')
|
105
115
|
@node.send(:chef_environment, 'testing')
|
106
116
|
|
107
|
-
@node.automatic_attrs['ec2'] = { :
|
117
|
+
@node.automatic_attrs['ec2'] = { instance_id: 'i-123456' }
|
108
118
|
|
109
119
|
@run_context = Chef::RunContext.new(@node, {}, @events)
|
110
120
|
@run_status = Chef::RunStatus.new(@node, @events)
|
@@ -119,9 +129,9 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
119
129
|
@handler.run_report_unsafe(@run_status)
|
120
130
|
|
121
131
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
122
|
-
:
|
123
|
-
:
|
124
|
-
|
132
|
+
query: { api_key: @handler.config[:api_key] },
|
133
|
+
body: hash_including(msg_title: 'Chef completed in 5 seconds on i-123456 ',
|
134
|
+
host: 'i-123456'),
|
125
135
|
)).to have_been_made.times(1)
|
126
136
|
end
|
127
137
|
|
@@ -130,9 +140,9 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
130
140
|
@handler.run_report_unsafe(@run_status)
|
131
141
|
|
132
142
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
133
|
-
:
|
134
|
-
:
|
135
|
-
|
143
|
+
query: { api_key: @handler.config[:api_key] },
|
144
|
+
body: hash_including(msg_title: 'Chef completed in 5 seconds on i-123456 ',
|
145
|
+
host: 'i-123456'),
|
136
146
|
)).to have_been_made.times(1)
|
137
147
|
end
|
138
148
|
|
@@ -141,9 +151,9 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
141
151
|
@handler.run_report_unsafe(@run_status)
|
142
152
|
|
143
153
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
144
|
-
:
|
145
|
-
:
|
146
|
-
|
154
|
+
query: { api_key: @handler.config[:api_key] },
|
155
|
+
body: hash_including(msg_title: "Chef completed in 5 seconds on #{@node.name} ",
|
156
|
+
host: @node.name),
|
147
157
|
)).to have_been_made.times(1)
|
148
158
|
end
|
149
159
|
end
|
@@ -166,9 +176,9 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
166
176
|
@handler.run_report_unsafe(@run_status)
|
167
177
|
|
168
178
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
169
|
-
:
|
170
|
-
:
|
171
|
-
|
179
|
+
query: { api_key: @handler.config[:api_key] },
|
180
|
+
body: hash_including(msg_title: "Chef completed in 5 seconds on #{@node.name} ",
|
181
|
+
host: @node.name),
|
172
182
|
)).to have_been_made.times(1)
|
173
183
|
end
|
174
184
|
|
@@ -177,9 +187,9 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
177
187
|
@handler.run_report_unsafe(@run_status)
|
178
188
|
|
179
189
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
180
|
-
:
|
181
|
-
:
|
182
|
-
|
190
|
+
query: { api_key: @handler.config[:api_key] },
|
191
|
+
body: hash_including(msg_title: 'Chef completed in 5 seconds on my-imaginary-hostname.local ',
|
192
|
+
host: 'my-imaginary-hostname.local'),
|
183
193
|
)).to have_been_made.times(1)
|
184
194
|
end
|
185
195
|
end
|
@@ -209,10 +219,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
209
219
|
@handler.run_report_unsafe(@run_status)
|
210
220
|
|
211
221
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
212
|
-
:
|
213
|
-
|
214
|
-
|
215
|
-
:
|
222
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
223
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
224
|
+
query: { source: 'chef' },
|
225
|
+
body: hash_including(tags: [
|
216
226
|
'env:hostile', 'role:highlander', 'tag:the_one_and_only', 'tag:datacenter:my-cloud'
|
217
227
|
]),
|
218
228
|
)).to have_been_made.times(1)
|
@@ -224,10 +234,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
224
234
|
@handler.run_report_unsafe(@run_status)
|
225
235
|
|
226
236
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
227
|
-
:
|
228
|
-
|
229
|
-
|
230
|
-
:
|
237
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
238
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
239
|
+
query: { source: 'chef' },
|
240
|
+
body: hash_including(tags: [
|
231
241
|
'env:hostile', 'role:highlander', 'custom-prefix-the_one_and_only', 'custom-prefix-datacenter:my-cloud'
|
232
242
|
]),
|
233
243
|
)).to have_been_made.times(1)
|
@@ -239,10 +249,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
239
249
|
@handler.run_report_unsafe(@run_status)
|
240
250
|
|
241
251
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
242
|
-
:
|
243
|
-
|
244
|
-
|
245
|
-
:
|
252
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
253
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
254
|
+
query: { source: 'chef' },
|
255
|
+
body: hash_including(tags: [
|
246
256
|
'env:hostile', 'role:highlander', 'the_one_and_only', 'datacenter:my-cloud'
|
247
257
|
]),
|
248
258
|
)).to have_been_made.times(1)
|
@@ -253,10 +263,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
253
263
|
@handler.run_report_unsafe(@run_status)
|
254
264
|
|
255
265
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
256
|
-
:
|
257
|
-
|
258
|
-
|
259
|
-
:
|
266
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
267
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
268
|
+
query: { source: 'chef' },
|
269
|
+
body: hash_including(tags: [
|
260
270
|
'custom-prefix-env:hostile', 'custom-prefix-role:highlander'
|
261
271
|
]),
|
262
272
|
)).to have_been_made.times(1)
|
@@ -267,10 +277,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
267
277
|
@handler.run_report_unsafe(@run_status)
|
268
278
|
|
269
279
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
270
|
-
:
|
271
|
-
|
272
|
-
|
273
|
-
:
|
280
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
281
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
282
|
+
query: { source: 'chef' },
|
283
|
+
body: hash_including(tags: [
|
274
284
|
'env:hostile', 'role:highlander'
|
275
285
|
]),
|
276
286
|
)).to have_been_made.times(1)
|
@@ -282,10 +292,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
282
292
|
@handler.run_report_unsafe(@run_status)
|
283
293
|
|
284
294
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
285
|
-
:
|
286
|
-
|
287
|
-
|
288
|
-
:
|
295
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
296
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
297
|
+
query: { source: 'chef' },
|
298
|
+
body: hash_including(tags: [
|
289
299
|
'env:hostile', 'role:highlander'
|
290
300
|
]),
|
291
301
|
)).to have_been_made.times(1)
|
@@ -299,10 +309,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
299
309
|
@handler.run_report_unsafe(@run_status)
|
300
310
|
|
301
311
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
302
|
-
:
|
303
|
-
|
304
|
-
|
305
|
-
:
|
312
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
313
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
314
|
+
query: { source: 'chef' },
|
315
|
+
body: hash_including(tags: [
|
306
316
|
'env:hostile', 'role:highlander', 'tag:allowed_tag'
|
307
317
|
]),
|
308
318
|
)).to have_been_made.times(1)
|
@@ -315,10 +325,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
315
325
|
@handler.run_report_unsafe(@run_status)
|
316
326
|
|
317
327
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
318
|
-
:
|
319
|
-
|
320
|
-
|
321
|
-
:
|
328
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
329
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
330
|
+
query: { source: 'chef' },
|
331
|
+
body: hash_including(tags: [
|
322
332
|
'env:hostile', 'role:highlander', 'tag:allowed_tag', 'tag:not_allowed_tag'
|
323
333
|
]),
|
324
334
|
)).to have_been_made.times(1)
|
@@ -336,10 +346,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
336
346
|
@handler.run_report_unsafe(@run_status)
|
337
347
|
|
338
348
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
339
|
-
:
|
340
|
-
|
341
|
-
|
342
|
-
:
|
349
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
350
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
351
|
+
query: { source: 'chef' },
|
352
|
+
body: hash_including(tags: [
|
343
353
|
'env:hostile', 'role:highlander'
|
344
354
|
]),
|
345
355
|
)).to have_been_made.times(1)
|
@@ -358,10 +368,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
358
368
|
@handler.run_report_unsafe(@run_status)
|
359
369
|
|
360
370
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
361
|
-
:
|
362
|
-
|
363
|
-
|
364
|
-
:
|
371
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
372
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
373
|
+
query: { source: 'chef' },
|
374
|
+
body: hash_including(tags: [
|
365
375
|
'env:hostile', 'role:highlander', 'policy_group:the_policy_group', 'policy_name:the_policy_name'
|
366
376
|
]),
|
367
377
|
)).to have_been_made.times(1)
|
@@ -370,6 +380,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
370
380
|
end
|
371
381
|
|
372
382
|
context 'tags submission retries' do
|
383
|
+
let(:dog) do
|
384
|
+
@handler.instance_variable_get(:@dogs)[0]
|
385
|
+
end
|
386
|
+
|
373
387
|
before(:each) do
|
374
388
|
@node = Chef::Node.build('chef.handler.datadog.test-tags-retries')
|
375
389
|
|
@@ -380,7 +394,6 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
380
394
|
@events = Chef::EventDispatch::Dispatcher.new
|
381
395
|
@run_context = Chef::RunContext.new(@node, {}, @events)
|
382
396
|
@run_status = Chef::RunStatus.new(@node, @events)
|
383
|
-
|
384
397
|
@expected_time = Time.now
|
385
398
|
allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 5)
|
386
399
|
@run_status.start_clock
|
@@ -397,44 +410,30 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
397
410
|
end
|
398
411
|
|
399
412
|
it 'retries no more than twice' do
|
400
|
-
|
413
|
+
# Define mock update_tags function which returns the result of an HTTP 404 error
|
414
|
+
allow(dog).to receive(:update_tags).and_return([404, 'Not Found'])
|
401
415
|
|
402
|
-
expect(
|
403
|
-
|
404
|
-
'application_key' => @handler.config[:application_key],
|
405
|
-
'source' => 'chef' },
|
406
|
-
:body => hash_including(:tags => [
|
407
|
-
'env:hostile', 'role:highlander', 'tag:the_one_and_only'
|
408
|
-
]),
|
409
|
-
)).to have_been_made.times(3)
|
416
|
+
expect(dog).to receive(:update_tags).exactly(3).times
|
417
|
+
@handler.run_report_unsafe(@run_status)
|
410
418
|
end
|
411
419
|
|
412
420
|
it 'stops retrying once submission is successful' do
|
413
|
-
|
421
|
+
# Define mock update_tags function which returns the result of an HTTP 404 error once
|
422
|
+
allow(dog).to receive(:update_tags).and_return([404, 'Not Found'], [201, 'Created'])
|
414
423
|
|
415
|
-
expect(
|
416
|
-
|
417
|
-
'application_key' => @handler.config[:application_key],
|
418
|
-
'source' => 'chef' },
|
419
|
-
:body => hash_including(:tags => [
|
420
|
-
'env:hostile', 'role:highlander', 'tag:the_one_and_only'
|
421
|
-
]),
|
422
|
-
)).to have_been_made.times(2)
|
424
|
+
expect(dog).to receive(:update_tags).exactly(2).times
|
425
|
+
@handler.run_report_unsafe(@run_status)
|
423
426
|
end
|
424
427
|
end
|
425
428
|
|
426
429
|
describe 'when not specified' do
|
427
|
-
it 'does not retry after a failed submission'
|
428
|
-
|
430
|
+
it 'does not retry after a failed submission' do
|
431
|
+
# Define mock update_tags function which returns the result of an HTTP 404 error
|
432
|
+
allow(dog).to receive(:update_tags).and_return([404, 'Not Found'])
|
429
433
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
'source' => 'chef' },
|
434
|
-
:body => hash_including(:tags => [
|
435
|
-
'env:hostile', 'role:highlander', 'tag:the_one_and_only'
|
436
|
-
]),
|
437
|
-
)).to have_been_made.times(1)
|
434
|
+
|
435
|
+
expect(dog).to receive(:update_tags).exactly(:once)
|
436
|
+
@handler.run_report_unsafe(@run_status)
|
438
437
|
end
|
439
438
|
end
|
440
439
|
end
|
@@ -507,16 +506,16 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
507
506
|
|
508
507
|
it 'sets event title correctly' do
|
509
508
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
510
|
-
:
|
511
|
-
:
|
509
|
+
query: { api_key: @handler.config[:api_key] },
|
510
|
+
body: hash_including(msg_title: "Chef failed in 2 seconds on #{@node.name} "),
|
512
511
|
)).to have_been_made.times(1)
|
513
512
|
end
|
514
513
|
|
515
514
|
it 'sets priority correctly' do
|
516
515
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
517
|
-
:
|
518
|
-
:
|
519
|
-
|
516
|
+
query: { api_key: @handler.config[:api_key] },
|
517
|
+
body: hash_including(alert_type: 'error',
|
518
|
+
priority: 'normal'),
|
520
519
|
)).to have_been_made.times(1)
|
521
520
|
end
|
522
521
|
|
@@ -525,8 +524,8 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
525
524
|
@handler.run_report_unsafe(@run_status)
|
526
525
|
|
527
526
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
528
|
-
:
|
529
|
-
:
|
527
|
+
query: { api_key: @handler.config[:api_key] },
|
528
|
+
body: /Alerting: @alice @bob/
|
530
529
|
)).to have_been_made.times(1)
|
531
530
|
end
|
532
531
|
end
|
@@ -556,9 +555,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
556
555
|
|
557
556
|
it 'posts an event' do
|
558
557
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
559
|
-
:
|
560
|
-
:
|
561
|
-
:
|
558
|
+
query: { api_key: @handler.config[:api_key] },
|
559
|
+
# FIXME: msg_text is "\n$$$\n- [whiskers] (dynamically defined)\n\n$$$\n" - is this a bug?
|
560
|
+
body: hash_including(#msg_text: 'Chef updated 1 resources out of 2 resources total.',
|
561
|
+
msg_title: "Chef completed in 8 seconds on #{@node.name} "),
|
562
562
|
)).to have_been_made.times(1)
|
563
563
|
end
|
564
564
|
end
|
@@ -578,15 +578,15 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
578
578
|
|
579
579
|
it 'only emits the run status metrics' do
|
580
580
|
expect(a_request(:post, METRICS_ENDPOINT).with(
|
581
|
-
:
|
581
|
+
query: { api_key: @handler.config[:api_key] }
|
582
582
|
)).to have_been_made.times(2)
|
583
583
|
end
|
584
584
|
|
585
585
|
it 'posts an event' do
|
586
586
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
587
|
-
:
|
588
|
-
:
|
589
|
-
|
587
|
+
query: { api_key: @handler.config[:api_key] },
|
588
|
+
body: hash_including(msg_text: 'Chef was unable to complete a run, an error during compilation may have occurred.',
|
589
|
+
msg_title: "Chef failed during compile phase on #{@node.name} "),
|
590
590
|
)).to have_been_made.times(1)
|
591
591
|
end
|
592
592
|
end
|
@@ -608,15 +608,15 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
608
608
|
|
609
609
|
it 'only emits the run status metrics' do
|
610
610
|
expect(a_request(:post, METRICS_ENDPOINT).with(
|
611
|
-
:
|
611
|
+
query: { api_key: @handler.config[:api_key] }
|
612
612
|
)).to have_been_made.times(2)
|
613
613
|
end
|
614
614
|
|
615
615
|
it 'posts an event' do
|
616
616
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
617
|
-
:
|
618
|
-
:
|
619
|
-
|
617
|
+
query: { api_key: @handler.config[:api_key] },
|
618
|
+
body: hash_including(msg_text: 'Chef was unable to complete a run, an error during compilation may have occurred.',
|
619
|
+
msg_title: "Chef failed during compile phase on #{@node.name} "),
|
620
620
|
)).to have_been_made.times(1)
|
621
621
|
end
|
622
622
|
end
|
@@ -734,6 +734,31 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
734
734
|
expect(handler.send(:endpoints)).to eq(triplets[0..1])
|
735
735
|
end
|
736
736
|
end
|
737
|
+
|
738
|
+
context 'when using api url instead of url' do
|
739
|
+
it 'returns available triplets' do
|
740
|
+
triplets = [
|
741
|
+
['https://app.datadoghq.com', 'api_key_2' , 'app_key_2'],
|
742
|
+
['https://app.example.com', 'api_key_3', 'app_key_3'],
|
743
|
+
['https://app.example.com', 'api_key_4', 'app_key_4']
|
744
|
+
]
|
745
|
+
handler = Chef::Handler::Datadog.new api_key: triplets[0][1],
|
746
|
+
application_key: triplets[0][2],
|
747
|
+
url: triplets[0][0],
|
748
|
+
extra_endpoints: [{
|
749
|
+
api_url: triplets[1][0],
|
750
|
+
url: triplets[0][0],
|
751
|
+
api_key: triplets[1][1],
|
752
|
+
application_key: triplets[1][2]
|
753
|
+
}, {
|
754
|
+
api_url: triplets[2][0],
|
755
|
+
url:triplets[0][0],
|
756
|
+
api_key: triplets[2][1],
|
757
|
+
application_key: triplets[2][2]
|
758
|
+
}]
|
759
|
+
expect(handler.send(:endpoints)).to eq(triplets)
|
760
|
+
end
|
761
|
+
end
|
737
762
|
end
|
738
763
|
|
739
764
|
context 'when reporting to multiple endpoints' do
|
@@ -744,17 +769,29 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
744
769
|
let(:host_tag_endpoint2) { base_url2 + '/api/v1/tags/hosts/' }
|
745
770
|
let(:metrics_endpoint2) { base_url2 + '/api/v1/series' }
|
746
771
|
let(:handler) do
|
747
|
-
Chef::Handler::Datadog.new
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
772
|
+
Chef::Handler::Datadog.new(api_key: API_KEY,
|
773
|
+
application_key: APPLICATION_KEY,
|
774
|
+
url: BASE_URL,
|
775
|
+
extra_endpoints: [{
|
776
|
+
api_key: api_key2,
|
777
|
+
application_key: application_key2,
|
778
|
+
url: base_url2
|
779
|
+
}])
|
780
|
+
end
|
781
|
+
|
782
|
+
let(:dogs) do
|
783
|
+
handler.instance_variable_get(:@dogs)
|
755
784
|
end
|
785
|
+
|
756
786
|
# Construct a good run_status
|
757
787
|
before(:each) do
|
788
|
+
dogs.each do |dog|
|
789
|
+
# Define mock functions to avoid failures when connecting to the app.example.com endpoint
|
790
|
+
allow(dog).to receive(:emit_point).and_return(true)
|
791
|
+
allow(dog).to receive(:emit_event).and_return([200, "{'event': 'My event'}"])
|
792
|
+
allow(dog).to receive(:update_tags).and_return([201, "Created"])
|
793
|
+
end
|
794
|
+
|
758
795
|
@node = Chef::Node.build('chef.handler.datadog.test')
|
759
796
|
@node.send(:chef_environment, 'testing')
|
760
797
|
@events = Chef::EventDispatch::Dispatcher.new
|
@@ -767,56 +804,51 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
767
804
|
@run_status.stop_clock
|
768
805
|
|
769
806
|
@run_status.run_context = @run_context
|
807
|
+
end
|
770
808
|
|
771
|
-
|
772
|
-
|
809
|
+
it 'should create multiple Dogapi clients' do
|
810
|
+
expect(dogs.length).to eq(2)
|
773
811
|
end
|
774
812
|
|
775
813
|
context 'emits metrics' do
|
776
|
-
it 'reports metrics' do
|
777
|
-
expect(
|
778
|
-
:query => { 'api_key' => API_KEY }
|
779
|
-
)).to have_been_made.times(5)
|
814
|
+
it 'reports metrics to the first endpoint' do
|
815
|
+
expect(dogs[0]).to receive(:emit_point).exactly(5).times
|
780
816
|
|
781
|
-
|
782
|
-
|
783
|
-
|
817
|
+
handler.run_report_unsafe(@run_status)
|
818
|
+
end
|
819
|
+
|
820
|
+
it 'reports metrics to the second endpoint' do
|
821
|
+
expect(dogs[1]).to receive(:emit_point).exactly(5).times
|
822
|
+
|
823
|
+
handler.run_report_unsafe(@run_status)
|
784
824
|
end
|
785
825
|
end
|
786
826
|
|
787
827
|
context 'emits events' do
|
788
|
-
it 'posts an event' do
|
789
|
-
expect(
|
790
|
-
:query => { 'api_key' => API_KEY },
|
791
|
-
:body => hash_including(:msg_text => 'Chef updated 0 resources out of 0 resources total.'),
|
792
|
-
:body => hash_including(:msg_title => "Chef completed in 5 seconds on #{@node.name} "),
|
793
|
-
:body => hash_including(:tags => ['env:testing']),
|
794
|
-
)).to have_been_made.times(1)
|
828
|
+
it 'posts an event to the first endpoint' do
|
829
|
+
expect(dogs[0]).to receive(:emit_event).exactly(:once)
|
795
830
|
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
831
|
+
handler.run_report_unsafe(@run_status)
|
832
|
+
end
|
833
|
+
|
834
|
+
it 'posts an event to the second endpoint' do
|
835
|
+
expect(dogs[1]).to receive(:emit_event).exactly(:once)
|
836
|
+
|
837
|
+
handler.run_report_unsafe(@run_status)
|
802
838
|
end
|
803
839
|
end
|
804
840
|
|
805
841
|
context 'sets tags' do
|
806
|
-
it 'puts the tags for the current node' do
|
807
|
-
expect(
|
808
|
-
:query => { 'api_key' => API_KEY,
|
809
|
-
'application_key' => APPLICATION_KEY,
|
810
|
-
'source' => 'chef' },
|
811
|
-
:body => { 'tags' => ['env:testing'] },
|
812
|
-
)).to have_been_made.times(1)
|
842
|
+
it 'puts the tags for the current node on the first endpoint' do
|
843
|
+
expect(dogs[0]).to receive(:update_tags).exactly(:once)
|
813
844
|
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
845
|
+
handler.run_report_unsafe(@run_status)
|
846
|
+
end
|
847
|
+
|
848
|
+
it 'puts the tags for the current node on the second endpoint' do
|
849
|
+
expect(dogs[1]).to receive(:update_tags).exactly(:once)
|
850
|
+
|
851
|
+
handler.run_report_unsafe(@run_status)
|
820
852
|
end
|
821
853
|
end
|
822
854
|
end
|