fluent-plugin-kubernetes_metadata_filter 1.2.0 → 1.2.1
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 +4 -4
- data/README.md +13 -1
- data/fluent-plugin-kubernetes_metadata_filter.gemspec +1 -1
- data/lib/fluent/plugin/filter_kubernetes_metadata.rb +71 -72
- data/lib/fluent/plugin/kubernetes_metadata_cache_strategy.rb +1 -0
- data/lib/fluent/plugin/kubernetes_metadata_common.rb +20 -0
- data/test/cassettes/kubernetes_docker_metadata_using_bearer_token.yml +1 -1
- data/test/cassettes/metadata_from_tag_and_journald_fields.yml +408 -0
- data/test/cassettes/metadata_from_tag_journald_and_kubernetes_fields.yml +540 -0
- data/test/plugin/test_filter_kubernetes_metadata.rb +266 -139
- data/test/plugin/test_watch_pods.rb +35 -3
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e681f40b4be02d8a14e5007db2a02b008a0d0c10
|
4
|
+
data.tar.gz: 90a8f673cc88889b277cdc82e324cf6010b61b9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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.
|
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:
|
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
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
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(
|
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
|
-
'
|
261
|
-
'
|
262
|
-
|
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(
|
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
|
-
|
272
|
-
|
273
|
-
|
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
|
-
|
281
|
-
|
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
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
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
|
-
|
301
|
-
|
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
|
-
|
305
|
-
new_es
|
287
|
+
return Time.parse(time)
|
306
288
|
end
|
307
289
|
|
308
|
-
def
|
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
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
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://
|
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
|