chef-handler-datadog 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,174 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'chef/handler'
4
+ require 'chef/mash'
5
+ require 'dogapi'
6
+
7
+ # helper class for sending events about chef runs
8
+ class DatadogChefEvents
9
+ def initialize
10
+ @dog = nil
11
+ @hostname = nil
12
+ @run_status = nil
13
+ @failure_notfications = nil
14
+
15
+ @alert_type = ''
16
+ @event_priority = ''
17
+ @event_title = ''
18
+ # TODO: refactor how event_body is constructed in the class methods
19
+ # handling of the event_body is a bit clunky and depends on the order of
20
+ # method calls
21
+ @event_body = ''
22
+ end
23
+
24
+ # set the dogapi client handle
25
+ #
26
+ # @param dogapi_client [Dogapi::Client] datadog api client handle
27
+ # @return [DatadogChefTags] instance reference to self enabling method chaining
28
+ def with_dogapi_client(dogapi_client)
29
+ @dog = dogapi_client
30
+ self
31
+ end
32
+
33
+ # set the target hostname (chef node name)
34
+ #
35
+ # @param hostname [String] hostname to use for the handler report
36
+ # @return [DatadogChefTags] instance reference to self enabling method chaining
37
+ def with_hostname(hostname)
38
+ @hostname = hostname
39
+ self
40
+ end
41
+
42
+ # set the chef run status used for the report
43
+ #
44
+ # @param run_status [Chef::RunStatus] current chef run status
45
+ # @return [DatadogChefTags] instance reference to self enabling method chaining
46
+ def with_run_status(run_status)
47
+ @run_status = run_status
48
+ self
49
+ end
50
+
51
+ # set the failure notification list
52
+ #
53
+ # @param failure_notifications [Array] set of datadog notification handles
54
+ # @return [DatadogChefTags] instance reference to self enabling method chaining
55
+ def with_failure_notifications(failure_notifications)
56
+ @failure_notifications = failure_notifications
57
+ self
58
+ end
59
+
60
+ # set the datadog host tags associated with the event
61
+ #
62
+ # @param [Array] the set of host tags
63
+ # @return [DatadogChefTags] instance reference to self enabling method chaining
64
+ def with_tags(tags)
65
+ @tags = tags
66
+ self
67
+ end
68
+
69
+ # Emit Chef event to Datadog
70
+ def emit_to_datadog
71
+ @event_body = ''
72
+ build_event_data
73
+ evt = @dog.emit_event(Dogapi::Event.new(@event_body,
74
+ msg_title: @event_title,
75
+ event_type: 'config_management.run',
76
+ event_object: @hostname,
77
+ alert_type: @alert_type,
78
+ priority: @event_priority,
79
+ source_type_name: 'chef',
80
+ tags: @tags
81
+ ), host: @hostname)
82
+
83
+ begin
84
+ # FIXME: nice-to-have: abstract format of return value away a bit
85
+ # in dogapi directly. See https://github.com/DataDog/dogapi-rb/issues/18
86
+ if evt.length < 2
87
+ Chef::Log.warn("Unexpected response from Datadog Event API: #{evt}")
88
+ else
89
+ # [http_response_code, {"event" => {"url" => "...", ...}}]
90
+ # 2xx means ok
91
+ if evt[0].to_i / 100 != 2
92
+ Chef::Log.warn("Could not submit event to Datadog (HTTP call failed): #{evt[0]}")
93
+ else
94
+ Chef::Log.debug("Successfully submitted Chef event to Datadog for #{@hostname} at #{evt[1]['event']['url']}")
95
+ end
96
+ end
97
+ rescue
98
+ Chef::Log.warn("Could not determine whether chef run was successfully submitted to Datadog: #{evt}")
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def pluralize(number, noun)
105
+ case number
106
+ when 0..1
107
+ "less than 1 #{noun}"
108
+ else
109
+ "#{number.round} #{noun}s"
110
+ end
111
+ rescue
112
+ Chef::Log.warn("Cannot make #{number} more legible")
113
+ "#{number} #{noun}s"
114
+ end
115
+
116
+ # Compose a list of resources updated during a run.
117
+ def update_resource_list
118
+ # No resources updated?
119
+ return unless @run_status.updated_resources.length.to_i > 0
120
+
121
+ if @run_status.failed?
122
+ # Shorten the list when there is a failure for stacktrace debugging
123
+ report_resources = @run_status.updated_resources.last(5)
124
+ else
125
+ report_resources = @run_status.updated_resources
126
+ end
127
+
128
+ @event_body = "\n$$$\n"
129
+ report_resources.each do |r|
130
+ @event_body << "- #{r} (#{r.defined_at})\n"
131
+ end
132
+ @event_body << "\n$$$\n"
133
+ end
134
+
135
+ # Marshal the Event data for submission
136
+ def build_event_data
137
+ # bail early in case of a compiletime failure
138
+ # OPTIMIZE: Use better inspectors to handle failure scenarios, refactor needed.
139
+ if @run_status.elapsed_time.nil?
140
+ @alert_type = 'error'
141
+ @event_title = "Chef failed during compile phase on #{@hostname} "
142
+ @event_priority = 'normal'
143
+ @event_body = 'Chef was unable to complete a run, an error during compilation may have occurred.'
144
+ else
145
+ run_time = pluralize(@run_status.elapsed_time, 'second')
146
+
147
+ # This is the first line of the Event body, the rest is appended here.
148
+ @event_body = "Chef updated #{@run_status.updated_resources.length} resources out of #{@run_status.all_resources.length} resources total."
149
+
150
+ # Update resource list, truncated when failed to 5
151
+ # update will add to the event_body
152
+ update_resource_list
153
+
154
+ if @run_status.success?
155
+ @alert_type = 'success'
156
+ @event_priority = 'low'
157
+ @event_title = "Chef completed in #{run_time} on #{@hostname} "
158
+ else
159
+ @alert_type = 'error'
160
+ @event_priority = 'normal'
161
+ @event_title = "Chef failed in #{run_time} on #{@hostname} "
162
+
163
+ if @failure_notifications
164
+ handles = @failure_notifications
165
+ # convert the notification handle array to a string
166
+ @event_body << "\nAlerting: #{handles.join(' ')}\n"
167
+ end
168
+
169
+ @event_body << "\n$$$\n#{@run_status.formatted_exception}\n$$$\n"
170
+ @event_body << "\n$$$\n#{@run_status.backtrace.join("\n")}\n$$$\n"
171
+ end
172
+ end
173
+ end
174
+ end # end module DatadogChefEvent
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+ require 'dogapi'
3
+
4
+ # helper class for sending datadog metrics from a chef run
5
+ class DatadogChefMetrics
6
+ def initialize
7
+ @dog = nil
8
+ @hostname = ''
9
+ @run_status = nil
10
+ end
11
+
12
+ # set the dogapi client handle
13
+ #
14
+ # @param dogapi_client [Dogapi::Client] datadog api client
15
+ # @return [DatadogChefMetrics] instance reference to self enabling method chaining
16
+ def with_dogapi_client(dogapi_client)
17
+ @dog = dogapi_client
18
+ self
19
+ end
20
+
21
+ # set the target hostname (chef node name)
22
+ #
23
+ # @param hostname [String] hostname used for reporting metrics
24
+ # @return [DatadogChefMetrics] instance reference to self enabling method chaining
25
+ def with_hostname(hostname)
26
+ @hostname = hostname
27
+ self
28
+ end
29
+
30
+ # set the chef run status used for the report
31
+ #
32
+ # @param run_status [Chef::RunStatus] current run status
33
+ # @return [DatadogChefMetrics] instance reference to self enabling method chaining
34
+ def with_run_status(run_status)
35
+ @run_status = run_status
36
+ self
37
+ end
38
+
39
+ # Emit Chef metrics to Datadog
40
+ def emit_to_datadog
41
+ # If there is a failure during compile phase, a large portion of
42
+ # run_status may be unavailable. Bail out here
43
+ warn_msg = 'Error during compile phase, no Datadog metrics available.'
44
+ return Chef::Log.warn(warn_msg) if @run_status.elapsed_time.nil?
45
+
46
+ @dog.emit_point('chef.resources.total', @run_status.all_resources.length, host: @hostname)
47
+ @dog.emit_point('chef.resources.updated', @run_status.updated_resources.length, host: @hostname)
48
+ @dog.emit_point('chef.resources.elapsed_time', @run_status.elapsed_time, host: @hostname)
49
+ Chef::Log.debug('Submitted Chef metrics back to Datadog')
50
+ rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT => e
51
+ Chef::Log.error("Could not send metrics to Datadog. Connection error:\n" + e)
52
+ end
53
+ end # end class DatadogChefMetrics
@@ -0,0 +1,111 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'chef/handler'
4
+ require 'chef/mash'
5
+ require 'dogapi'
6
+
7
+ # helper class for sending datadog tags from chef runs
8
+ class DatadogChefTags
9
+ def initialize
10
+ @node = nil
11
+ @run_status = nil
12
+ @application_key = nil
13
+ @combined_host_tags = nil
14
+ end
15
+
16
+ # set the dogapi client handle
17
+ #
18
+ # @param dogapi_client [Dogapi::Client] datadog api client handle
19
+ # @return [DatadogChefTags] instance reference to self enabling method chaining
20
+ def with_dogapi_client(dogapi_client)
21
+ @dog = dogapi_client
22
+ self
23
+ end
24
+
25
+ # attribute accessor for combined array of tags
26
+ #
27
+ # @return [Array] the set of host tags based off the chef run
28
+ attr_reader :combined_host_tags
29
+
30
+ # set the chef run status used for the report
31
+ #
32
+ # @param run_status [Chef::RunStatus] current chef run status
33
+ # @return [DatadogChefTags] instance reference to self enabling method chaining
34
+ def with_run_status(run_status)
35
+ @run_status = run_status
36
+ # Build up an array of Chef tags that will be sent back
37
+ # Selects all [env, roles, tags] from the Node's object and reformats
38
+ # them to `key:value` e.g. `role:database-master`.
39
+ @node = run_status.node
40
+ # generate the combined tags
41
+ chef_env = node_env.split # converts a string into an array
42
+ chef_roles = node_roles
43
+ chef_tags = node_tags
44
+
45
+ # Combine (union) all arrays. Removes duplicates if found.
46
+ @combined_host_tags = chef_env | chef_roles | chef_tags
47
+ self
48
+ end
49
+
50
+ # set the target hostname (chef node name)
51
+ #
52
+ # @param hostname [String] hostname to use for the handler report
53
+ # @return [DatadogChefTags] instance reference to self enabling method chaining
54
+ def with_hostname(hostname)
55
+ @hostname = hostname
56
+ self
57
+ end
58
+
59
+ # set the datadog application key
60
+ #
61
+ # TODO: the application key is only needed for error checking, e.g. an app key exists
62
+ # would be cleaner to push this check up to the data prep method in the
63
+ # calling handler class
64
+ #
65
+ # @param application_key [String] datadog application key used for chef reports
66
+ # @return [DatadogChefTags] instance reference to self enabling method chaining
67
+ def with_application_key(application_key)
68
+ @application_key = application_key
69
+ if @application_key.nil?
70
+ Chef::Log.warn('You need an application key to let Chef tag your nodes ' \
71
+ 'in Datadog. Visit https://app.datadoghq.com/account/settings#api to ' \
72
+ 'create one and update your datadog attributes in the datadog cookbook.'
73
+ )
74
+ fail ArgumentError, 'Missing Datadog Application Key'
75
+ end
76
+ self
77
+ end
78
+
79
+ # send updated chef run generated tags to Datadog
80
+ def send_update_to_datadog
81
+ rc = @dog.update_tags(@hostname, combined_host_tags, 'chef')
82
+ begin
83
+ # See FIXME above about why I feel dirty repeating this code here
84
+ if rc.length < 2
85
+ Chef::Log.warn("Unexpected response from Datadog Event API: #{rc}")
86
+ else
87
+ if rc[0].to_i / 100 != 2
88
+ Chef::Log.warn("Could not submit #{combined_host_tags} tags for #{@hostname} to Datadog: #{rc}")
89
+ else
90
+ Chef::Log.debug("Successfully updated #{@hostname}'s tags to #{combined_host_tags.join(', ')}")
91
+ end
92
+ end
93
+ rescue
94
+ Chef::Log.warn("Could not determine whether #{@hostname}'s tags were successfully submitted to Datadog: #{rc}")
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def node_roles
101
+ @node.run_list.roles.map! { |role| 'role:' + role }
102
+ end
103
+
104
+ def node_env
105
+ 'env:' + @node.chef_environment if @node.respond_to?('chef_environment')
106
+ end
107
+
108
+ def node_tags
109
+ @node.tags.map! { |tag| 'tag:' + tag } if @node.tags
110
+ end
111
+ end # end class DatadogChefTags
@@ -2,5 +2,5 @@
2
2
  # Helper module for version number only.
