fluent-plugin-kubernetes-objects 1.0.0 → 1.1.4

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
  SHA256:
3
- metadata.gz: d39161509a5767c7b3bb242c99b750af77fd3d5999b37afc58fc8a450f9f68be
4
- data.tar.gz: c87dd9f4fe3c9003cc56f5033d0492eb0f4c558ad2fefe00cb312c7ed8896910
3
+ metadata.gz: 23311c5c8d08571e1421a02d990106536269c56c13a7010eb33ff468374524d7
4
+ data.tar.gz: 30a04f002df00e89d8d7ba000f060d6d410d99ce6d1b9301d46b8309ef330561
5
5
  SHA512:
6
- metadata.gz: 030e4ff7c8ed1a20fd6b27b10a8324e07e0e0d47c4ee36438c199a919ff8c71fadb728bd3c50ba91bf23db801acdd0873704d71201ad4c7321db94ee4e98cd79
7
- data.tar.gz: 2eaa921a968b667d146b195239e8ed2661d7662116abc6c1388d8a1248abb1c75043dfa4bb3e3cafd431039867e7fb018219cfabc047358fd56ecade3622fbec
6
+ metadata.gz: 6dea9c0003540c9ed06b715c64cb7ba4fdce1fa538d3e0b5e11a3c0ab23b4b254f80074bd9872d26600e3b6b2fe181ea221ba33fac91c91b02925b2515a48c34
7
+ data.tar.gz: db71c9f00e2ff3b2d35f2340b95b7a4f826fe38f2ed3bc771d444296ea80748c0127b5b38b8b1d677253a9af9e7c420180ba1bb43f589f99141b7c412e056d42
data/Gemfile CHANGED
@@ -1,6 +1,10 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ group :test do
4
+ gem 'simplecov', require: false
5
+ end
6
+
7
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
8
 
5
9
  # Specify your gem's dependencies in fluent-plugin-kubernetes_objects_input.gemspec
6
10
  gemspec
@@ -1,91 +1,106 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-kubernetes-objects (1.0.0)
5
- fluentd (~> 1.0)
6
- kubeclient (~> 3.0)
4
+ fluent-plugin-kubernetes-objects (1.1.4)
5
+ fluentd (~> 1.9.1)
6
+ http_parser.rb (= 0.5.3)
7
+ kubeclient (~> 4.6.0)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
10
11
  specs:
11
- addressable (2.5.2)
12
+ addressable (2.6.0)
12
13
  public_suffix (>= 2.0.2, < 4.0)
13
- cool.io (1.5.3)
14
+ concurrent-ruby (1.1.6)
15
+ cool.io (1.6.0)
14
16
  crack (0.4.3)
15
17
  safe_yaml (~> 1.0.0)
16
- dig_rb (1.0.1)
17
- domain_name (0.5.20170404)
18
+ docile (1.3.1)
19
+ domain_name (0.5.20190701)
18
20
  unf (>= 0.0.5, < 1.0.0)
19
- fluentd (1.1.0)
21
+ ffi (1.12.2)
22
+ ffi-compiler (1.0.1)
23
+ ffi (>= 1.0.0)
24
+ rake
25
+ fluentd (1.9.2)
20
26
  cool.io (>= 1.4.5, < 2.0.0)
21
- dig_rb (~> 1.0.0)
22
27
  http_parser.rb (>= 0.5.1, < 0.7.0)
23
- msgpack (>= 0.7.0, < 2.0.0)
28
+ msgpack (>= 1.3.1, < 2.0.0)
24
29
  serverengine (>= 2.0.4, < 3.0.0)
25
30
  sigdump (~> 0.2.2)
26
31
  strptime (>= 0.2.2, < 1.0.0)
27
- tzinfo (~> 1.0)
32
+ tzinfo (>= 1.0, < 3.0)
28
33
  tzinfo-data (~> 1.0)
29
34
  yajl-ruby (~> 1.0)
30
- hashdiff (0.3.7)
31
- http (2.2.2)
35
+ hashdiff (0.3.8)
36
+ http (4.3.0)
32
37
  addressable (~> 2.3)
33
38
  http-cookie (~> 1.0)
34
- http-form_data (~> 1.0.1)
35
- http_parser.rb (~> 0.6.0)
39
+ http-form_data (~> 2.2)
40
+ http-parser (~> 1.2.0)
41
+ http-accept (1.7.0)
36
42
  http-cookie (1.0.3)
37
43
  domain_name (~> 0.5)
