fluent-plugin-kubernetes_metadata_filter 0.3.0 → 0.4.0
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/Gemfile +2 -1
- data/Rakefile +7 -7
- data/fluent-plugin-kubernetes_metadata_filter.gemspec +2 -2
- data/lib/fluent/plugin/filter_kubernetes_metadata.rb +52 -13
- data/test/helper.rb +3 -3
- data/test/plugin/test_filter_kubernetes_metadata.rb +45 -37
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c85f8cb8e0e93bb71aaafe430cbeacedb7877a8
|
4
|
+
data.tar.gz: e7148afb3e76d346a5b1bda9a5952021682b71cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06fe87cf491110b44c962ce7f092b4dd55aaeb90db9d229c37f673ccdfd981a38af47670feb2eec7749521a149e0512bfa485340d0513ca084b477ea565869de
|
7
|
+
data.tar.gz: b477f9416509a823f2a400d67784c6dc570158088a21cf65c27847e4db1495dd2e730d6f942694ce95d53844d11026abac7aa69b77ed3bdce86664f7528b5a36
|
data/Gemfile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem
|
3
|
+
gem 'codeclimate-test-reporter', :group => :test, :require => nil
|
4
|
+
gem 'rubocop', require: false
|
4
5
|
|
5
6
|
# Specify your gem's dependencies in fluent-plugin-add.gemspec
|
6
7
|
gemspec
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'bump/tasks'
|
4
4
|
|
5
5
|
task :test => [:base_test]
|
6
6
|
|
@@ -11,13 +11,13 @@ Rake::TestTask.new(:base_test) do |t|
|
|
11
11
|
# To run test for only one file (or file path pattern)
|
12
12
|
# $ bundle exec rake base_test TEST=test/test_specified_path.rb
|
13
13
|
# $ bundle exec rake base_test TEST=test/test_*.rb
|
14
|
-
t.libs <<
|
15
|
-
t.test_files = Dir[
|
14
|
+
t.libs << 'test'
|
15
|
+
t.test_files = Dir['test/**/test_*.rb'].sort
|
16
16
|
t.verbose = true
|
17
17
|
#t.warning = true
|
18
18
|
end
|
19
19
|
|
20
|
-
desc
|
20
|
+
desc 'Add copyright headers'
|
21
21
|
task :headers do
|
22
22
|
require 'rubygems'
|
23
23
|
require 'copyright_header'
|
@@ -25,7 +25,7 @@ task :headers do
|
|
25
25
|
args = {
|
26
26
|
:license => 'ASL2',
|
27
27
|
:copyright_software => 'Fluentd Kubernetes Metadata Filter Plugin',
|
28
|
-
:copyright_software_description =>
|
28
|
+
:copyright_software_description => 'Enrich Fluentd events with Kubernetes metadata',
|
29
29
|
:copyright_holders => ['Red Hat, Inc.'],
|
30
30
|
:copyright_years => ['2015'],
|
31
31
|
:add_path => 'lib:test',
|
@@ -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 = "0.
|
7
|
+
gem.version = "0.4.0"
|
8
8
|
gem.authors = ["Jimmi Dyson"]
|
9
9
|
gem.email = ["jimmidyson@gmail.com"]
|
10
10
|
gem.description = %q{Filter plugin to add Kubernetes metadata}
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |gem|
|
|
22
22
|
|
23
23
|
gem.add_runtime_dependency "fluentd"
|
24
24
|
gem.add_runtime_dependency "lru_redux"
|
25
|
-
gem.add_runtime_dependency "kubeclient"
|
25
|
+
gem.add_runtime_dependency "kubeclient", "~> 0.1.15"
|
26
26
|
gem.add_runtime_dependency "fluent-plugin-docker_metadata_filter"
|
27
27
|
|
28
28
|
gem.add_development_dependency "bundler", "~> 1.3"
|
@@ -20,9 +20,10 @@ module Fluent
|
|
20
20
|
class KubernetesMetadataFilter < Fluent::Filter
|
21
21
|
Fluent::Plugin.register_filter('kubernetes_metadata', self)
|
22
22
|
|
23
|
+
config_param :kubernetes_url, :string
|
23
24
|
config_param :cache_size, :integer, :default => 1000
|
24
25
|
config_param :cache_ttl, :integer, :default => 60 * 60
|
25
|
-
config_param :
|
26
|
+
config_param :watch, :bool, :default => true
|
26
27
|
config_param :apiVersion, :string, :default => 'v1beta3'
|
27
28
|
config_param :client_cert, :string, :default => ''
|
28
29
|
config_param :client_key, :string, :default => ''
|
@@ -38,12 +39,12 @@ module Fluent
|
|
38
39
|
metadata = @client.get_pod(pod_name, namespace)
|
39
40
|
if metadata
|
40
41
|
return {
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
42
|
+
uid: metadata['metadata']['uid'],
|
43
|
+
namespace: metadata['metadata']['namespace'],
|
44
|
+
pod_name: metadata['metadata']['name'],
|
45
|
+
container_name: container_name,
|
46
|
+
labels: metadata['metadata']['labels'].to_h,
|
47
|
+
host: metadata['spec']['host']
|
47
48
|
}
|
48
49
|
end
|
49
50
|
rescue KubeException
|
@@ -73,9 +74,7 @@ module Fluent
|
|
73
74
|
|
74
75
|
if @bearer_token_file.present?
|
75
76
|
bearer_token = File.read(@bearer_token_file)
|
76
|
-
|
77
|
-
req['authorization'] ||= "Bearer #{bearer_token}"
|
78
|
-
end
|
77
|
+
@client.bearer_token(bearer_token)
|
79
78
|
end
|
80
79
|
|
81
80
|
begin
|
@@ -89,15 +88,22 @@ module Fluent
|
|
89
88
|
end
|
90
89
|
@cache = LruRedux::TTL::ThreadSafeCache.new(@cache_size, @cache_ttl)
|
91
90
|
@container_name_to_kubernetes_name_regexp_compiled = Regexp.compile(@container_name_to_kubernetes_name_regexp)
|
91
|
+
|
92
|
+
if @watch
|
93
|
+
thread = Thread.new(self) { |this|
|
94
|
+
this.start_watch
|
95
|
+
}
|
96
|
+
thread.abort_on_exception = true
|
97
|
+
end
|
92
98
|
end
|
93
99
|
|
94
100
|
def filter_stream(tag, es)
|
95
101
|
new_es = MultiEventStream.new
|
96
102
|
|
97
103
|
es.each {|time, record|
|
98
|
-
if record.has_key?(:docker) && record[:docker].has_key?(:name)
|
104
|
+
if record.has_key?(:docker) && record[:docker].has_key?(:id) && record[:docker].has_key?(:name)
|
99
105
|
this = self
|
100
|
-
metadata = @cache.getset(record[:docker][:
|
106
|
+
metadata = @cache.getset(record[:docker][:id]){
|
101
107
|
match_data = record[:docker][:name].match(@container_name_to_kubernetes_name_regexp_compiled)
|
102
108
|
if match_data
|
103
109
|
this.get_metadata(
|
@@ -116,6 +122,39 @@ module Fluent
|
|
116
122
|
|
117
123
|
new_es
|
118
124
|
end
|
119
|
-
end
|
120
125
|
|
126
|
+
def start_watch
|
127
|
+
resource_version = @client.get_pods.resourceVersion
|
128
|
+
watcher = @client.watch_pods(resource_version)
|
129
|
+
watcher.each do |notice|
|
130
|
+
puts notice
|
131
|
+
case notice.type
|
132
|
+
when 'MODIFIED'
|
133
|
+
if notice.object.status.containerStatuses
|
134
|
+
notice.object.status.containerStatuses.each { |container_status|
|
135
|
+
if container_status['containerId']
|
136
|
+
containerId = container_status['containerId'].sub(/^docker:\/\//, '')
|
137
|
+
cached = @cache[containerId]
|
138
|
+
if cached
|
139
|
+
# Only thing that can be modified is labels
|
140
|
+
cached[:labels] = v.object.metadata.labels.to_h
|
141
|
+
@cache[containerId] = cached
|
142
|
+
end
|
143
|
+
end
|
144
|
+
}
|
145
|
+
end
|
146
|
+
when 'DELETED'
|
147
|
+
if notice.object.status.containerStatuses
|
148
|
+
notice.object.status.containerStatuses.each { |container_status|
|
149
|
+
if container_status['containerId']
|
150
|
+
@cache.delete(container_status['containerId'].sub(/^docker:\/\//, ''))
|
151
|
+
end
|
152
|
+
}
|
153
|
+
end
|
154
|
+
else
|
155
|
+
# ignoring...
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
121
160
|
end
|
data/test/helper.rb
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
|
-
require
|
19
|
+
require 'codeclimate-test-reporter'
|
20
20
|
SimpleCov.start do
|
21
21
|
formatter SimpleCov::Formatter::MultiFormatter[
|
22
22
|
SimpleCov::Formatter::HTMLFormatter,
|
@@ -34,7 +34,7 @@ require 'webmock/test_unit'
|
|
34
34
|
require 'vcr'
|
35
35
|
|
36
36
|
VCR.configure do |config|
|
37
|
-
config.cassette_library_dir =
|
37
|
+
config.cassette_library_dir = 'test/cassettes'
|
38
38
|
config.hook_into :webmock # or :fakeweb
|
39
39
|
config.ignore_hosts 'codeclimate.com'
|
40
40
|
end
|
@@ -55,7 +55,7 @@ def ipv6_enabled?
|
|
55
55
|
require 'socket'
|
56
56
|
|
57
57
|
begin
|
58
|
-
TCPServer.open(
|
58
|
+
TCPServer.open('::1', 0)
|
59
59
|
true
|
60
60
|
rescue
|
61
61
|
false
|
@@ -43,9 +43,10 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
|
|
43
43
|
|
44
44
|
test 'kubernetes url' do
|
45
45
|
VCR.use_cassette('valid_kubernetes_api_server') do
|
46
|
-
d = create_driver(
|
46
|
+
d = create_driver('
|
47
47
|
kubernetes_url https://localhost:8443
|
48
|
-
|
48
|
+
watch false
|
49
|
+
')
|
49
50
|
assert_equal('https://localhost:8443', d.instance.kubernetes_url)
|
50
51
|
assert_equal(1000, d.instance.cache_size)
|
51
52
|
end
|
@@ -53,10 +54,11 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
|
|
53
54
|
|
54
55
|
test 'cache size' do
|
55
56
|
VCR.use_cassette('valid_kubernetes_api_server') do
|
56
|
-
d = create_driver(
|
57
|
+
d = create_driver('
|
57
58
|
kubernetes_url https://localhost:8443
|
59
|
+
watch false
|
58
60
|
cache_size 1
|
59
|
-
|
61
|
+
')
|
60
62
|
assert_equal('https://localhost:8443', d.instance.kubernetes_url)
|
61
63
|
assert_equal(1, d.instance.cache_size)
|
62
64
|
end
|
@@ -65,11 +67,12 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
|
|
65
67
|
test 'invalid API server config' do
|
66
68
|
VCR.use_cassette('invalid_api_server_config') do
|
67
69
|
assert_raise Fluent::ConfigError do
|
68
|
-
d = create_driver(
|
70
|
+
d = create_driver('
|
69
71
|
kubernetes_url https://localhost:8443
|
70
72
|
bearer_token_file test/plugin/test.token
|
73
|
+
watch false
|
71
74
|
verify_ssl false
|
72
|
-
|
75
|
+
')
|
73
76
|
end
|
74
77
|
end
|
75
78
|
end
|
@@ -77,10 +80,11 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
|
|
77
80
|
|
78
81
|
sub_test_case 'filter_stream' do
|
79
82
|
|
80
|
-
def emit(msg, config
|
83
|
+
def emit(msg, config='
|
81
84
|
kubernetes_url https://localhost:8443
|
85
|
+
watch false
|
82
86
|
cache_size 1
|
83
|
-
|
87
|
+
')
|
84
88
|
d = create_driver(config)
|
85
89
|
d.run {
|
86
90
|
d.emit(msg, @time)
|
@@ -90,22 +94,23 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
|
|
90
94
|
test 'with docker & kubernetes metadata' do
|
91
95
|
VCR.use_cassette('kubernetes_docker_metadata') do
|
92
96
|
msg = {
|
93
|
-
|
94
|
-
|
95
|
-
|
97
|
+
docker: {
|
98
|
+
id: '/49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459',
|
99
|
+
name: '/k8s_fabric8-console-container.efbd6e64_fabric8-console-controller-98rqc_default_c76927af-f563-11e4-b32d-54ee7527188d_42cbc279'
|
100
|
+
}
|
96
101
|
}
|
97
102
|
es = emit(msg)
|
98
103
|
expected_kube_metadata = {
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
}
|
104
|
+
kubernetes: {
|
105
|
+
host: 'jimmi-redhat.localnet',
|
106
|
+
pod_name: 'fabric8-console-controller-98rqc',
|
107
|
+
container_name: 'fabric8-console-container',
|
108
|
+
namespace: 'default',
|
109
|
+
uid: 'c76927af-f563-11e4-b32d-54ee7527188d',
|
110
|
+
labels: {
|
111
|
+
component: 'fabric8Console'
|
108
112
|
}
|
113
|
+
}
|
109
114
|
}
|
110
115
|
assert_equal(msg.merge(expected_kube_metadata), es.instance_variable_get(:@record_array)[0])
|
111
116
|
end
|
@@ -114,26 +119,28 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
|
|
114
119
|
test 'with docker & kubernetes metadata using bearer token' do
|
115
120
|
VCR.use_cassette('kubernetes_docker_metadata_using_bearer_token') do
|
116
121
|
msg = {
|
117
|
-
|
118
|
-
|
119
|
-
|
122
|
+
docker: {
|
123
|
+
id: '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459',
|
124
|
+
name: '/k8s_fabric8-console-container.efbd6e64_fabric8-console-controller-98rqc_default_c76927af-f563-11e4-b32d-54ee7527188d_42cbc279'
|
125
|
+
}
|
120
126
|
}
|
121
|
-
es = emit(msg,
|
127
|
+
es = emit(msg, '
|
122
128
|
kubernetes_url https://localhost:8443
|
123
129
|
verify_ssl false
|
130
|
+
watch false
|
124
131
|
bearer_token_file test/plugin/test.token
|
125
|
-
|
132
|
+
')
|
126
133
|
expected_kube_metadata = {
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
}
|
134
|
+
kubernetes: {
|
135
|
+
host: 'jimmi-redhat.localnet',
|
136
|
+
pod_name: 'fabric8-console-controller-98rqc',
|
137
|
+
container_name: 'fabric8-console-container',
|
138
|
+
namespace: 'default',
|
139
|
+
uid: 'c76927af-f563-11e4-b32d-54ee7527188d',
|
140
|
+
labels: {
|
141
|
+
component: 'fabric8Console'
|
136
142
|
}
|
143
|
+
}
|
137
144
|
}
|
138
145
|
assert_equal(msg.merge(expected_kube_metadata), es.instance_variable_get(:@record_array)[0])
|
139
146
|
end
|
@@ -142,9 +149,10 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
|
|
142
149
|
test 'with docker metadata, non-kubernetes' do
|
143
150
|
VCR.use_cassette('non_kubernetes_docker_metadata') do
|
144
151
|
msg = {
|
145
|
-
|
146
|
-
|
147
|
-
|
152
|
+
docker: {
|
153
|
+
id: '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459',
|
154
|
+
name: '/k8s_POD.c0b903ca_fabric8-forge-controller-ymkew_default_bcde9961-f4b7-11e4-bdbf-54ee7527188d_e1f00705'
|
155
|
+
}
|
148
156
|
}
|
149
157
|
es = emit(msg)
|
150
158
|
assert_equal(msg, es.instance_variable_get(:@record_array)[0])
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-kubernetes_metadata_filter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jimmi Dyson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: kubeclient
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.1.15
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.1.15
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: fluent-plugin-docker_metadata_filter
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|