3
3
  # Real deal in 'chef/handler/datadog.rb'
4
4
  module ChefHandlerDatadog
5
- VERSION = '0.6.0'
5
+ VERSION = '0.7.0'
6
6
  end
@@ -182,13 +182,12 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
182
182
  end
183
183
  end
184
184
 
185
- describe 'handles tags correctly' do
185
+ context 'tags' do
186
186
  before(:each) do
187
187
  @node = Chef::Node.build('chef.handler.datadog.test-tags')
188
188
 
189
189
  @node.send(:chef_environment, 'hostile')
190
190
  @node.send(:run_list, 'role[highlander]')
191
- @node.normal.tags = ['the_one_and_only']
192
191
 
193
192
  @events = Chef::EventDispatch::Dispatcher.new
194
193
  @run_context = Chef::RunContext.new(@node, {}, @events)
@@ -200,20 +199,37 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
200
199
  @run_status.stop_clock
201
200
 
202
201
  @run_status.run_context = @run_context
202
+ end
203
203
 
204
- # Run the report
205
- @handler.run_report_unsafe(@run_status)
204
+ describe 'when specified' do
205
+ it 'sets the role and env and tags' do
206
+ @node.normal.tags = ['the_one_and_only']
207
+ @handler.run_report_unsafe(@run_status)
208
+
209
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
210
+ :query => { 'api_key' => @handler.config[:api_key],
211
+ 'application_key' => @handler.config[:application_key],
212
+ 'source' => 'chef' },
213
+ :body => hash_including(:tags => [
214
+ 'env:hostile', 'role:highlander', 'tag:the_one_and_only'
215
+ ]),
216
+ )).to have_been_made.times(1)
217
+ end
206
218
  end
