chef-handler-datadog 0.2.0 → 0.3.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.
Files changed (37) hide show
  1. checksums.yaml +9 -9
  2. data/.gitignore +4 -3
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +36 -0
  5. data/.travis.yml +7 -2
  6. data/Appraisals +24 -0
  7. data/CHANGELOG.md +23 -0
  8. data/Gemfile +7 -1
  9. data/README.md +16 -3
  10. data/Rakefile +7 -7
  11. data/chef-handler-datadog.gemspec +17 -12
  12. data/gemfiles/chef_10.14.0.gemfile +12 -0
  13. data/gemfiles/chef_10.26.0.gemfile +13 -0
  14. data/gemfiles/chef_10.30.2.gemfile +12 -0
  15. data/gemfiles/chef_11.8.2.gemfile +13 -0
  16. data/lib/chef-handler-datadog.rb +4 -1
  17. data/lib/chef/handler/datadog.rb +112 -89
  18. data/spec/datadog_spec.rb +279 -0
  19. data/spec/spec_helper.rb +48 -0
  20. data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_event_title_correctly.yml +218 -0
  21. data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_priority_correctly.yml +218 -0
  22. data/spec/support/cassettes/Chef_Handler_Datadog/handles_no_application_key/fails_when_no_application_key_is_provided.yml +142 -0
  23. data/spec/support/cassettes/Chef_Handler_Datadog/handles_tags_correctly/sets_the_role_and_env_and_tags.yml +215 -0
  24. 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 +214 -0
  25. data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/uses_the_instance_id_when_config_is_specified.yml +214 -0
  26. data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/uses_the_instance_id_when_no_config_specified.yml +214 -0
  27. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_events/posts_an_event.yml +214 -0
  28. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_events/sets_priority_correctly.yml +214 -0
  29. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_metrics/reports_metrics.yml +214 -0
  30. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/get_and_set_tags/gets_the_tags_for_the_current_node.yml +214 -0
  31. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/get_and_set_tags/puts_the_tags_for_the_current_node.yml +214 -0
  32. data/spec/support/cassettes/Chef_Handler_Datadog/updated_resources/posts_an_event.yml +217 -0
  33. metadata +102 -15
  34. data/gemfiles/Gemfile.chef-10 +0 -5
  35. data/gemfiles/Gemfile.chef-11 +0 -5
  36. data/test/helper.rb +0 -18
  37. data/test/test_chef-handler-datadog.rb +0 -7
