fluent-plugin-kubernetes_metadata_filter_fix 2.2.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +56 -0
  3. data/.gitignore +20 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE.txt +201 -0
  6. data/README.md +210 -0
  7. data/Rakefile +37 -0
  8. data/fluent-plugin-kubernetes_metadata_filter.gemspec +36 -0
  9. data/lib/fluent/plugin/filter_kubernetes_metadata.rb +387 -0
  10. data/lib/fluent/plugin/kubernetes_metadata_cache_strategy.rb +98 -0
  11. data/lib/fluent/plugin/kubernetes_metadata_common.rb +113 -0
  12. data/lib/fluent/plugin/kubernetes_metadata_stats.rb +46 -0
  13. data/lib/fluent/plugin/kubernetes_metadata_watch_namespaces.rb +60 -0
  14. data/lib/fluent/plugin/kubernetes_metadata_watch_pods.rb +63 -0
  15. data/test/cassettes/invalid_api_server_config.yml +53 -0
  16. data/test/cassettes/kubernetes_docker_metadata.yml +228 -0
  17. data/test/cassettes/kubernetes_docker_metadata_annotations.yml +239 -0
  18. data/test/cassettes/kubernetes_docker_metadata_dotted_labels.yml +231 -0
  19. data/test/cassettes/kubernetes_docker_metadata_using_bearer_token.yml +248 -0
  20. data/test/cassettes/metadata_from_tag_and_journald_fields.yml +408 -0
  21. data/test/cassettes/metadata_from_tag_journald_and_kubernetes_fields.yml +540 -0
  22. data/test/cassettes/metadata_with_namespace_id.yml +276 -0
  23. data/test/cassettes/non_kubernetes_docker_metadata.yml +97 -0
  24. data/test/cassettes/valid_kubernetes_api_server.yml +55 -0
  25. data/test/helper.rb +64 -0
  26. data/test/plugin/test.token +1 -0
  27. data/test/plugin/test_cache_stats.rb +36 -0
  28. data/test/plugin/test_cache_strategy.rb +196 -0
  29. data/test/plugin/test_filter_kubernetes_metadata.rb +970 -0
  30. data/test/plugin/test_watch_namespaces.rb +91 -0
  31. data/test/plugin/test_watch_pods.rb +145 -0
  32. data/test/plugin/watch_test.rb +57 -0
  33. metadata +280 -0
