fluent-plugin-kubernetes_metadata_filter 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '0971b8dc580d4813a1859834d5fc5ba334eb3633'
4
- data.tar.gz: 3a054314a366671caf9307a81dd9e38ea6aa7dd5
3
+ metadata.gz: e681f40b4be02d8a14e5007db2a02b008a0d0c10
4
+ data.tar.gz: 90a8f673cc88889b277cdc82e324cf6010b61b9d
5
5
  SHA512:
6
- metadata.gz: 6852eb69fd3f256a6a2825daf6cbe3a58bb8aa646dd054c7d99c65ca9928d2fc4adc87791fbb31f4326e213cc2b1f58957a49da1bfa2c58c0d3864e2883e8d28
7
- data.tar.gz: e640578dd09913bdc9879508970a3528386e6e2fffc6c63acc3aa21358ab8e8d3444f8f6c39b91172f2945a87350612c1225c19976ed574e2edb170962a00662
6
+ metadata.gz: '036584634cb5609c106c3e6b6492958782a1701aea68f7a2ab5223dd3b9476c86a92c1e982ed49bfd4be2ab1f19f2a639515271982eea8dd2d993ba1c3fe98f7'
7
+ data.tar.gz: 0acf8ca916880e819bc197aa52a1de26dfa5bc7af1920d77a2b8d8cd931d2dfe2adba368561b6c297751572dfa5fc3954f379c927801579d38793061ab6712e0
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 1.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 = "1.2.0"
7
+ gem.version = "1.2.1"
8
8
  gem.authors = ["Jimmi Dyson"]
9
9
  gem.email = ["jimmidyson@gmail.com"]
10
10
  gem.description = %q{Filter plugin to add Kubernetes metadata}
@@ -55,7 +55,7 @@ module Fluent
55
55
  # format:
56
56
  # CONTAINER_NAME=k8s_$containername.$containerhash_$podname_$namespacename_$poduuid_$rand32bitashex
57
57
  # CONTAINER_FULL_ID=dockeridassha256hexvalue
58
- config_param :use_journal, :bool, default: false
58
+ config_param :use_journal, :bool, default: nil
59
59
  # Field 2 is the container_hash, field 5 is the pod_id, and field 6 is the pod_randhex
60
60
  # I would have included them as named groups, but you can't have named groups that are
61
61
  # non-capturing :P
@@ -69,6 +69,7 @@ module Fluent
69
69
  config_param :allow_orphans, :bool, default: true
70
70
  config_param :orphaned_namespace_name, :string, default: '.orphaned'
71
71
  config_param :orphaned_namespace_id, :string, default: 'orphaned'
72
+ config_param :lookup_from_k8s_field, :bool, default: true
72
73
 
73
74
  def fetch_pod_metadata(namespace_name, pod_name)
74
75
  log.trace("fetching pod metadata: #{namespace_name}/#{pod_name}") if log.trace?
@@ -234,13 +235,10 @@ module Fluent
234
235
  namespace_thread.abort_on_exception = true
235
236
  end
236
237
  end
237
- if @use_journal
238
- log.debug "Will stream from the journal"
239
- self.class.class_eval { alias_method :filter_stream, :filter_stream_from_journal }
240
- else
241
- log.debug "Will stream from the files"
242
- self.class.class_eval { alias_method :filter_stream, :filter_stream_from_files }
243
- end
238
+ @time_fields = []
239
+ @time_fields.push('_SOURCE_REALTIME_TIMESTAMP', '__REALTIME_TIMESTAMP') if @use_journal || @use_journal.nil?
240
+ @time_fields.push('time') unless @use_journal
241
+ @time_fields.push('@timestamp') if @lookup_from_k8s_field
244
242
 
245
243
  @annotations_regexps = []
246
244
  @annotation_match.each do |regexp|
@@ -253,94 +251,95 @@ module Fluent
253
251
 
254
252
  end
255
253
 
256
- def get_metadata_for_record(match_data, cache_key, create_time, batch_miss_cache)
257
- namespace_name = match_data['namespace']
258
- pod_name = match_data['pod_name']
254
+ def get_metadata_for_record(namespace_name, pod_name, container_name, container_id, create_time, batch_miss_cache)
259
255
  metadata = {
260
- 'container_name' => match_data['container_name'],
261
- 'namespace_name' => namespace_name,
262
- 'pod_name' => pod_name
256
+ 'docker' => {'container_id' => container_id},
257
+ 'kubernetes' => {
258
+ 'container_name' => container_name,
259
+ 'namespace_name' => namespace_name,
260
+ 'pod_name' => pod_name
261
+ }
263
262
  }
264
263
  if @kubernetes_url.present?
