fluent-plugin-s3 1.7.0 → 1.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +10 -0
- data/VERSION +1 -1
- data/docs/howto.md +1 -1
- data/docs/input.md +9 -0
- data/docs/output.md +8 -0
- data/lib/fluent/plugin/in_s3.rb +29 -4
- data/lib/fluent/plugin/out_s3.rb +8 -2
- data/test/test_in_s3.rb +113 -3
- 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: 1450176cd690d79412b7522ce8e67163c2f3c9c1f87941e57d6b3f3410bdf330
|
4
|
+
data.tar.gz: ee66229b8cd65ef2507feb5229d54322ed2f076e2daefb3f32e3b0e2ba47c634
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0428c1da0ef734a65d86aec878374636cf4bfd10ed2ab06578d3d8a9cc8ee607e62b4a85c05144599dec2167995dbd836b70cb7cfb66f38fc38d5e82dc1073a
|
7
|
+
data.tar.gz: bb4d7820ff8fa7fa3e58092b69fc78bb4804d92854206fb61c4efa21b415519eff682cf64763a9ec237f30f8997ab20b0b395bb8f1f17a8c88a9c63b3381b02b
|
data/ChangeLog
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
Release 1.7.2 - 2022/10/19
|
2
|
+
|
3
|
+
* in_s3: Add `event_bridge_mode` parameter
|
4
|
+
* out_s3: Fix `s3_object_key_format` check to allow `%{hex_random}` as well as `%{uuid_flush}` or `${chunk_id}`
|
5
|
+
|
6
|
+
Release 1.7.1 - 2022/07/15
|
7
|
+
|
8
|
+
* in_s3: Add `match_regexp` parameter to selectively download S3 files based on the object key
|
9
|
+
* out_s3: Support `ssl_ca_bundle` and `ssl_ca_directory` parameter
|
10
|
+
|
1
11
|
Release 1.7.0 - 2022/06/14
|
2
12
|
|
3
13
|
* in_s3: Allow multi workers
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.7.
|
1
|
+
1.7.2
|
data/docs/howto.md
CHANGED
@@ -7,7 +7,7 @@ downstream processors to better identify the source of a given record.
|
|
7
7
|
|
8
8
|
# IAM Policy
|
9
9
|
|
10
|
-
The following is an example for a IAM policy needed to write to an s3 bucket (matches my-s3bucket/logs, my-s3bucket
|
10
|
+
The following is an example for a IAM policy needed to write to an s3 bucket (matches my-s3bucket/logs, my-s3bucket/test, etc.).
|
11
11
|
|
12
12
|
{
|
13
13
|
"Version": "2012-10-17",
|
data/docs/input.md
CHANGED
@@ -18,6 +18,7 @@ See also [Configuration: credentials](credentials.md) for common comprehensive p
|
|
18
18
|
s3_bucket YOUR_S3_BUCKET_NAME
|
19
19
|
s3_region ap-northeast-1
|
20
20
|
add_object_metadata true
|
21
|
+
match_regexp production_.*
|
21
22
|
|
22
23
|
<sqs>
|
23
24
|
queue_name YOUR_SQS_QUEUE_NAME
|
@@ -28,6 +29,10 @@ See also [Configuration: credentials](credentials.md) for common comprehensive p
|
|
28
29
|
|
29
30
|
Whether or not object metadata should be added to the record. Defaults to `false`. See below for details.
|
30
31
|
|
32
|
+
## match_regexp
|
33
|
+
|
34
|
+
If provided, process the S3 object only if its keys matches the regular expression
|
35
|
+
|
31
36
|
## s3_bucket (required)
|
32
37
|
|
33
38
|
S3 bucket name.
|
@@ -96,3 +101,7 @@ The long polling interval. Default is 20.
|
|
96
101
|
### retry_error_interval
|
97
102
|
|
98
103
|
Interval to retry polling SQS if polling unsuccessful, in seconds. Default is 300.
|
104
|
+
|
105
|
+
### event_bridge_mode
|
106
|
+
When true, Amazon S3 Event Notification should be configured using the EventBridge integration. Default is false.
|
107
|
+
See [Configure S3 event notification using EventBridge](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventBridge.html) for additional information.
|
data/docs/output.md
CHANGED
@@ -81,6 +81,14 @@ This fixes the following error often seen in Windows:
|
|
81
81
|
|
82
82
|
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (Seahorse::Client::NetworkingError)
|
83
83
|
|
84
|
+
## ssl_ca_bundle
|
85
|
+
|
86
|
+
Full path to the SSL certificate authority bundle file that should be used when verifying peer certificates. If you do not pass `ssl_ca_bundle` or `ssl_ca_directory` the the system default will be used if available.
|
87
|
+
|
88
|
+
## ssl_ca_directory
|
89
|
+
|
90
|
+
Full path of the directory that contains the unbundled SSL certificate authority files for verifying peer certificates. If you do not pass `ssl_ca_bundle` or `ssl_ca_directory` the the system default will be used if available.
|
91
|
+
|
84
92
|
## ssl_verify_peer
|
85
93
|
|
86
94
|
Verify SSL certificate of the endpoint. Default is true. Set false when you want to ignore the endpoint SSL certificate.
|
data/lib/fluent/plugin/in_s3.rb
CHANGED
@@ -90,6 +90,8 @@ module Fluent::Plugin
|
|
90
90
|
config_param :check_apikey_on_start, :bool, default: true
|
91
91
|
desc "URI of proxy environment"
|
92
92
|
config_param :proxy_uri, :string, default: nil
|
93
|
+
desc "Optional RegEx to match incoming messages"
|
94
|
+
config_param :match_regexp, :regexp, default: nil
|
93
95
|
|
94
96
|
config_section :sqs, required: true, multi: false do
|
95
97
|
desc "SQS queue name"
|
@@ -108,6 +110,8 @@ module Fluent::Plugin
|
|
108
110
|
config_param :wait_time_seconds, :integer, default: 20
|
109
111
|
desc "Polling error retry interval."
|
110
112
|
config_param :retry_error_interval, :integer, default: 300
|
113
|
+
desc "Event bridge mode"
|
114
|
+
config_param :event_bridge_mode, :bool, default: false
|
111
115
|
end
|
112
116
|
|
113
117
|
desc "Tag string"
|
@@ -203,8 +207,12 @@ module Fluent::Plugin
|
|
203
207
|
begin
|
204
208
|
body = Yajl.load(message.body)
|
205
209
|
log.debug(body)
|
206
|
-
next unless body
|
207
|
-
|
210
|
+
next unless is_valid_queue(body) # skip test queue
|
211
|
+
if @match_regexp
|
212
|
+
raw_key = get_raw_key(body)
|
213
|
+
key = CGI.unescape(raw_key)
|
214
|
+
next unless @match_regexp.match?(key)
|
215
|
+
end
|
208
216
|
process(body)
|
209
217
|
rescue => e
|
210
218
|
log.warn(error: e)
|
@@ -219,6 +227,24 @@ module Fluent::Plugin
|
|
219
227
|
end
|
220
228
|
end
|
221
229
|
|
230
|
+
def is_valid_queue(body)
|
231
|
+
if @sqs.event_bridge_mode
|
232
|
+
log.debug("checking for eventbridge property")
|
233
|
+
!!body["detail"]
|
234
|
+
else
|
235
|
+
log.debug("checking for Records property")
|
236
|
+
!!body["Records"]
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def get_raw_key(body)
|
241
|
+
if @sqs.event_bridge_mode
|
242
|
+
body["detail"]["object"]["key"]
|
243
|
+
else
|
244
|
+
body["Records"].first["s3"]["object"]["key"]
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
222
248
|
def setup_credentials
|
223
249
|
options = {}
|
224
250
|
credentials_options = {}
|
@@ -311,8 +337,7 @@ module Fluent::Plugin
|
|
311
337
|
end
|
312
338
|
|
313
339
|
def process(body)
|
314
|
-
|
315
|
-
raw_key = s3["object"]["key"]
|
340
|
+
raw_key = get_raw_key(body)
|
316
341
|
key = CGI.unescape(raw_key)
|
317
342
|
|
318
343
|
io = @bucket.object(key).get.body
|
data/lib/fluent/plugin/out_s3.rb
CHANGED
@@ -97,6 +97,10 @@ module Fluent::Plugin
|
|
97
97
|
config_param :enable_dual_stack, :bool, default: false
|
98
98
|
desc "If false, the certificate of endpoint will not be verified"
|
99
99
|
config_param :ssl_verify_peer, :bool, :default => true
|
100
|
+
desc "Full path to the SSL certificate authority bundle file that should be used when verifying peer certificates. If unspecified, defaults to the system CA if available."
|
101
|
+
config_param :ssl_ca_bundle, :string, :default => nil
|
102
|
+
desc "Full path of the directory that contains the unbundled SSL certificate authority files for verifying peer certificates. If you do not pass ssl_ca_bundle or ssl_ca_directory the the system default will be used if available."
|
103
|
+
config_param :ssl_ca_directory, :string, :default => nil
|
100
104
|
desc "The format of S3 object keys"
|
101
105
|
config_param :s3_object_key_format, :string, default: "%{path}%{time_slice}_%{index}.%{file_extension}"
|
102
106
|
desc "If true, the bucket name is always left in the request URI and never moved to the host as a sub-domain"
|
@@ -249,6 +253,8 @@ module Fluent::Plugin
|
|
249
253
|
options[:compute_checksums] = @compute_checksums unless @compute_checksums.nil?
|
250
254
|
options[:signature_version] = @signature_version unless @signature_version.nil?
|
251
255
|
options[:ssl_verify_peer] = @ssl_verify_peer
|
256
|
+
options[:ssl_ca_bundle] = @ssl_ca_bundle if @ssl_ca_bundle
|
257
|
+
options[:ssl_ca_directory] = @ssl_ca_directory if @ssl_ca_directory
|
252
258
|
log.on_trace do
|
253
259
|
options[:http_wire_trace] = true
|
254
260
|
options[:logger] = log
|
@@ -465,8 +471,8 @@ module Fluent::Plugin
|
|
465
471
|
end
|
466
472
|
|
467
473
|
is_working_on_parallel = @buffer_config.flush_thread_count > 1 || system_config.workers > 1
|
468
|
-
if is_working_on_parallel && ['${chunk_id}', '%{uuid_flush}'].none? { |key| @s3_object_key_format.include?(key) }
|
469
|
-
log.warn "No ${chunk_id} or %{
|
474
|
+
if is_working_on_parallel && ['${chunk_id}', '%{uuid_flush}', '%{hex_random}'].none? { |key| @s3_object_key_format.include?(key) }
|
475
|
+
log.warn "No ${chunk_id}, %{uuid_flush} or %{hex_random} in s3_object_key_format with multiple flush threads or multiple workers. Recommend to set ${chunk_id}, %{uuid_flush} or %{hex_random} to avoid data lost by object conflict"
|
470
476
|
end
|
471
477
|
end
|
472
478
|
|
data/test/test_in_s3.rb
CHANGED
@@ -166,9 +166,9 @@ buffer_type memory
|
|
166
166
|
aws_key_id sqs_test_key_id
|
167
167
|
</sqs>
|
168
168
|
EOS
|
169
|
-
|
170
|
-
|
171
|
-
|
169
|
+
create_driver(conf)
|
170
|
+
}
|
171
|
+
end
|
172
172
|
|
173
173
|
def test_sqs_with_invalid_aws_keys_missing_key_id
|
174
174
|
assert_raise(Fluent::ConfigError, "sqs/aws_key_id or sqs/aws_sec_key is missing") {
|
@@ -613,4 +613,114 @@ EOS
|
|
613
613
|
]
|
614
614
|
assert_equal(expected_records, events.map {|_tag, _time, record| record })
|
615
615
|
end
|
616
|
+
|
617
|
+
def test_regexp_matching
|
618
|
+
setup_mocks
|
619
|
+
d = create_driver(CONFIG + "\ncheck_apikey_on_start false\nstore_as text\nformat none\nmatch_regexp .*_key?")
|
620
|
+
|
621
|
+
s3_object = stub(Object.new)
|
622
|
+
s3_response = stub(Object.new)
|
623
|
+
s3_response.body { StringIO.new("aaa bbb ccc") }
|
624
|
+
s3_object.get { s3_response }
|
625
|
+
@s3_bucket.object(anything).at_least(1) { s3_object }
|
626
|
+
|
627
|
+
body = {
|
628
|
+
"Records" => [
|
629
|
+
{
|
630
|
+
"s3" => {
|
631
|
+
"object" => {
|
632
|
+
"key" => "test_key"
|
633
|
+
}
|
634
|
+
}
|
635
|
+
}
|
636
|
+
]
|
637
|
+
}
|
638
|
+
message = Struct::StubMessage.new(1, 1, Yajl.dump(body))
|
639
|
+
@sqs_poller.get_messages(anything, anything) do |config, stats|
|
640
|
+
config.before_request.call(stats) if config.before_request
|
641
|
+
stats.request_count += 1
|
642
|
+
if stats.request_count >= 1
|
643
|
+
d.instance.instance_variable_set(:@running, false)
|
644
|
+
end
|
645
|
+
[message]
|
646
|
+
end
|
647
|
+
d.run(expect_emits: 1)
|
648
|
+
events = d.events
|
649
|
+
assert_equal({ "message" => "aaa bbb ccc" }, events.first[2])
|
650
|
+
end
|
651
|
+
|
652
|
+
def test_regexp_not_matching
|
653
|
+
setup_mocks
|
654
|
+
d = create_driver(CONFIG + "\ncheck_apikey_on_start false\nstore_as text\nformat none\nmatch_regexp live?_key")
|
655
|
+
|
656
|
+
body = {
|
657
|
+
"Records" => [
|
658
|
+
{
|
659
|
+
"s3" => {
|
660
|
+
"object" => {
|
661
|
+
"key" => "test_key"
|
662
|
+
}
|
663
|
+
}
|
664
|
+
}
|
665
|
+
]
|
666
|
+
}
|
667
|
+
message = Struct::StubMessage.new(1, 1, Yajl.dump(body))
|
668
|
+
@sqs_poller.get_messages(anything, anything) do |config, stats|
|
669
|
+
config.before_request.call(stats) if config.before_request
|
670
|
+
stats.request_count += 1
|
671
|
+
if stats.request_count >= 1
|
672
|
+
d.instance.instance_variable_set(:@running, false)
|
673
|
+
end
|
674
|
+
[message]
|
675
|
+
end
|
676
|
+
assert_nothing_raised do
|
677
|
+
d.run {}
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
def test_event_bridge_mode
|
682
|
+
setup_mocks
|
683
|
+
d = create_driver("
|
684
|
+
aws_key_id test_key_id
|
685
|
+
aws_sec_key test_sec_key
|
686
|
+
s3_bucket test_bucket
|
687
|
+
buffer_type memory
|
688
|
+
check_apikey_on_start false
|
689
|
+
store_as text
|
690
|
+
format none
|
691
|
+
<sqs>
|
692
|
+
event_bridge_mode true
|
693
|
+
queue_name test_queue
|
694
|
+
queue_owner_aws_account_id 123456789123
|
695
|
+
</sqs>
|
696
|
+
")
|
697
|
+
|
698
|
+
s3_object = stub(Object.new)
|
699
|
+
s3_response = stub(Object.new)
|
700
|
+
s3_response.body { StringIO.new("aaa") }
|
701
|
+
s3_object.get { s3_response }
|
702
|
+
@s3_bucket.object(anything).at_least(1) { s3_object }
|
703
|
+
|
704
|
+
body = {
|
705
|
+
"detail" => {
|
706
|
+
"object" => {
|
707
|
+
"key" => "test_key"
|
708
|
+
}
|
709
|
+
}
|
710
|
+
}
|
711
|
+
|
712
|
+
message = Struct::StubMessage.new(1, 1, Yajl.dump(body))
|
713
|
+
@sqs_poller.get_messages(anything, anything) do |config, stats|
|
714
|
+
config.before_request.call(stats) if config.before_request
|
715
|
+
stats.request_count += 1
|
716
|
+
if stats.request_count >= 1
|
717
|
+
d.instance.instance_variable_set(:@running, false)
|
718
|
+
end
|
719
|
+
[message]
|
720
|
+
end
|
721
|
+
d.run(expect_emits: 1)
|
722
|
+
events = d.events
|
723
|
+
assert_equal({ "message" => "aaa" }, events.first[2])
|
724
|
+
end
|
725
|
+
|
616
726
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-s3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.7.
|
4
|
+
version: 1.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-10-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|