chef-handler-datadog 0.12.1 → 0.15.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 +33 -0
- 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 +18 -13
- data/lib/chef/handler/datadog_chef_events.rb +3 -0
- data/lib/chef/handler/datadog_chef_tags.rb +2 -1
- data/lib/chef_handler_datadog.rb +1 -1
- data/spec/datadog_spec.rb +216 -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 +13 -24
- 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.44.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:')
|
@@ -129,15 +129,20 @@ class Chef
|
|
129
129
|
def prepare_the_pack
|
130
130
|
dogs = []
|
131
131
|
endpoints.each do |url, api_key, app_key|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
132
|
+
begin
|
133
|
+
dogs.push(Dogapi::Client.new(
|
134
|
+
api_key,
|
135
|
+
app_key,
|
136
|
+
nil, # host
|
137
|
+
nil, # device
|
138
|
+
false, # silent
|
139
|
+
nil, # timeout
|
140
|
+
url,
|
141
|
+
config[:skip_ssl_validation]
|
142
|
+
))
|
143
|
+
rescue => e
|
144
|
+
Chef::Log.error("Could not create API Client '#{url}'\n #{e.to_s}")
|
145
|
+
end
|
141
146
|
end
|
142
147
|
dogs
|
143
148
|
end
|
@@ -159,7 +164,7 @@ class Chef
|
|
159
164
|
# then add extra endpoints
|
160
165
|
extra_endpoints = @config[:extra_endpoints] || []
|
161
166
|
extra_endpoints.each do |endpoint|
|
162
|
-
url = endpoint[:url] || config_url()
|
167
|
+
url = endpoint[:api_url] || endpoint[:url] || config_url()
|
163
168
|
api_key = endpoint[:api_key]
|
164
169
|
app_key = endpoint[:application_key]
|
165
170
|
endpoints << [url, api_key, app_key] if validate_keys(api_key, app_key, false)
|
@@ -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,11 +187,29 @@ 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
|
195
|
+
|
196
|
+
describe 'when dogapi-rb fails to calculate a hostname' do
|
197
|
+
before(:each) do
|
198
|
+
allow(Dogapi::Client).to receive(:new).and_raise("getaddrinfo: Name or service not known")
|
199
|
+
|
200
|
+
@handler = Chef::Handler::Datadog.new(
|
201
|
+
api_key: API_KEY,
|
202
|
+
application_key: APPLICATION_KEY,
|
203
|
+
)
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'the reporter should not fail the chef run' do
|
207
|
+
@handler.config[:hostname] = 'my-imaginary-hostname.local'
|
208
|
+
@handler.run_report_unsafe(@run_status)
|
209
|
+
|
210
|
+
expect(a_request(:post, EVENTS_ENDPOINT)).to have_been_made.times(0)
|
211
|
+
end
|
212
|
+
end
|
185
213
|
end
|
186
214
|
|
187
215
|
context 'tags' do
|
@@ -209,10 +237,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
209
237
|
@handler.run_report_unsafe(@run_status)
|
210
238
|
|
211
239
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
212
|
-
:
|
213
|
-
|
214
|
-
|
215
|
-
:
|
240
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
241
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
242
|
+
query: { source: 'chef' },
|
243
|
+
body: hash_including(tags: [
|
216
244
|
'env:hostile', 'role:highlander', 'tag:the_one_and_only', 'tag:datacenter:my-cloud'
|
217
245
|
]),
|
218
246
|
)).to have_been_made.times(1)
|
@@ -224,10 +252,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
224
252
|
@handler.run_report_unsafe(@run_status)
|
225
253
|
|
226
254
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
227
|
-
:
|
228
|
-
|
229
|
-
|
230
|
-
:
|
255
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
256
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
257
|
+
query: { source: 'chef' },
|
258
|
+
body: hash_including(tags: [
|
231
259
|
'env:hostile', 'role:highlander', 'custom-prefix-the_one_and_only', 'custom-prefix-datacenter:my-cloud'
|
232
260
|
]),
|
233
261
|
)).to have_been_made.times(1)
|
@@ -239,10 +267,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
239
267
|
@handler.run_report_unsafe(@run_status)
|
240
268
|
|
241
269
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
242
|
-
:
|
243
|
-
|
244
|
-
|
245
|
-
:
|
270
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
271
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
272
|
+
query: { source: 'chef' },
|
273
|
+
body: hash_including(tags: [
|
246
274
|
'env:hostile', 'role:highlander', 'the_one_and_only', 'datacenter:my-cloud'
|
247
275
|
]),
|
248
276
|
)).to have_been_made.times(1)
|
@@ -253,10 +281,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
253
281
|
@handler.run_report_unsafe(@run_status)
|
254
282
|
|
255
283
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
256
|
-
:
|
257
|
-
|
258
|
-
|
259
|
-
:
|
284
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
285
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
286
|
+
query: { source: 'chef' },
|
287
|
+
body: hash_including(tags: [
|
260
288
|
'custom-prefix-env:hostile', 'custom-prefix-role:highlander'
|
261
289
|
]),
|
262
290
|
)).to have_been_made.times(1)
|
@@ -267,10 +295,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
267
295
|
@handler.run_report_unsafe(@run_status)
|
268
296
|
|
269
297
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
270
|
-
:
|
271
|
-
|
272
|
-
|
273
|
-
:
|
298
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
299
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
300
|
+
query: { source: 'chef' },
|
301
|
+
body: hash_including(tags: [
|
274
302
|
'env:hostile', 'role:highlander'
|
275
303
|
]),
|
276
304
|
)).to have_been_made.times(1)
|
@@ -282,10 +310,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
282
310
|
@handler.run_report_unsafe(@run_status)
|
283
311
|
|
284
312
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
285
|
-
:
|
286
|
-
|
287
|
-
|
288
|
-
:
|
313
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
314
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
315
|
+
query: { source: 'chef' },
|
316
|
+
body: hash_including(tags: [
|
289
317
|
'env:hostile', 'role:highlander'
|
290
318
|
]),
|
291
319
|
)).to have_been_made.times(1)
|
@@ -299,10 +327,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
299
327
|
@handler.run_report_unsafe(@run_status)
|
300
328
|
|
301
329
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
302
|
-
:
|
303
|
-
|
304
|
-
|
305
|
-
:
|
330
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
331
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
332
|
+
query: { source: 'chef' },
|
333
|
+
body: hash_including(tags: [
|
306
334
|
'env:hostile', 'role:highlander', 'tag:allowed_tag'
|
307
335
|
]),
|
308
336
|
)).to have_been_made.times(1)
|
@@ -315,10 +343,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
315
343
|
@handler.run_report_unsafe(@run_status)
|
316
344
|
|
317
345
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
318
|
-
:
|
319
|
-
|
320
|
-
|
321
|
-
:
|
346
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
347
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
348
|
+
query: { source: 'chef' },
|
349
|
+
body: hash_including(tags: [
|
322
350
|
'env:hostile', 'role:highlander', 'tag:allowed_tag', 'tag:not_allowed_tag'
|
323
351
|
]),
|
324
352
|
)).to have_been_made.times(1)
|
@@ -336,10 +364,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
336
364
|
@handler.run_report_unsafe(@run_status)
|
337
365
|
|
338
366
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
339
|
-
:
|
340
|
-
|
341
|
-
|
342
|
-
:
|
367
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
368
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
369
|
+
query: { source: 'chef' },
|
370
|
+
body: hash_including(tags: [
|
343
371
|
'env:hostile', 'role:highlander'
|
344
372
|
]),
|
345
373
|
)).to have_been_made.times(1)
|
@@ -358,10 +386,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
358
386
|
@handler.run_report_unsafe(@run_status)
|
359
387
|
|
360
388
|
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
361
|
-
:
|
362
|
-
|
363
|
-
|
364
|
-
:
|
389
|
+
headers: { 'Dd-Api-Key' => @handler.config[:api_key],
|
390
|
+
'Dd-Application-Key' => @handler.config[:application_key] },
|
391
|
+
query: { source: 'chef' },
|
392
|
+
body: hash_including(tags: [
|
365
393
|
'env:hostile', 'role:highlander', 'policy_group:the_policy_group', 'policy_name:the_policy_name'
|
366
394
|
]),
|
367
395
|
)).to have_been_made.times(1)
|
@@ -370,6 +398,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
370
398
|
end
|
371
399
|
|
372
400
|
context 'tags submission retries' do
|
401
|
+
let(:dog) do
|
402
|
+
@handler.instance_variable_get(:@dogs)[0]
|
403
|
+
end
|
404
|
+
|
373
405
|
before(:each) do
|
374
406
|
@node = Chef::Node.build('chef.handler.datadog.test-tags-retries')
|
375
407
|
|
@@ -380,7 +412,6 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
380
412
|
@events = Chef::EventDispatch::Dispatcher.new
|
381
413
|
@run_context = Chef::RunContext.new(@node, {}, @events)
|
382
414
|
@run_status = Chef::RunStatus.new(@node, @events)
|
383
|
-
|
384
415
|
@expected_time = Time.now
|
385
416
|
allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 5)
|
386
417
|
@run_status.start_clock
|
@@ -397,44 +428,30 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
397
428
|
end
|
398
429
|
|
399
430
|
it 'retries no more than twice' do
|
400
|
-
|
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'])
|
401
433
|
|
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)
|
434
|
+
expect(dog).to receive(:update_tags).exactly(3).times
|
435
|
+
@handler.run_report_unsafe(@run_status)
|
410
436
|
end
|
411
437
|
|
412
438
|
it 'stops retrying once submission is successful' do
|
413
|
-
|
439
|
+
# Define mock update_tags function which returns the result of an HTTP 404 error once
|
440
|
+
allow(dog).to receive(:update_tags).and_return([404, 'Not Found'], [201, 'Created'])
|
414
441
|
|
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)
|
442
|
+
expect(dog).to receive(:update_tags).exactly(2).times
|
443
|
+
@handler.run_report_unsafe(@run_status)
|
423
444
|
end
|
424
445
|
end
|
425
446
|
|
426
447
|
describe 'when not specified' do
|
427
|
-
it 'does not retry after a failed submission'
|
428
|
-
|
448
|
+
it 'does not retry after a failed submission' do
|
449
|
+
# Define mock update_tags function which returns the result of an HTTP 404 error
|
450
|
+
allow(dog).to receive(:update_tags).and_return([404, 'Not Found'])
|
429
451
|
|
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)
|
452
|
+
|
453
|
+
expect(dog).to receive(:update_tags).exactly(:once)
|
454
|
+
@handler.run_report_unsafe(@run_status)
|
438
455
|
end
|
439
456
|
end
|
440
457
|
end
|
@@ -507,16 +524,16 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
507
524
|
|
508
525
|
it 'sets event title correctly' do
|
509
526
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
510
|
-
:
|
511
|
-
:
|
527
|
+
query: { api_key: @handler.config[:api_key] },
|
528
|
+
body: hash_including(msg_title: "Chef failed in 2 seconds on #{@node.name} "),
|
512
529
|
)).to have_been_made.times(1)
|
513
530
|
end
|
514
531
|
|
515
532
|
it 'sets priority correctly' do
|
516
533
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
517
|
-
:
|
518
|
-
:
|
519
|
-
|
534
|
+
query: { api_key: @handler.config[:api_key] },
|
535
|
+
body: hash_including(alert_type: 'error',
|
536
|
+
priority: 'normal'),
|
520
537
|
)).to have_been_made.times(1)
|
521
538
|
end
|
522
539
|
|
@@ -525,8 +542,8 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
525
542
|
@handler.run_report_unsafe(@run_status)
|
526
543
|
|
527
544
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
528
|
-
:
|
529
|
-
:
|
545
|
+
query: { api_key: @handler.config[:api_key] },
|
546
|
+
body: /Alerting: @alice @bob/
|
530
547
|
)).to have_been_made.times(1)
|
531
548
|
end
|
532
549
|
end
|
@@ -556,9 +573,10 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
556
573
|
|
557
574
|
it 'posts an event' do
|
558
575
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
559
|
-
:
|
560
|
-
:
|
561
|
-
:
|
576
|
+
query: { api_key: @handler.config[:api_key] },
|
577
|
+
# FIXME: msg_text is "\n$$$\n- [whiskers] (dynamically defined)\n\n$$$\n" - is this a bug?
|
578
|
+
body: hash_including(#msg_text: 'Chef updated 1 resources out of 2 resources total.',
|
579
|
+
msg_title: "Chef completed in 8 seconds on #{@node.name} "),
|
562
580
|
)).to have_been_made.times(1)
|
563
581
|
end
|
564
582
|
end
|
@@ -578,15 +596,15 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
578
596
|
|
579
597
|
it 'only emits the run status metrics' do
|
580
598
|
expect(a_request(:post, METRICS_ENDPOINT).with(
|
581
|
-
:
|
599
|
+
query: { api_key: @handler.config[:api_key] }
|
582
600
|
)).to have_been_made.times(2)
|
583
601
|
end
|
584
602
|
|
585
603
|
it 'posts an event' do
|
586
604
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
587
|
-
:
|
588
|
-
:
|
589
|
-
|
605
|
+
query: { api_key: @handler.config[:api_key] },
|
606
|
+
body: hash_including(msg_text: 'Chef was unable to complete a run, an error during compilation may have occurred.',
|
607
|
+
msg_title: "Chef failed during compile phase on #{@node.name} "),
|
590
608
|
)).to have_been_made.times(1)
|
591
609
|
end
|
592
610
|
end
|
@@ -608,15 +626,15 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
608
626
|
|
609
627
|
it 'only emits the run status metrics' do
|
610
628
|
expect(a_request(:post, METRICS_ENDPOINT).with(
|
611
|
-
:
|
629
|
+
query: { api_key: @handler.config[:api_key] }
|
612
630
|
)).to have_been_made.times(2)
|
613
631
|
end
|
614
632
|
|
615
633
|
it 'posts an event' do
|
616
634
|
expect(a_request(:post, EVENTS_ENDPOINT).with(
|
617
|
-
:
|
618
|
-
:
|
619
|
-
|
635
|
+
query: { api_key: @handler.config[:api_key] },
|
636
|
+
body: hash_including(msg_text: 'Chef was unable to complete a run, an error during compilation may have occurred.',
|
637
|
+
msg_title: "Chef failed during compile phase on #{@node.name} "),
|
620
638
|
)).to have_been_made.times(1)
|
621
639
|
end
|
622
640
|
end
|
@@ -734,6 +752,31 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
734
752
|
expect(handler.send(:endpoints)).to eq(triplets[0..1])
|
735
753
|
end
|
736
754
|
end
|
755
|
+
|
756
|
+
context 'when using api url instead of url' do
|
757
|
+
it 'returns available triplets' do
|
758
|
+
triplets = [
|
759
|
+
['https://app.datadoghq.com', 'api_key_2' , 'app_key_2'],
|
760
|
+
['https://app.example.com', 'api_key_3', 'app_key_3'],
|
761
|
+
['https://app.example.com', 'api_key_4', 'app_key_4']
|
762
|
+
]
|
763
|
+
handler = Chef::Handler::Datadog.new api_key: triplets[0][1],
|
764
|
+
application_key: triplets[0][2],
|
765
|
+
url: triplets[0][0],
|
766
|
+
extra_endpoints: [{
|
767
|
+
api_url: triplets[1][0],
|
768
|
+
url: triplets[0][0],
|
769
|
+
api_key: triplets[1][1],
|
770
|
+
application_key: triplets[1][2]
|
771
|
+
}, {
|
772
|
+
api_url: triplets[2][0],
|
773
|
+
url:triplets[0][0],
|
774
|
+
api_key: triplets[2][1],
|
775
|
+
application_key: triplets[2][2]
|
776
|
+
}]
|
777
|
+
expect(handler.send(:endpoints)).to eq(triplets)
|
778
|
+
end
|
779
|
+
end
|
737
780
|
end
|
738
781
|
|
739
782
|
context 'when reporting to multiple endpoints' do
|
@@ -744,17 +787,29 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
744
787
|
let(:host_tag_endpoint2) { base_url2 + '/api/v1/tags/hosts/' }
|
745
788
|
let(:metrics_endpoint2) { base_url2 + '/api/v1/series' }
|
746
789
|
let(:handler) do
|
747
|
-
Chef::Handler::Datadog.new
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
790
|
+
Chef::Handler::Datadog.new(api_key: API_KEY,
|
791
|
+
application_key: APPLICATION_KEY,
|
792
|
+
url: BASE_URL,
|
793
|
+
extra_endpoints: [{
|
794
|
+
api_key: api_key2,
|
795
|
+
application_key: application_key2,
|
796
|
+
url: base_url2
|
797
|
+
}])
|
798
|
+
end
|
799
|
+
|
800
|
+
let(:dogs) do
|
801
|
+
handler.instance_variable_get(:@dogs)
|
755
802
|
end
|
803
|
+
|
756
804
|
# Construct a good run_status
|
757
805
|
before(:each) do
|
806
|
+
dogs.each do |dog|
|
807
|
+
# Define mock functions to avoid failures when connecting to the app.example.com endpoint
|
808
|
+
allow(dog).to receive(:emit_point).and_return(true)
|
809
|
+
allow(dog).to receive(:emit_event).and_return([200, "{'event': 'My event'}"])
|
810
|
+
allow(dog).to receive(:update_tags).and_return([201, "Created"])
|
811
|
+
end
|
812
|
+
|
758
813
|
@node = Chef::Node.build('chef.handler.datadog.test')
|
759
814
|
@node.send(:chef_environment, 'testing')
|
760
815
|
@events = Chef::EventDispatch::Dispatcher.new
|
@@ -767,56 +822,51 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
767
822
|
@run_status.stop_clock
|
768
823
|
|
769
824
|
@run_status.run_context = @run_context
|
825
|
+
end
|
770
826
|
|
771
|
-
|
772
|
-
|
827
|
+
it 'should create multiple Dogapi clients' do
|
828
|
+
expect(dogs.length).to eq(2)
|
773
829
|
end
|
774
830
|
|
775
831
|
context 'emits metrics' do
|
776
|
-
it 'reports metrics' do
|
777
|
-
expect(
|
778
|
-
:query => { 'api_key' => API_KEY }
|
779
|
-
)).to have_been_made.times(5)
|
832
|
+
it 'reports metrics to the first endpoint' do
|
833
|
+
expect(dogs[0]).to receive(:emit_point).exactly(5).times
|
780
834
|
|
781
|
-
|
782
|
-
|
783
|
-
|
835
|
+
handler.run_report_unsafe(@run_status)
|
836
|
+
end
|
837
|
+
|
838
|
+
it 'reports metrics to the second endpoint' do
|
839
|
+
expect(dogs[1]).to receive(:emit_point).exactly(5).times
|
840
|
+
|
841
|
+
handler.run_report_unsafe(@run_status)
|
784
842
|
end
|
785
843
|
end
|
786
844
|
|
787
845
|
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)
|
846
|
+
it 'posts an event to the first endpoint' do
|
847
|
+
expect(dogs[0]).to receive(:emit_event).exactly(:once)
|
795
848
|
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
849
|
+
handler.run_report_unsafe(@run_status)
|
850
|
+
end
|
851
|
+
|
852
|
+
it 'posts an event to the second endpoint' do
|
853
|
+
expect(dogs[1]).to receive(:emit_event).exactly(:once)
|
854
|
+
|
855
|
+
handler.run_report_unsafe(@run_status)
|
802
856
|
end
|
803
857
|
end
|
804
858
|
|
805
859
|
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)
|
860
|
+
it 'puts the tags for the current node on the first endpoint' do
|
861
|
+
expect(dogs[0]).to receive(:update_tags).exactly(:once)
|
813
862
|
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
863
|
+
handler.run_report_unsafe(@run_status)
|
864
|
+
end
|
865
|
+
|
866
|
+
it 'puts the tags for the current node on the second endpoint' do
|
867
|
+
expect(dogs[1]).to receive(:update_tags).exactly(:once)
|
868
|
+
|
869
|
+
handler.run_report_unsafe(@run_status)
|
820
870
|
end
|
821
871
|
end
|
822
872
|
end
|