fluent-plugin-kubernetes_metadata_filter 2.1.3 → 2.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8e478872fe7fd194bb1746e4e44a917a7d07067b
4
- data.tar.gz: dfc10c0b81a8a3a8a805e53fb914bf5525f4e328
2
+ SHA256:
3
+ metadata.gz: 0762066546f02f63127244e84c7c44e7f70b83737bd6abc27ab37f4a01be1fa8
4
+ data.tar.gz: 11372dfe77e89ed7c2bc2b0b4a2d48a51ea2a132b8b6e1cd9b1538ed4f8f3b3b
5
5
  SHA512:
6
- metadata.gz: 27ac4b15b101d557411aebc943d5d1e5b464ec94d4e5e9318b960f0c022b09232f6112936af84b30a17834ee67562a3d0f12cea477639672089e1d3afd3541ae
7
- data.tar.gz: bd79142fc9afde71d94ab772e65cc36cb118e0d6624014275fe2a151d5353e3e25a214ee8fc8a74e8e0d519e475cc0aa8ee364ace1f25091e0af88498685de26
6
+ metadata.gz: ea2b022e7da9df5da158ce02f24c187fc605e6c4da8b7aecea9d0847cfac9d29fa91c59a9748b32643f3e40baffc9974cefe153e74e171b33d02a74dbb856d44
7
+ data.tar.gz: dfd3d105bcb61a94edf76c3862fd6bbd615f5634e1c3fd3a621aac246f6f17186fcaddf703a59a4201b286d39a19b8f9b3eed532213820b0d70419f0b06f9021
data/README.md CHANGED
@@ -44,7 +44,8 @@ This must used named capture groups for `container_name`, `pod_name` & `namespac
44
44
  * `watch` - set up a watch on pods on the API server for updates to metadata (default: `true`)
45
45
  * `de_dot` - replace dots in labels and annotations with configured `de_dot_separator`, required for ElasticSearch 2.x compatibility (default: `true`)
46
46
  * `de_dot_separator` - separator to use if `de_dot` is enabled (default: `_`)
47
- * `use_journal` - If false (default), messages are expected to be formatted and tagged as if read by the fluentd in\_tail plugin with wildcard filename. If true, messages are expected to be formatted as if read from the systemd journal. The `MESSAGE` field has the full message. The `CONTAINER_NAME` field has the encoded k8s metadata (see below). The `CONTAINER_ID_FULL` field has the full container uuid. This requires docker to use the `--log-driver=journald` log driver.
47
+ * *DEPRECATED* `use_journal` - If false, messages are expected to be formatted and tagged as if read by the fluentd in\_tail plugin with wildcard filename. If true, messages are expected to be formatted as if read from the systemd journal. The `MESSAGE` field has the full message. The `CONTAINER_NAME` field has the encoded k8s metadata (see below). The `CONTAINER_ID_FULL` field has the full container uuid. This requires docker to use the `--log-driver=journald` log driver. If unset (the default), the plugin will use the `CONTAINER_NAME` and `CONTAINER_ID_FULL` fields
48
+ if available, otherwise, will use the tag in the `tag_to_kubernetes_name_regexp` format.
48
49
  * `container_name_to_kubernetes_regexp` - The regular expression used to extract the k8s metadata encoded in the journal `CONTAINER_NAME` field (default: `'^(?<name_prefix>[^_]+)_(?<container_name>[^\._]+)(\.(?<container_hash>[^_]+))?_(?<pod_name>[^_]+)_(?<namespace>[^_]+)_[^_]+_[^_]+$'`
49
50
  * This corresponds to the definition [in the source](https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/dockertools/docker.go#L317)
50
51
  * `annotation_match` - Array of regular expressions matching annotation field names. Matched annotations are added to a log record.
@@ -52,6 +53,7 @@ This must used named capture groups for `container_name`, `pod_name` & `namespac
52
53
  when true (default: `true`)
53
54
  * `orphaned_namespace_name` - The namespace to associate with records where the namespace can not be determined (default: `.orphaned`)
54
55
  * `orphaned_namespace_id` - The namespace id to associate with records where the namespace can not be determined (default: `orphaned`)
