fluent-plugin-kubernetes_metadata_filter_v0.14 0.24.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.
@@ -0,0 +1,55 @@
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:13:54 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:13:54 GMT
55
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,63 @@
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
+ require 'codeclimate-test-reporter'
20
+ SimpleCov.start do
21
+ formatter SimpleCov::Formatter::MultiFormatter.new [
22
+ SimpleCov::Formatter::HTMLFormatter,
23
+ CodeClimate::TestReporter::Formatter
24
+ ]
25
+ end
26
+
27
+ require 'rr'
28
+ require 'test/unit'
29
+ require 'test/unit/rr'
30
+ require 'fileutils'
31
+ require 'fluent/log'
32
+ require 'fluent/test'
33
+ require 'webmock/test_unit'
34
+ require 'vcr'
35
+
36
+ VCR.configure do |config|
37
+ config.cassette_library_dir = 'test/cassettes'
38
+ config.hook_into :webmock # or :fakeweb
39
+ config.ignore_hosts 'codeclimate.com'
40
+ end
41
+
42
+ unless defined?(Test::Unit::AssertionFailedError)
43
+ class Test::Unit::AssertionFailedError < StandardError
44
+ end
45
+ end
46
+
47
+ def unused_port
48
+ s = TCPServer.open(0)
49
+ port = s.addr[1]
50
+ s.close
51
+ port
52
+ end
53
+
54
+ def ipv6_enabled?
55
+ require 'socket'
56
+
57
+ begin
58
+ TCPServer.open('::1', 0)
59
+ true
60
+ rescue
61
+ false
62
+ end
63
+ end
@@ -0,0 +1 @@
1
+ 12345
@@ -0,0 +1,537 @@
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
+ require_relative '../helper'
20
+ require 'fluent/plugin/filter_kubernetes_metadata'
21
+
22
+ require 'webmock/test_unit'
23
+ WebMock.disable_net_connect!
24
+
25
+ class KubernetesMetadataFilterTest < Test::Unit::TestCase
26
+ include Fluent
27
+
28
+ setup do
29
+ Fluent::Test.setup
30
+ @time = Fluent::Engine.now
31
+ end
32
+
33
+ def create_driver(conf = '')
34
+ Test::FilterTestDriver.new(KubernetesMetadataFilter, 'var.log.containers.fabric8-console-controller-98rqc_default_fabric8-console-container-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459.log').configure(conf, true)
35
+ end
36
+
37
+ sub_test_case 'configure' do
38
+ test 'check default' do
39
+ d = create_driver
40
+ assert_equal(1000, d.instance.cache_size)
41
+ end
42
+
43
+ test 'kubernetes url' do
44
+ VCR.use_cassette('valid_kubernetes_api_server') do
45
+ d = create_driver('
46
+ kubernetes_url https://localhost:8443
47
+ watch false
48
+ ')
49
+ assert_equal('https://localhost:8443', d.instance.kubernetes_url)
50
+ assert_equal(1000, d.instance.cache_size)
51
+ end
52
+ end
53
+
54
+ test 'cache size' do
55
+ VCR.use_cassette('valid_kubernetes_api_server') do
56
+ d = create_driver('
57
+ kubernetes_url https://localhost:8443
58
+ watch false
59
+ cache_size 1
60
+ ')
61
+ assert_equal('https://localhost:8443', d.instance.kubernetes_url)
62
+ assert_equal(1, d.instance.cache_size)
63
+ end
64
+ end
65
+
66
+ test 'invalid API server config' do
67
+ VCR.use_cassette('invalid_api_server_config') do
68
+ assert_raise Fluent::ConfigError do
69
+ create_driver('
70
+ kubernetes_url https://localhost:8443
71
+ bearer_token_file test/plugin/test.token
72
+ watch false
73
+ verify_ssl false
74
+ ')
75
+ end
76
+ end
77
+ end
78
+
79
+ test 'service account credentials' do
80
+ VCR.use_cassette('valid_kubernetes_api_server') do
81
+ begin
82
+ ENV['KUBERNETES_SERVICE_HOST'] = 'localhost'
83
+ ENV['KUBERNETES_SERVICE_PORT'] = '8443'
84
+
85
+ Dir.mktmpdir { |dir|
86
+ # Fake token file and CA crt.
87
+ expected_cert_path = File.join(dir, KubernetesMetadataFilter::K8_POD_CA_CERT)
88
+ expected_token_path = File.join(dir, KubernetesMetadataFilter::K8_POD_TOKEN)
89
+
90
+ File.open(expected_cert_path, "w") {}
91
+ File.open(expected_token_path, "w") {}
92
+
93
+ d = create_driver("
94
+ watch false
95
+ secret_dir #{dir}
96
+ ")
97
+
98
+ assert_equal(d.instance.kubernetes_url, "https://localhost:8443/api")
99
+ assert_equal(d.instance.ca_file, expected_cert_path)
100
+ assert_equal(d.instance.bearer_token_file, expected_token_path)
101
+ }
102
+ ensure
103
+ ENV['KUBERNETES_SERVICE_HOST'] = nil
104
+ ENV['KUBERNETES_SERVICE_PORT'] = nil
105
+ end
106
+ end
107
+ end
108
+
109
+ test 'service account credential files are tested for existence' do
110
+ VCR.use_cassette('valid_kubernetes_api_server') do
111
+ begin
112
+ ENV['KUBERNETES_SERVICE_HOST'] = 'localhost'
113
+ ENV['KUBERNETES_SERVICE_PORT'] = '8443'
114
+
115
+ Dir.mktmpdir { |dir|
116
+ d = create_driver("
117
+ watch false
118
+ secret_dir #{dir}
119
+ ")
120
+ assert_equal(d.instance.kubernetes_url, "https://localhost:8443/api")
121
+ assert_false(d.instance.ca_file.present?)
122
+ assert_false(d.instance.bearer_token_file.present?)
123
+ }
124
+ ensure
125
+ ENV['KUBERNETES_SERVICE_HOST'] = nil
126
+ ENV['KUBERNETES_SERVICE_PORT'] = nil
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ sub_test_case 'filter_stream' do
133
+
134
+ def emit(msg={}, config='
135
+ kubernetes_url https://localhost:8443
136
+ watch false
137
+ cache_size 1
138
+ ')
139
+ d = create_driver(config)
140
+ d.run {
141
+ d.emit(msg, @time)
142
+ }.filtered
143
+ end
144
+
145
+ def emit_with_tag(tag, msg={}, config='
146
+ kubernetes_url https://localhost:8443
147
+ watch false
148
+ cache_size 1
149
+ ')
150
+ d = create_driver(config)
151
+ d.run {
152
+ d.emit_with_tag(tag, msg, @time)
153
+ }.filtered
154
+ end
155
+
156
+ test 'with docker & kubernetes metadata' do
157
+ VCR.use_cassette('kubernetes_docker_metadata') do
158
+ es = emit()
159
+ expected_kube_metadata = {
160
+ 'docker' => {
161
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
162
+ },
163
+ 'kubernetes' => {
164
+ 'host' => 'jimmi-redhat.localnet',
165
+ 'pod_name' => 'fabric8-console-controller-98rqc',
166
+ 'container_name' => 'fabric8-console-container',
167
+ 'namespace_name' => 'default',
168
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
169
+ 'labels' => {
170
+ 'component' => 'fabric8Console'
171
+ }
172
+ }
173
+ }
174
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
175
+ end
176
+ end
177
+
178
+ test 'with docker & kubernetes metadata & namespace_id enabled' do
179
+ VCR.use_cassette('metadata_with_namespace_id') do
180
+ es = emit({}, '
181
+ kubernetes_url https://localhost:8443
182
+ watch false
183
+ cache_size 1
184
+ include_namespace_id true
185
+ ')
186
+ expected_kube_metadata = {
187
+ 'docker' => {
188
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
189
+ },
190
+ 'kubernetes' => {
191
+ 'host' => 'jimmi-redhat.localnet',
192
+ 'pod_name' => 'fabric8-console-controller-98rqc',
193
+ 'container_name' => 'fabric8-console-container',
194
+ 'namespace_name' => 'default',
195
+ 'namespace_id' => '898268c8-4a36-11e5-9d81-42010af0194c',
196
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
197
+ 'labels' => {
198
+ 'component' => 'fabric8Console'
199
+ }
200
+ }
201
+ }
202
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
203
+ end
204
+ end
205
+
206
+ test 'with docker & kubernetes metadata using bearer token' do
207
+ VCR.use_cassette('kubernetes_docker_metadata_using_bearer_token') do
208
+ es = emit({}, '
209
+ kubernetes_url https://localhost:8443
210
+ verify_ssl false
211
+ watch false
212
+ bearer_token_file test/plugin/test.token
213
+ ')
214
+ expected_kube_metadata = {
215
+ 'docker' => {
216
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
217
+ },
218
+ 'kubernetes' => {
219
+ 'host' => 'jimmi-redhat.localnet',
220
+ 'pod_name' => 'fabric8-console-controller-98rqc',
221
+ 'container_name' => 'fabric8-console-container',
222
+ 'namespace_name' => 'default',
223
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
224
+ 'labels' => {
225
+ 'component' => 'fabric8Console'
226
+ }
227
+ }
228
+ }
229
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
230
+ end
231
+ end
232
+
233
+ test 'with docker & kubernetes metadata but no configured api server' do
234
+ es = emit({}, '')
235
+ expected_kube_metadata = {
236
+ 'docker' => {
237
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
238
+ },
239
+ 'kubernetes' => {
240
+ 'pod_name' => 'fabric8-console-controller-98rqc',
241
+ 'container_name' => 'fabric8-console-container',
242
+ 'namespace_name' => 'default',
243
+ }
244
+ }
245
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
246
+ end
247
+
248
+ test 'with docker & inaccessible kubernetes metadata' do
249
+ stub_request(:any, 'https://localhost:8443/api').to_return(
250
+ 'body' => {
251
+ 'versions' => ['v1beta3', 'v1']
252
+ }.to_json
253
+ )
254
+ stub_request(:any, 'https://localhost:8443/api/v1/namespaces/default/pods/fabric8-console-controller-98rqc').to_timeout
255
+ es = emit()
256
+ expected_kube_metadata = {
257
+ 'docker' => {
258
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
259
+ },
260
+ 'kubernetes' => {
261
+ 'pod_name' => 'fabric8-console-controller-98rqc',
262
+ 'container_name' => 'fabric8-console-container',
263
+ 'namespace_name' => 'default'
264
+ }
265
+ }
266
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
267
+ end
268
+
269
+ test 'with dot in pod name' do
270
+ stub_request(:any, 'https://localhost:8443/api').to_return(
271
+ 'body' => {
272
+ 'versions' => ['v1beta3', 'v1']
273
+ }.to_json
274
+ )
275
+ stub_request(:any, 'https://localhost:8443/api/v1/namespaces/default/pods/fabric8-console-controller.98rqc').to_timeout
276
+ es = emit_with_tag('var.log.containers.fabric8-console-controller.98rqc_default_fabric8-console-container-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459.log', {}, '')
277
+ expected_kube_metadata = {
278
+ 'docker' => {
279
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
280
+ },
281
+ 'kubernetes' => {
282
+ 'pod_name' => 'fabric8-console-controller.98rqc',
283
+ 'container_name' => 'fabric8-console-container',
284
+ 'namespace_name' => 'default'
285
+ }
286
+ }
287
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
288
+ end
289
+
290
+ test 'with docker metadata, non-kubernetes' do
291
+ es = emit_with_tag('non-kubernetes', {}, '')
292
+ assert_false(es.instance_variable_get(:@record_array)[0].has_key?(:kubernetes))
293
+ end
294
+
295
+ test 'merges json log data' do
296
+ json_log = {
297
+ 'hello' => 'world'
298
+ }
299
+ msg = {
300
+ 'log' => "#{json_log.to_json}"
301
+ }
302
+ es = emit_with_tag('non-kubernetes', msg, '')
303
+ assert_equal(msg.merge(json_log), es.instance_variable_get(:@record_array)[0])
304
+ end
305
+
306
+ test 'merges json log data in MESSAGE' do
307
+ json_log = {
308
+ 'hello' => 'world'
309
+ }
310
+ msg = {
311
+ 'MESSAGE' => "#{json_log.to_json}"
312
+ }
313
+ es = emit_with_tag('non-kubernetes', msg, 'use_journal true')
314
+ assert_equal(msg.merge(json_log), es.instance_variable_get(:@record_array)[0])
315
+ end
316
+
317
+ test 'merges json log data with message field' do
318
+ json_log = {
319
+ 'timeMillis' => 1459853347608,
320
+ 'thread' => 'main',
321
+ 'level' => 'INFO',
322
+ 'loggerName' => 'org.apache.camel.spring.SpringCamelContext',
323
+ 'message' => 'Total 1 routes, of which 1 is started.',
324
+ 'endOfBatch' => false,
325
+ 'loggerFqcn' => 'org.apache.logging.slf4j.Log4jLogger'
326
+ }
327
+ msg = {
328
+ 'log' => "#{json_log.to_json}"
329
+ }
330
+ es = emit_with_tag('non-kubernetes', msg, '')
331
+ assert_equal(msg.merge(json_log), es.instance_variable_get(:@record_array)[0])
332
+ end
333
+
334
+ test 'merges json log data with message field in MESSAGE' do
335
+ json_log = {
336
+ 'timeMillis' => 1459853347608,
337
+ 'thread' => 'main',
338
+ 'level' => 'INFO',
339
+ 'loggerName' => 'org.apache.camel.spring.SpringCamelContext',
340
+ 'message' => 'Total 1 routes, of which 1 is started.',
341
+ 'endOfBatch' => false,
342
+ 'loggerFqcn' => 'org.apache.logging.slf4j.Log4jLogger'
343
+ }
344
+ msg = {
345
+ 'MESSAGE' => "#{json_log.to_json}"
346
+ }
347
+ es = emit_with_tag('non-kubernetes', msg, 'use_journal true')
348
+ assert_equal(msg.merge(json_log), es.instance_variable_get(:@record_array)[0])
349
+ end
350
+
351
+ test 'emit individual fields from json, throw out whole original string' do
352
+ json_log = {
353
+ 'hello' => 'world',
354
+ 'more' => 'data'
355
+ }
356
+ msg = {
357
+ 'log' => "#{json_log.to_json}"
358
+ }
359
+ es = emit_with_tag('non-kubernetes', msg, 'preserve_json_log false')
360
+ assert_equal(json_log, es.instance_variable_get(:@record_array)[0])
361
+ end
362
+
363
+ test 'emit individual fields from json, throw out whole original string in MESSAGE' do
364
+ json_log = {
365
+ 'hello' => 'world',
366
+ 'more' => 'data'
367
+ }
368
+ msg = {
369
+ 'MESSAGE' => "#{json_log.to_json}"
370
+ }
371
+ es = emit_with_tag('non-kubernetes', msg, '
372
+ preserve_json_log false
373
+ use_journal true
374
+ ')
375
+ assert_equal(json_log, es.instance_variable_get(:@record_array)[0])
376
+ end
377
+
378
+ test 'with kubernetes dotted labels, de_dot enabled' do
379
+ VCR.use_cassette('kubernetes_docker_metadata_dotted_labels') do
380
+ es = emit()
381
+ expected_kube_metadata = {
382
+ 'docker' => {
383
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
384
+ },
385
+ 'kubernetes' => {
386
+ 'host' => 'jimmi-redhat.localnet',
387
+ 'pod_name' => 'fabric8-console-controller-98rqc',
388
+ 'container_name' => 'fabric8-console-container',
389
+ 'namespace_name' => 'default',
390
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
391
+ 'labels' => {
392
+ 'kubernetes_io/test' => 'somevalue'
393
+ }
394
+ }
395
+ }
396
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
397
+ end
398
+ end
399
+
400
+ test 'with kubernetes dotted labels, de_dot disabled' do
401
+ VCR.use_cassette('kubernetes_docker_metadata_dotted_labels') do
402
+ es = emit({}, '
403
+ kubernetes_url https://localhost:8443
404
+ watch false
405
+ cache_size 1
406
+ de_dot false
407
+ ')
408
+ expected_kube_metadata = {
409
+ 'docker' => {
410
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
411
+ },
412
+ 'kubernetes' => {
413
+ 'host' => 'jimmi-redhat.localnet',
414
+ 'pod_name' => 'fabric8-console-controller-98rqc',
415
+ 'container_name' => 'fabric8-console-container',
416
+ 'namespace_name' => 'default',
417
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
418
+ 'labels' => {
419
+ 'kubernetes.io/test' => 'somevalue'
420
+ }
421
+ }
422
+ }
423
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
424
+ end
425
+ end
426
+
427
+ test 'invalid de_dot_separator config' do
428
+ assert_raise Fluent::ConfigError do
429
+ create_driver('
430
+ de_dot_separator contains.
431
+ ')
432
+ end
433
+ end
434
+
435
+ test 'with records from journald and docker & kubernetes metadata' do
436
+ # with use_journal true should ignore tags and use CONTAINER_NAME and CONTAINER_ID_FULL
437
+ tag = 'var.log.containers.junk1_junk2_junk3-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed450.log'
438
+ msg = {
439
+ 'CONTAINER_NAME' => 'k8s_fabric8-console-container.db89db89_fabric8-console-controller-98rqc_default_c76927af-f563-11e4-b32d-54ee7527188d_89db89db',
440
+ 'CONTAINER_ID_FULL' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459',
441
+ 'randomfield' => 'randomvalue'
442
+ }
443
+ VCR.use_cassette('kubernetes_docker_metadata') do
444
+ es = emit_with_tag(tag, msg, '
445
+ kubernetes_url https://localhost:8443
446
+ watch false
447
+ cache_size 1
448
+ use_journal true
449
+ ')
450
+ expected_kube_metadata = {
451
+ 'docker' => {
452
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
453
+ },
454
+ 'kubernetes' => {
455
+ 'host' => 'jimmi-redhat.localnet',
456
+ 'pod_name' => 'fabric8-console-controller-98rqc',
457
+ 'container_name' => 'fabric8-console-container',
458
+ 'namespace_name' => 'default',
459
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
460
+ 'labels' => {
461
+ 'component' => 'fabric8Console'
462
+ }
463
+ }
464
+ }.merge(msg)
465
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
466
+ end
467
+ end
468
+
469
+ test 'with records from journald and docker & kubernetes metadata & namespace_id enabled' do
470
+ # with use_journal true should ignore tags and use CONTAINER_NAME and CONTAINER_ID_FULL
471
+ tag = 'var.log.containers.junk1_junk2_junk3-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed450.log'
472
+ msg = {
473
+ 'CONTAINER_NAME' => 'k8s_fabric8-console-container.db89db89_fabric8-console-controller-98rqc_default_c76927af-f563-11e4-b32d-54ee7527188d_89db89db',
474
+ 'CONTAINER_ID_FULL' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459',
475
+ 'randomfield' => 'randomvalue'
476
+ }
477
+ VCR.use_cassette('metadata_with_namespace_id') do
478
+ es = emit_with_tag(tag, msg, '
479
+ kubernetes_url https://localhost:8443
480
+ watch false
481
+ cache_size 1
482
+ include_namespace_id true
483
+ use_journal true
484
+ ')
485
+ expected_kube_metadata = {
486
+ 'docker' => {
487
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
488
+ },
489
+ 'kubernetes' => {
490
+ 'host' => 'jimmi-redhat.localnet',
491
+ 'pod_name' => 'fabric8-console-controller-98rqc',
492
+ 'container_name' => 'fabric8-console-container',
493
+ 'namespace_name' => 'default',
494
+ 'namespace_id' => '898268c8-4a36-11e5-9d81-42010af0194c',
495
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
496
+ 'labels' => {
497
+ 'component' => 'fabric8Console'
498
+ }
499
+ }
500
+ }.merge(msg)
501
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
502
+ end
503
+ end
504
+
505
+ test 'with kubernetes annotations' do
506
+ VCR.use_cassette('kubernetes_docker_metadata_annotations') do
507
+ es = emit({},'
508
+ kubernetes_url https://localhost:8443
509
+ watch false
510
+ cache_size 1
511
+ annotation_match [ "^custom.+", "two"]
512
+ ')
513
+ expected_kube_metadata = {
514
+ 'docker' => {
515
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
516
+ },
517
+ 'kubernetes' => {
518
+ 'host' => 'jimmi-redhat.localnet',
519
+ 'pod_name' => 'fabric8-console-controller-98rqc',
520
+ 'container_name' => 'fabric8-console-container',
521
+ 'namespace_name' => 'default',
522
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
523
+ 'labels' => {
524
+ 'component' => 'fabric8Console'
525
+ },
526
+ 'annotations' => {
527
+ 'custom.field1' => 'hello_kitty',
528
+ 'field.two' => 'value'
529
+ }
530
+ }
531
+ }
532
+ assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
533
+ end
534
+ end
535
+
536
+ end
537
+ end