207
219
 
208
- it 'sets the role and env and tags' do
209
- expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
210
- :query => { 'api_key' => @handler.config[:api_key],
211
- 'application_key' => @handler.config[:application_key],
212
- 'source' => 'chef' },
213
- :body => hash_including(:tags => [
214
- 'env:hostile', 'role:highlander', 'tag:the_one_and_only'
215
- ]),
216
- )).to have_been_made.times(1)
220
+ describe 'when unspecified' do
221
+ it 'sets role, env and nothing else' do
222
+ @handler.run_report_unsafe(@run_status)
223
+
224
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
225
+ :query => { 'api_key' => @handler.config[:api_key],
226
+ 'application_key' => @handler.config[:application_key],
227
+ 'source' => 'chef' },
228
+ :body => hash_including(:tags => [
229
+ 'env:hostile', 'role:highlander'
230
+ ]),
231
+ )).to have_been_made.times(1)
232
+ end
217
233
  end
218
234
  end
219
235
 
@@ -5,10 +5,12 @@ http_interactions:
5
5
  uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
6
6
  body:
7
7
  encoding: UTF-8
8
- string: ! '{"series":[{"metric":"chef.resources.total","points":[[1410264919,0.0]],"type":"gauge","host":"chef.handler.datadog.test-tags","device":null}]}'
8
+ string: '{"series":[{"metric":"chef.resources.total","points":[[1428248966,0.0]],"type":"gauge","host":"chef.handler.datadog.test-tags","device":null}]}'
9
9
  headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