265
- pod_metadata = get_pod_metadata(cache_key, namespace_name, pod_name, create_time, batch_miss_cache)
266
- metadata.merge!(pod_metadata) if pod_metadata
267
- end
268
- metadata
269
- end
264
+ pod_metadata = get_pod_metadata(container_id, namespace_name, pod_name, create_time, batch_miss_cache)
270
265
 
271
- def create_time_from_record(record)
272
- time = if @use_journal
273
- record['_SOURCE_REALTIME_TIMESTAMP'].nil? ? record['_SOURCE_REALTIME_TIMESTAMP'] : record['__REALTIME_TIMESTAMP']
274
- else
275
- record['time']
266
+ if (pod_metadata.include? 'containers') && (pod_metadata['containers'].include? container_id)
267
+ metadata['kubernetes']['container_image'] = pod_metadata['containers'][container_id]['image']
268
+ metadata['kubernetes']['container_image_id'] = pod_metadata['containers'][container_id]['image_id']
276
269
  end
277
- (time.nil? || time.chop.empty?) ? Time.now : Time.parse(time)
278
- end
279
270
 
280
- def filter_stream(tag, es)
281
- es
271
+ metadata['kubernetes'].merge!(pod_metadata) if pod_metadata
272
+ metadata['kubernetes'].delete('containers')
273
+ end
274
+ metadata
282
275
  end
283
276
 
284
- def filter_stream_from_files(tag, es)
285
- return es if (es.respond_to?(:empty?) && es.empty?) || !es.is_a?(Fluent::EventStream)
286
- new_es = MultiEventStream.new
287
-
288
- match_data = tag.match(@tag_to_kubernetes_name_regexp_compiled)
289
- batch_miss_cache = {}
290
- if match_data
291
- container_id = match_data['docker_id']
292
- metadata = {
293
- 'docker' => {
294
- 'container_id' => container_id
295
- },
296
- 'kubernetes' => get_metadata_for_record(match_data, container_id, create_time_from_record(es.first[1]), batch_miss_cache)
297
- }
277
+ def create_time_from_record(record, internal_time)
278
+ time_key = @time_fields.detect{ |ii| record.has_key?(ii) }
279
+ time = record[time_key]
280
+ if time.nil? || time.chop.empty?
281
+ return internal_time
298
282
  end
299
-
300
- es.each do |time, record|
301
- record = record.merge(Marshal.load(Marshal.dump(metadata))) if metadata
302
- new_es.add(time, record)
283
+ if ['_SOURCE_REALTIME_TIMESTAMP', '__REALTIME_TIMESTAMP'].include?(time_key)
284
+ timei= time.to_i
285
+ return Time.at(timei / 1000000, timei % 1000000)
303
286
  end
304
- dump_stats
305
- new_es
287
+ return Time.parse(time)
306
288
  end
307
289
 
308
- def filter_stream_from_journal(tag, es)
290
+ def filter_stream(tag, es)
309
291
  return es if (es.respond_to?(:empty?) && es.empty?) || !es.is_a?(Fluent::EventStream)
310
- new_es = MultiEventStream.new
292
+ new_es = Fluent::MultiEventStream.new
293
+ tag_match_data = tag.match(@tag_to_kubernetes_name_regexp_compiled) unless @use_journal
294
+ tag_metadata = nil
311
295
  batch_miss_cache = {}
312
296
  es.each do |time, record|
313
- metadata = nil
314
- if record.has_key?('CONTAINER_NAME') && record.has_key?('CONTAINER_ID_FULL')
315
- metadata = record['CONTAINER_NAME'].match(@container_name_to_kubernetes_regexp_compiled) do |match_data|
316
- container_id = record['CONTAINER_ID_FULL']
317
- metadata = {
318
- 'docker' => {
319
- 'container_id' => container_id
320
- },
321
- 'kubernetes' => get_metadata_for_record(match_data, container_id, create_time_from_record(record), batch_miss_cache)
322
- }
323
-
324
- metadata
325
- end
326
- unless metadata
327
- log.debug "Error: could not match CONTAINER_NAME from record #{record}"
328
- @stats.bump(:container_name_match_failed)
329
- end
330
- elsif record.has_key?('CONTAINER_NAME') && record['CONTAINER_NAME'].start_with?('k8s_')
331
- log.debug "Error: no container name and id in record #{record}"
332
- @stats.bump(:container_name_id_missing)
297
+ if tag_match_data && tag_metadata.nil?
298
+ tag_metadata = get_metadata_for_record(tag_match_data['namespace'], tag_match_data['pod_name'], tag_match_data['container_name'],
299
+ tag_match_data['docker_id'], create_time_from_record(record, time), batch_miss_cache)
300
+ end
301
+ metadata = Marshal.load(Marshal.dump(tag_metadata)) if tag_metadata
302
+ if (@use_journal || @use_journal.nil?) &&
303
+ (j_metadata = get_metadata_for_journal_record(record, time, batch_miss_cache))
304
+ metadata = j_metadata
305
+ end
306
+ if @lookup_from_k8s_field && record.has_key?('kubernetes') && record.has_key?('docker') &&
307
+ record['kubernetes'].respond_to?(:has_key?) && record['docker'].respond_to?(:has_key?) &&
308
+ record['kubernetes'].has_key?('namespace_name') &&
309
+ record['kubernetes'].has_key?('pod_name') &&
310
+ record['kubernetes'].has_key?('container_name') &&
311
+ record['docker'].has_key?('container_id') &&
312
+ (k_metadata = get_metadata_for_record(record['kubernetes']['namespace_name'], record['kubernetes']['pod_name'],
313
+ record['kubernetes']['container_name'], record['docker']['container_id'],
314
+ create_time_from_record(record, time), batch_miss_cache))
315
+ metadata = k_metadata
333
316
  end