56
+ * `lookup_from_k8s_field` - If the field `kubernetes` is present, lookup the metadata from the given subfields such as `kubernetes.namespace_name`, `kubernetes.pod_name`, etc. This allows you to avoid having to pass in metadata to lookup in an explicitly formatted tag name or in an explicitly formatted `CONTAINER_NAME` value. For example, set `kubernetes.namespace_name`, `kubernetes.pod_name`, `kubernetes.container_name`, and `docker.id` in the record, and the filter will fill in the rest. (default: `true`)
55
57
 
56
58
  **NOTE:** As of the release 2.1.x of this plugin, it no longer supports parsing the source message into JSON and attaching it to the
57
59
  payload. The following configuration options are removed:
@@ -59,6 +61,16 @@ payload. The following configuration options are removed:
59
61
  * `merge_json_log`
60
62
  * `preserve_json_log`
61
63
 
64
+ **NOTE** As of this release, the use of `use_journal` is **DEPRECATED**. If this setting is not present, the plugin will
65
+ attempt to figure out the source of the metadata fields from the following:
66
+ - If `lookup_from_k8s_field true` (the default) and the following fields are present in the record:
67
+ `docker.container_id`, `kubernetes.namespace_name`, `kubernetes.pod_name`, `kubernetes.container_name`,
68
+ then the plugin will use those values as the source to use to lookup the metadata
69
+ - If `use_journal true`, or `use_journal` is unset, and the fields `CONTAINER_NAME` and `CONTAINER_ID_FULL` are present in the record,
70
+ then the plugin will parse those values using `container_name_to_kubernetes_regexp` and use those as the source to lookup the metadata
71
+ - Otherwise, if the tag matches `tag_to_kubernetes_name_regexp`, the plugin will parse the tag and use those values to
72
+ lookup the metdata
73
+
62
74
  Reading from the JSON formatted log files with `in_tail` and wildcard filenames:
