chef-handler-datadog 0.12.0 → 0.14.0
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/.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
|
[](http://badge.fury.io/rb/chef-handler-datadog)
|
|
6
|
-
[](https://codeclimate.com/github/DataDog/chef-handler-datadog)
|
|
8
|
-
[](https://gemnasium.com/DataDog/chef-handler-datadog)
|
|
6
|
+
[](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
|