334
317
 
335
318
  record = record.merge(metadata) if metadata
336
-
337
319
  new_es.add(time, record)
338
320
  end
339
-
340
321
  dump_stats
341
322
  new_es
342
323
  end
343
324
 
325
+ def get_metadata_for_journal_record(record, time, batch_miss_cache)
326
+ metadata = nil
327
+ if record.has_key?('CONTAINER_NAME') && record.has_key?('CONTAINER_ID_FULL')
328
+ metadata = record['CONTAINER_NAME'].match(@container_name_to_kubernetes_regexp_compiled) do |match_data|
329
+ get_metadata_for_record(match_data['namespace'], match_data['pod_name'], match_data['container_name'],
330
+ record['CONTAINER_ID_FULL'], create_time_from_record(record, time), batch_miss_cache)
331
+ end
332
+ unless metadata
333
+ log.debug "Error: could not match CONTAINER_NAME from record #{record}"
334
+ @stats.bump(:container_name_match_failed)
335
+ end
336
+ elsif record.has_key?('CONTAINER_NAME') && record['CONTAINER_NAME'].start_with?('k8s_')
337
+ log.debug "Error: no container name and id in record #{record}"
338
+ @stats.bump(:container_name_id_missing)
339
+ end
340
+ metadata
341
+ end
342
+
344
343
  def de_dot!(h)
345
344
  h.keys.each do |ref|
346
345
  if h[ref] && ref =~ /\./
@@ -83,6 +83,7 @@ module KubernetesMetadata
83
83
  end
84
84
  @id_cache[key] = ids unless batch_miss_cache.key?("#{namespace_name}_#{pod_name}")
85
85
  end
86
+
86
87
  # remove namespace info that is only used for comparison
87
88
  metadata.delete('creation_timestamp')
88
89
  metadata.delete_if{|k,v| v.nil?}
@@ -54,10 +54,30 @@ module KubernetesMetadata
54
54
  self.de_dot!(labels)
55
55
  self.de_dot!(annotations)
56
56
  end
57
+
58
+ # collect container informations
59
+ container_meta = {}
60
+ begin
61
+ pod_object['status']['containerStatuses'].each do|container_status|
62
+ # get plain container id (eg. docker://hash -> hash)
63
+ container_id = container_status['containerID'].sub /^[-_a-zA-Z0-9]+:\/\//, ''
64
+ container_meta[container_id] = {
65
+ 'name' => container_status['name'],
66
+ 'image' => container_status['image'],
67
+ 'image_id' => container_status['imageID']
68
+ }
69
+ end
70
+ rescue
71
+ log.on_debug do
72
+ log.debug("parsing container meta information failed for: #{pod_object['metadata']['namespace']}/#{pod_object['metadata']['name']} ")
73
+ end
74
+ end
75
+
57
76
  kubernetes_metadata = {
58
77
  'namespace_name' => pod_object['metadata']['namespace'],
59
78
  'pod_id' => pod_object['metadata']['uid'],
60
79
  'pod_name' => pod_object['metadata']['name'],
80
+ 'containers' => syms_to_strs(container_meta),
61
81
  'labels' => labels,
62
82
  'host' => pod_object['spec']['nodeName'],
63
83
  'master_url' => @kubernetes_url
@@ -174,7 +174,7 @@ http_interactions:
174
174
  "restartCount": 2,
175
175
  "image": "fabric8/hawtio-kubernetes:latest",
176
176
  "imageID": "docker://b2bd1a24a68356b2f30128e6e28e672c1ef92df0d9ec01ec0c7faea5d77d2303",
177
- "containerID": "docker://1b1d1f61c1205fe73328c75b2945e2ce05acfba2fde16299a8103fb22e9ec58a"
177
+ "containerID": "docker://49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459"
178
178
  },
179
179
  {
180
180
  "name": "POD",
@@ -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