fluent-plugin-uuid2podname 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2760530a2419309be346b3d0531f020e92be9f8a35fafcd082426d5f042d59eb
4
+ data.tar.gz: 5d3a96095809d20da23eec232e162cb958ae924ee2e4fc6a82b118525cdf7002
5
+ SHA512:
6
+ metadata.gz: 655ae58ca351ae95c4c93de51d3fcea4b01b11a7934cd955338610235a277a308f7209b6b986a11cea0ea6fb822e833616ea84e999ea832ba7299c76e9333137
7
+ data.tar.gz: b6e880b4070dd6ddabe17ae77fb780b5394f86dbfaab80c944d45d5458cc27165be440d23dd6fb4798b1ce0e9fa3b5885f41487773886b33c4ddac1bc3fcd52a
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,43 @@
1
+ # fluent-plugin-uuid2podname
2
+
3
+ [Fluentd](https://fluentd.org/) filter plugin to do something.
4
+
5
+ TODO: write description for you plugin.
6
+
7
+ ## Installation
8
+
9
+ ### RubyGems
10
+
11
+ ```
12
+ $ gem install fluent-plugin-uuid2podname
13
+ ```
14
+
15
+ ### Bundler
16
+
17
+ Add following line to your Gemfile:
18
+
19
+ ```ruby
20
+ gem "fluent-plugin-uuid2podname"
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ ```
26
+ $ bundle
27
+ ```
28
+
29
+ ## Configuration
30
+
31
+ You can generate configuration template:
32
+
33
+ ```
34
+ $ fluent-plugin-config-format filter uuid2podname
35
+ ```
36
+
37
+ You can copy and paste generated documents here.
38
+
39
+ ## Copyright
40
+
41
+ * Copyright(c) 2018- SaintLiber
42
+ * License
43
+ *
@@ -0,0 +1,13 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs.push("lib", "test")
8
+ t.test_files = FileList["test/**/test_*.rb"]
9
+ t.verbose = true
10
+ t.warning = true
11
+ end
12
+
13
+ task default: [:test]
@@ -0,0 +1,27 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "fluent-plugin-uuid2podname"
6
+ spec.version = "0.0.1"
7
+ spec.authors = ["geovisor"]
8
+ spec.email = ["geovisor@163.com"]
9
+
10
+ spec.summary = "geovis.com.cn"
11
+ spec.description = "a fluent plugin by geovisor"
12
+ spec.homepage = "http://geovis.com.cn"
13
+ spec.license = ""
14
+
15
+ test_files, files = `git ls-files -z`.split("\x0").partition do |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ end
18
+ spec.files = files
19
+ spec.executables = files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = test_files
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.14"
24
+ spec.add_development_dependency "rake", "~> 12.0"
25
+ spec.add_development_dependency "test-unit", "~> 3.0"
26
+ spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
27
+ end
@@ -0,0 +1,195 @@
1
+
2
+
3
+ require "fluent/plugin/filter"
4
+
5
+ module Fluent
6
+ module Plugin
7
+ class Uuid2podnameFilter < Fluent::Plugin::Filter
8
+ Fluent::Plugin.register_filter("uuid2podname", self)
9
+
10
+ K8_POD_CA_CERT = 'ca.crt'
11
+ K8_POD_TOKEN = 'token'
12
+ desc 'use the k8s insecure port,like 8080,if true then init the http kubeclient'
13
+ config_param :insecure, :bool, default: false
14
+ desc 'the kube-apiserver restful url'
15
+ config_param :kubernetes_url, :string, default: nil
16
+ desc 'the k8s serviceAccount for comunicating with kube-apiserver'
17
+ config_param :secret_dir, :string, default: '/var/run/secrets/kubernetes.io/serviceaccount'
18
+
19
+ config_param :apiVersion, :string, default: 'v1'
20
+ config_param :client_cert, :string, default: nil
21
+ config_param :client_key, :string, default: nil
22
+ config_param :ca_file, :string, default: nil
23
+ config_param :verify_ssl, :bool, default: true
24
+ config_param :bearer_token_file, :string, default: nil
25
+
26
+ def configure(conf)
27
+ super
28
+
29
+ def log.trace?
30
+ level == Fluent::Log::LEVEL_TRACE
31
+ end
32
+ require 'kubeclient'
33
+
34
+ log.debug "Uuid2podname Filter configure"
35
+
36
+ # Use Kubernetes default service account if we're in a pod.
37
+ if @kubernetes_url.nil?
38
+ log.debug "Kubernetes URL is not set - inspecting environment"
39
+
40
+ env_host = ENV['KUBERNETES_SERVICE_HOST']
41
+ env_port = ENV['KUBERNETES_SERVICE_PORT']
42
+ if !env_host.nil? && !env_port.nil?
43
+ if insecure
44
+ @kubernetes_url = "http://#{env_host}:#{env_port}/api"
45
+ else
46
+ @kubernetes_url = "https://#{env_host}:#{env_port}/api"
47
+ end
48
+ log.debug "Kubernetes URL is now '#{@kubernetes_url}'"
49
+ end
50
+ end
51
+
52
+ # Use SSL certificate and bearer token from Kubernetes service account.
53
+ if Dir.exist?(@secret_dir)
54
+ log.debug "Found directory with secrets: #{@secret_dir}"
55
+ ca_cert = File.join(@secret_dir, K8_POD_CA_CERT)
56
+ pod_token = File.join(@secret_dir, K8_POD_TOKEN)
57
+
58
+ if @ca_file.nil? and File.exist?(ca_cert)
59
+ log.debug "Found CA certificate: #{ca_cert}"
60
+ @ca_file = ca_cert
61
+ end
62
+
63
+ if @bearer_token_file.nil? and File.exist?(pod_token)
64
+ log.debug "Found pod token: #{pod_token}"
65
+ @bearer_token_file = pod_token
66
+ end
67
+ end
68
+
69
+ if !@kubernetes_url.nil?
70
+ if insecure
71
+ log.debug "Creating insecure K8S client"
72
+ @client = Kubeclient::Client.new @kubernetes_url, @apiVersion
73
+ else
74
+ ssl_options = {
75
+ client_cert: !@client_cert.nil? ? OpenSSL::X509::Certificate.new(File.read(@client_cert)) : nil,
76
+ client_key: !@client_key.nil? ? OpenSSL::PKey::RSA.new(File.read(@client_key)) : nil,
77
+ ca_file: @ca_file,
78
+ verify_ssl: @verify_ssl ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
79
+ }
80
+
81
+ auth_options = {}
82
+
83
+ if !@bearer_token_file.nil?
84
+ bearer_token = File.read(@bearer_token_file)
85
+ auth_options[:bearer_token] = bearer_token
86
+ end
87
+
88
+ log.debug "Creating secure K8S client"
89
+ @client = Kubeclient::Client.new @kubernetes_url, @apiVersion,
90
+ ssl_options: ssl_options,
91
+ auth_options: auth_options
92
+ end
93
+
94
+ begin
95
+ @client.api_valid?
96
+ rescue KubeException => kube_error
97
+ raise Fluent::ConfigError, "Invalid Kubernetes API #{@apiVersion} endpoint #{@kubernetes_url}: #{kube_error.message}"
98
+ end
99
+ @podsHash = {}
100
+ fetch_pods
101
+ end
102
+ end
103
+
104
+ def filter_stream(tag, es)
105
+ log.debug "Uuid2podname Filter filter"
106
+ return es if (es.respond_to?(:empty?) && es.empty?) || !es.is_a?(Fluent::EventStream)
107
+ new_es = Fluent::MultiEventStream.new
108
+ es.each do |time, record|
109
+ metadata = nil
110
+ if @podsHash.has_key?(record['uuid'])
111
+ metadata = @podsHash[record['uuid']]
112
+ log.debug "find pod for uuid: #{record['uuid']}"
113
+ else
114
+ fetch_pods
115
+ if @podsHash.has_key?(record['uuid'])
116
+ metadata = @podsHash[record['uuid']]
117
+ else
118
+ log.error "pod does not exist: #{record['uuid']}"
119
+ end
120
+ end
121
+ record = record.merge(metadata) if metadata
122
+ new_es.add(time, record)
123
+ end
124
+
125
+ new_es
126
+ end
127
+
128
+ def fetch_pods()
129
+ log.debug "Uuid2podname Filter fetch_pods"
130
+ newPodsHash = {}
131
+ @client.get_pods.each do |pod_object|
132
+ kubernetes_metadata = parse_pod_metadata(pod_object)
133
+ newPodsHash[kubernetes_metadata['kubernetes']['pod_id']] = kubernetes_metadata
134
+ end
135
+ @podsHash = newPodsHash.merge @podsHash
136
+ end
137
+
138
+ def parse_pod_metadata(pod_object)
139
+ labels = syms_to_strs(pod_object['metadata']['labels'].to_h)
140
+ if @de_dot
141
+ self.de_dot!(labels)
142
+ self.de_dot!(annotations)
143
+ end
144
+
145
+ # collect container informations
146
+ container_meta = {}
147
+ begin
148
+ pod_object['status']['containerStatuses'].each do|container_status|
149
+ # get plain container id (eg. docker://hash -> hash)
150
+ container_id = container_status['containerID'].sub /^[-_a-zA-Z0-9]+:\/\//, ''
151
+ container_meta[container_id] = {
152
+ 'name' => container_status['name'],
153
+ 'image' => container_status['image'],
154
+ 'image_id' => container_status['imageID']
155
+ }
156
+ end
157
+ rescue
158
+ log.debug("parsing container meta information failed for: #{pod_object['metadata']['namespace']}/#{pod_object['metadata']['name']} ")
159
+ end
160
+
161
+ kubernetes_metadata = {
162
+ 'namespace_name' => pod_object['metadata']['namespace'],
163
+ 'pod_id' => pod_object['metadata']['uid'],
164
+ 'pod_name' => pod_object['metadata']['name'],
165
+ 'containers' => syms_to_strs(container_meta),
166
+ 'labels' => labels,
167
+ 'host' => pod_object['spec']['nodeName'],
168
+ 'master_url' => @kubernetes_url
169
+ }
170
+ metadata = {
171
+ 'kubernetes' => kubernetes_metadata
172
+ }
173
+ return metadata
174
+ end
175
+
176
+ def syms_to_strs(hsh)
177
+ newhsh = {}
178
+ hsh.each_pair do |kk,vv|
179
+ if vv.is_a?(Hash)
180
+ vv = syms_to_strs(vv)
181
+ end
182
+ if kk.is_a?(Symbol)
183
+ newhsh[kk.to_s] = vv
184
+ else
185
+ newhsh[kk] = vv
186
+ end
187
+ end
188
+ newhsh
189
+ end
190
+
191
+ end
192
+ end
193
+ end
194
+
195
+
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift(File.expand_path("../../", __FILE__))
2
+ require "test-unit"
3
+ require "fluent/test"
4
+ require "fluent/test/driver/filter"
5
+ require "fluent/test/helpers"
6
+
7
+ Test::Unit::TestCase.include(Fluent::Test::Helpers)
8
+ Test::Unit::TestCase.extend(Fluent::Test::Helpers)
@@ -0,0 +1,18 @@
1
+ require "helper"
2
+ require "fluent/plugin/filter_uuid2podname.rb"
3
+
4
+ class Uuid2podnameFilterTest < Test::Unit::TestCase
5
+ setup do
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ test "failure" do
10
+ flunk
11
+ end
12
+
13
+ private
14
+
15
+ def create_driver(conf)
16
+ Fluent::Test::Driver::Filter.new(Fluent::Plugin::Uuid2podnameFilter).configure(conf)
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-uuid2podname
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - geovisor
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: test-unit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fluentd
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.14.10
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '2'
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 0.14.10
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '2'
75
+ description: a fluent plugin by geovisor
76
+ email:
77
+ - geovisor@163.com
78
+ executables: []
79
+ extensions: []
80
+ extra_rdoc_files: []
81
+ files:
82
+ - Gemfile
83
+ - README.md
84
+ - Rakefile
85
+ - fluent-plugin-uuid2podname.gemspec
86
+ - lib/fluent/plugin/filter_uuid2podname.rb
87
+ - test/helper.rb
88
+ - test/plugin/test_filter_uuid2podname.rb
89
+ homepage: http://geovis.com.cn
90
+ licenses:
91
+ - ''
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.7.8
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: geovis.com.cn
113
+ test_files:
114
+ - test/helper.rb
115
+ - test/plugin/test_filter_uuid2podname.rb