10
12
  Accept:
11
- - ! '*/*'
13
+ - "*/*"
12
14
  User-Agent:
13
15
  - Ruby
14
16
  Content-Type:
@@ -21,27 +23,31 @@ http_interactions:
21
23
  Content-Type:
22
24
  - text/json; charset=UTF-8
23
25
  Date:
24
- - Tue, 09 Sep 2014 12:15:14 GMT
26
+ - Sun, 05 Apr 2015 15:49:21 GMT
25
27
  Server:
26
- - dogdispatcher/5.2.0
28
+ - dogdispatcher/6.1.23
29
+ Strict-Transport-Security:
30
+ - max-age=15724800;
27
31
  Content-Length:
28
32
  - '15'
29
33
  Connection:
30
34
  - keep-alive
31
35
  body:
32
- encoding: US-ASCII
33
- string: ! '{"status":"ok"}'
36
+ encoding: UTF-8
37
+ string: '{"status":"ok"}'
34
38
  http_version:
35
- recorded_at: Tue, 09 Sep 2014 12:15:19 GMT
39
+ recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
36
40
  - request:
37
41
  method: post
38
42
  uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
39
43
  body:
40
44
  encoding: UTF-8
41
- string: ! '{"series":[{"metric":"chef.resources.updated","points":[[1410264919,0.0]],"type":"gauge","host":"chef.handler.datadog.test-tags","device":null}]}'
45
+ string: '{"series":[{"metric":"chef.resources.updated","points":[[1428248966,0.0]],"type":"gauge","host":"chef.handler.datadog.test-tags","device":null}]}'
42
46
  headers:
