fluent-plugin-kubernetes-objects 1.0.0 → 1.1.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 +6 -2
- data/Gemfile.lock +38 -30
- data/README.md +1 -1
- data/Rakefile +6 -6
- data/fluent-plugin-kubernetes-objects.gemspec +23 -23
- data/lib/fluent/plugin/in_kubernetes_objects.rb +79 -79
- data/test/fluent/plugin/in_kubernetes_objects_test.rb +29 -20
- data/test/test_helper.rb +47 -36
- metadata +22 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6cfb891f22b53744c43fc6c2e1518d84a6b9f777715b8e76cdf6203d060dfebb
|
|
4
|
+
data.tar.gz: 33e009c355bddf26ab670daf63891344edcba1e25cc449f482fd4021ff9537f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 16d37fd0ff1778a2f02d60bb08fb45137fd18bacd4484add87df8d7d6fbda0a231225dcc443dc20d93df7ce6aee1bc03e22f08020260eb80af413959f693529d
|
|
7
|
+
data.tar.gz: 66ccb72b7b271c55d67e573fbb614a57e7c6a4fa1bc8755d2eb47d09af3e5481865219c3e8ee3a291416365f53d5d3341b4cc510f32f4418be8ae9915f7a0aab
|
data/Gemfile
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
source
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
-
|
|
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
|
data/Gemfile.lock
CHANGED
|
@@ -2,21 +2,22 @@ PATH
|
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
4
|
fluent-plugin-kubernetes-objects (1.0.0)
|
|
5
|
-
fluentd (~> 1.
|
|
6
|
-
kubeclient (~>
|
|
5
|
+
fluentd (~> 1.3)
|
|
6
|
+
kubeclient (~> 4.2)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
10
10
|
specs:
|
|
11
|
-
addressable (2.
|
|
11
|
+
addressable (2.6.0)
|
|
12
12
|
public_suffix (>= 2.0.2, < 4.0)
|
|
13
13
|
cool.io (1.5.3)
|
|
14
14
|
crack (0.4.3)
|
|
15
15
|
safe_yaml (~> 1.0.0)
|
|
16
16
|
dig_rb (1.0.1)
|
|
17
|
-
|
|
17
|
+
docile (1.3.1)
|
|
18
|
+
domain_name (0.5.20180417)
|
|
18
19
|
unf (>= 0.0.5, < 1.0.0)
|
|
19
|
-
fluentd (1.
|
|
20
|
+
fluentd (1.3.3)
|
|
20
21
|
cool.io (>= 1.4.5, < 2.0.0)
|
|
21
22
|
dig_rb (~> 1.0.0)
|
|
22
23
|
http_parser.rb (>= 0.5.1, < 0.7.0)
|
|
@@ -27,65 +28,72 @@ GEM
|
|
|
27
28
|
tzinfo (~> 1.0)
|
|
28
29
|
tzinfo-data (~> 1.0)
|
|
29
30
|
yajl-ruby (~> 1.0)
|
|
30
|
-
hashdiff (0.3.
|
|
31
|
-
http (
|
|
31
|
+
hashdiff (0.3.8)
|
|
32
|
+
http (3.3.0)
|
|
32
33
|
addressable (~> 2.3)
|
|
33
34
|
http-cookie (~> 1.0)
|
|
34
|
-
http-form_data (~>
|
|
35
|
+
http-form_data (~> 2.0)
|
|
35
36
|
http_parser.rb (~> 0.6.0)
|
|
36
37
|
http-cookie (1.0.3)
|
|
37
38
|
domain_name (~> 0.5)
|
|
38
|
-
http-form_data (1.
|
|
39
|
+
http-form_data (2.1.1)
|
|
39
40
|
http_parser.rb (0.6.0)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
json (2.1.0)
|
|
42
|
+
kubeclient (4.2.2)
|
|
43
|
+
http (~> 3.0)
|
|
44
|
+
recursive-open-struct (~> 1.0, >= 1.0.4)
|
|
43
45
|
rest-client (~> 2.0)
|
|
44
|
-
mime-types (3.
|
|
46
|
+
mime-types (3.2.2)
|
|
45
47
|
mime-types-data (~> 3.2015)
|
|
46
|
-
mime-types-data (3.
|
|
48
|
+
mime-types-data (3.2018.0812)
|
|
47
49
|
minitest (5.11.3)
|
|
48
|
-
msgpack (1.2.
|
|
50
|
+
msgpack (1.2.6)
|
|
49
51
|
netrc (0.11.0)
|
|
50
|
-
power_assert (1.1.
|
|
51
|
-
public_suffix (3.0.
|
|
52
|
-
rake (
|
|
53
|
-
recursive-open-struct (1.0
|
|
52
|
+
power_assert (1.1.3)
|
|
53
|
+
public_suffix (3.0.3)
|
|
54
|
+
rake (12.3.2)
|
|
55
|
+
recursive-open-struct (1.1.0)
|
|
54
56
|
rest-client (2.0.2)
|
|
55
57
|
http-cookie (>= 1.0.2, < 2.0)
|
|
56
58
|
mime-types (>= 1.16, < 4.0)
|
|
57
59
|
netrc (~> 0.8)
|
|
58
60
|
safe_yaml (1.0.4)
|
|
59
|
-
serverengine (2.0
|
|
61
|
+
serverengine (2.1.0)
|
|
60
62
|
sigdump (~> 0.2.2)
|
|
61
63
|
sigdump (0.2.4)
|
|
64
|
+
simplecov (0.16.1)
|
|
65
|
+
docile (~> 1.1)
|
|
66
|
+
json (>= 1.8, < 3)
|
|
67
|
+
simplecov-html (~> 0.10.0)
|
|
68
|
+
simplecov-html (0.10.2)
|
|
62
69
|
strptime (0.2.3)
|
|
63
|
-
test-unit (3.
|
|
70
|
+
test-unit (3.3.0)
|
|
64
71
|
power_assert
|
|
65
72
|
thread_safe (0.3.6)
|
|
66
73
|
tzinfo (1.2.5)
|
|
67
74
|
thread_safe (~> 0.1)
|
|
68
|
-
tzinfo-data (1.2018.
|
|
75
|
+
tzinfo-data (1.2018.9)
|
|
69
76
|
tzinfo (>= 1.0.0)
|
|
70
77
|
unf (0.1.4)
|
|
71
78
|
unf_ext
|
|
72
79
|
unf_ext (0.0.7.5)
|
|
73
|
-
webmock (3.
|
|
80
|
+
webmock (3.5.1)
|
|
74
81
|
addressable (>= 2.3.6)
|
|
75
82
|
crack (>= 0.3.2)
|
|
76
83
|
hashdiff
|
|
77
|
-
yajl-ruby (1.
|
|
84
|
+
yajl-ruby (1.4.1)
|
|
78
85
|
|
|
79
86
|
PLATFORMS
|
|
80
87
|
ruby
|
|
81
88
|
|
|
82
89
|
DEPENDENCIES
|
|
83
|
-
bundler (~>
|
|
90
|
+
bundler (~> 2.0)
|
|
84
91
|
fluent-plugin-kubernetes-objects!
|
|
85
|
-
minitest (~> 5.
|
|
86
|
-
rake (~>
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
minitest (~> 5.11)
|
|
93
|
+
rake (~> 12.3)
|
|
94
|
+
simplecov
|
|
95
|
+
test-unit (~> 3.3)
|
|
96
|
+
webmock (~> 3.5)
|
|
89
97
|
|
|
90
98
|
BUNDLED WITH
|
|
91
|
-
|
|
99
|
+
2.0.1
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[
|
|
1
|
+
[](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
|
|
2
|
-
require
|
|
1
|
+
require 'bundler/gem_tasks'
|
|
2
|
+
require 'rake/testtask'
|
|
3
3
|
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
|
5
|
-
t.libs <<
|
|
6
|
-
t.libs <<
|
|
7
|
-
t.test_files = FileList[
|
|
5
|
+
t.libs << 'test'
|
|
6
|
+
t.libs << 'lib'
|
|
7
|
+
t.test_files = FileList['test/**/*_test.rb']
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
task :
|
|
10
|
+
task default: :test
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
Gem::Specification.new do |spec|
|
|
2
|
-
spec.name =
|
|
3
|
-
spec.version =
|
|
4
|
-
spec.authors = [
|
|
5
|
-
spec.email = [
|
|
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 =
|
|
8
|
-
spec.description =
|
|
9
|
-
spec.homepage =
|
|
10
|
-
spec.license =
|
|
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
12
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
13
13
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
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
20
|
|
|
21
|
-
spec.require_paths = [
|
|
21
|
+
spec.require_paths = ['lib']
|
|
22
22
|
spec.test_files = Dir.glob('test/**/**.rb')
|
|
23
23
|
spec.files = %w[
|
|
24
24
|
CODE_OF_CONDUCT.md README.md LICENSE
|
|
@@ -27,17 +27,17 @@ Gem::Specification.new do |spec|
|
|
|
27
27
|
Rakefile
|
|
28
28
|
] + Dir.glob('lib/**/**').reject(&File.method(:directory?))
|
|
29
29
|
|
|
30
|
-
spec.bindir =
|
|
30
|
+
spec.bindir = 'exe'
|
|
31
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
32
32
|
|
|
33
33
|
spec.required_ruby_version = '>= 2.3.0'
|
|
34
34
|
|
|
35
|
-
spec.add_runtime_dependency
|
|
36
|
-
spec.add_runtime_dependency
|
|
35
|
+
spec.add_runtime_dependency 'fluentd', '~> 1.3'
|
|
36
|
+
spec.add_runtime_dependency 'kubeclient', '~> 4.2'
|
|
37
37
|
|
|
38
|
-
spec.add_development_dependency
|
|
39
|
-
spec.add_development_dependency
|
|
40
|
-
spec.add_development_dependency
|
|
41
|
-
spec.add_development_dependency
|
|
42
|
-
spec.add_development_dependency
|
|
38
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
|
39
|
+
spec.add_development_dependency 'minitest', '~> 5.11'
|
|
40
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
|
41
|
+
spec.add_development_dependency 'test-unit', '~> 3.3' # required by fluent/test.rb
|
|
42
|
+
spec.add_development_dependency 'webmock', '~> 3.5'
|
|
43
43
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
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 =
|
|
8
|
+
VERSION = '1.1.0'.freeze
|
|
9
9
|
|
|
10
10
|
Fluent::Plugin.register_input('kubernetes_objects', self)
|
|
11
11
|
|
|
@@ -76,17 +76,17 @@ module Fluent::Plugin
|
|
|
76
76
|
|
|
77
77
|
config_section :storage do
|
|
78
78
|
# use memory by default
|
|
79
|
-
config_set_default :usage,
|
|
80
|
-
config_set_default :@type,
|
|
79
|
+
config_set_default :usage, 'checkpoints'
|
|
80
|
+
config_set_default :@type, 'local'
|
|
81
81
|
config_set_default :persistent, false
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
def configure(conf)
|
|
85
85
|
super
|
|
86
86
|
|
|
87
|
-
raise Fluent::ConfigError,
|
|
87
|
+
raise Fluent::ConfigError, 'At least one <pull> or <watch> is required, but found none.' if @pull_objects.empty? && @watch_objects.empty?
|
|
88
88
|
|
|
89
|
-
@storage = storage_create usage:
|
|
89
|
+
@storage = storage_create usage: 'checkpoints'
|
|
90
90
|
|
|
91
91
|
parse_tag
|
|
92
92
|
initialize_client
|
|
@@ -118,51 +118,51 @@ module Fluent::Plugin
|
|
|
118
118
|
def initialize_client
|
|
119
119
|
# mostly borrowed from Fluentd Kubernetes Metadata Filter Plugin
|
|
120
120
|
if @kubernetes_url.nil?
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
|
127
127
|
end
|
|
128
128
|
|
|
129
|
-
raise Fluent::ConfigError,
|
|
129
|
+
raise Fluent::ConfigError, 'kubernetes url is not set' unless @kubernetes_url
|
|
130
130
|
|
|
131
131
|
# Use SSL certificate and bearer token from Kubernetes service account.
|
|
132
132
|
if Dir.exist?(@secret_dir)
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
secret_ca_file = File.join(@secret_dir, 'ca.crt')
|
|
134
|
+
secret_token_file = File.join(@secret_dir, 'token')
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
if @ca_file.nil? && File.exist?(secret_ca_file)
|
|
137
|
+
@ca_file = secret_ca_file
|
|
138
|
+
end
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
if @bearer_token_file.nil? && File.exist?(secret_token_file)
|
|
141
|
+
@bearer_token_file = secret_token_file
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
144
|
|
|
145
145
|
ssl_options = {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
auth_options = {}
|
|
153
153
|
auth_options[:bearer_token] = File.read(@bearer_token_file) if @bearer_token_file
|
|
154
154
|
|
|
155
155
|
@client = Kubeclient::Client.new(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
@kubernetes_url, @api_version,
|
|
157
|
+
ssl_options: ssl_options,
|
|
158
|
+
auth_options: auth_options
|
|
159
159
|
)
|
|
160
160
|
|
|
161
161
|
begin
|
|
162
|
-
|
|
162
|
+
@client.api_valid?
|
|
163
163
|
rescue KubeException => kube_error
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
raise Fluent::ConfigError, "Invalid Kubernetes API #{@api_version} endpoint #{@kubernetes_url}: #{kube_error.message}"
|
|
165
|
+
end
|
|
166
166
|
end
|
|
167
167
|
|
|
168
168
|
def start_pullers
|
|
@@ -171,14 +171,14 @@ module Fluent::Plugin
|
|
|
171
171
|
|
|
172
172
|
def start_watchers
|
|
173
173
|
@watchers = @watch_objects.map do |o|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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 do |watcher|
|
|
180
|
+
create_watcher_thread resource_name, watcher
|
|
181
|
+
end
|
|
182
182
|
end
|
|
183
183
|
end
|
|
184
184
|
|
|
@@ -189,49 +189,49 @@ module Fluent::Plugin
|
|
|
189
189
|
pull_interval = options.delete :interval
|
|
190
190
|
|
|
191
191
|
thread_create :"pull_#{resource_name}" do
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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') do
|
|
205
|
+
result.fetch('metadata', {})['resourceVersion']
|
|
206
|
+
end
|
|
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
|
|
222
222
|
end
|
|
223
223
|
end
|
|
224
224
|
|
|
225
225
|
def create_watcher_thread(object_name, watcher)
|
|
226
|
-
thread_create(:"watch_#{object_name}")
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
226
|
+
thread_create(:"watch_#{object_name}") do
|
|
227
|
+
tag = generate_tag "#{object_name}.watch"
|
|
228
|
+
watcher.each do |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
|
+
end
|
|
234
|
+
end
|
|
235
235
|
end
|
|
236
236
|
end
|
|
237
237
|
end
|
|
@@ -10,8 +10,10 @@ describe Fluent::Plugin::KubernetesObjectsInput do
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
it { expect(::Fluent::Plugin::KubernetesObjectsInput::VERSION).wont_be_nil }
|
|
13
|
+
puts 'Test: Version will not be nil'
|
|
13
14
|
|
|
14
15
|
it "should require at least one <pull> or <watch> section" do
|
|
16
|
+
puts 'Test: should require at least one <pull> or <watch> section'
|
|
15
17
|
expect{create_input_driver("kubernetes_url #{k8s_url}")}.must_raise Fluent::ConfigError
|
|
16
18
|
expect(create_input_driver(<<~CONF)).wont_be_nil
|
|
17
19
|
kubernetes_url #{k8s_url}
|
|
@@ -29,6 +31,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
|
|
|
29
31
|
|
|
30
32
|
describe "config: kubernetes_url" do
|
|
31
33
|
it "should read from environment variables by default" do
|
|
34
|
+
puts 'Test: should read from environment variables by default'
|
|
32
35
|
ENV['KUBERNETES_SERVICE_HOST'] = k8s_host
|
|
33
36
|
ENV['KUBERNETES_SERVICE_PORT'] = k8s_port
|
|
34
37
|
expect(create_input_driver(<<~CONF).instance.kubernetes_url).must_equal k8s_url
|
|
@@ -39,6 +42,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
|
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
it "should panic if not set" do
|
|
45
|
+
puts 'Test: should panic if not set'
|
|
42
46
|
ENV['KUBERNETES_SERVICE_HOST'] = nil
|
|
43
47
|
ENV['KUBERNETES_SERVICE_PORT'] = nil
|
|
44
48
|
expect{ create_input_driver(<<~CONF) }.must_raise Fluent::ConfigError
|
|
@@ -49,6 +53,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
|
|
|
49
53
|
end
|
|
50
54
|
|
|
51
55
|
it "should use pick the right path" do
|
|
56
|
+
puts 'Test: should use pick the right path'
|
|
52
57
|
ENV['KUBERNETES_SERVICE_HOST'] = k8s_host
|
|
53
58
|
ENV['KUBERNETES_SERVICE_PORT'] = k8s_port
|
|
54
59
|
expect(create_input_driver(<<~CONF).instance.kubernetes_url).must_equal k8s_url('apis')
|
|
@@ -62,6 +67,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
|
|
|
62
67
|
|
|
63
68
|
describe "emit events" do
|
|
64
69
|
it "can pull one resource" do
|
|
70
|
+
puts 'Test: can pull one resource'
|
|
65
71
|
d = create_input_driver(<<~CONF)
|
|
66
72
|
kubernetes_url #{k8s_url}
|
|
67
73
|
<pull>
|
|
@@ -76,6 +82,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
|
|
|
76
82
|
end
|
|
77
83
|
|
|
78
84
|
it "can pull multiple resources" do
|
|
85
|
+
puts 'Test: can pull multiple resources'
|
|
79
86
|
d = create_input_driver(<<~CONF)
|
|
80
87
|
kubernetes_url #{k8s_url}
|
|
81
88
|
<pull>
|
|
@@ -94,6 +101,7 @@ describe Fluent::Plugin::KubernetesObjectsInput do
|
|
|
94
101
|
end
|
|
95
102
|
|
|
96
103
|
it "can watch resources" do
|
|
104
|
+
puts 'Test: can watch resources'
|
|
97
105
|
d = create_input_driver(<<~CONF)
|
|
98
106
|
kubernetes_url #{k8s_url}
|
|
99
107
|
<watch>
|
|
@@ -107,27 +115,28 @@ describe Fluent::Plugin::KubernetesObjectsInput do
|
|
|
107
115
|
end
|
|
108
116
|
|
|
109
117
|
it "should use checkpoints for watching" do
|
|
118
|
+
puts 'Test: should use checkpoints for watching'
|
|
110
119
|
begin
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
require 'tempfile'
|
|
121
|
+
f = Tempfile.new("fluentd-k8s-objects-test", encoding: 'utf-8')
|
|
122
|
+
f.write('{"events": "123456"}')
|
|
123
|
+
f.close
|
|
124
|
+
|
|
125
|
+
d = create_input_driver(<<~CONF)
|
|
126
|
+
kubernetes_url #{k8s_url}
|
|
127
|
+
<storage>
|
|
128
|
+
path #{f.path}
|
|
129
|
+
</storage>
|
|
130
|
+
<watch>
|
|
131
|
+
resource_name events
|
|
132
|
+
</watch>
|
|
133
|
+
CONF
|
|
134
|
+
|
|
135
|
+
stub_k8s_events params: {resourceVersion: "123456"}
|
|
136
|
+
|
|
137
|
+
d.run expect_emits: 1, timeout: 3
|
|
138
|
+
ensure
|
|
139
|
+
f.unlink
|
|
131
140
|
end
|
|
132
141
|
end
|
|
133
142
|
end
|
data/test/test_helper.rb
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
require 'simplecov'
|
|
2
|
+
SimpleCov.start
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __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
|
|
10
|
+
require 'fluent/plugin/in_kubernetes_objects'
|
|
9
11
|
$VERBOSE = _verbose
|
|
10
12
|
|
|
11
|
-
require
|
|
12
|
-
require
|
|
13
|
-
require
|
|
14
|
-
require
|
|
15
|
-
require
|
|
13
|
+
require 'fluent/test'
|
|
14
|
+
require 'fluent/test/driver/input'
|
|
15
|
+
require 'fluent/test/helpers'
|
|
16
|
+
require 'minitest/autorun'
|
|
17
|
+
require 'webmock/minitest'
|
|
16
18
|
|
|
17
19
|
# make assertions from webmock available in minitest/spec
|
|
18
20
|
module Minitest::Expectations
|
|
@@ -21,20 +23,27 @@ module Minitest::Expectations
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
module PluginTestHelper
|
|
24
|
-
def k8s_host
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
def k8s_host
|
|
27
|
+
'127.0.0.1'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def k8s_port
|
|
31
|
+
'8001'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def k8s_url(path = 'api')
|
|
35
|
+
"https://#{k8s_host}:#{k8s_port}/#{path}"
|
|
36
|
+
end
|
|
27
37
|
|
|
28
38
|
def fluentd_conf_for(*lines)
|
|
29
|
-
basic_config = [
|
|
30
|
-
]
|
|
39
|
+
basic_config = []
|
|
31
40
|
(basic_config + lines).join("\n")
|
|
32
41
|
end
|
|
33
42
|
|
|
34
43
|
def create_input_driver(*configs)
|
|
35
|
-
Fluent::Test::Driver::Input.new(Fluent::Plugin::KubernetesObjectsInput).tap
|
|
44
|
+
Fluent::Test::Driver::Input.new(Fluent::Plugin::KubernetesObjectsInput).tap do |d|
|
|
36
45
|
d.configure(fluentd_conf_for(*configs))
|
|
37
|
-
|
|
46
|
+
end
|
|
38
47
|
end
|
|
39
48
|
|
|
40
49
|
def stub_k8s_requests
|
|
@@ -49,47 +58,49 @@ module PluginTestHelper
|
|
|
49
58
|
end
|
|
50
59
|
|
|
51
60
|
def stub_k8s_api
|
|
52
|
-
open(File.expand_path('
|
|
61
|
+
File.open(File.expand_path('api.json', __dir__)).tap do |f|
|
|
53
62
|
stub_request(:get, k8s_url).to_return(body: f.read)
|
|
54
|
-
|
|
63
|
+
end.close
|
|
55
64
|
end
|
|
56
65
|
|
|
57
66
|
def stub_k8s_apis
|
|
58
|
-
open(File.expand_path('
|
|
67
|
+
File.open(File.expand_path('apis.json', __dir__)).tap do |f|
|
|
59
68
|
stub_request(:get, k8s_url('apis')).to_return(body: f.read)
|
|
60
|
-
|
|
69
|
+
end.close
|
|
61
70
|
end
|
|
62
71
|
|
|
63
72
|
def stub_k8s_v1
|
|
64
|
-
open(File.expand_path('
|
|
73
|
+
File.open(File.expand_path('v1.json', __dir__)).tap do |f|
|
|
65
74
|
stub_request(:get, "#{k8s_url}/v1").to_return(body: f.read)
|
|
66
|
-
|
|
75
|
+
end.close
|
|
67
76
|
end
|
|
68
77
|
|
|
69
78
|
def stub_k8s_namespaces
|
|
70
|
-
open(File.expand_path('
|
|
71
|
-
stub_request(:get, "#{k8s_url}/v1/namespaces").to_return(body: f.read
|
|
72
|
-
|
|
79
|
+
File.open(File.expand_path('namespaces.json', __dir__)).tap do |f|
|
|
80
|
+
stub_request(:get, "#{k8s_url}/v1/namespaces").to_return(body: f.read)
|
|
81
|
+
end.close
|
|
73
82
|
end
|
|
74
83
|
|
|
75
84
|
def stub_k8s_nodes
|
|
76
|
-
open(File.expand_path('
|
|
77
|
-
stub_request(:get, "#{k8s_url}/v1/nodes").to_return(body: f.read
|
|
78
|
-
|
|
85
|
+
File.open(File.expand_path('nodes.json', __dir__)).tap do |f|
|
|
86
|
+
stub_request(:get, "#{k8s_url}/v1/nodes").to_return(body: f.read)
|
|
87
|
+
end.close
|
|
79
88
|
end
|
|
80
89
|
|
|
81
90
|
def stub_k8s_pods
|
|
82
|
-
open(File.expand_path('
|
|
83
|
-
stub_request(:get, "#{k8s_url}/v1/pods").to_return(body: f.read
|
|
84
|
-
|
|
91
|
+
File.open(File.expand_path('pods.json', __dir__)).tap do |f|
|
|
92
|
+
stub_request(:get, "#{k8s_url}/v1/pods").to_return(body: f.read)
|
|
93
|
+
end.close
|
|
85
94
|
end
|
|
86
95
|
|
|
87
96
|
def stub_k8s_events(params: nil)
|
|
88
|
-
open(File.expand_path('
|
|
97
|
+
File.open(File.expand_path('events.json', __dir__)).tap do |f|
|
|
89
98
|
url = "#{k8s_url}/v1/watch/events"
|
|
90
|
-
url << '?' << params.map { |k, v|
|
|
91
|
-
stub_request(:get, url)
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
url << '?' << params.map { |k, v| "#{k}=#{v}" }.join('&') if params
|
|
100
|
+
stub_request(:get, url)
|
|
101
|
+
.to_return(body: f.read,
|
|
102
|
+
headers: { 'Content-Type' => 'application/json',
|
|
103
|
+
'Transfer-Encoding' => 'chunked' })
|
|
104
|
+
end.close
|
|
94
105
|
end
|
|
95
106
|
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.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Splunk Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2019-03-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: fluentd
|
|
@@ -16,102 +16,102 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1.
|
|
19
|
+
version: '1.3'
|
|
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.
|
|
26
|
+
version: '1.3'
|
|
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: '
|
|
33
|
+
version: '4.2'
|
|
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: '
|
|
40
|
+
version: '4.2'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: bundler
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
47
|
+
version: '2.0'
|
|
48
48
|
type: :development
|
|
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: '2.0'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
56
|
+
name: minitest
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '5.11'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
68
|
+
version: '5.11'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
70
|
+
name: rake
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '3
|
|
75
|
+
version: '12.3'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '3
|
|
82
|
+
version: '12.3'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: test-unit
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
89
|
+
version: '3.3'
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
96
|
+
version: '3.3'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: webmock
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
101
|
- - "~>"
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '3.
|
|
103
|
+
version: '3.5'
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
108
|
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '3.
|
|
110
|
+
version: '3.5'
|
|
111
111
|
description: A Fluentd input plugin for collecting Kubernetes objects, e.g. pods,
|
|
112
112
|
namespaces, events, etc. by pulling or watching.
|
|
113
113
|
email:
|
|
114
|
-
-
|
|
114
|
+
- DataEdge@splunk.com
|
|
115
115
|
executables: []
|
|
116
116
|
extensions: []
|
|
117
117
|
extra_rdoc_files: []
|
|
@@ -152,8 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
152
152
|
- !ruby/object:Gem::Version
|
|
153
153
|
version: '0'
|
|
154
154
|
requirements: []
|
|
155
|
-
|
|
156
|
-
rubygems_version: 2.7.6
|
|
155
|
+
rubygems_version: 3.0.1
|
|
157
156
|
signing_key:
|
|
158
157
|
specification_version: 4
|
|
159
158
|
summary: Fluentd Plugin for Kubernetes Objects.
|