@@ -0,0 +1,98 @@
1
+ #
2
+ # Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
3
+ # Kubernetes metadata
4
+ #
5
+ # Copyright 2017 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
+ module KubernetesMetadata
20
+ module CacheStrategy
21
+ def get_pod_metadata(key, namespace_name, pod_name, record_create_time, batch_miss_cache)
22
+ metadata = {}
23
+ ids = @id_cache[key]
24
+ if !ids.nil?
25
+ # FAST PATH
26
+ # Cache hit, fetch metadata from the cache
27
+ metadata = @cache.fetch(ids[:pod_id]) do
28
+ @stats.bump(:pod_cache_miss)
29
+ m = fetch_pod_metadata(namespace_name, pod_name)
30
+ (m.nil? || m.empty?) ? {'pod_id'=>ids[:pod_id]} : m
31
+ end
32
+ metadata.merge!(@namespace_cache.fetch(ids[:namespace_id]) do
33
+ @stats.bump(:namespace_cache_miss)
34
+ m = fetch_namespace_metadata(namespace_name) unless @skip_namespace_metadata
35
+ (m.nil? || m.empty?) ? {'namespace_id'=>ids[:namespace_id]} : m
36
+ end)
37
+ else
38
+ # SLOW PATH
39
+ @stats.bump(:id_cache_miss)
40
+ return batch_miss_cache["#{namespace_name}_#{pod_name}"] if batch_miss_cache.key?("#{namespace_name}_#{pod_name}")
41
+ pod_metadata = fetch_pod_metadata(namespace_name, pod_name)
42
+ if @skip_namespace_metadata
43
+ ids = { :pod_id=> pod_metadata['pod_id'] }
44
+ @id_cache[key] = ids
45
+ return pod_metadata
46
+ end
47
+ namespace_metadata = fetch_namespace_metadata(namespace_name)
48
+ ids = { :pod_id=> pod_metadata['pod_id'], :namespace_id => namespace_metadata['namespace_id'] }
49
+ if !ids[:pod_id].nil? && !ids[:namespace_id].nil?
50
+ # pod found and namespace found
51
+ metadata = pod_metadata
52
+ metadata.merge!(namespace_metadata)
53
+ else
54
+ if ids[:pod_id].nil? && !ids[:namespace_id].nil?
55
+ # pod not found, but namespace found
56
+ @stats.bump(:id_cache_pod_not_found_namespace)
57
+ ns_time = Time.parse(namespace_metadata['creation_timestamp'])
58
+ if ns_time <= record_create_time
59
+ # namespace is older then record for pod
60
+ ids[:pod_id] = key
61
+ metadata = @cache.fetch(ids[:pod_id]) do
62
+ m = { 'pod_id' => ids[:pod_id] }
63
+ end
64
+ end
65
+ metadata.merge!(namespace_metadata)
66
+ else
67
+ if !ids[:pod_id].nil? && ids[:namespace_id].nil?
68
+ # pod found, but namespace NOT found
69
+ # this should NEVER be possible since pod meta can
70
+ # only be retrieved with a namespace
71
+ @stats.bump(:id_cache_namespace_not_found_pod)
72
+ else
73
+ # nothing found
74
+ @stats.bump(:id_cache_orphaned_record)
75
+ end
76
+ if @allow_orphans
77
+ log.trace("orphaning message for: #{namespace_name}/#{pod_name} ") if log.trace?
78
+ metadata = {
79
+ 'orphaned_namespace' => namespace_name,
80
+ 'namespace_name' => @orphaned_namespace_name,
81
+ 'namespace_id' => @orphaned_namespace_id
82
+ }
83
+ else
84
+ metadata = {}
85
+ end
86
+ batch_miss_cache["#{namespace_name}_#{pod_name}"] = metadata
87
+ end
88
+ end
89
+ @id_cache[key] = ids unless batch_miss_cache.key?("#{namespace_name}_#{pod_name}")
90
+ end
91
+
92
+ # remove namespace info that is only used for comparison
93
+ metadata.delete('creation_timestamp')
94
+ metadata.delete_if{|k,v| v.nil?}
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,113 @@
1
+ #
2
+ # Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
3
+ # Kubernetes metadata
4
+ #
5
+ # Copyright 2017 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
+ module KubernetesMetadata
20
+ module Common
21
+
22
+ def match_annotations(annotations)
23
+ result = {}
24
+ @annotations_regexps.each do |regexp|
25
+ annotations.each do |key, value|
26
+ if ::Fluent::StringUtil.match_regexp(regexp, key.to_s)
27
+ result[key] = value
28
+ end
29
+ end
30
+ end
31
+ result
32
+ end
33
+
34
+ def parse_namespace_metadata(namespace_object)
35
+ labels = String.new
36
+ labels = syms_to_strs(namespace_object['metadata']['labels'].to_h) unless @skip_labels
37
+
38
+ annotations = match_annotations(syms_to_strs(namespace_object['metadata']['annotations'].to_h))
39
+ if @de_dot
40
+ self.de_dot!(labels) unless @skip_labels
41
+ self.de_dot!(annotations)
42
+ end
43
+ kubernetes_metadata = {
44
+ 'namespace_id' => namespace_object['metadata']['uid'],
45
+ 'creation_timestamp' => namespace_object['metadata']['creationTimestamp']
46
+ }
47
+ kubernetes_metadata['namespace_labels'] = labels unless labels.empty?
48
+ kubernetes_metadata['namespace_annotations'] = annotations unless annotations.empty?
49
+ return kubernetes_metadata
50
+ end
51
+
52
+ def parse_pod_metadata(pod_object)
53
+ labels = String.new
54
+ labels = syms_to_strs(pod_object['metadata']['labels'].to_h) unless @skip_labels
55
+
56
+ annotations = match_annotations(syms_to_strs(pod_object['metadata']['annotations'].to_h))
57
+ if @de_dot
58
+ self.de_dot!(labels) unless @skip_labels
59
+ self.de_dot!(annotations)
60
+ end
61
+
62
+ # collect container informations
63
+ container_meta = {}
64
+ begin
65
+ pod_object['status']['containerStatuses'].each do|container_status|
66
+ # get plain container id (eg. docker://hash -> hash)
67
+ container_id = container_status['containerID'].sub /^[-_a-zA-Z0-9]+:\/\//, ''
68
+ unless @skip_container_metadata
69
+ container_meta[container_id] = {
70
+ 'name' => container_status['name'],
71
+ 'image' => container_status['image'],
72
+ 'image_id' => container_status['imageID']
73
+ }
74
+ else
75
+ container_meta[container_id] = {
76
+ 'name' => container_status['name']
77
+ }
78
+ end
79
+ end
80
+ rescue => e
81
+ log.debug("parsing container meta information failed for: #{pod_object['metadata']['namespace']}/#{pod_object['metadata']['name']} adfs #{e}")
82
+ end
83
+
84
+ kubernetes_metadata = {
85
+ 'namespace_name' => pod_object['metadata']['namespace'],
86
+ 'pod_id' => pod_object['metadata']['uid'],
87
+ 'pod_name' => pod_object['metadata']['name'],
88
+ 'containers' => syms_to_strs(container_meta),
89
+ 'host' => pod_object['spec']['nodeName']
90
+ }
91
+ kubernetes_metadata['annotations'] = annotations unless annotations.empty?
92
+ kubernetes_metadata['labels'] = labels unless labels.empty?
93
+ kubernetes_metadata['master_url'] = @kubernetes_url unless @skip_master_url
94
+ return kubernetes_metadata
95
+ end
96
+
97
+ def syms_to_strs(hsh)
98
+ newhsh = {}
99
+ hsh.each_pair do |kk,vv|
100
+ if vv.is_a?(Hash)
101
+ vv = syms_to_strs(vv)
102
+ end
103
+ if kk.is_a?(Symbol)
104
+ newhsh[kk.to_s] = vv
105
+ else
106
+ newhsh[kk] = vv
107
+ end
108
+ end
109
+ newhsh
110
+ end
111
+
112
+ end
113
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
3
+ # Kubernetes metadata
4
+ #
5
+ # Copyright 2017 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
+ require 'lru_redux'
20
+ module KubernetesMetadata
21
+ class Stats
22
+
23
+ def initialize
24
+ @stats = ::LruRedux::TTL::ThreadSafeCache.new(1000, 3600)
25
+ end
26
+
27
+ def bump(key)
28
+ @stats[key] = @stats.getset(key) { 0 } + 1
29
+ end
30
+
31
+ def set(key, value)
32
+ @stats[key] = value
33
+ end
34
+
35
+ def [](key)
36
+ @stats[key]
37
+ end
38
+
39
+ def to_s
40
+ "stats - " + [].tap do |a|
41
+ @stats.each {|k,v| a << "#{k.to_s}: #{v}"}
42
+ end.join(', ')
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,60 @@
1
+ #
2
+ # Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
3
+ # Kubernetes metadata
4
+ #
5
+ # Copyright 2017 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
+ require_relative 'kubernetes_metadata_common'
20
+
21
+ module KubernetesMetadata
22
+ module WatchNamespaces
23
+
24
+ include ::KubernetesMetadata::Common
25
+
26
+ def start_namespace_watch
27
+ begin
28
+ resource_version = @client.get_namespaces.resourceVersion
29
+ watcher = @client.watch_namespaces(resource_version)
30
+ rescue Exception=>e
31
+ message = "start_namespace_watch: Exception encountered setting up namespace watch from Kubernetes API #{@apiVersion} endpoint #{@kubernetes_url}: #{e.message}"
32
+ message += " (#{e.response})" if e.respond_to?(:response)
33
+ log.debug(message)
34
+ raise Fluent::ConfigError, message
35
+ end
36
+ watcher.each do |notice|
37
+ case notice.type
38
+ when 'MODIFIED'
39
+ cache_key = notice.object['metadata']['uid']
40
+ cached = @namespace_cache[cache_key]
41
+ if cached
42
+ @namespace_cache[cache_key] = parse_namespace_metadata(notice.object)
43
+ @stats.bump(:namespace_cache_watch_updates)
44
+ else
45
+ @stats.bump(:namespace_cache_watch_misses)
46
+ end
47
+ when 'DELETED'
48
+ # ignore and let age out for cases where
49
+ # deleted but still processing logs
50
+ @stats.bump(:namespace_cache_watch_deletes_ignored)
51
+ else
52
+ # Don't pay attention to creations, since the created namespace may not
53
+ # be used by any pod on this node.
54
+ @stats.bump(:namespace_cache_watch_ignored)
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,63 @@
1
+ #
2
+ # Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
3
+ # Kubernetes metadata
4
+ #
5
+ # Copyright 2017 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
+ require_relative 'kubernetes_metadata_common'
20
+
21
+ module KubernetesMetadata
22
+ module WatchPods
23
+
24
+ include ::KubernetesMetadata::Common
25
+
26
+ def start_pod_watch
27
+ begin
28
+ resource_version = @client.get_pods.resourceVersion
29
+ watcher = @client.watch_pods(resource_version)
30
+ rescue Exception => e
31
+ message = "Exception encountered fetching metadata from Kubernetes API endpoint: #{e.message}"
32
+ message += " (#{e.response})" if e.respond_to?(:response)
33
+
34
+ raise Fluent::ConfigError, message
35
+ end
36
+
37
+ watcher.each do |notice|
38
+ case notice.type
39
+ when 'MODIFIED'
40
+ cache_key = notice.object['metadata']['uid']
41
+ cached = @cache[cache_key]
42
+ if cached
43
+ @cache[cache_key] = parse_pod_metadata(notice.object)
44
+ @stats.bump(:pod_cache_watch_updates)
45
+ elsif ENV['K8S_NODE_NAME'] == notice.object['spec']['nodeName'] then
46
+ @cache[cache_key] = parse_pod_metadata(notice.object)
47
+ @stats.bump(:pod_cache_host_updates)
48
+ else
49
+ @stats.bump(:pod_cache_watch_misses)
50
+ end
51
+ when 'DELETED'
52
+ # ignore and let age out for cases where pods
53
+ # deleted but still processing logs
54
+ @stats.bump(:pod_cache_watch_delete_ignored)
55
+ else
56
+ # Don't pay attention to creations, since the created pod may not
57
+ # end up on this node.
58
+ @stats.bump(:pod_cache_watch_ignored)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ 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,228 @@
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
+ recorded_with: VCR 2.9.3