fluent-plugin-kubernetes_metadata_filter-rh 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +57 -0
  3. data/.gitignore +19 -0
  4. data/.rubocop.yml +57 -0
  5. data/Gemfile +9 -0
  6. data/Gemfile.lock +156 -0
  7. data/LICENSE.txt +201 -0
  8. data/README.md +253 -0
  9. data/Rakefile +41 -0
  10. data/fluent-plugin-kubernetes_metadata_filter.gemspec +34 -0
  11. data/lib/fluent/plugin/filter_kubernetes_metadata.rb +378 -0
  12. data/lib/fluent/plugin/kubernetes_metadata_cache_strategy.rb +102 -0
  13. data/lib/fluent/plugin/kubernetes_metadata_common.rb +120 -0
  14. data/lib/fluent/plugin/kubernetes_metadata_stats.rb +46 -0
  15. data/lib/fluent/plugin/kubernetes_metadata_util.rb +40 -0
  16. data/lib/fluent/plugin/kubernetes_metadata_watch_namespaces.rb +154 -0
  17. data/lib/fluent/plugin/kubernetes_metadata_watch_pods.rb +172 -0
  18. data/test/cassettes/invalid_api_server_config.yml +53 -0
  19. data/test/cassettes/kubernetes_docker_metadata_annotations.yml +205 -0
  20. data/test/cassettes/kubernetes_docker_metadata_dotted_labels.yml +197 -0
  21. data/test/cassettes/kubernetes_get_api_v1.yml +193 -0
  22. data/test/cassettes/kubernetes_get_api_v1_using_token.yml +195 -0
  23. data/test/cassettes/kubernetes_get_namespace_default.yml +69 -0
  24. data/test/cassettes/kubernetes_get_namespace_default_using_token.yml +71 -0
  25. data/test/cassettes/kubernetes_get_pod.yml +146 -0
  26. data/test/cassettes/kubernetes_get_pod_using_token.yml +148 -0
  27. data/test/cassettes/metadata_from_tag_and_journald_fields.yml +153 -0
  28. data/test/cassettes/metadata_from_tag_journald_and_kubernetes_fields.yml +285 -0
  29. data/test/cassettes/valid_kubernetes_api_server.yml +55 -0
  30. data/test/cassettes/valid_kubernetes_api_server_using_token.yml +57 -0
  31. data/test/helper.rb +82 -0
  32. data/test/plugin/test.token +1 -0
  33. data/test/plugin/test_cache_stats.rb +33 -0
  34. data/test/plugin/test_cache_strategy.rb +194 -0
  35. data/test/plugin/test_filter_kubernetes_metadata.rb +1012 -0
  36. data/test/plugin/test_utils.rb +56 -0
  37. data/test/plugin/test_watch_namespaces.rb +245 -0
  38. data/test/plugin/test_watch_pods.rb +344 -0
  39. data/test/plugin/watch_test.rb +74 -0
  40. metadata +269 -0
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
5
+ # Kubernetes metadata
6
+ #
7
+ # Copyright 2017 Red Hat, Inc.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ #
21
+ # TODO: this is mostly copy-paste from kubernetes_metadata_watch_namespaces.rb unify them
22
+ require_relative 'kubernetes_metadata_common'
23
+
24
+ module KubernetesMetadata
25
+ module WatchPods
26
+ include ::KubernetesMetadata::Common
27
+
28
+ def set_up_pod_thread
29
+ # Any failures / exceptions in the initial setup should raise
30
+ # Fluent:ConfigError, so that users can inspect potential errors in
31
+ # the configuration.
32
+ pod_watcher = start_pod_watch
33
+
34
+ Thread.current[:pod_watch_retry_backoff_interval] = @watch_retry_interval
35
+ Thread.current[:pod_watch_retry_count] = 0
36
+
37
+ # Any failures / exceptions in the followup watcher notice
38
+ # processing will be swallowed and retried. These failures /
39
+ # exceptions could be caused by Kubernetes API being temporarily
40
+ # down. We assume the configuration is correct at this point.
41
+ loop do
42
+ pod_watcher ||= get_pods_and_start_watcher
43
+ process_pod_watcher_notices(pod_watcher)
44
+ rescue GoneError => e
45
+ # Expected error. Quietly go back through the loop in order to
46
+ # start watching from the latest resource versions
47
+ @stats.bump(:pod_watch_gone_errors)
48
+ log.info('410 Gone encountered. Restarting pod watch to reset resource versions.', e)
49
+ pod_watcher = nil
50
+ rescue StandardError => e
51
+ @stats.bump(:pod_watch_failures)
52
+ if Thread.current[:pod_watch_retry_count] < @watch_retry_max_times
53
+ # Instead of raising exceptions and crashing Fluentd, swallow
54
+ # the exception and reset the watcher.
55
+ log.info(
56
+ 'Exception encountered parsing pod watch event. The ' \
57
+ 'connection might have been closed. Sleeping for ' \
58
+ "#{Thread.current[:pod_watch_retry_backoff_interval]} " \
59
+ 'seconds and resetting the pod watcher.', e
60
+ )
61
+ sleep(Thread.current[:pod_watch_retry_backoff_interval])
62
+ Thread.current[:pod_watch_retry_count] += 1
63
+ Thread.current[:pod_watch_retry_backoff_interval] *= @watch_retry_exponential_backoff_base
64
+ pod_watcher = nil
65
+ else
66
+ # Since retries failed for many times, log as errors instead
67
+ # of info and raise exceptions and trigger Fluentd to restart.
68
+ message =
69
+ 'Exception encountered parsing pod watch event. The ' \
70
+ 'connection might have been closed. Retried ' \
71
+ "#{@watch_retry_max_times} times yet still failing. Restarting."
72
+ log.error(message, e)
73
+ raise Fluent::UnrecoverableError, message
74
+ end
75
+ end
76
+ end
77
+
78
+ def start_pod_watch
79
+ get_pods_and_start_watcher
80
+ rescue StandardError => e
81
+ message = 'start_pod_watch: Exception encountered setting up pod watch ' \
82
+ "from Kubernetes API #{@apiVersion} endpoint " \
83
+ "#{@kubernetes_url}: #{e.message}"
84
+ message += " (#{e.response})" if e.respond_to?(:response)
85
+ log.debug(message)
86
+
87
+ raise Fluent::ConfigError, message
88
+ end
89
+
90
+ # List all pods, record the resourceVersion and return a watcher starting
91
+ # from that resourceVersion.
92
+ def get_pods_and_start_watcher
93
+ options = {
94
+ resource_version: '0' # Fetch from API server cache instead of etcd quorum read
95
+ }
96
+ if ENV['K8S_NODE_NAME']
97
+ options[:field_selector] = 'spec.nodeName=' + ENV['K8S_NODE_NAME']
98
+ end
99
+ if @last_seen_resource_version
100
+ options[:resource_version] = @last_seen_resource_version
101
+ else
102
+ pods = @client.get_pods(options)
103
+ pods[:items].each do |pod|
104
+ cache_key = pod[:metadata][:uid]
105
+ @cache[cache_key] = parse_pod_metadata(pod)
106
+ @stats.bump(:pod_cache_host_updates)
107
+ end
108
+
109
+ # continue watching from most recent resourceVersion
110
+ options[:resource_version] = pods[:metadata][:resourceVersion]
111
+ end
112
+
113
+ watcher = @client.watch_pods(options)
114
+ reset_pod_watch_retry_stats
115
+ watcher
116
+ end
117
+
118
+ # Reset pod watch retry count and backoff interval as there is a
119
+ # successful watch notice.
120
+ def reset_pod_watch_retry_stats
121
+ Thread.current[:pod_watch_retry_count] = 0
122
+ Thread.current[:pod_watch_retry_backoff_interval] = @watch_retry_interval
123
+ end
124
+
125
+ # Process a watcher notice and potentially raise an exception.
126
+ def process_pod_watcher_notices(watcher)
127
+ watcher.each do |notice|
128
+ # store version we processed to not reprocess it ... do not unset when there is no version in response
129
+ version = ( # TODO: replace with &.dig once we are on ruby 2.5+
130
+ notice[:object] && notice[:object][:metadata] && notice[:object][:metadata][:resourceVersion]
131
+ )
132
+ @last_seen_resource_version = version if version
133
+
134
+ case notice[:type]
135
+ when 'MODIFIED'
136
+ reset_pod_watch_retry_stats
137
+ cache_key = notice.dig(:object, :metadata, :uid)
138
+ cached = @cache[cache_key]
139
+ if cached
140
+ @cache[cache_key] = parse_pod_metadata(notice[:object])
141
+ @stats.bump(:pod_cache_watch_updates)
142
+ elsif ENV['K8S_NODE_NAME'] == notice[:object][:spec][:nodeName]
143
+ @cache[cache_key] = parse_pod_metadata(notice[:object])
144
+ @stats.bump(:pod_cache_host_updates)
145
+ else
146
+ @stats.bump(:pod_cache_watch_misses)
147
+ end
148
+ when 'DELETED'
149
+ reset_pod_watch_retry_stats
150
+ # ignore and let age out for cases where pods
151
+ # deleted but still processing logs
152
+ @stats.bump(:pod_cache_watch_delete_ignored)
153
+ when 'ERROR'
154
+ if notice[:object] && notice[:object][:code] == 410
155
+ @last_seen_resource_version = nil # requested resourceVersion was too old, need to reset
156
+ @stats.bump(:pod_watch_gone_notices)
157
+ raise GoneError
158
+ else
159
+ @stats.bump(:pod_watch_error_type_notices)
160
+ message = notice[:object][:message] if notice[:object] && notice[:object][:message]
161
+ raise "Error while watching pods: #{message}"
162
+ end
163
+ else
164
+ reset_pod_watch_retry_stats
165
+ # Don't pay attention to creations, since the created pod may not
166
+ # end up on this node.
167
+ @stats.bump(:pod_cache_watch_ignored)
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,53 @@
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
+ Authorization:
35
+ - Bearer YzYyYzFlODMtODdhNS00ZTMyLWIzMmItNmY4NDc4OTI1ZWF
36
+ response:
37
+ status:
38
+ code: 401
39
+ message: Unauthorized
40
+ headers:
41
+ Content-Type:
42
+ - text/plain; charset=utf-8
43
+ Date:
44
+ - Sat, 09 May 2015 14:04:39 GMT
45
+ Content-Length:
46
+ - '13'
47
+ body:
48
+ encoding: UTF-8
49
+ string: |
50
+ Unauthorized
51
+ http_version:
52
+ recorded_at: Sat, 09 May 2015 14:04:39 GMT
53
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,205 @@
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/v1/namespaces/default/pods/fabric8-console-controller-98rqc
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
+ Transfer-Encoding:
44
+ - chunked
45
+ body:
46
+ encoding: UTF-8
47
+ string: |-
48
+ {
49
+ "kind": "Pod",
50
+ "apiVersion": "v1",
51
+ "metadata": {
52
+ "name": "fabric8-console-controller-98rqc",
53
+ "generateName": "fabric8-console-controller-",
54
+ "namespace": "default",
55
+ "selfLink": "/api/v1/namespaces/default/pods/fabric8-console-controller-98rqc",
56
+ "uid": "c76927af-f563-11e4-b32d-54ee7527188d",
57
+ "resourceVersion": "122",
58
+ "creationTimestamp": "2015-05-08T09:22:42Z",
59
+ "labels": {
60
+ "component": "fabric8Console"
61
+ },
62
+ "annotations": {
63
+ "kubernetes.io/config.hash": "c171c44f5b9345c6dc17b0e95030318c",
64
+ "kubernetes.io/config.mirror": "c171c44f5b9345c6dc17b0e95030318c",
65
+ "kubernetes.io/config.seen": "2016-06-06T08:08:35.680437994Z",
66
+ "kubernetes.io/config.source": "file",
67
+ "custom.field1": "hello_kitty",
68
+ "field.two": "value"
69
+ }
70
+ },
71
+ "spec": {
72
+ "volumes": [
73
+ {
74
+ "name": "openshift-cert-secrets",
75
+ "hostPath": null,
76
+ "emptyDir": null,
77
+ "gcePersistentDisk": null,
78
+ "gitRepo": null,
79
+ "secret": {
80
+ "secretName": "openshift-cert-secrets"
81
+ },
82
+ "nfs": null,
83
+ "iscsi": null,
84
+ "glusterfs": null
85
+ }
86
+ ],
87
+ "containers": [
88
+ {
89
+ "name": "fabric8-console-container",
90
+ "image": "fabric8/hawtio-kubernetes:latest",
91
+ "ports": [
92
+ {
93
+ "containerPort": 9090,
94
+ "protocol": "TCP"
95
+ }
96
+ ],
97
+ "env": [
98
+ {
99
+ "name": "OAUTH_CLIENT_ID",
100
+ "value": "fabric8-console"
101
+ },
102
+ {
103
+ "name": "OAUTH_AUTHORIZE_URI",
104
+ "value": "https://localhost:8443/oauth/authorize"
105
+ }
106
+ ],
107
+ "resources": {},
108
+ "volumeMounts": [
109
+ {
110
+ "name": "openshift-cert-secrets",
111
+ "readOnly": true,
112
+ "mountPath": "/etc/secret-volume"
113
+ }
114
+ ],
115
+ "terminationMessagePath": "/dev/termination-log",
116
+ "imagePullPolicy": "IfNotPresent",
117
+ "capabilities": {}
118
+ }
119
+ ],
120
+ "restartPolicy": "Always",
121
+ "dnsPolicy": "ClusterFirst",
122
+ "nodeName": "jimmi-redhat.localnet"
123
+ },
124
+ "status": {
125
+ "phase": "Running",
126
+ "Condition": [
127
+ {
128
+ "type": "Ready",
129
+ "status": "True"
130
+ }
131
+ ],
132
+ "hostIP": "172.17.42.1",
133
+ "podIP": "172.17.0.8",
134
+ "containerStatuses": [
135
+ {
136
+ "name": "fabric8-console-container",
137
+ "state": {
138
+ "running": {
139
+ "startedAt": "2015-05-08T09:22:44Z"
140
+ }
141
+ },
142
+ "lastState": {},
143
+ "ready": true,
144
+ "restartCount": 0,
145
+ "image": "fabric8/hawtio-kubernetes:latest",
146
+ "imageID": "docker://b2bd1a24a68356b2f30128e6e28e672c1ef92df0d9ec01ec0c7faea5d77d2303",
147
+ "containerID": "docker://49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459"
148
+ }
149
+ ]
150
+ }
151
+ }
152
+ http_version:
153
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
154
+ - request:
155
+ method: get
156
+ uri: https://localhost:8443/api/v1/namespaces/default
157
+ body:
158
+ encoding: US-ASCII
159
+ string: ''
160
+ headers:
161
+ Accept:
162
+ - "*/*; q=0.5, application/xml"
163
+ Accept-Encoding:
164
+ - gzip, deflate
165
+ User-Agent:
166
+ - Ruby
167
+ response:
168
+ status:
169
+ code: 200
170
+ message: OK
171
+ headers:
172
+ Content-Type:
173
+ - application/json
174
+ Date:
175
+ - Fri, 08 May 2015 10:35:37 GMT
176
+ Transfer-Encoding:
177
+ - chunked
178
+ body:
179
+ encoding: UTF-8
180
+ string: |-
181
+ {
182
+ "kind": "Namespace",
183
+ "apiVersion": "v1",
184
+ "metadata": {
185
+ "name": "default",
186
+ "selfLink": "/api/v1/namespaces/default",
187
+ "uid": "898268c8-4a36-11e5-9d81-42010af0194c",
188
+ "resourceVersion": "6",
189
+ "creationTimestamp": "2015-05-08T09:22:01Z",
190
+ "annotations": {
191
+ "workspaceId": "myWorkspaceName"
192
+ }
193
+ },
194
+ "spec": {
195
+ "finalizers": [
196
+ "kubernetes"
197
+ ]
198
+ },
199
+ "status": {
200
+ "phase": "Active"
201
+ }
202
+ }
203
+ http_version:
204
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
205
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,197 @@
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/v1/namespaces/default/pods/fabric8-console-controller-98rqc
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
+ Transfer-Encoding:
44
+ - chunked
45
+ body:
46
+ encoding: UTF-8
47
+ string: |-
48
+ {
49
+ "kind": "Pod",
50
+ "apiVersion": "v1",
51
+ "metadata": {
52
+ "name": "fabric8-console-controller-98rqc",
53
+ "generateName": "fabric8-console-controller-",
54
+ "namespace": "default",
55
+ "selfLink": "/api/v1/namespaces/default/pods/fabric8-console-controller-98rqc",
56
+ "uid": "c76927af-f563-11e4-b32d-54ee7527188d",
57
+ "resourceVersion": "122",
58
+ "creationTimestamp": "2015-05-08T09:22:42Z",
59
+ "labels": {
60
+ "kubernetes.io/test": "somevalue"
61
+ }
62
+ },
63
+ "spec": {
64
+ "volumes": [
65
+ {
66
+ "name": "openshift-cert-secrets",
67
+ "hostPath": null,
68
+ "emptyDir": null,
69
+ "gcePersistentDisk": null,
70
+ "gitRepo": null,
71
+ "secret": {
72
+ "secretName": "openshift-cert-secrets"
73
+ },
74
+ "nfs": null,
75
+ "iscsi": null,
76
+ "glusterfs": null
77
+ }
78
+ ],
79
+ "containers": [
80
+ {
81
+ "name": "fabric8-console-container",
82
+ "image": "fabric8/hawtio-kubernetes:latest",
83
+ "ports": [
84
+ {
85
+ "containerPort": 9090,
86
+ "protocol": "TCP"
87
+ }
88
+ ],
89
+ "env": [
90
+ {
91
+ "name": "OAUTH_CLIENT_ID",
92
+ "value": "fabric8-console"
93
+ },
94
+ {
95
+ "name": "OAUTH_AUTHORIZE_URI",
96
+ "value": "https://localhost:8443/oauth/authorize"
97
+ }
98
+ ],
99
+ "resources": {},
100
+ "volumeMounts": [
101
+ {
102
+ "name": "openshift-cert-secrets",
103
+ "readOnly": true,
104
+ "mountPath": "/etc/secret-volume"
105
+ }
106
+ ],
107
+ "terminationMessagePath": "/dev/termination-log",
108
+ "imagePullPolicy": "IfNotPresent",
109
+ "capabilities": {}
110
+ }
111
+ ],
112
+ "restartPolicy": "Always",
113
+ "dnsPolicy": "ClusterFirst",
114
+ "nodeName": "jimmi-redhat.localnet"
115
+ },
116
+ "status": {
117
+ "phase": "Running",
118
+ "Condition": [
119
+ {
120
+ "type": "Ready",
121
+ "status": "True"
122
+ }
123
+ ],
124
+ "hostIP": "172.17.42.1",
125
+ "podIP": "172.17.0.8",
126
+ "containerStatuses": [
127
+ {
128
+ "name": "fabric8-console-container",
129
+ "state": {
130
+ "running": {
131
+ "startedAt": "2015-05-08T09:22:44Z"
132
+ }
133
+ },
134
+ "lastState": {},
135
+ "ready": true,
136
+ "restartCount": 0,
137
+ "image": "fabric8/hawtio-kubernetes:latest",
138
+ "imageID": "docker://b2bd1a24a68356b2f30128e6e28e672c1ef92df0d9ec01ec0c7faea5d77d2303",
139
+ "containerID": "docker://49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459"
140
+ }
141
+ ]
142
+ }
143
+ }
144
+ http_version:
145
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
146
+ - request:
147
+ method: get
148
+ uri: https://localhost:8443/api/v1/namespaces/default
149
+ body:
150
+ encoding: US-ASCII
151
+ string: ''
152
+ headers:
153
+ Accept:
154
+ - "*/*; q=0.5, application/xml"
155
+ Accept-Encoding:
156
+ - gzip, deflate
157
+ User-Agent:
158
+ - Ruby
159
+ response:
160
+ status:
161
+ code: 200
162
+ message: OK
163
+ headers:
164
+ Content-Type:
165
+ - application/json
166
+ Date:
167
+ - Fri, 08 May 2015 10:35:37 GMT
168
+ Transfer-Encoding:
169
+ - chunked
170
+ body:
171
+ encoding: UTF-8
172
+ string: |-
173
+ {
174
+ "kind": "Namespace",
175
+ "apiVersion": "v1",
176
+ "metadata": {
177
+ "name": "default",
178
+ "selfLink": "/api/v1/namespaces/default",
179
+ "uid": "898268c8-4a36-11e5-9d81-42010af0194c",
180
+ "resourceVersion": "6",
181
+ "creationTimestamp": "2015-05-08T09:22:01Z",
182
+ "labels": {
183
+ "kubernetes.io/namespacetest": "somevalue"
184
+ }
185
+ },
186
+ "spec": {
187
+ "finalizers": [
188
+ "kubernetes"
189
+ ]
190
+ },
191
+ "status": {
192
+ "phase": "Active"
193
+ }
194
+ }
195
+ http_version:
196
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
197
+ recorded_with: VCR 2.9.3