fluent-plugin-label-router 0.2.0 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +7 -5
- data/fluent-plugin-label-router.gemspec +1 -1
- data/lib/fluent/plugin/out_label_router.rb +33 -15
- data/test/plugin/test_out_label_router.rb +31 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2c9fe1a41256dc29a1a7ff87833cfb6f7f4ca6e4ab330b185aa85f66e0e35b3
|
4
|
+
data.tar.gz: 2440249e93baffc3de72dd31fe70ef6d83ce5f4832b9af615a338bb855489cb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fc6928ca8716774f8291eb013b737f31d2e6d02b34dee5d473ae644c7898aa8145aca73b3691c9ed4520165d3ee19f63da7dee72d48dc1b416c4fd54e45e79f
|
7
|
+
data.tar.gz: cc9afbd8db7ac5c1f10001c6bc91403eb9961b529773f210f3c9b2ac7bf877c792a10e18f6b04cec5b1526762238b3f081f51cce08b4d4a867ebba63f28030d7
|
data/README.md
CHANGED
@@ -74,11 +74,13 @@ Configuration reference
|
|
74
74
|
|
75
75
|
|
76
76
|
#### \<match\>
|
77
|
-
| Parameter
|
78
|
-
|
79
|
-
| labels
|
80
|
-
| namespaces
|
81
|
-
|
|
77
|
+
| Parameter | Description | Type | Default |
|
78
|
+
|-----------------|-------------------------------------------------------------------------------|----------|----------|
|
79
|
+
| labels | Label definition to match record. Example: `app:nginx` | Hash | nil |
|
80
|
+
| namespaces | Comma separated list of namespaces. Ignored if left empty. | []string | nil |
|
81
|
+
| hosts | Comma separated list of hosts. Ignored if left empty. | []string | nil |
|
82
|
+
| container_names | Comma separated list of container names. Ignored if left empty. | []string | nil |
|
83
|
+
| negate | Negate the selector meaning to exclude matches | bool | false |
|
82
84
|
|
83
85
|
## Rules of thumb
|
84
86
|
|
@@ -41,11 +41,15 @@ module Fluent
|
|
41
41
|
desc "New tag if selectors matched"
|
42
42
|
config_param :tag, :string, :default => ""
|
43
43
|
|
44
|
-
config_section :match, param_name: :
|
44
|
+
config_section :match, param_name: :matches, multi: true do
|
45
45
|
desc "Label definition to match record. Example: app:nginx. You can specify more values as comma separated list: key1:value1,key2:value2"
|
46
46
|
config_param :labels, :hash, :default => {}
|
47
47
|
desc "List of namespace definition to filter the record. Ignored if left empty."
|
48
48
|
config_param :namespaces, :array, :default => [], value_type: :string
|
49
|
+
desc "List of hosts definition to filter the record. Ignored if left empty."
|
50
|
+
config_param :hosts, :array, :default => [], value_type: :string
|
51
|
+
desc "List of container names definition to filter the record. Ignored if left empty."
|
52
|
+
config_param :container_names, :array, :default => [], value_type: :string
|
49
53
|
desc "Negate the selection making it an exclude"
|
50
54
|
config_param :negate, :bool, :default => false
|
51
55
|
end
|
@@ -55,9 +59,9 @@ module Fluent
|
|
55
59
|
|
56
60
|
|
57
61
|
class Route
|
58
|
-
def initialize(
|
62
|
+
def initialize(matches, tag, router)
|
59
63
|
@router = router
|
60
|
-
@
|
64
|
+
@matches = matches
|
61
65
|
@tag = tag
|
62
66
|
end
|
63
67
|
|
@@ -68,12 +72,12 @@ module Fluent
|
|
68
72
|
# 3. If match == false and negate == false -> continue
|
69
73
|
# 4. If match == false and negate == true -> continue
|
70
74
|
# There is no match at all -> return false
|
71
|
-
def match?(
|
72
|
-
@
|
73
|
-
if
|
75
|
+
def match?(metadata)
|
76
|
+
@matches.each do |match|
|
77
|
+
if filter_select(match, metadata) and !match.negate
|
74
78
|
return true
|
75
79
|
end
|
76
|
-
if
|
80
|
+
if filter_select(match, metadata) and match.negate
|
77
81
|
return false
|
78
82
|
end
|
79
83
|
end
|
@@ -81,12 +85,21 @@ module Fluent
|
|
81
85
|
end
|
82
86
|
|
83
87
|
# Returns true if filter passes (filter match)
|
84
|
-
def filter_select(
|
88
|
+
def filter_select(match, metadata)
|
89
|
+
# Break on container_name mismatch
|
90
|
+
unless match.hosts.empty? || match.hosts.include?(metadata[:host])
|
91
|
+
return false
|
92
|
+
end
|
93
|
+
# Break on host mismatch
|
94
|
+
unless match.container_names.empty? || match.container_names.include?(metadata[:container_name])
|
95
|
+
return false
|
96
|
+
end
|
85
97
|
# Break if list of namespaces is not empty and does not include actual namespace
|
86
|
-
unless
|
98
|
+
unless match.namespaces.empty? || match.namespaces.include?(metadata[:namespace])
|
87
99
|
return false
|
88
100
|
end
|
89
|
-
|
101
|
+
|
102
|
+
match_labels(metadata[:labels], match.labels)
|
90
103
|
end
|
91
104
|
|
92
105
|
def emit(tag, time, record)
|
@@ -104,8 +117,9 @@ module Fluent
|
|
104
117
|
@router.emit_stream(@tag, es)
|
105
118
|
end
|
106
119
|
end
|
120
|
+
|
107
121
|
def match_labels(input, match)
|
108
|
-
|
122
|
+
(match.to_a - input.to_a).empty?
|
109
123
|
end
|
110
124
|
end
|
111
125
|
|
@@ -121,11 +135,13 @@ module Fluent
|
|
121
135
|
end
|
122
136
|
event_stream = Hash.new {|h, k| h[k] = Fluent::MultiEventStream.new }
|
123
137
|
es.each do |time, record|
|
124
|
-
|
125
|
-
|
138
|
+
input_metadata = { labels: @access_to_labels.call(record).to_h,
|
139
|
+
namespace: @access_to_namespace.call(record).to_s,
|
140
|
+
container: @access_to_container_name.call(record).to_s,
|
141
|
+
host: @access_to_host.call(record).to_s}
|
126
142
|
orphan_record = true
|
127
143
|
@routers.each do |r|
|
128
|
-
if r.match?(
|
144
|
+
if r.match?(input_metadata)
|
129
145
|
orphan_record = false
|
130
146
|
if @sticky_tags
|
131
147
|
@route_map[tag].push(r)
|
@@ -163,7 +179,7 @@ module Fluent
|
|
163
179
|
@routes.each do |rule|
|
164
180
|
route_router = event_emitter_router(rule['@label'])
|
165
181
|
puts rule
|
166
|
-
@routers << Route.new(rule.
|
182
|
+
@routers << Route.new(rule.matches, rule.tag.to_s, route_router)
|
167
183
|
end
|
168
184
|
|
169
185
|
if @default_route != '' or @default_tag != ''
|
@@ -172,6 +188,8 @@ module Fluent
|
|
172
188
|
|
173
189
|
@access_to_labels = record_accessor_create("$.kubernetes.labels")
|
174
190
|
@access_to_namespace = record_accessor_create("$.kubernetes.namespace_name")
|
191
|
+
@access_to_host = record_accessor_create("$.kubernetes.host")
|
192
|
+
@access_to_container_name = record_accessor_create("$.kubernetes.container_name")
|
175
193
|
|
176
194
|
@batch = @emit_mode == :batch
|
177
195
|
end
|
@@ -65,29 +65,47 @@ class LabelRouterOutputTest < Test::Unit::TestCase
|
|
65
65
|
namespaces dev,sandbox
|
66
66
|
</match>
|
67
67
|
</route>
|
68
|
+
<route>
|
69
|
+
<match>
|
70
|
+
labels app:nginx
|
71
|
+
namespaces dev,sandbox
|
72
|
+
container_names mycontainer
|
73
|
+
</match>
|
74
|
+
</route>
|
68
75
|
)
|
69
76
|
d = Fluent::Test::Driver::BaseOwner.new(Fluent::Plugin::LabelRouterOutput)
|
70
77
|
d.configure(routing_conf)
|
71
78
|
|
72
|
-
r1 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[0].
|
79
|
+
r1 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[0].matches, d.instance.routes[0].tag,nil)
|
73
80
|
# Selector matched: GO
|
74
|
-
assert_equal(true, r1.match?({'app' => 'app1'},
|
81
|
+
assert_equal(true, r1.match?(labels: { 'app' => 'app1' }, namespace: ''))
|
75
82
|
# Exclude match: NO GO
|
76
|
-
assert_equal(false, r1.match?({
|
83
|
+
assert_equal(false, r1.match?(labels: { 'app' => 'app2' }, namespace: ''))
|
77
84
|
# Nothing matched: NO GO
|
78
|
-
assert_equal(false, r1.match?({
|
85
|
+
assert_equal(false, r1.match?(labels: { 'app3' => 'app2' }, namespace: ''))
|
79
86
|
|
80
|
-
r2 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[1].
|
87
|
+
r2 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[1].matches, d.instance.routes[1].tag,nil)
|
81
88
|
# Match selector and namespace: GO
|
82
|
-
assert_equal(true, r2.match?({
|
89
|
+
assert_equal(true, r2.match?(labels: { 'app' => 'app1' }, namespace: 'test'))
|
83
90
|
# Exclude via namespace
|
84
|
-
assert_equal(false, r2.match?({
|
91
|
+
assert_equal(false, r2.match?(labels: { 'app' => 'app2' }, namespace: 'system'))
|
85
92
|
# Nothing matched: NO GO
|
86
|
-
assert_equal(false, r2.match?({
|
93
|
+
assert_equal(false, r2.match?(labels: { 'app3' => 'app' }, namespace: 'system'))
|
94
|
+
|
95
|
+
r3 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[2].matches, d.instance.routes[2].tag,nil)
|
96
|
+
assert_equal(true, r3.match?(labels: { 'app' => 'nginx' }, namespace: 'dev'))
|
97
|
+
assert_equal(true, r3.match?(labels: { 'app' => 'nginx' }, namespace: 'sandbox'))
|
98
|
+
assert_equal(false, r3.match?(labels: { 'app' => 'nginx2' }, namespace: 'sandbox'))
|
87
99
|
|
88
|
-
|
89
|
-
|
90
|
-
assert_equal(true,
|
100
|
+
r4 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[3].matches, d.instance.routes[3].tag,nil)
|
101
|
+
# Matching container name
|
102
|
+
assert_equal(true, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'dev', container_name: 'mycontainer'))
|
103
|
+
# Missing container name is equal to wrong container
|
104
|
+
assert_equal(false, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'sandbox'))
|
105
|
+
# Wrong container name
|
106
|
+
assert_equal(false, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'dev', container_name: 'mycontainer2'))
|
107
|
+
# Wrong label but good namespace and container_name
|
108
|
+
assert_equal(false, r4.match?(labels: { 'app' => 'nginx2' }, namespace: 'sandbox', container_name: 'mycontainer2'))
|
91
109
|
end
|
92
110
|
end
|
93
111
|
|
@@ -146,7 +164,7 @@ default_tag "new_tag"
|
|
146
164
|
|
147
165
|
sub_test_case 'test_empty_router' do
|
148
166
|
test 'normal' do
|
149
|
-
|
167
|
+
CONFIG3 = %[
|
150
168
|
<route>
|
151
169
|
tag new_app_tag
|
152
170
|
<match>
|
@@ -156,7 +174,7 @@ default_tag "new_tag"
|
|
156
174
|
</route>
|
157
175
|
]
|
158
176
|
event_time = event_time("2019-07-17 11:11:11 UTC")
|
159
|
-
d = create_driver(
|
177
|
+
d = create_driver(CONFIG3)
|
160
178
|
d.run(default_tag: 'test') do
|
161
179
|
d.feed(event_time, {"kubernetes" => {"labels" => {"app" => "app1"} } } )
|
162
180
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-label-router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Banzai Cloud
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|