fluentd-plugin-annotation-filter 1.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: 1768b27d7704200041610300fc039585b4375ca418d561f0396fe6283aac37d8
4
+ data.tar.gz: ca5091f841efcc2e01d9d25f2ddd72b624d974da1e1f7dfd8c568bf8dfad7d51
5
+ SHA512:
6
+ metadata.gz: 1c61d281421542d367272a98ede9480f9cb5ac9d8cb21d333ea4e598c662bd4721a5a0e8dc061c3c6c0c31d3773289abf5069fe37eb4fcccdbe534668482238f
7
+ data.tar.gz: f04505e998d45e85952aa84979245accf314f6c11a7d6a2319033949021c940afef018fc74e69ba10f604b3a245c3bbed6f27270c204a68d8244e4e70da92f37
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,124 @@
1
+ # Fluentd Plugin: Kubernetes Annotation Filter
2
+
3
+ Checks whether the container name is included in an annotation on the pod that is the source of a log entry.
4
+
5
+ ## Development
6
+
7
+ ### Running Locally
8
+
9
+ It can be a bit of a challenge to get fluentd running locally for "poke-it-and-see" style testing. One approach is to:
10
+
11
+ 1. Get a docker container with fluentd in it
12
+ 1. Create an `app/plugins` directory
13
+ 1. Copy `lib/fluent/plugin/*` from this repository into that directory
14
+ 1. Create a fluentd configuration that uses this plugin, taking input from a file in the `/app` directory. An example
15
+ configuration can be found at [example/fluentd-test.conf](example/fluentd-test.conf).
16
+ 1. Run the container
17
+ 1. Put your test lines into the file
18
+ 1. Watch the output
19
+
20
+ This is not a particularly nice way to develop anything, but it does _work_. You'll then need to copy the modified
21
+ source code _back_ into this repository.
22
+
23
+ ### Tests
24
+
25
+ You can run tests locally with:
26
+
27
+ ```
28
+ > rspec
29
+ ```
30
+
31
+ Or in docker with:
32
+
33
+ ```
34
+ > make test
35
+ ```
36
+
37
+ The tests are written using Fluent's [Test Driver](https://docs.fluentd.org/plugin-development/plugin-test-code); this
38
+ requires the `test-unit` gem be included (for some helper methods we're not using) in addition to `rspec`, which is
39
+ actually used to run the tests (in accordance with what all the rest of DRE's Ruby code uses).
40
+
41
+ ## Operations
42
+
43
+ ### Installation
44
+
45
+ Add the following to your Gemfile:
46
+
47
+ ```ruby
48
+ gem 'fluent-plugin-kubernetes-annotations-filter
49
+ ```
50
+
51
+ ### Dependencies
52
+
53
+ This plugin relies on _Kubernetes metadata_ being available on log records. This metadata can be obtained by use of the
54
+ [kuberenetes_metadata_filter](https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter) plugin.
55
+
56
+ Specifically, this plugin relies on the following fields:
57
+
58
+ | Field | Content |
59
+ |-----------------------------|----------------------------------------------------------------|
60
+ | `kubernetes.container_name` | The name of the container the record was emitted from |
61
+ | `kubernetes.annotations` | The annotations applied to the pod the record was emitted from |
62
+
63
+ ### Configuration
64
+
65
+ An example configuration could look like:
66
+
67
+ ```
68
+ <filter camelid>
69
+ @type kubernetes_annotation
70
+
71
+ <contains_container_name>
72
+ annotation dromedary
73
+ </contains_container_name>
74
+ </filter>
75
+ ```
76
+
77
+ This would look for the value of `kubernetes.container_name` in the `kubernetes.annotations.dromedary` field of records
78
+ tagged "camelid"; for example, these records would be allowed to pass through the filter:
79
+
80
+ ```
81
+ {"message": "hi", "kubernetes": {"containter_name": "beluga", ..., "annotations": { "dromedary": "[\"beluga\"]" } } }
82
+ {"message": "wat", "kubernetes": {"containter_name": "humpback", ..., "annotations": { "dromedary": "[\"minke\", \"humpback\"]" } } }
83
+ ```
84
+
85
+ but these ones would not:
86
+
87
+ ```
88
+ {"message": "hi", "kubernetes": {"containter_name": "pelican", ..., "annotations": { "dromedary": "[\"minke\", \"humpback\"]" } } }
89
+ {"message": "wat", "kubernetes": {"containter_name": "gannet", ..., "annotations": { } } }
90
+ ```
91
+
92
+ Note that the value of the provided annotation is expected to be a _JSON array_ inside a string (this appears to be the
93
+ way people suggest encoding data of this kind).
94
+
95
+ The `pass_through_events_without_kubernetes_tags` option can be used to control whether objects without Kubernetes tags
96
+ are passed through the filter or dropped. It defaults to `false`.
97
+
98
+ ## Maintainers
99
+
100
+ delivery-engineers@redbubble.com
101
+
102
+ fluentd-plugin-annotation-filter
103
+
104
+ Copyright (c) Redbubble
105
+
106
+ Permission is hereby granted, free of charge, to any person obtaining
107
+ a copy of this software and associated documentation files (the
108
+ "Software"), to deal in the Software without restriction, including
109
+ without limitation the rights to use, copy, modify, merge, publish,
110
+ distribute, sublicense, and/or sell copies of the Software, and to
111
+ permit persons to whom the Software is furnished to do so, subject to
112
+ the following conditions:
113
+
114
+ The above copyright notice and this permission notice shall be included
115
+ in all copies or substantial portions of the Software.
116
+
117
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
118
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
119
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
120
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
121
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
122
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
123
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
124
+
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "fluentd-plugin-annotation-filter"
7
+ gem.version = ENV["VERSION"]
8
+ gem.authors = ["Delivery Engineering"]
9
+ gem.email = ["delivery-engineers@redbubble.com"]
10
+ gem.description = %q{Fluentd plugin to filter based on Kubernetes annotations}
11
+ gem.summary = %q{A filter plugin to drop log entries without the right set of Kubernetes annotations}
12
+ gem.homepage = "https://github.com/redbubble/fluentd-plugin-annotation-filter"
13
+ gem.license = "MIT"
14
+
15
+ gem.files = Dir['lib/**/*'] + %w(Gemfile README.md fluentd-plugin-annotation-filter.gemspec)
16
+ gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.required_ruby_version = '>= 2.5.0'
21
+
22
+ gem.add_runtime_dependency "fluentd", '~> 1.3.3', '>= 1.3.3'
23
+
24
+ gem.add_development_dependency "bundler", "~> 1.3"
25
+ gem.add_development_dependency "rspec", "~> 3.0" # Like all our other Ruby projects, our tests are in RSpec
26
+ gem.add_development_dependency "test-unit", "~> 3.3" # TestUnit is, however, used by fluentd's test driver and must be included
27
+ end
@@ -0,0 +1,63 @@
1
+ require "json"
2
+ require "fluent/plugin/filter"
3
+
4
+ module Fluent
5
+ module Plugin
6
+ class KubernetesAnnotationFilter < Filter
7
+ Fluent::Plugin.register_filter("kubernetes_annotation", self)
8
+
9
+ attr_reader :containing_annotations
10
+
11
+ def initialize
12
+ super
13
+ end
14
+
15
+ config_param :pass_through_events_without_kubernetes_tags, :bool, default: false
16
+
17
+ config_section :contains_container_name, param_name: :contains_sections, multi: true do
18
+ desc "The name of the Kuberntes annotation that must contain the value in the value field"
19
+ config_param :annotation, :string
20
+ end
21
+
22
+ def configure(conf)
23
+ super
24
+
25
+ @containing_annotations = @contains_sections.map(&:annotation)
26
+ end
27
+
28
+ def filter(_, _, record)
29
+ begin
30
+ if(record.has_key?("kubernetes") && record["kubernetes"].has_key?("annotations"))
31
+ unless annotations_contain_container_name?(record)
32
+ return nil
33
+ end
34
+ elsif(!@pass_through_events_without_kubernetes_tags)
35
+ return nil
36
+ end
37
+
38
+ rescue => e
39
+ log.warn "failed to filter by kubernetes annotation", error: e
40
+ log.warn_backtrace
41
+ end
42
+
43
+ return record
44
+ end
45
+
46
+ private
47
+
48
+ def annotations_contain_container_name?(record)
49
+ return false if containing_annotations.size == 0
50
+
51
+ container_name = record['kubernetes']['container_name']
52
+
53
+ containing_annotations.all? { |annotation|
54
+ content = record["kubernetes"]["annotations"][annotation]
55
+
56
+ if(content)
57
+ JSON.parse(content)&.include?(container_name)
58
+ end
59
+ }
60
+ end
61
+ end
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluentd-plugin-annotation-filter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Delivery Engineering
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-11-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.3
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: 1.3.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.3.3
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: 1.3.3
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.3'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.3'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: test-unit
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.3'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.3'
75
+ description: Fluentd plugin to filter based on Kubernetes annotations
76
+ email:
77
+ - delivery-engineers@redbubble.com
78
+ executables: []
79
+ extensions: []
80
+ extra_rdoc_files: []
81
+ files:
82
+ - Gemfile
83
+ - README.md
84
+ - fluentd-plugin-annotation-filter.gemspec
85
+ - lib/fluent/plugin/filter-kubernetes-annotation.rb
86
+ homepage: https://github.com/redbubble/fluentd-plugin-annotation-filter
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 2.5.0
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubygems_version: 3.0.3
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: A filter plugin to drop log entries without the right set of Kubernetes annotations
109
+ test_files: []