fluent-plugin-uuid2podname 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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