@@ -0,0 +1,279 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Chef::Handler::Datadog, :vcr => :new_episodes do
5
+ # The #report method currently long and clunky, and we need to simulate a
6
+ # Chef run to test all aspects of this, as well as push values into the test.
7
+ before(:all) do
8
+ # This is used in validating that requests have actually been made,
9
+ # as in a 'Fucntional test'. We've recorded the tests with VCR, and use
10
+ # these to assert that the final product is correct. This is also
11
+ # exercising the API client, which may be helpful as well.
12
+ # There is a fair amount of duplication in the repsonse returned.
13
+ BASE_URL = 'https://app.datadoghq.com'
14
+ EVENTS_ENDPOINT = BASE_URL + '/api/v1/events'
15
+ HOST_TAG_ENDPOINT = BASE_URL + '/api/v1/tags/hosts/'
16
+ METRICS_ENDPOINT = BASE_URL + '/api/v1/series'
17
+ end
18
+
19
+ before(:each) do
20
+ @handler = Chef::Handler::Datadog.new(
21
+ :api_key => API_KEY,
22
+ :application_key => APPLICATION_KEY,
23
+ )
24
+ end
25
+
26
+ describe 'reports metrics event and sets tags' do
27
+ # Construct a good run_status
28
+ before(:each) do
29
+ @node = Chef::Node.build('chef.handler.datadog.test')
30
+ @node.send(:chef_environment, 'testing')
31
+ @events = Chef::EventDispatch::Dispatcher.new
32
+ @run_context = Chef::RunContext.new(@node, {}, @events)
33
+ @run_status = Chef::RunStatus.new(@node, @events)
34
+
35
+ @expected_time = Time.now
36
+ Time.stub(:now).and_return(@expected_time, @expected_time + 5)
37
+ @run_status.start_clock
38
+ @run_status.stop_clock
39
+
40
+ @run_status.run_context = @run_context
41
+
42
+ # Run the report
43
+ @handler.run_report_unsafe(@run_status)
44
+ end
45
+
46
+ context 'emits metrics' do
47
+ it 'reports metrics' do
48
+ expect(a_request(:post, METRICS_ENDPOINT).with(
49
+ :query => { 'api_key' => @handler.config[:api_key] }
50
+ )).to have_been_made.times(3)
51
+ end
52
+ end
53
+
54
+ context 'emits events' do
55
+ it 'posts an event' do
56
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
57
+ :query => { 'api_key' => @handler.config[:api_key] },
58
+ :body => hash_including(:msg_text => 'Chef updated 0 resources out of 0 resources total.'),
59
+ :body => hash_including(:msg_title => "Chef completed in 5 seconds on #{@node.name} "),
60
+ )).to have_been_made.times(1)
61
+ end
62
+
63
+ it 'sets priority correctly' do
64
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
65
+ :query => { 'api_key' => @handler.config[:api_key] },
66
+ :body => hash_including(:priority => 'low'),
67
+ )).to have_been_made.times(1)
68
+ end
69
+ end
70
+
71
+ context 'get and set tags' do
72
+ it 'gets the tags for the current node' do
73
+ expect(a_request(:get, HOST_TAG_ENDPOINT + @node.name).with(
74
+ :query => { 'api_key' => @handler.config[:api_key],
75
+ 'application_key' => @handler.config[:application_key] },
76
+ )).to have_been_made.times(1)
77
+ end
78
+
79
+ it 'puts the tags for the current node' do
80
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
81
+ :query => { 'api_key' => @handler.config[:api_key],
82
+ 'application_key' => @handler.config[:application_key] },
83
+ :body => { 'tags' => ['env:testing'] },
84
+ )).to have_been_made.times(1)
85
+ end
86
+ end
87
+ end
88
+
89
+ describe 'reports correct hostname on an ec2 node' do
90
+ before(:each) do
91
+ @node = Chef::Node.build('chef.handler.datadog.test-ec2')
92
+ @node.send(:chef_environment, 'testing')
93
+
94
+ @node.automatic_attrs['ec2'] = { :instance_id => 'i-123456' }
95
+
96
+ @run_context = Chef::RunContext.new(@node, {}, @events)
97
+ @run_status = Chef::RunStatus.new(@node, @events)
98
+ @expected_time = Time.now
99
+ Time.stub(:now).and_return(@expected_time, @expected_time + 5)
100
+ @run_status.start_clock
101
+ @run_status.stop_clock
102
+ @run_status.run_context = @run_context
103
+ end
104
+
105
+ it 'uses the instance id when no config specified' do
106
+ @handler.run_report_unsafe(@run_status)
107
+
108
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
109
+ :query => { 'api_key' => @handler.config[:api_key] },
110
+ :body => hash_including(:msg_title => 'Chef completed in 5 seconds on i-123456 '),
111
+ :body => hash_including(:host => 'i-123456'),
112
+ )).to have_been_made.times(1)
113
+ end
114
+
115
+ it 'uses the instance id when config is specified' do
116
+ @handler.config[:use_ec2_instance_id] = true
117
+ @handler.run_report_unsafe(@run_status)
118
+
119
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
120
+ :query => { 'api_key' => @handler.config[:api_key] },
121
+ :body => hash_including(:msg_title => 'Chef completed in 5 seconds on i-123456 '),
122
+ :body => hash_including(:host => 'i-123456'),
123
+ )).to have_been_made.times(1)
124
+ end
125
+
126
+ it 'does not use the instance id when config specified to false' do
127
+ @handler.config[:use_ec2_instance_id] = false
128
+ @handler.run_report_unsafe(@run_status)
129
+
130
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
131
+ :query => { 'api_key' => @handler.config[:api_key] },
132
+ :body => hash_including(:msg_title => "Chef completed in 5 seconds on #{@node.name} "),
133
+ :body => hash_including(:host => @node.name),
134
+ )).to have_been_made.times(1)
135
+ end
136
+ end
137
+
138
+ describe 'handles tags correctly' do
139
+ before(:each) do
140
+ @node = Chef::Node.build('chef.handler.datadog.test-tags')
141
+
142
+ @node.send(:chef_environment, 'hostile')
143
+ @node.send(:run_list, 'role[highlander]')
144
+ @node.normal.tags = ['the_one_and_only']
145
+
146
+ @events = Chef::EventDispatch::Dispatcher.new
147
+ @run_context = Chef::RunContext.new(@node, {}, @events)
148
+ @run_status = Chef::RunStatus.new(@node, @events)
149
+
150
+ @expected_time = Time.now
151
+ Time.stub(:now).and_return(@expected_time, @expected_time + 5)
152
+ @run_status.start_clock
153
+ @run_status.stop_clock
154
+
155
+ @run_status.run_context = @run_context
156
+
157
+ # Run the report
158
+ @handler.run_report_unsafe(@run_status)
159
+ end
160
+
161
+ it 'sets the role and env and tags' do
162
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
163
+ :query => { 'api_key' => @handler.config[:api_key],
164
+ 'application_key' => @handler.config[:application_key] },
165
+ :body => hash_including(:tags => [
166
+ 'env:hostile', 'role:highlander', 'tag:the_one_and_only'
167
+ ]),
168
+ )).to have_been_made.times(1)
169
+ end
170
+ end
171
+
172
+ describe 'handles no application_key' do
173
+ before(:each) do
174
+ @node = Chef::Node.build('chef.handler.datadog.test-noapp')
175
+
176
+ @node.send(:chef_environment, 'hostile')
177
+ @node.send(:run_list, 'role[highlander]')
178
+ @node.normal.tags = ['the_one_and_only']
179
+
180
+ @events = Chef::EventDispatch::Dispatcher.new
181
+ @run_context = Chef::RunContext.new(@node, {}, @events)
182
+ @run_status = Chef::RunStatus.new(@node, @events)
183
+
184
+ @expected_time = Time.now
185
+ Time.stub(:now).and_return(@expected_time, @expected_time + 5)
186
+ @run_status.start_clock
187
+ @run_status.stop_clock
188
+
189
+ @run_status.run_context = @run_context
190
+ end
191
+
192
+ it 'fails when no application key is provided' do
193
+ @handler.config[:application_key] = nil
194
+
195
+ # TODO: figure out how to capture output of Chef::Log
196
+ # Run the report, catch the error
197
+ expect { @handler.run_report_unsafe(@run_status) }.to raise_error
198
+ end
199
+ end
200
+
201
+ describe 'failed Chef run' do
202
+ before(:each) do
203
+ @node = Chef::Node.build('chef.handler.datadog.test-failed')
204
+
205
+ @node.send(:chef_environment, 'hostile')
206
+ @node.send(:run_list, 'role[highlander]')
207
+ @node.normal.tags = ['the_one_and_only']
208
+
209
+ @events = Chef::EventDispatch::Dispatcher.new
210
+ @run_context = Chef::RunContext.new(@node, {}, @events)
211
+ @run_status = Chef::RunStatus.new(@node, @events)
212
+
213
+ @expected_time = Time.now
214
+ Time.stub(:now).and_return(@expected_time, @expected_time + 2)
215
+ @run_status.start_clock
216
+ @run_status.stop_clock
217
+
218
+ @run_status.run_context = @run_context
219
+
220
+ # Construct an exception
221
+ exception = Chef::Exceptions::UnsupportedAction.new('Something awry.')
222
+ exception.set_backtrace(['file.rb:2', 'file.rb:1'])
223
+ @run_status.exception = exception
224
+
225
+ # Run the report
226
+ @handler.run_report_unsafe(@run_status)
227
+ end
228
+
229
+ it 'sets event title correctly' do
230
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
231
+ :query => { 'api_key' => @handler.config[:api_key] },
232
+ :body => hash_including(:msg_title => "Chef failed in 2 seconds on #{@node.name} "),
233
+ )).to have_been_made.times(1)
234
+ end
235
+
236
+ it 'sets priority correctly' do
237
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
238
+ :query => { 'api_key' => @handler.config[:api_key] },
239
+ :body => hash_including(:alert_type => 'success'),
240
+ :body => hash_including(:priority => 'normal'),
241
+ )).to have_been_made.times(1)
242
+ end
243
+ end
244
+
245
+ describe 'updated resources' do
246
+ before(:each) do
247
+ @node = Chef::Node.build('chef.handler.datadog.test-resources')
248
+ @node.send(:chef_environment, 'resources')
249
+ @events = Chef::EventDispatch::Dispatcher.new
250
+ @run_context = Chef::RunContext.new(@node, {}, @events)
251
+ @run_status = Chef::RunStatus.new(@node, @events)
252
+
253
+ all_resources = [Chef::Resource.new('whiskers'), Chef::Resource.new('paws')]
254
+ all_resources.first.updated_by_last_action(true)
255
+ @run_context.resource_collection.all_resources.replace(all_resources)
256
+
257
+ @expected_time = Time.now
258
+ Time.stub(:now).and_return(@expected_time, @expected_time + 8)
259
+ @run_status.start_clock
260
+ @run_status.stop_clock
261
+
262
+ @run_status.run_context = @run_context
263
+
264
+ # Run the report
265
+ @handler.run_report_unsafe(@run_status)
266
+ end
267
+
268
+ it 'posts an event' do
269
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
270
+ :query => { 'api_key' => @handler.config[:api_key] },
271
+ :body => hash_including(:msg_text => 'Chef updated 1 resources out of 2 resources total.'),
272
+ :body => hash_including(:msg_title => "Chef completed in 8 seconds on #{@node.name} "),
273
+ )).to have_been_made.times(1)
274
+ end
275
+ end
276
+
277
+ # TODO: test failures:
278
+ # @run_status.exception = Exception.new('Boy howdy!')
279
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+
5
+ require 'dotenv'
6
+ require 'rspec'
7
+ require 'vcr'
8
+ require 'webmock/rspec'
9
+
10
+ # Include our code
11
+ require 'chef/handler/datadog'
12
+
13
+ # Load credentials from .env
14
+ Dotenv.load
15
+
16
+ API_KEY = ENV['API_KEY']
17
+ APPLICATION_KEY = ENV['APPLICATION_KEY']
18
+
19
+ RSpec.configure do |config|
20
+ config.treat_symbols_as_metadata_keys_with_true_values = true
21
+ config.run_all_when_everything_filtered = true
22
+ config.filter_run :focus
23
+
24
+ # Run specs in random order to surface order dependencies. If you find an
25
+ # order dependency and want to debug it, you can fix the order by providing
26
+ # the seed, which is printed after each run.
27
+ # --seed 1234
28
+ config.order = 'random'
29
+ end
30
+
31
+ VCR.configure do |c|
32
+ c.cassette_library_dir = 'spec/support/cassettes'
33
+ c.configure_rspec_metadata!
34
+ c.default_cassette_options = {
35
+ :record => :once,
36
+ # :record => :new_episodes, # uncomment during development
37
+ }
38
+
39
+ # Remove any test-specific data
40
+ c.before_record do |i|
41
+ i.response.headers.delete('Set-Cookie')
42
+ i.response.headers.delete('X-Dd-Version')
43
+ end
44
+ c.filter_sensitive_data('<API_KEY>') { API_KEY }
45
+ c.filter_sensitive_data('<APPLICATION_KEY>') { APPLICATION_KEY }
46
+
47
+ c.hook_into :webmock
48
+ end
@@ -0,0 +1,218 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"series":[{"metric":"chef.resources.total","points":[[1390096494,0.0]],"type":"gauge","host":"chef.handler.datadog.test-failed","device":null}]}'
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Ruby
14
+ Content-Type:
15
+ - application/json
16
+ response:
17
+ status:
18
+ code: 202
19
+ message: Accepted
20
+ headers:
21
+ Content-Type:
22
+ - text/json; charset=UTF-8
23
+ Date:
24
+ - Sun, 19 Jan 2014 01:54:44 GMT
25
+ Server:
26
+ - dogdispatcher/4.10.0
27
+ Content-Length:
28
+ - '15'
29
+ Connection:
30
+ - keep-alive
31
+ body:
32
+ encoding: US-ASCII
33
+ string: ! '{"status":"ok"}'
34
+ http_version:
35
+ recorded_at: Sun, 19 Jan 2014 01:54:54 GMT
36
+ - request:
37
+ method: post
38
+ uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
39
+ body:
40
+ encoding: UTF-8
41
+ string: ! '{"series":[{"metric":"chef.resources.updated","points":[[1390096494,0.0]],"type":"gauge","host":"chef.handler.datadog.test-failed","device":null}]}'
42
+ headers:
43
+ Accept:
44
+ - ! '*/*'
45
+ User-Agent:
46
+ - Ruby
47
+ Content-Type:
48
+ - application/json
49
+ response:
50
+ status:
51
+ code: 202
52
+ message: Accepted
53
+ headers:
54
+ Content-Type:
55
+ - text/json; charset=UTF-8
56
+ Date:
57
+ - Sun, 19 Jan 2014 01:54:48 GMT
58
+ Server:
59
+ - dogdispatcher/4.10.0
60
+ Content-Length:
61
+ - '15'
62
+ Connection:
63
+ - keep-alive
64
+ body:
65
+ encoding: US-ASCII
66
+ string: ! '{"status":"ok"}'
67
+ http_version:
68
+ recorded_at: Sun, 19 Jan 2014 01:54:54 GMT
69
+ - request:
70
+ method: post
71
+ uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
72
+ body:
73
+ encoding: UTF-8
74
+ string: ! '{"series":[{"metric":"chef.resources.elapsed_time","points":[[1390096494,2.0]],"type":"gauge","host":"chef.handler.datadog.test-failed","device":null}]}'
75
+ headers:
76
+ Accept:
77
+ - ! '*/*'
78
+ User-Agent:
79
+ - Ruby
80
+ Content-Type:
81
+ - application/json
82
+ response:
83
+ status:
84
+ code: 202
85
+ message: Accepted
86
+ headers:
87
+ Content-Type:
88
+ - text/json; charset=UTF-8
89
+ Date:
90
+ - Sun, 19 Jan 2014 01:54:48 GMT
91
+ Server:
92
+ - dogdispatcher/4.10.0
93
+ Content-Length:
94
+ - '15'
95
+ Connection:
96
+ - keep-alive
97
+ body:
98
+ encoding: US-ASCII
99
+ string: ! '{"status":"ok"}'
100
+ http_version:
101
+ recorded_at: Sun, 19 Jan 2014 01:54:54 GMT
102
+ - request:
103
+ method: post
104
+ uri: https://app.datadoghq.com/api/v1/events?api_key=<API_KEY>
105
+ body:
106
+ encoding: UTF-8
107
+ string: ! '{"msg_text":"Chef updated 0 resources out of 0 resources total.\n@@@\nChef::Exceptions::UnsupportedAction:
108
+ Something awry.\n@@@\n\n@@@\nfile.rb:2\nfile.rb:1\n@@@\n","date_happened":1390096494,"msg_title":"Chef
109
+ failed in 2 seconds on chef.handler.datadog.test-failed ","priority":"normal","parent":null,"tags":[],"aggregation_key":"chef.handler.datadog.test-failed","alert_type":"error","event_type":"config_management.run","source_type_name":"chef","title":"Chef
110
+ failed in 2 seconds on chef.handler.datadog.test-failed ","text":"Chef updated
111
+ 0 resources out of 0 resources total.\n@@@\nChef::Exceptions::UnsupportedAction:
112
+ Something awry.\n@@@\n\n@@@\nfile.rb:2\nfile.rb:1\n@@@\n","host":"chef.handler.datadog.test-failed","device":null}'
113
+ headers:
114
+ Accept:
115
+ - ! '*/*'
116
+ User-Agent:
117
+ - Ruby
118
+ Content-Type:
119
+ - application/json
120
+ response:
121
+ status:
122
+ code: 202
123
+ message: Accepted
124
+ headers:
125
+ Content-Type:
126
+ - text/json; charset=UTF-8
127
+ Date:
128
+ - Sun, 19 Jan 2014 01:54:48 GMT
129
+ Server:
130
+ - dogdispatcher/4.10.0
131
+ Content-Length:
132
+ - '474'
133
+ Connection:
134
+ - keep-alive
135
+ body:
136
+ encoding: US-ASCII
137
+ string: ! '{"status": "ok", "event": {"priority": "normal", "date_happened":
138
+ 1390096494, "handle": null, "title": "Chef failed in 2 seconds on chef.handler.datadog.test-failed
139
+ ", "url": "https://app.datadoghq.com/event/jump_to?event_id=2111137870265175278",
140
+ "text": "Chef updated 0 resources out of 0 resources total.\n@@@\nChef::Exceptions::UnsupportedAction:
141
+ Something awry.\n@@@\n\n@@@\nfile.rb:2\nfile.rb:1\n@@@\n", "tags": [], "related_event_id":
142
+ null, "id": 2111137870265175278}}'
143
+ http_version:
144
+ recorded_at: Sun, 19 Jan 2014 01:54:54 GMT
145
+ - request:
146
+ method: get
147
+ uri: https://app.datadoghq.com/api/v1/tags/hosts/chef.handler.datadog.test-failed?api_key=<API_KEY>&application_key=<APPLICATION_KEY>
148
+ body:
149
+ encoding: US-ASCII
150
+ string: ''
151
+ headers:
152
+ Accept:
153
+ - ! '*/*'
154
+ User-Agent:
155
+ - Ruby
156
+ response:
157
+ status:
158
+ code: 200
159
+ message: OK
160
+ headers:
161
+ Cache-Control:
162
+ - no-cache
163
+ Content-Type:
164
+ - application/json
165
+ Date:
166
+ - Sun, 19 Jan 2014 01:54:49 GMT
167
+ Pragma:
168
+ - no-cache
169
+ Server:
170
+ - gunicorn/0.17.4
171
+ Content-Length:
172
+ - '44'
173
+ Connection:
174
+ - keep-alive
175
+ body:
176
+ encoding: US-ASCII
177
+ string: ! '{"tags": ["env:hostile", "role:highlander"]}'
178
+ http_version:
179
+ recorded_at: Sun, 19 Jan 2014 01:54:54 GMT
180
+ - request:
181
+ method: put
182
+ uri: https://app.datadoghq.com/api/v1/tags/hosts/chef.handler.datadog.test-failed?api_key=<API_KEY>&application_key=<APPLICATION_KEY>
183
+ body:
184
+ encoding: UTF-8
185
+ string: ! '{"tags":["env:hostile","role:highlander","tag:the_one_and_only"]}'
186
+ headers:
187
+ Accept:
188
+ - ! '*/*'
189
+ User-Agent:
190
+ - Ruby
191
+ Content-Type:
192
+ - application/json
193
+ response:
194
+ status:
195
+ code: 201
196
+ message: Created
197
+ headers:
198
+ Cache-Control:
199
+ - no-cache
200
+ Content-Type:
201
+ - application/json
202
+ Date:
203
+ - Sun, 19 Jan 2014 01:54:49 GMT
204
+ Pragma:
205
+ - no-cache
206
+ Server:
207
+ - gunicorn/0.17.4
208
+ Content-Length:
209
+ - '88'
210
+ Connection:
211
+ - keep-alive
212
+ body:
213
+ encoding: US-ASCII
214
+ string: ! '{"host": "chef.handler.datadog.test-failed", "tags": ["env:hostile",
215
+ "role:highlander"]}'
216
+ http_version:
217
+ recorded_at: Sun, 19 Jan 2014 01:54:54 GMT
218
+ recorded_with: VCR 2.8.0