fluent-plugin-kubernetes_metadata_filter 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d2300a4324a73e67a50f1151cbbfb89beb7f3091
4
- data.tar.gz: 95aa9acea4987f1e167e6c0975ad1fff2907b6a1
3
+ metadata.gz: 7c85f8cb8e0e93bb71aaafe430cbeacedb7877a8
4
+ data.tar.gz: e7148afb3e76d346a5b1bda9a5952021682b71cb
5
5
  SHA512:
6
- metadata.gz: 75d9e411f23df7047576e2cb93cf8c025af632235c41b9491ffed5cc8434361603ed654dd1cc605a4c2bd8c7cdc29edf750c9ab0902519a1db317c1ff4701cb0
7
- data.tar.gz: f01249b3c1d1e6fe99e15f9a87a1a00060b98d1a78333976d3a1eb7af891f6e7a77dbe433a5226966d9b30456599e53e77cce39d72eb881be0ae381b511a6323
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 "codeclimate-test-reporter", group: :test, require: nil
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 "bundler/gem_tasks"
2
- require "rake/testtask"
3
- require "bump/tasks"
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 << "test"
15
- t.test_files = Dir["test/**/test_*.rb"].sort
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 "Add copyright headers"
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 => "Enrich Fluentd events with Kubernetes metadata",
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.3.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 :kubernetes_url, :string
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
- :uid => metadata['metadata']['uid'],
42
- :namespace => metadata['metadata']['namespace'],
43
- :pod_name => metadata['metadata']['name'],
44
- :container_name => container_name,
45
- :labels => metadata['metadata']['labels'].to_h,
46
- :host => metadata['spec']['host']
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
- RestClient.add_before_execution_proc do |req, params|
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][:name]){
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
@@ -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 "codeclimate-test-reporter"
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 = "test/cassettes"
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("::1", 0)
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
- :docker => {
94
- :name => '/k8s_fabric8-console-container.efbd6e64_fabric8-console-controller-98rqc_default_c76927af-f563-11e4-b32d-54ee7527188d_42cbc279'
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
- :kubernetes => {
100
- :host => "jimmi-redhat.localnet",
101
- :pod_name =>"fabric8-console-controller-98rqc",
102
- :container_name => "fabric8-console-container",
103
- :namespace => "default",
104
- :uid => "c76927af-f563-11e4-b32d-54ee7527188d",
105
- :labels => {
106
- :component => "fabric8Console"
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
- :docker => {
118
- :name => '/k8s_fabric8-console-container.efbd6e64_fabric8-console-controller-98rqc_default_c76927af-f563-11e4-b32d-54ee7527188d_42cbc279'
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
- :kubernetes => {
128
- :host => "jimmi-redhat.localnet",
129
- :pod_name =>"fabric8-console-controller-98rqc",
130
- :container_name => "fabric8-console-container",
131
- :namespace => "default",
132
- :uid => "c76927af-f563-11e4-b32d-54ee7527188d",
133
- :labels => {
134
- :component => "fabric8Console"
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
- :docker => {
146
- :name => '/k8s_POD.c0b903ca_fabric8-forge-controller-ymkew_default_bcde9961-f4b7-11e4-bdbf-54ee7527188d_e1f00705'
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.3.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-10 00:00:00.000000000 Z
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: '0'
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: '0'
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