47
+ Accept-Encoding:
48
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
43
49
  Accept:
44
- - ! '*/*'
50
+ - "*/*"
45
51
  User-Agent:
46
52
  - Ruby
47
53
  Content-Type:
@@ -54,27 +60,31 @@ http_interactions:
54
60
  Content-Type:
55
61
  - text/json; charset=UTF-8
56
62
  Date:
57
- - Tue, 09 Sep 2014 12:15:15 GMT
63
+ - Sun, 05 Apr 2015 15:49:22 GMT
58
64
  Server:
59
- - dogdispatcher/5.1.1
65
+ - dogdispatcher/6.1.23
66
+ Strict-Transport-Security:
67
+ - max-age=15724800;
60
68
  Content-Length:
61
69
  - '15'
62
70
  Connection:
63
71
  - keep-alive
64
72
  body:
65
- encoding: US-ASCII
66
- string: ! '{"status":"ok"}'
73
+ encoding: UTF-8
74
+ string: '{"status":"ok"}'
67
75
  http_version:
68
- recorded_at: Tue, 09 Sep 2014 12:15:19 GMT
76
+ recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
69
77
  - request:
70
78
  method: post
71
79
  uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
72
80
  body:
73
81
  encoding: UTF-8
74
- string: ! '{"series":[{"metric":"chef.resources.elapsed_time","points":[[1410264919,5.0]],"type":"gauge","host":"chef.handler.datadog.test-tags","device":null}]}'
82
+ string: '{"series":[{"metric":"chef.resources.elapsed_time","points":[[1428248966,5.0]],"type":"gauge","host":"chef.handler.datadog.test-tags","device":null}]}'
75
83
  headers:
84
+ Accept-Encoding:
85
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
76
86
  Accept:
77
- - ! '*/*'
87
+ - "*/*"
78
88
  User-Agent:
79
89
  - Ruby
80
90
  Content-Type:
@@ -87,30 +97,34 @@ http_interactions:
87
97
  Content-Type:
88
98
  - text/json; charset=UTF-8
89
99
  Date:
90
- - Tue, 09 Sep 2014 12:15:15 GMT
100
+ - Sun, 05 Apr 2015 15:49:23 GMT
91
101
  Server:
92
- - dogdispatcher/5.1.1
102
+ - dogdispatcher/6.1.23
103
+ Strict-Transport-Security:
104
+ - max-age=15724800;
93
105
  Content-Length:
94
106
  - '15'
95
107
  Connection:
96
108
  - keep-alive
97
109
  body:
98
- encoding: US-ASCII
99
- string: ! '{"status":"ok"}'
110
+ encoding: UTF-8
111
+ string: '{"status":"ok"}'
100
112
  http_version:
101
- recorded_at: Tue, 09 Sep 2014 12:15:19 GMT
113
+ recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
102
114
  - request:
103
115
  method: post
104
116
  uri: https://app.datadoghq.com/api/v1/events?api_key=<API_KEY>
105
117
  body:
106
118
  encoding: UTF-8
107
- string: ! '{"msg_text":"Chef updated 0 resources out of 0 resources total.","date_happened":1410264919,"msg_title":"Chef
119
+ string: '{"msg_text":"Chef updated 0 resources out of 0 resources total.","date_happened":1428248966,"msg_title":"Chef
108
120
  completed in 5 seconds on chef.handler.datadog.test-tags ","priority":"low","parent":null,"tags":["env:hostile","role:highlander","tag:the_one_and_only"],"aggregation_key":"chef.handler.datadog.test-tags","alert_type":"success","event_type":"config_management.run","source_type_name":"chef","title":"Chef