63
75
  ```
64
76
  <source>
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |gem|
6
6
  gem.name = "fluent-plugin-kubernetes_metadata_filter"
7
- gem.version = "2.1.3"
7
+ gem.version = "2.1.4"
8
8
  gem.authors = ["Jimmi Dyson"]
9
9
  gem.email = ["jimmidyson@gmail.com"]
10
10
  gem.description = %q{Filter plugin to add Kubernetes metadata}
@@ -57,7 +57,7 @@ module Fluent::Plugin
57
57
  # format:
58
58
  # CONTAINER_NAME=k8s_$containername.$containerhash_$podname_$namespacename_$poduuid_$rand32bitashex
59
59
  # CONTAINER_FULL_ID=dockeridassha256hexvalue
60
- config_param :use_journal, :bool, default: false
60
+ config_param :use_journal, :bool, default: nil
61
61
  # Field 2 is the container_hash, field 5 is the pod_id, and field 6 is the pod_randhex
62
62
  # I would have included them as named groups, but you can't have named groups that are
63
63
  # non-capturing :P
@@ -71,6 +71,7 @@ module Fluent::Plugin
71
71
  config_param :allow_orphans, :bool, default: true
72
72
  config_param :orphaned_namespace_name, :string, default: '.orphaned'
73
73
  config_param :orphaned_namespace_id, :string, default: 'orphaned'
74
+ config_param :lookup_from_k8s_field, :bool, default: true
74
75
 
75
76
  def fetch_pod_metadata(namespace_name, pod_name)
76
77
  log.trace("fetching pod metadata: #{namespace_name}/#{pod_name}") if log.trace?
@@ -243,13 +244,10 @@ module Fluent::Plugin
243
244
  namespace_thread.abort_on_exception = true
244
245
  end
245
246
  end
246
- if @use_journal
247
- log.debug "Will stream from the journal"
248
- self.class.class_eval { alias_method :filter_stream, :filter_stream_from_journal }
249
- else
250
- log.debug "Will stream from the files"
251
- self.class.class_eval { alias_method :filter_stream, :filter_stream_from_files }
252
- end
247
+ @time_fields = []
248
+ @time_fields.push('_SOURCE_REALTIME_TIMESTAMP', '__REALTIME_TIMESTAMP') if @use_journal || @use_journal.nil?
249
+ @time_fields.push('time') unless @use_journal
250
+ @time_fields.push('@timestamp') if @lookup_from_k8s_field
253
251
 
254
252
  @annotations_regexps = []
255
253
  @annotation_match.each do |regexp|
@@ -262,102 +260,93 @@ module Fluent::Plugin
262
260
 
263
261
  end
264
262
 
265
- def get_metadata_for_record(match_data, container_id, create_time, batch_miss_cache)
266
- namespace_name = match_data['namespace']
267
- pod_name = match_data['pod_name']
268
- container_name = match_data['container_name']
263
+ def get_metadata_for_record(namespace_name, pod_name, container_name, container_id, create_time, batch_miss_cache)
269
264
  metadata = {
270
- 'container_name' => container_name,
271
- 'namespace_name' => namespace_name,
272
- 'pod_name' => pod_name
265
+ 'docker' => {'container_id' => container_id},
266
+ 'kubernetes' => {
267
+ 'container_name' => container_name,
268
+ 'namespace_name' => namespace_name,
269
+ 'pod_name' => pod_name
270
+ }
273
271
  }
274
272
  if @kubernetes_url.present?
275
273
  pod_metadata = get_pod_metadata(container_id, namespace_name, pod_name, create_time, batch_miss_cache)
276
274
 
277
275
  if (pod_metadata.include? 'containers') && (pod_metadata['containers'].include? container_id)
278
- metadata['container_image'] = pod_metadata['containers'][container_id]['image']
279
- metadata['container_image_id'] = pod_metadata['containers'][container_id]['image_id']
276
+ metadata['kubernetes']['container_image'] = pod_metadata['containers'][container_id]['image']
277
+ metadata['kubernetes']['container_image_id'] = pod_metadata['containers'][container_id]['image_id']
280
278
  end
281
279
 
282
- metadata.merge!(pod_metadata) if pod_metadata
283
- metadata.delete('containers')
280
+ metadata['kubernetes'].merge!(pod_metadata) if pod_metadata
281
+ metadata['kubernetes'].delete('containers')
284
282
  end
285
283
  metadata
286
284
  end
287
285
 
288
- def create_time_from_record(record)
289
- time = if @use_journal
290
- record['_SOURCE_REALTIME_TIMESTAMP'].nil? ? record['_SOURCE_REALTIME_TIMESTAMP'] : record['__REALTIME_TIMESTAMP']
291
- else
292
- record['time']
293
- end
294
- (time.nil? || time.chop.empty?) ? Time.now : Time.parse(time)
286
+ def create_time_from_record(record, internal_time)
287
+ time_key = @time_fields.detect{ |ii| record.has_key?(ii) }
288
+ time = record[time_key]
289
+ if time.nil? || time.chop.empty?
290
+ return internal_time
291
+ end
292
+ if ['_SOURCE_REALTIME_TIMESTAMP', '__REALTIME_TIMESTAMP'].include?(time_key)
293
+ timei= time.to_i
294
+ return Time.at(timei / 1000000, timei % 1000000)
295
+ end
296
+ return Time.parse(time)
295
297
  end
296
298
 
297
299
  def filter_stream(tag, es)
298
- es
299
- end
300
-
301
- def filter_stream_from_files(tag, es)
302
300
  return es if (es.respond_to?(:empty?) && es.empty?) || !es.is_a?(Fluent::EventStream)
303
301
  new_es = Fluent::MultiEventStream.new
304
-
305
- match_data = tag.match(@tag_to_kubernetes_name_regexp_compiled)
302
+ tag_match_data = tag.match(@tag_to_kubernetes_name_regexp_compiled) unless @use_journal
303
+ tag_metadata = nil
306
304
  batch_miss_cache = {}
307
- metadata = nil
308
-
309
305
  es.each do |time, record|
310
- if match_data && metadata.nil?
311
- container_id = match_data['docker_id']
312
- metadata = {
313
- 'docker' => {
314
- 'container_id' => container_id
315
- },
316
- 'kubernetes' => get_metadata_for_record(match_data, container_id, create_time_from_record(record), batch_miss_cache)
317
- }
306
+ if tag_match_data && tag_metadata.nil?
307
+ tag_metadata = get_metadata_for_record(tag_match_data['namespace'], tag_match_data['pod_name'], tag_match_data['container_name'],
308
+ tag_match_data['docker_id'], create_time_from_record(record, time), batch_miss_cache)
309
+ end
310
+ metadata = Marshal.load(Marshal.dump(tag_metadata)) if tag_metadata
311
+ if (@use_journal || @use_journal.nil?) &&
312
+ (j_metadata = get_metadata_for_journal_record(record, time, batch_miss_cache))
313
+ metadata = j_metadata
314
+ end
315
+ if @lookup_from_k8s_field && record.has_key?('kubernetes') && record.has_key?('docker') &&
316
+ record['kubernetes'].respond_to?(:has_key?) && record['docker'].respond_to?(:has_key?) &&
317
+ record['kubernetes'].has_key?('namespace_name') &&
318
+ record['kubernetes'].has_key?('pod_name') &&
319
+ record['kubernetes'].has_key?('container_name') &&
320
+ record['docker'].has_key?('container_id') &&
321
+ (k_metadata = get_metadata_for_record(record['kubernetes']['namespace_name'], record['kubernetes']['pod_name'],
322
+ record['kubernetes']['container_name'], record['docker']['container_id'],
323
+ create_time_from_record(record, time), batch_miss_cache))
324
+ metadata = k_metadata
318
325
  end
319
326
 
320
- record = record.merge(Marshal.load(Marshal.dump(metadata))) if metadata
327
+ record = record.merge(metadata) if metadata
321
328
  new_es.add(time, record)
322
329
  end
323
330
  dump_stats
324
331
  new_es
325
332
  end
326
333
 
327
- def filter_stream_from_journal(tag, es)
328
- return es if (es.respond_to?(:empty?) && es.empty?) || !es.is_a?(Fluent::EventStream)
329
- new_es = Fluent::MultiEventStream.new
330
- batch_miss_cache = {}
331
- es.each do |time, record|
332
- metadata = nil
333
- if record.has_key?('CONTAINER_NAME') && record.has_key?('CONTAINER_ID_FULL')
334
- metadata = record['CONTAINER_NAME'].match(@container_name_to_kubernetes_regexp_compiled) do |match_data|
335
- container_id = record['CONTAINER_ID_FULL']
336
- metadata = {
337
- 'docker' => {
338
- 'container_id' => container_id
339
- },
340
- 'kubernetes' => get_metadata_for_record(match_data, container_id, create_time_from_record(record), batch_miss_cache)
341
- }
342
-
343
- metadata
344
- end
345
- unless metadata
346
- log.debug "Error: could not match CONTAINER_NAME from record #{record}"
347
- @stats.bump(:container_name_match_failed)
348
- end
349
- elsif record.has_key?('CONTAINER_NAME') && record['CONTAINER_NAME'].start_with?('k8s_')
350
- log.debug "Error: no container name and id in record #{record}"
351
- @stats.bump(:container_name_id_missing)
334
+ def get_metadata_for_journal_record(record, time, batch_miss_cache)
335
+ metadata = nil
336
+ if record.has_key?('CONTAINER_NAME') && record.has_key?('CONTAINER_ID_FULL')
337
+ metadata = record['CONTAINER_NAME'].match(@container_name_to_kubernetes_regexp_compiled) do |match_data|
338
+ get_metadata_for_record(match_data['namespace'], match_data['pod_name'], match_data['container_name'],
339
+ record['CONTAINER_ID_FULL'], create_time_from_record(record, time), batch_miss_cache)
352
340
  end
353
-
354
- record = record.merge(metadata) if metadata
355
-
356
- new_es.add(time, record)
341
+ unless metadata
342
+ log.debug "Error: could not match CONTAINER_NAME from record #{record}"
343
+ @stats.bump(:container_name_match_failed)
344
+ end
345
+ elsif record.has_key?('CONTAINER_NAME') && record['CONTAINER_NAME'].start_with?('k8s_')
346
+ log.debug "Error: no container name and id in record #{record}"
347
+ @stats.bump(:container_name_id_missing)
357
348
  end
358
-
359
- dump_stats
360
- new_es
349
+ metadata
361
350
  end
362
351
 
363
352
  def de_dot!(h)
@@ -0,0 +1,408 @@
1
+ #
2
+ # Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
3
+ # Kubernetes metadata
4
+ #
5
+ # Copyright 2015 Red Hat, Inc.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ ---
20
+ http_interactions:
21
+ - request:
22
+ method: get
23
+ uri: https://localhost:8443/api
24
+ body:
25
+ encoding: US-ASCII
26
+ string: ''
27
+ headers:
28
+ Accept:
29
+ - "*/*; q=0.5, application/xml"
30
+ Accept-Encoding:
31
+ - gzip, deflate
32
+ User-Agent:
33
+ - Ruby
34
+ response:
35
+ status:
36
+ code: 200
37
+ message: OK
38
+ headers:
39
+ Content-Type:
40
+ - application/json
41
+ Date:
42
+ - Fri, 08 May 2015 10:35:37 GMT
43
+ Content-Length:
44
+ - '67'
45
+ body:
46
+ encoding: UTF-8
47
+ string: |-
48
+ {
49
+ "versions": [
50
+ "v1"
51
+ ]
52
+ }
53
+ http_version:
54
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
55
+ - request:
56
+ method: get
57
+ uri: https://localhost:8443/api/v1/namespaces/default/pods/fabric8-console-controller-98rqc
58
+ body:
59
+ encoding: US-ASCII
60
+ string: ''
61
+ headers:
62
+ Accept:
63
+ - "*/*; q=0.5, application/xml"
64
+ Accept-Encoding:
65
+ - gzip, deflate
66
+ User-Agent:
67
+ - Ruby
68
+ response:
69
+ status:
70
+ code: 200
71
+ message: OK
72
+ headers:
73
+ Content-Type:
74
+ - application/json
75
+ Date:
76
+ - Fri, 08 May 2015 10:35:37 GMT
77
+ Transfer-Encoding:
78
+ - chunked
79
+ body:
80
+ encoding: UTF-8
81
+ string: |-
82
+ {
83
+ "kind": "Pod",
84
+ "apiVersion": "v1",
85
+ "metadata": {
86
+ "name": "fabric8-console-controller-98rqc",
87
+ "generateName": "fabric8-console-controller-",
88
+ "namespace": "default",
89
+ "selfLink": "/api/v1/namespaces/default/pods/fabric8-console-controller-98rqc",
90
+ "uid": "c76927af-f563-11e4-b32d-54ee7527188d",
91
+ "resourceVersion": "122",
92
+ "creationTimestamp": "2015-05-08T09:22:42Z",
93
+ "labels": {
94
+ "component": "fabric8Console"
95
+ }
96
+ },
97
+ "spec": {
98
+ "volumes": [
99
+ {
100
+ "name": "openshift-cert-secrets",
101
+ "hostPath": null,
102
+ "emptyDir": null,
103
+ "gcePersistentDisk": null,
104
+ "gitRepo": null,
105
+ "secret": {
106
+ "secretName": "openshift-cert-secrets"
107
+ },
108
+ "nfs": null,
109
+ "iscsi": null,
110
+ "glusterfs": null
111
+ }
112
+ ],
113
+ "containers": [
114
+ {
115
+ "name": "fabric8-console-container",
116
+ "image": "fabric8/hawtio-kubernetes:latest",
117
+ "ports": [
118
+ {
119
+ "containerPort": 9090,
120
+ "protocol": "TCP"
121
+ }
122
+ ],
123
+ "env": [
124
+ {
125
+ "name": "OAUTH_CLIENT_ID",
126
+ "value": "fabric8-console"
127
+ },
128
+ {
129
+ "name": "OAUTH_AUTHORIZE_URI",
130
+ "value": "https://localhost:8443/oauth/authorize"
131
+ }
132
+ ],
133
+ "resources": {},
134
+ "volumeMounts": [
135
+ {
136
+ "name": "openshift-cert-secrets",
137
+ "readOnly": true,
138
+ "mountPath": "/etc/secret-volume"
139
+ }
140
+ ],
141
+ "terminationMessagePath": "/dev/termination-log",
142
+ "imagePullPolicy": "IfNotPresent",
143
+ "capabilities": {}
144
+ }
145
+ ],
146
+ "restartPolicy": "Always",
147
+ "dnsPolicy": "ClusterFirst",
148
+ "nodeName": "jimmi-redhat.localnet"
149
+ },
150
+ "status": {
151
+ "phase": "Running",
152
+ "Condition": [
153
+ {
154
+ "type": "Ready",
155
+ "status": "True"
156
+ }
157
+ ],
158
+ "hostIP": "172.17.42.1",
159
+ "podIP": "172.17.0.8",
160
+ "containerStatuses": [
161
+ {
162
+ "name": "fabric8-console-container",
163
+ "state": {
164
+ "running": {
165
+ "startedAt": "2015-05-08T09:22:44Z"
166
+ }
167
+ },
168
+ "lastState": {},
169
+ "ready": true,
170
+ "restartCount": 0,
171
+ "image": "fabric8/hawtio-kubernetes:latest",
172
+ "imageID": "docker://b2bd1a24a68356b2f30128e6e28e672c1ef92df0d9ec01ec0c7faea5d77d2303",
173
+ "containerID": "docker://49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459"
174
+ }
175
+ ]
176
+ }
177
+ }
178
+ http_version:
179
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
180
+ - request:
181
+ method: get
182
+ uri: https://localhost:8443/api/v1/namespaces/default
183
+ body:
184
+ encoding: US-ASCII
185
+ string: ''
186
+ headers:
187
+ Accept:
188
+ - "*/*; q=0.5, application/xml"
189
+ Accept-Encoding:
190
+ - gzip, deflate
191
+ User-Agent:
192
+ - Ruby
193
+ response:
194
+ status:
195
+ code: 200
196
+ message: OK
197
+ headers:
198
+ Content-Type:
199
+ - application/json
200
+ Date:
201
+ - Fri, 08 May 2015 10:35:37 GMT
202
+ Transfer-Encoding:
203
+ - chunked
204
+ body:
205
+ encoding: UTF-8
206
+ string: |-
207
+ {
208
+ "kind": "Namespace",
209
+ "apiVersion": "v1",
210
+ "metadata": {
211
+ "name": "default",
212
+ "selfLink": "/api/v1/namespaces/default",
213
+ "uid": "898268c8-4a36-11e5-9d81-42010af0194c",
214
+ "resourceVersion": "6",
215
+ "creationTimestamp": "2015-05-08T09:22:01Z"
216
+ },
217
+ "spec": {
218
+ "finalizers": [
219
+ "kubernetes"
220
+ ]
221
+ },
222
+ "status": {
223
+ "phase": "Active"
224
+ }
225
+ }
226
+ http_version:
227
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
228
+ - request:
229
+ method: get
230
+ uri: https://localhost:8443/api/v1/namespaces/default
231
+ body:
232
+ encoding: US-ASCII
233
+ string: ''
234
+ headers:
235
+ Accept:
236
+ - "*/*; q=0.5, application/xml"
237
+ Accept-Encoding:
238
+ - gzip, deflate
239
+ User-Agent:
240
+ - Ruby
241
+ response:
242
+ status:
243
+ code: 200
244
+ message: OK
245
+ headers:
246
+ Content-Type:
247
+ - application/json
248
+ Date:
249
+ - Fri, 08 May 2015 10:35:37 GMT
250
+ Transfer-Encoding:
251
+ - chunked
252
+ body:
253
+ encoding: UTF-8
254
+ string: |-
255
+ {
256
+ "kind": "Namespace",
257
+ "apiVersion": "v1",
258
+ "metadata": {
259
+ "name": "default",
260
+ "selfLink": "/api/v1/namespaces/default",
261
+ "uid": "898268c8-4a36-11e5-9d81-42010af0194c",
262
+ "resourceVersion": "6",
263
+ "creationTimestamp": "2015-05-08T09:22:01Z"
264
+ },
265
+ "spec": {
266
+ "finalizers": [
267
+ "kubernetes"
268
+ ]
269
+ },
270
+ "status": {
271
+ "phase": "Active"
272
+ }
273
+ }
274
+ http_version:
275
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
276
+ - request:
277
+ method: get
278
+ uri: https://localhost:8443/api/v1/namespaces/journald-namespace-name/pods/journald-pod-name
279
+ body:
280
+ encoding: US-ASCII
281
+ string: ''
282
+ headers:
283
+ Accept:
284
+ - "*/*; q=0.5, application/xml"
285
+ Accept-Encoding:
286
+ - gzip, deflate
287
+ User-Agent:
288
+ - Ruby
289
+ response:
290
+ status:
291
+ code: 200
292
+ message: OK
293
+ headers:
294
+ Content-Type:
295
+ - application/json
296
+ Date:
297
+ - Fri, 08 May 2015 10:35:37 GMT
298
+ Transfer-Encoding:
299
+ - chunked
300
+ body:
301
+ encoding: UTF-8
302
+ string: |-
303
+ {
304
+ "kind": "Pod",
305
+ "apiVersion": "v1",
306
+ "metadata": {
307
+ "name": "journald-pod-name",
308
+ "generateName": "journald-pod-name-",
309
+ "namespace": "journald-namespace-name",
310
+ "selfLink": "/api/v1/namespaces/journald-namespace-name/pods/journald-pod-name",
311
+ "uid": "5e1c1e27-b637-4e81-80b6-6d8a8c404d3b",
312
+ "resourceVersion": "122",
313
+ "creationTimestamp": "2015-05-08T09:22:42Z",
314
+ "labels": {
315
+ "component": "journald-test"
316
+ }
317
+ },
318
+ "spec": {
319
+ "containers": [
320
+ {
321
+ "name": "journald-container-name",
322
+ "image": "journald-container-image:latest",
323
+ "terminationMessagePath": "/dev/termination-log",
324
+ "imagePullPolicy": "IfNotPresent",
325
+ "capabilities": {}
326
+ }
327
+ ],
328
+ "nodeName": "jimmi-redhat.localnet"
329
+ },
330
+ "status": {
331
+ "phase": "Running",
332
+ "Condition": [
333
+ {
334
+ "type": "Ready",
335
+ "status": "True"
336
+ }
337
+ ],
338
+ "hostIP": "172.17.42.1",
339
+ "podIP": "172.17.0.8",
340
+ "containerStatuses": [
341
+ {
342
+ "name": "journald-container-name",
343
+ "state": {
344
+ "running": {
345
+ "startedAt": "2015-05-08T09:22:44Z"
346
+ }
347
+ },
348
+ "lastState": {},
349
+ "ready": true,
350
+ "restartCount": 0,
351
+ "image": "journald-container-image:latest",
352
+ "imageID": "docker://dda4c95705fb7050b701b10a7fe928ca5bc971a1dcb521ae3c339194cbf36b47",
353
+ "containerID": "docker://838350c64bacba968d39a30a50789b2795291fceca6ccbff55298671d46b0e3b"
354
+ }
355
+ ]
356
+ }
357
+ }
358
+ http_version:
359
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
360
+ - request:
361
+ method: get
362
+ uri: https://localhost:8443/api/v1/namespaces/journald-namespace-name
363
+ body:
364
+ encoding: US-ASCII
365
+ string: ''
366
+ headers:
367
+ Accept:
368
+ - "*/*; q=0.5, application/xml"
369
+ Accept-Encoding:
370
+ - gzip, deflate
371
+ User-Agent:
372
+ - Ruby
373
+ response:
374
+ status:
375
+ code: 200
376
+ message: OK
377
+ headers:
378
+ Content-Type:
379
+ - application/json
380
+ Date:
381
+ - Fri, 08 May 2015 10:35:37 GMT
382
+ Transfer-Encoding:
383
+ - chunked
384
+ body:
385
+ encoding: UTF-8
386
+ string: |-
387
+ {
388
+ "kind": "Namespace",
389
+ "apiVersion": "v1",
390
+ "metadata": {
391
+ "name": "journald-namespace-name",
392
+ "selfLink": "/api/v1/namespaces/journald-namespace-name",
393
+ "uid": "8282888f-733f-4f23-a3d3-1fdfa3bdacf2",
394
+ "resourceVersion": "6",
395
+ "creationTimestamp": "2015-05-08T09:22:01Z"
396
+ },
397
+ "spec": {
398
+ "finalizers": [
399
+ "kubernetes"
400
+ ]
401
+ },
402
+ "status": {
403
+ "phase": "Active"
404
+ }
405
+ }
406
+ http_version:
407
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
408
+ recorded_with: VCR 2.9.3