38
- http-form_data (1.0.3)
39
- http_parser.rb (0.6.0)
40
- kubeclient (3.0.0)
41
- http (~> 2.2.2)
42
- recursive-open-struct (~> 1.0.4)
44
+ http-form_data (2.2.0)
45
+ http-parser (1.2.1)
46
+ ffi-compiler (>= 1.0, < 2.0)
47
+ http_parser.rb (0.5.3)
48
+ json (2.3.1)
49
+ kubeclient (4.6.0)
50
+ http (>= 3.0, < 5.0)
51
+ recursive-open-struct (~> 1.0, >= 1.0.4)
43
52
  rest-client (~> 2.0)
44
- mime-types (3.1)
53
+ mime-types (3.3.1)
45
54
  mime-types-data (~> 3.2015)
46
- mime-types-data (3.2016.0521)
55
+ mime-types-data (3.2019.1009)
47
56
  minitest (5.11.3)
48
- msgpack (1.2.4)
57
+ msgpack (1.3.3)
49
58
  netrc (0.11.0)
50
- power_assert (1.1.1)
51
- public_suffix (3.0.2)
52
- rake (10.5.0)
53
- recursive-open-struct (1.0.5)
54
- rest-client (2.0.2)
59
+ power_assert (1.1.3)
60
+ public_suffix (3.0.3)
61
+ rake (13.0.1)
62
+ recursive-open-struct (1.1.0)
63
+ rest-client (2.1.0)
64
+ http-accept (>= 1.7.0, < 2.0)
55
65
  http-cookie (>= 1.0.2, < 2.0)
56
66
  mime-types (>= 1.16, < 4.0)
57
67
  netrc (~> 0.8)
58
68
  safe_yaml (1.0.4)
59
- serverengine (2.0.6)
69
+ serverengine (2.2.1)
60
70
  sigdump (~> 0.2.2)
61
71
  sigdump (0.2.4)
72
+ simplecov (0.16.1)
73
+ docile (~> 1.1)
74
+ json (>= 1.8, < 3)
75
+ simplecov-html (~> 0.10.0)
76
+ simplecov-html (0.10.2)
62
77
  strptime (0.2.3)
63
- test-unit (3.2.7)
78
+ test-unit (3.3.0)
64
79
  power_assert
65
- thread_safe (0.3.6)
66
- tzinfo (1.2.5)
67
- thread_safe (~> 0.1)
68
- tzinfo-data (1.2018.3)
80
+ tzinfo (2.0.1)
81
+ concurrent-ruby (~> 1.0)
82
+ tzinfo-data (1.2019.3)
69
83
  tzinfo (>= 1.0.0)
70
84
  unf (0.1.4)
71
85
  unf_ext
72
- unf_ext (0.0.7.5)
73
- webmock (3.3.0)
86
+ unf_ext (0.0.7.6)
87
+ webmock (3.5.1)
74
88
  addressable (>= 2.3.6)
75
89
  crack (>= 0.3.2)
76
90
  hashdiff
77
- yajl-ruby (1.3.1)
91
+ yajl-ruby (1.4.1)
78
92
 
79
93
  PLATFORMS
80
94
  ruby
81
95
 
82
96
  DEPENDENCIES
83
- bundler (~> 1.16)
97
+ bundler (~> 2.0)
84
98
  fluent-plugin-kubernetes-objects!
85
- minitest (~> 5.0)
86
- rake (~> 10.0)
87
- test-unit (~> 3.0)
88
- webmock (~> 3.2)
99
+ minitest (~> 5.11)
100
+ rake (>= 12.0)
101
+ simplecov
102
+ test-unit (~> 3.3)
103
+ webmock (~> 3.5)
89
104
 
90
105
  BUNDLED WITH