109
121
  completed in 5 seconds on chef.handler.datadog.test-tags ","text":"Chef updated
110
122
  0 resources out of 0 resources total.","host":"chef.handler.datadog.test-tags","device":null}'
111
123
  headers:
124
+ Accept-Encoding:
125
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
112
126
  Accept:
113
- - ! '*/*'
127
+ - "*/*"
114
128
  User-Agent:
115
129
  - Ruby
116
130
  Content-Type:
@@ -123,32 +137,36 @@ http_interactions:
123
137
  Content-Type:
124
138
  - text/json; charset=UTF-8
125
139
  Date:
126
- - Tue, 09 Sep 2014 12:15:16 GMT
140
+ - Sun, 05 Apr 2015 15:49:23 GMT
127
141
  Server:
128
- - dogdispatcher/5.1.1
142
+ - dogdispatcher/6.1.23
143
+ Strict-Transport-Security:
144
+ - max-age=15724800;
129
145
  Content-Length:
130
- - '428'
146
+ - '420'
131
147
  Connection:
132
148
  - keep-alive
133
149
  body:
134
- encoding: US-ASCII
135
- string: ! '{"status": "ok", "event": {"priority": "low", "date_happened": 1410264919,
150
+ encoding: UTF-8
151
+ string: '{"status": "ok", "event": {"priority": "low", "date_happened": 1428248966,
136
152
  "handle": null, "title": "Chef completed in 5 seconds on chef.handler.datadog.test-tags
137
- ", "url": "https://app.datadoghq.com/event/jump_to?event_id=2449507933236142332",
153
+ ", "url": "https://app.datadoghq.com/event/event?id=2751230185062799345",
138
154
  "text": "Chef updated 0 resources out of 0 resources total.", "tags": ["env:hostile",
139
155
  "role:highlander", "tag:the_one_and_only"], "related_event_id": null, "id":
140
- 2449507933236142332}}'
156
+ 2751230185062799345}}'
141
157
  http_version:
142
- recorded_at: Tue, 09 Sep 2014 12:15:19 GMT
158
+ recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
143
159
  - request:
144
160
  method: put
145
161
  uri: https://app.datadoghq.com/api/v1/tags/hosts/chef.handler.datadog.test-tags?api_key=<API_KEY>&application_key=<APPLICATION_KEY>&source=chef
146
162
  body:
147
163
  encoding: UTF-8
148
- string: ! '{"tags":["env:hostile","role:highlander","tag:the_one_and_only"]}'
164
+ string: '{"tags":["env:hostile","role:highlander","tag:the_one_and_only"]}'
149
165
  headers:
166
+ Accept-Encoding:
167
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
150
168
  Accept:
151
- - ! '*/*'
169
+ - "*/*"
152
170
  User-Agent:
153
171
  - Ruby
154
172
  Content-Type:
@@ -163,19 +181,25 @@ http_interactions:
163
181
  Content-Type:
164
182
  - application/json
165
183
  Date:
166
- - Tue, 09 Sep 2014 12:15:16 GMT
184
+ - Sun, 05 Apr 2015 15:49:24 GMT
167
185
  Pragma:
168
186
  - no-cache
169
187
  Server:
170
188
  - gunicorn/19.1.0
189
+ Strict-Transport-Security:
190
+ - max-age=15724800;
191
+ X-Dd-Debug:
192
+ - mPU4gm+hKkKT8ia9ZdY5CzVKb87xvoCEvNtumo6b6Z8=
193
+ X-Frame-Options:
194
+ - SAMEORIGIN
171
195
  Content-Length:
172
196
  - '110'
173
197
  Connection:
174
198
  - keep-alive
175
199
  body:
176
- encoding: US-ASCII
177
- string: ! '{"host": "chef.handler.datadog.test-tags", "tags": ["env:hostile",
200
+ encoding: UTF-8
201
+ string: '{"host": "chef.handler.datadog.test-tags", "tags": ["env:hostile",
178
202
  "role:highlander", "tag:the_one_and_only"]}'
179
203
  http_version:
180
- recorded_at: Tue, 09 Sep 2014 12:15:19 GMT
181
- recorded_with: VCR 2.9.2
204
+ recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
205
+ recorded_with: VCR 2.9.3