91
- 1.16.1
106
+ 2.1.4
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [ ![Codeship Status for splunk/fluent-plugin-kubernetes-objects](https://app.codeship.com/projects/8ae91f00-261e-0136-02ab-6e830b67b562/status?branch=master)](https://app.codeship.com/projects/286766)
1
+ [![CircleCI](https://circleci.com/gh/git-lfs/git-lfs.svg?style=shield&circle-token=856152c2b02bfd236f54d21e1f581f3e4ebf47ad)](https://circleci.com/gh/splunk/fluent-plugin-kubernetes-objects)
2
2
  # fluent-plugin-kubernetes-objects
3
3
 
4
4
  [Fluentd](https://fluentd.org/) input plugin to collect [objects](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) in a kubernetes cluster.
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['test/**/*_test.rb']
8
8
  end
9
9
 
10
- task :default => :test
10
+ task default: :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.4
@@ -1,43 +1,33 @@
1
1
  Gem::Specification.new do |spec|
2
- spec.name = "fluent-plugin-kubernetes-objects"
3
- spec.version = "1.0.0"
4
- spec.authors = ["Gimi Liang"]
5
- spec.email = ["zliang@splunk.com"]
2
+ spec.name = 'fluent-plugin-kubernetes-objects'
3
+ spec.version = File.read('VERSION')
4
+ spec.authors = ['Splunk Inc.']
5
+ spec.email = ['DataEdge@splunk.com']
6
6
 
7
- spec.summary = %q{Fluentd Plugin for Kubernetes Objects.}
8
- spec.description = %q{A Fluentd input plugin for collecting Kubernetes objects, e.g. pods, namespaces, events, etc. by pulling or watching.}
9
- spec.homepage = "https://github.com/splunk/fluent-plugin-kubernetes-objects"
10
- spec.license = "Apache-2.0"
7
+ spec.summary = 'Fluentd Plugin for Kubernetes Objects.'
8
+ spec.description = 'A Fluentd input plugin for collecting Kubernetes objects, e.g. pods, namespaces, events, etc. by pulling or watching.'
9
+ spec.homepage = 'https://github.com/splunk/fluent-plugin-kubernetes-objects'
10
+ spec.license = 'Apache-2.0'
11
11
 
12
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
13
- # to allow pushing to a single host or delete this section to allow pushing to any host.
14
- # if spec.respond_to?(:metadata)
15
- # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
16
- # else
17
- # raise "RubyGems 2.0 or newer is required to protect against " \
18
- # "public gem pushes."
19
- # end
20
-
21
- spec.require_paths = ["lib"]
12
+ spec.require_paths = ['lib']
22
13
  spec.test_files = Dir.glob('test/**/**.rb')
23
14
  spec.files = %w[
24
15
  CODE_OF_CONDUCT.md README.md LICENSE
25
16
  fluent-plugin-kubernetes-objects.gemspec
26
17
  Gemfile Gemfile.lock
27
- Rakefile
18
+ Rakefile VERSION
28
19
  ] + Dir.glob('lib/**/**').reject(&File.method(:directory?))
29
20
 
30
- spec.bindir = "exe"
21
+ spec.bindir = 'exe'
31
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
-
33
23
  spec.required_ruby_version = '>= 2.3.0'
24
+ spec.add_runtime_dependency 'fluentd', '~> 1.9.1'
25
+ spec.add_runtime_dependency 'kubeclient', '~> 4.6.0'
26
+ spec.add_runtime_dependency 'http_parser.rb', '= 0.5.3'
34
27
 
35
- spec.add_runtime_dependency "fluentd", "~> 1.0"
36
- spec.add_runtime_dependency "kubeclient", "~> 3.0"
37
-
38
- spec.add_development_dependency "bundler", "~> 1.16"
39
- spec.add_development_dependency "rake", "~> 10.0"
40
- spec.add_development_dependency "test-unit", "~> 3.0" # required by fluent/test.rb
41
- spec.add_development_dependency "minitest", "~> 5.0"
42
- spec.add_development_dependency "webmock", "~> 3.2"
28
+ spec.add_development_dependency 'bundler', '~> 2.0'
29
+ spec.add_development_dependency 'minitest', '~> 5.11'
30
+ spec.add_development_dependency 'rake', '>= 12.0'
31
+ spec.add_development_dependency 'test-unit', '~> 3.3' # required by fluent/test.rb
32
+ spec.add_development_dependency 'webmock', '~> 3.5'
43
33
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "fluent/plugin/input"
3
+ require 'fluent/plugin/input'
4
4
  require 'kubeclient'
5
5
 
6
6
  module Fluent::Plugin
7
7
  class KubernetesObjectsInput < Fluent::Plugin::Input
8
- VERSION = "1.0.0"
8
+ VERSION = '1.1.2'.freeze
9
9
 
10
10
  Fluent::Plugin.register_input('kubernetes_objects', self)
11
11
 
@@ -72,21 +72,24 @@ module Fluent::Plugin
72
72
 
73
73
  desc 'A selector to restrict the list of returned objects by fields.'
74
74
  config_param :field_selector, :string, default: nil
75
+
76
+ desc 'The interval at which the objects will be watched.'
77
+ config_param :interval, :time, default: 15 * 60
75
78
  end
76
79
 
77
80
  config_section :storage do
78
81
  # use memory by default
79
- config_set_default :usage, "checkpoints"
80
- config_set_default :@type, "local"
82
+ config_set_default :usage, 'checkpoints'
83
+ config_set_default :@type, 'local'
81
84
  config_set_default :persistent, false
82
85
  end
83
86
 
84
87
  def configure(conf)
85
88
  super
86
89
 
87
- raise Fluent::ConfigError, "At least one <pull> or <watch> is required, but found none." if @pull_objects.empty? && @watch_objects.empty?
90
+ raise Fluent::ConfigError, 'At least one <pull> or <watch> is required, but found none.' if @pull_objects.empty? && @watch_objects.empty?
88
91
 
89
- @storage = storage_create usage: "checkpoints"
92
+ @storage = storage_create usage: 'checkpoints'
90
93
 
91
94
  parse_tag
92
95
  initialize_client
@@ -99,7 +102,6 @@ module Fluent::Plugin
99
102
  end
100
103
 
101
104
  def close
102
- @watchers.each &:finish if @watchers
103
105
  super
104
106
  end
105
107
 
@@ -115,54 +117,69 @@ module Fluent::Plugin
115
117
  [@tag_prefix, item_name, @tag_suffix].join
116
118
  end
117
119
 
120
+ def init_with_kubeconfig()
121
+ options = {}
122
+ config = Kubeclient::Config.read @kubeconfig
123
+ current_context = config.context
124
+
125
+ @client = Kubeclient::Client.new(
126
+ current_context.api_endpoint,
127
+ current_context.api_version,
128
+ options.merge(
129
+ ssl_options: current_context.ssl_options,
130
+ auth_options: current_context.auth_options
131
+ )
132
+ )
133
+ end
134
+
118
135
  def initialize_client
119
136
  # mostly borrowed from Fluentd Kubernetes Metadata Filter Plugin
120
137
  if @kubernetes_url.nil?
121
- # Use Kubernetes default service account if we're in a pod.
122
- env_host = ENV['KUBERNETES_SERVICE_HOST']
123
- env_port = ENV['KUBERNETES_SERVICE_PORT']
124
- if env_host && env_port
125
- @kubernetes_url = "https://#{env_host}:#{env_port}/#{@api_version == 'v1' ? 'api' : 'apis'}"
126
- end
138
+ # Use Kubernetes default service account if we're in a pod.
139
+ env_host = ENV['KUBERNETES_SERVICE_HOST']
140
+ env_port = ENV['KUBERNETES_SERVICE_PORT']
141
+ if env_host && env_port
142
+ @kubernetes_url = "https://#{env_host}:#{env_port}/#{@api_version == 'v1' ? 'api' : 'apis'}"
143
+ end
127
144
  end
128
145
 
129
- raise Fluent::ConfigError, "kubernetes url is not set" unless @kubernetes_url
146
+ raise Fluent::ConfigError, 'kubernetes url is not set' unless @kubernetes_url
130
147
 
131
148
  # Use SSL certificate and bearer token from Kubernetes service account.
132
149
  if Dir.exist?(@secret_dir)
133
- secret_ca_file = File.join(@secret_dir, 'ca.cert')
134
- secret_token_file = File.join(@secret_dir, 'token')
150
+ secret_ca_file = File.join(@secret_dir, 'ca.crt')
151
+ secret_token_file = File.join(@secret_dir, 'token')
135
152
 
136
- if @ca_file.nil? and File.exist?(secret_ca_file)
137
- @ca_file = secret_ca_file
138
- end
153
+ if @ca_file.nil? && File.exist?(secret_ca_file)
154
+ @ca_file = secret_ca_file
155
+ end
139
156
 
140
- if @bearer_token_file.nil? and File.exist?(secret_token_file)
141
- @bearer_token_file = secret_token_file
142
- end
157
+ if @bearer_token_file.nil? && File.exist?(secret_token_file)
158
+ @bearer_token_file = secret_token_file
159
+ end
143
160
  end
144
161
 
145
162
  ssl_options = {
146
- client_cert: @client_cert && OpenSSL::X509::Certificate.new(File.read(@client_cert)),
147
- client_key: @client_key && OpenSSL::PKey::RSA.new(File.read(@client_key)),
148
- ca_file: @ca_file,
149
- verify_ssl: @insecure_ssl ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
163
+ client_cert: @client_cert && OpenSSL::X509::Certificate.new(File.read(@client_cert)),
164
+ client_key: @client_key && OpenSSL::PKey::RSA.new(File.read(@client_key)),
165
+ ca_file: @ca_file,
166
+ verify_ssl: @insecure_ssl ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
150
167
  }
151
168
 
152
169
  auth_options = {}
153
170
  auth_options[:bearer_token] = File.read(@bearer_token_file) if @bearer_token_file
154
171
 
155
172
  @client = Kubeclient::Client.new(
156
- @kubernetes_url, @api_version,
157
- ssl_options: ssl_options,
158
- auth_options: auth_options
173
+ @kubernetes_url, @api_version,
174
+ ssl_options: ssl_options,
175
+ auth_options: auth_options
159
176
  )
160
177
 
161
178
  begin
162
- @client.api_valid?
179
+ @client.api_valid?
163
180
  rescue KubeException => kube_error
164
- raise Fluent::ConfigError, "Invalid Kubernetes API #{@api_version} endpoint #{@kubernetes_url}: #{kube_error.message}"
165
- end
181
+ raise Fluent::ConfigError, "Invalid Kubernetes API #{@api_version} endpoint #{@kubernetes_url}: #{kube_error.message}"
182
+ end
166
183
  end
167
184
 
168
185
  def start_pullers
@@ -170,16 +187,7 @@ module Fluent::Plugin
170
187
  end
171
188
 
172
189
  def start_watchers
173
- @watchers = @watch_objects.map do |o|
174
- o = o.to_h.dup
175
- o[:as] = :raw
176
- resource_name = o.delete(:resource_name)
177
- version = @storage.get(resource_name)
178
- o[:resource_version] = version if version
179
- @client.public_send("watch_#{resource_name}", o).tap { |watcher|
180
- create_watcher_thread resource_name, watcher
181
- }
182
- end
190
+ @watch_objects.each(&method(:create_watcher_thread))
183
191
  end
184
192
 
185
193
  def create_pull_thread(conf)
@@ -189,49 +197,68 @@ module Fluent::Plugin
189
197
  pull_interval = options.delete :interval
190
198
 
191
199
  thread_create :"pull_#{resource_name}" do
192
- tag = generate_tag resource_name
193
- while thread_current_running?
194
- log.debug "Going to pull #{resource_name}"
195
- response = @client.public_send "get_#{resource_name}", options
196
- now = Fluent::Engine.now
197
- es = Fluent::MultiEventStream.new
198
-
199
- # code copied from kubeclient
200
- # kubeclient will create one open struct object for each item in the response,
201
- # but this is totally unecessary in this plugin, thus we use as: :raw.
202
- result = JSON.parse(response)
203
-
204
- resource_version = result.fetch('resourceVersion') {
205
- result.fetch('metadata', {})['resourceVersion']
206
- }
207
-
208
- update_op = if resource_version
209
- ->(item) { item['metadata'].update requestResourceVersion: resource_version }
210
- else
211
- ->(item) {}
212
- end
213
-
214
- # result['items'] might be nil due to https://github.com/kubernetes/kubernetes/issues/13096
215
- items = result['items'].to_a
216
- log.debug { "Received #{items.size} #{resource_name}" }
217
- items.each { |item| es.add now, item.tap(&update_op) }
218
- router.emit_stream(tag, es)
219
-
220
- sleep(pull_interval)
221
- end
200
+ tag = generate_tag resource_name
201
+ while thread_current_running?
202
+ log.debug "Going to pull #{resource_name}"
203
+ response = @client.public_send "get_#{resource_name}", options
204
+ now = Fluent::Engine.now
205
+ es = Fluent::MultiEventStream.new
206
+
207
+ # code copied from kubeclient
208
+ # kubeclient will create one open struct object for each item in the response,
209
+ # but this is totally unecessary in this plugin, thus we use as: :raw.
210
+ result = JSON.parse(response)
211
+
212
+ resource_version = result.fetch('resourceVersion') do
213
+ result.fetch('metadata', {})['resourceVersion']
214
+ end
215
+
216
+ update_op = if resource_version
217
+ ->(item) { item['metadata'].update requestResourceVersion: resource_version }
218
+ else
219
+ ->(item) {}
220
+ end
221
+
222
+ # result['items'] might be nil due to https://github.com/kubernetes/kubernetes/issues/13096
223
+ items = result['items'].to_a
224
+ log.debug { "Received #{items.size} #{resource_name}" }
225
+ items.each { |item| es.add now, item.tap(&update_op) }
226
+ router.emit_stream(tag, es)
227
+
228
+ sleep(pull_interval)
229
+ end
222
230
  end
223
231
  end
224
232
 
225
- def create_watcher_thread(object_name, watcher)
226
- thread_create(:"watch_#{object_name}") {
227
- tag = generate_tag "#{object_name}.watch"
228
- watcher.each { |entity|
229
- log.trace { "Received new object from watching #{object_name}"}
230
- entity = JSON.parse(entity)
231
- router.emit tag, Fluent::Engine.now, entity
232
- @storage.put object_name, entity['object']['metadata']['resourceVersion']
233
- }
234
- }
233
+ def create_watcher_thread(conf)
234
+ options = conf.to_h.dup
235
+ options[:as] = :raw
236
+ resource_name = options[:resource_name]
237
+ version = @storage.get(resource_name)
238
+ if version
239
+ options[:resource_version] = version
240
+ else
241
+ options[:resource_version] = 0
242
+ end
243
+
244
+ thread_create :"watch_#{resource_name}" do
245
+ while thread_current_running?
246
+ @client.public_send("watch_#{resource_name}", options).tap do |watcher|
247
+ tag = generate_tag "#{resource_name}"
248
+ watcher.each do |entity|
249
+ begin
250
+ entity = JSON.parse(entity)
251
+ router.emit tag, Fluent::Engine.now, entity
252
+ options[:resource_version] = entity['object']['metadata']['resourceVersion']
253
+ @storage.put resource_name, entity['object']['metadata']['resourceVersion']
254
+ rescue => e
255
+ log.info "Got exception #{e} parsing entity #{entity}. Resetting watcher."
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end
235
261
  end
236
262
  end
237
263
  end
264
+
@@ -1,4 +1,5 @@
1
1
  require "test_helper"
2
+ require 'fluent/plugin/in_kubernetes_objects.rb'
2
3
 
3
4
  describe Fluent::Plugin::KubernetesObjectsInput do
4
5
  include Fluent::Test::Helpers
@@ -10,8 +11,10 @@ describe Fluent::Plugin::KubernetesObjectsInput do
10
11
  }
11
12
 
12
13
  it { expect(::Fluent::Plugin::KubernetesObjectsInput::VERSION).wont_be_nil }
14
+ puts 'Test: Version will not be nil'
13
15
 
14
16
  it "should require at least one <pull> or <watch> section" do
17
+ puts 'Test: should require at least one <pull> or <watch> section'
15
18
  expect{create_input_driver("kubernetes_url #{k8s_url}")}.must_raise Fluent::ConfigError
16
19
  expect(create_input_driver(<<~CONF)).wont_be_nil
17
20
  kubernetes_url #{k8s_url}
@@ -29,6 +32,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
29
32
 
30
33
  describe "config: kubernetes_url" do
31
34
  it "should read from environment variables by default" do
35
+ puts 'Test: should read from environment variables by default'
32
36
  ENV['KUBERNETES_SERVICE_HOST'] = k8s_host
33
37
  ENV['KUBERNETES_SERVICE_PORT'] = k8s_port
34
38
  expect(create_input_driver(<<~CONF).instance.kubernetes_url).must_equal k8s_url
@@ -39,6 +43,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
39
43
  end
40
44
 
41
45
  it "should panic if not set" do
46
+ puts 'Test: should panic if not set'
42
47
  ENV['KUBERNETES_SERVICE_HOST'] = nil
43
48
  ENV['KUBERNETES_SERVICE_PORT'] = nil
44
49
  expect{ create_input_driver(<<~CONF) }.must_raise Fluent::ConfigError
@@ -49,6 +54,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
49
54
  end
50
55
 
51
56
  it "should use pick the right path" do
57
+ puts 'Test: should use pick the right path'
52
58
  ENV['KUBERNETES_SERVICE_HOST'] = k8s_host
53
59
  ENV['KUBERNETES_SERVICE_PORT'] = k8s_port
54
60
  expect(create_input_driver(<<~CONF).instance.kubernetes_url).must_equal k8s_url('apis')
@@ -62,6 +68,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
62
68
 
63
69
  describe "emit events" do
64
70
  it "can pull one resource" do
71
+ puts 'Test: can pull one resource'
65
72
  d = create_input_driver(<<~CONF)
66
73
  kubernetes_url #{k8s_url}
67
74
  <pull>
@@ -76,6 +83,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
76
83
  end
77
84
 
78
85
  it "can pull multiple resources" do
86
+ puts 'Test: can pull multiple resources'
79
87
  d = create_input_driver(<<~CONF)
80
88
  kubernetes_url #{k8s_url}
81
89
  <pull>
@@ -94,6 +102,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
94
102
  end
95
103
 
96
104
  it "can watch resources" do
105
+ puts 'Test: can watch resources'
97
106
  d = create_input_driver(<<~CONF)
98
107
  kubernetes_url #{k8s_url}
99
108
  <watch>
@@ -101,33 +110,38 @@ describe Fluent::Plugin::KubernetesObjectsInput do
101
110
  </watch>
102
111
  CONF
103
112
 
113
+ stub_k8s_events params: {resourceVersion: "0"}
114
+ stub_k8s_events params: {resourceVersion: "6621683"}
115
+
104
116
  d.run expect_emits: 1, timeout: 3
105
117
  events = d.events
106
- expect(events.all? { |e| e[0] == 'kubernetes.events.watch'}).must_equal true
118
+ expect(events.all? { |e| e[0] == 'kubernetes.events'}).must_equal true
107
119
  end
108
120
 
109
121
  it "should use checkpoints for watching" do
122
+ puts 'Test: should use checkpoints for watching'
110
123
  begin
111
- require 'tempfile'
112
- f = Tempfile.new("fluentd-k8s-objects-test", encoding: 'utf-8')
113
- f.write('{"events": "123456"}')
114
- f.close
115
-
116
- d = create_input_driver(<<~CONF)
117
- kubernetes_url #{k8s_url}
118
- <storage>
119
- path #{f.path}
120
- </storage>
121
- <watch>
122
- resource_name events
123
- </watch>
124
- CONF
125
-
126
- stub_k8s_events params: {resourceVersion: "123456"}
127
-
128
- d.run expect_emits: 1, timeout: 3
124
+ require 'tempfile'
125
+ f = Tempfile.new("fluentd-k8s-objects-test", encoding: 'utf-8')
126
+ f.write('{"events": "123456"}')
127
+ f.close
128
+
129
+ d = create_input_driver(<<~CONF)
130
+ kubernetes_url #{k8s_url}
131
+ <storage>
132
+ path #{f.path}
133
+ </storage>
134
+ <watch>
135
+ resource_name events
136
+ </watch>
137
+ CONF
138
+
139
+ stub_k8s_events params: {resourceVersion: "123456"}
140
+ stub_k8s_events params: {resourceVersion: "6621683"}
141
+
142
+ d.run expect_emits: 1, timeout: 3
129
143
  ensure
130
- f.unlink
144
+ f.unlink
131
145
  end
132
146
  end
133
147
  end
@@ -1,18 +1,19 @@
1
- $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
- #$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
1
+ require 'simplecov'
2
+ SimpleCov.start
3
3
 
4
- # suppress warning, when require the 'http' library, it shows circle require warnning,
4
+ $LOAD_PATH.unshift(File.expand_path('..', __dir__))
5
+
6
+ # suppress warning, when require the 'http' library shows circle require warning
5
7
  # which is pretty annoying (kubeclient depends on http for watch_stream)
6
8
  _verbose = $VERBOSE
7
9
  $VERBOSE = nil
8
- require "fluent/plugin/in_kubernetes_objects"
9
10
  $VERBOSE = _verbose
10
11
 
11
- require "fluent/test"
12
- require "fluent/test/driver/input"
13
- require "fluent/test/helpers"
14
- require "minitest/autorun"
15
- require "webmock/minitest"
12
+ require 'fluent/test'
13
+ require 'fluent/test/driver/input'
14
+ require 'fluent/test/helpers'
15
+ require 'minitest/autorun'
16
+ require 'webmock/minitest'
16
17
 
17
18
  # make assertions from webmock available in minitest/spec
18
19
  module Minitest::Expectations
@@ -21,20 +22,27 @@ module Minitest::Expectations
21
22
  end
22
23
 
23
24
  module PluginTestHelper
24
- def k8s_host() "127.0.0.1" end
25
- def k8s_port() "8001" end
26
- def k8s_url(path='api') "https://#{k8s_host}:#{k8s_port}/#{path}" end
25
+ def k8s_host
26
+ '127.0.0.1'
27
+ end
28
+
29
+ def k8s_port
30
+ '8001'
31
+ end
32
+
33
+ def k8s_url(path = 'api')
34
+ "https://#{k8s_host}:#{k8s_port}/#{path}"
35
+ end
27
36
 
28
37
  def fluentd_conf_for(*lines)
29
- basic_config = [
30
- ]
38
+ basic_config = []
31
39
  (basic_config + lines).join("\n")
32
40
  end
33
41
 
34
42
  def create_input_driver(*configs)
35
- Fluent::Test::Driver::Input.new(Fluent::Plugin::KubernetesObjectsInput).tap { |d|
43
+ Fluent::Test::Driver::Input.new(Fluent::Plugin::KubernetesObjectsInput).tap do |d|
36
44
  d.configure(fluentd_conf_for(*configs))
37
- }
45
+ end
38
46
  end
39
47
 
40
48
  def stub_k8s_requests
@@ -49,47 +57,49 @@ module PluginTestHelper
49
57
  end
50
58
 
51
59
  def stub_k8s_api
52
- open(File.expand_path('../api.json', __FILE__)).tap { |f|
60
+ File.open(File.expand_path('api.json', __dir__)).tap do |f|
53
61
  stub_request(:get, k8s_url).to_return(body: f.read)
54
- }.close
62
+ end.close
55
63
  end
56
64
 
57
65
  def stub_k8s_apis
58
- open(File.expand_path('../apis.json', __FILE__)).tap { |f|
66
+ File.open(File.expand_path('apis.json', __dir__)).tap do |f|
59
67
  stub_request(:get, k8s_url('apis')).to_return(body: f.read)
60
- }.close
68
+ end.close
61
69
  end
62
70
 
63
71
  def stub_k8s_v1
64
- open(File.expand_path('../v1.json', __FILE__)).tap { |f|
72
+ File.open(File.expand_path('v1.json', __dir__)).tap do |f|
65
73
  stub_request(:get, "#{k8s_url}/v1").to_return(body: f.read)
66
- }.close
74
+ end.close
67
75
  end
68
76
 
69
77
  def stub_k8s_namespaces
70
- open(File.expand_path('../namespaces.json', __FILE__)).tap { |f|
71
- stub_request(:get, "#{k8s_url}/v1/namespaces").to_return(body: f.read())
72
- }.close
78
+ File.open(File.expand_path('namespaces.json', __dir__)).tap do |f|
79
+ stub_request(:get, "#{k8s_url}/v1/namespaces").to_return(body: f.read)
80
+ end.close
73
81
  end
74
82
 
75
83
  def stub_k8s_nodes
76
- open(File.expand_path('../nodes.json', __FILE__)).tap { |f|
77
- stub_request(:get, "#{k8s_url}/v1/nodes").to_return(body: f.read())
78
- }.close
84
+ File.open(File.expand_path('nodes.json', __dir__)).tap do |f|
85
+ stub_request(:get, "#{k8s_url}/v1/nodes").to_return(body: f.read)
86
+ end.close
79
87
  end
80
88
 
81
89
  def stub_k8s_pods
82
- open(File.expand_path('../pods.json', __FILE__)).tap { |f|
83
- stub_request(:get, "#{k8s_url}/v1/pods").to_return(body: f.read())
84
- }.close
90
+ File.open(File.expand_path('pods.json', __dir__)).tap do |f|
91
+ stub_request(:get, "#{k8s_url}/v1/pods").to_return(body: f.read)
92
+ end.close
85
93
  end
86
94
 
87
95
  def stub_k8s_events(params: nil)
88
- open(File.expand_path('../events.json', __FILE__)).tap { |f|
96
+ File.open(File.expand_path('events.json', __dir__)).tap do |f|
89
97
  url = "#{k8s_url}/v1/watch/events"
90
- url << '?' << params.map { |k, v| "#{k}=#{v}" }.join('&') if params
91
- stub_request(:get, url).
92
- to_return(body: f.read(), headers: {"Content-Type" => "application/json", "Transfer-Encoding" => "chunked"})
93
- }.close
98
+ url << '?' << params.map { |k, v| "#{k}=#{v}" }.join('&') if params
99
+ stub_request(:get, url)
100
+ .to_return(body: f.read,
101
+ headers: { 'Content-Type' => 'application/json',
102
+ 'Transfer-Encoding' => 'chunked' })
103
+ end.close
94
104
  end
95
105
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-kubernetes-objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
- - Gimi Liang
7
+ - Splunk Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-15 00:00:00.000000000 Z
11
+ date: 2020-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -16,102 +16,116 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: 1.9.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: 1.9.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: kubeclient
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '3.0'
33
+ version: 4.6.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '3.0'
40
+ version: 4.6.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: http_parser.rb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.5.3
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.5.3
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '1.16'
61
+ version: '2.0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '1.16'
68
+ version: '2.0'
55
69
  - !ruby/object:Gem::Dependency
56
- name: rake
70
+ name: minitest
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '10.0'
75
+ version: '5.11'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '10.0'
82
+ version: '5.11'
69
83
  - !ruby/object:Gem::Dependency
70
- name: test-unit
84
+ name: rake
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - "~>"
87
+ - - ">="
74
88
  - !ruby/object:Gem::Version
75
- version: '3.0'
89
+ version: '12.0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - "~>"
94
+ - - ">="
81
95
  - !ruby/object:Gem::Version
82
- version: '3.0'
96
+ version: '12.0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: minitest
98
+ name: test-unit
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '5.0'
103
+ version: '3.3'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '5.0'
110
+ version: '3.3'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: webmock
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '3.2'
117
+ version: '3.5'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '3.2'
124
+ version: '3.5'
111
125
  description: A Fluentd input plugin for collecting Kubernetes objects, e.g. pods,
112
126
  namespaces, events, etc. by pulling or watching.
113
127
  email:
114
- - zliang@splunk.com
128
+ - DataEdge@splunk.com
115
129
  executables: []
116
130
  extensions: []
117
131
  extra_rdoc_files: []
@@ -122,6 +136,7 @@ files:
122
136
  - LICENSE
123
137
  - README.md
124
138
  - Rakefile
139
+ - VERSION
125
140
  - fluent-plugin-kubernetes-objects.gemspec
126
141
  - lib/fluent/plugin/in_kubernetes_objects.rb
127
142
  - test/fluent/plugin/in_kubernetes_objects_test.rb
@@ -152,8 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
167
  - !ruby/object:Gem::Version
153
168
  version: '0'
154
169
  requirements: []
155
- rubyforge_project:
156
- rubygems_version: 2.7.6
170
+ rubygems_version: 3.1.1
157
171
  signing_key:
158
172
  specification_version: 4
159
173
  summary: Fluentd Plugin for Kubernetes Objects.