fluent-plugin-s3 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/linux.yml +5 -3
- data/.github/workflows/stale-actions.yml +2 -2
- data/ChangeLog +7 -0
- data/VERSION +1 -1
- data/docs/input.md +8 -0
- data/docs/output.md +4 -0
- data/fluent-plugin-s3.gemspec +3 -0
- data/lib/fluent/plugin/in_s3.rb +20 -0
- data/lib/fluent/plugin/out_s3.rb +6 -2
- data/test/test_in_s3.rb +99 -1
- data/test/test_out_s3.rb +167 -118
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db01fa7706627c40baf9e272644c4449c47e4adac7c67ae336099c1c65021e04
|
4
|
+
data.tar.gz: d74f9c06bcce4606b62d06ba416f934824213e42b508cf49dc093392c34692fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 920c6ddc28b300bf9b00c2a21005d4adfeefc2e6c59ddb9afffedb2fcd45145baf70e2f7ec01997c12380d7b31def2289ece915a3099d0045b086314c914a555
|
7
|
+
data.tar.gz: eb84c4fc47ad9840fb375d65f532f7f5df701ce733b8959c6e037ffd45010548555ae5695b9e0839d4af60967ec791b5cb4cd049e103653b7b441a4f2bf54209
|
data/.github/workflows/linux.yml
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
name: linux
|
2
2
|
on:
|
3
|
-
|
4
|
-
|
3
|
+
push:
|
4
|
+
branches: [master]
|
5
|
+
pull_request:
|
6
|
+
branches: [master]
|
5
7
|
jobs:
|
6
8
|
build:
|
7
9
|
runs-on: ${{ matrix.os }}
|
8
10
|
strategy:
|
9
11
|
fail-fast: false
|
10
12
|
matrix:
|
11
|
-
ruby: [ '
|
13
|
+
ruby: [ '3.1', '3.0', '2.7' ]
|
12
14
|
os:
|
13
15
|
- ubuntu-latest
|
14
16
|
name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
|
@@ -18,5 +18,5 @@ jobs:
|
|
18
18
|
close-pr-message: "This PR was automatically closed because of stale in 30 days"
|
19
19
|
stale-pr-label: "stale"
|
20
20
|
stale-issue-label: "stale"
|
21
|
-
exempt-issue-labels: "bug,help wanted"
|
22
|
-
exempt-pr-labels: "bug,help wanted"
|
21
|
+
exempt-issue-labels: "bug,help wanted,enhancement"
|
22
|
+
exempt-pr-labels: "bug,help wanted,enhancement"
|
data/ChangeLog
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
Release 1.7.0 - 2022/06/14
|
2
|
+
|
3
|
+
* in_s3: Allow multi workers
|
4
|
+
* in_s3: Support alternative AWS key ID and secret for SQS
|
5
|
+
* out_s3: Add warning for multi workers
|
6
|
+
* out_s3: Support object tagging
|
7
|
+
|
1
8
|
Release 1.6.1 - 2021/08/19
|
2
9
|
|
3
10
|
* in_s3/out_s3: Don't raise error when s3_endpoint is used for VPC endpoint (GitHub: #384)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.7.0
|
data/docs/input.md
CHANGED
@@ -77,6 +77,14 @@ SQS queue name. Need to create SQS queue on the region same as S3 bucket.
|
|
77
77
|
|
78
78
|
SQS Owner Account ID
|
79
79
|
|
80
|
+
### aws_key_id
|
81
|
+
|
82
|
+
Alternative aws key id for SQS
|
83
|
+
|
84
|
+
### aws_sec_key
|
85
|
+
|
86
|
+
Alternative aws key secret for SQS
|
87
|
+
|
80
88
|
### skip_delete
|
81
89
|
|
82
90
|
When true, messages are not deleted after polling block. Default is false.
|
data/docs/output.md
CHANGED
@@ -438,6 +438,10 @@ It would be useful when you use S3 compatible storage that accepts only signatur
|
|
438
438
|
|
439
439
|
Given a threshold to treat events as delay, output warning logs if delayed events were put into s3.
|
440
440
|
|
441
|
+
## tagging
|
442
|
+
|
443
|
+
The S3 tag-set for the object. The tag-set must be encoded as URL Query parameters. (For example, "Key1=Value1").
|
444
|
+
|
441
445
|
## \<bucket_lifecycle_rule\> section
|
442
446
|
|
443
447
|
Specify one or more lifecycle rules for the bucket
|
data/fluent-plugin-s3.gemspec
CHANGED
@@ -23,4 +23,7 @@ Gem::Specification.new do |gem|
|
|
23
23
|
gem.add_development_dependency "test-unit", ">= 3.0.8"
|
24
24
|
gem.add_development_dependency "test-unit-rr", ">= 1.0.3"
|
25
25
|
gem.add_development_dependency "timecop"
|
26
|
+
# aws-sdk-core requires one of ox, oga, libxml, nokogiri or rexml,
|
27
|
+
# and rexml is no longer default gem as of Ruby 3.0.
|
28
|
+
gem.add_development_dependency "rexml"
|
26
29
|
end
|
data/lib/fluent/plugin/in_s3.rb
CHANGED
@@ -98,6 +98,10 @@ module Fluent::Plugin
|
|
98
98
|
config_param :queue_owner_aws_account_id, :string, default: nil
|
99
99
|
desc "Use 's3_region' instead"
|
100
100
|
config_param :endpoint, :string, default: nil
|
101
|
+
desc "AWS access key id for SQS user"
|
102
|
+
config_param :aws_key_id, :string, default: nil, secret: true
|
103
|
+
desc "AWS secret key for SQS user."
|
104
|
+
config_param :aws_sec_key, :string, default: nil, secret: true
|
101
105
|
desc "Skip message deletion"
|
102
106
|
config_param :skip_delete, :bool, default: false
|
103
107
|
desc "The long polling interval."
|
@@ -136,6 +140,14 @@ module Fluent::Plugin
|
|
136
140
|
raise Fluent::ConfigError, "sqs/queue_name is required"
|
137
141
|
end
|
138
142
|
|
143
|
+
if !!@aws_key_id ^ !!@aws_sec_key
|
144
|
+
raise Fluent::ConfigError, "aws_key_id or aws_sec_key is missing"
|
145
|
+
end
|
146
|
+
|
147
|
+
if !!@sqs.aws_key_id ^ !!@sqs.aws_sec_key
|
148
|
+
raise Fluent::ConfigError, "sqs/aws_key_id or sqs/aws_sec_key is missing"
|
149
|
+
end
|
150
|
+
|
139
151
|
Aws.use_bundled_cert! if @use_bundled_cert
|
140
152
|
|
141
153
|
@extractor = EXTRACTOR_REGISTRY.lookup(@store_as).new(log: log)
|
@@ -144,6 +156,10 @@ module Fluent::Plugin
|
|
144
156
|
@parser = parser_create(conf: parser_config, default_type: DEFAULT_PARSE_TYPE)
|
145
157
|
end
|
146
158
|
|
159
|
+
def multi_workers_ready?
|
160
|
+
true
|
161
|
+
end
|
162
|
+
|
147
163
|
def start
|
148
164
|
super
|
149
165
|
|
@@ -275,6 +291,10 @@ module Fluent::Plugin
|
|
275
291
|
options[:region] = @s3_region if @s3_region
|
276
292
|
options[:endpoint] = @sqs.endpoint if @sqs.endpoint
|
277
293
|
options[:http_proxy] = @proxy_uri if @proxy_uri
|
294
|
+
if @sqs.aws_key_id && @sqs.aws_sec_key
|
295
|
+
options[:access_key_id] = @sqs.aws_key_id
|
296
|
+
options[:secret_access_key] = @sqs.aws_sec_key
|
297
|
+
end
|
278
298
|
log.on_trace do
|
279
299
|
options[:http_wire_trace] = true
|
280
300
|
options[:logger] = log
|
data/lib/fluent/plugin/out_s3.rb
CHANGED
@@ -147,6 +147,8 @@ module Fluent::Plugin
|
|
147
147
|
config_param :signature_version, :string, default: nil # use nil to follow SDK default configuration
|
148
148
|
desc "Given a threshold to treat events as delay, output warning logs if delayed events were put into s3"
|
149
149
|
config_param :warn_for_delay, :time, default: nil
|
150
|
+
desc "Arbitrary S3 tag-set for the object"
|
151
|
+
config_param :tagging, :string, default: nil
|
150
152
|
desc "Arbitrary S3 metadata headers to set for the object"
|
151
153
|
config_param :s3_metadata, :hash, default: nil
|
152
154
|
config_section :bucket_lifecycle_rule, param_name: :bucket_lifecycle_rules, multi: true do
|
@@ -360,6 +362,7 @@ module Fluent::Plugin
|
|
360
362
|
put_options[:grant_read] = @grant_read if @grant_read
|
361
363
|
put_options[:grant_read_acp] = @grant_read_acp if @grant_read_acp
|
362
364
|
put_options[:grant_write_acp] = @grant_write_acp if @grant_write_acp
|
365
|
+
put_options[:tagging] = @tagging if @tagging
|
363
366
|
|
364
367
|
if @s3_metadata
|
365
368
|
put_options[:metadata] = {}
|
@@ -461,8 +464,9 @@ module Fluent::Plugin
|
|
461
464
|
log.warn "The default value of s3_object_key_format will use ${chunk_id} instead of %{index} to avoid object conflict in v2"
|
462
465
|
end
|
463
466
|
|
464
|
-
|
465
|
-
|
467
|
+
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 %{uuid_flush} in s3_object_key_format with multiple flush threads or multiple workers. Recommend to set ${chunk_id} or %{uuid_flush} to avoid data lost by object conflict"
|
466
470
|
end
|
467
471
|
end
|
468
472
|
|
data/test/test_in_s3.rb
CHANGED
@@ -84,7 +84,7 @@ class S3InputTest < Test::Unit::TestCase
|
|
84
84
|
|
85
85
|
def test_unknown_store_as
|
86
86
|
config = CONFIG + "\nstore_as unknown"
|
87
|
-
assert_raise(Fluent::
|
87
|
+
assert_raise(Fluent::NotFoundPluginError) do
|
88
88
|
create_driver(config)
|
89
89
|
end
|
90
90
|
end
|
@@ -153,6 +153,104 @@ EOS
|
|
153
153
|
}
|
154
154
|
end
|
155
155
|
|
156
|
+
def test_sqs_with_invalid_keys_missing_secret_key
|
157
|
+
assert_raise(Fluent::ConfigError, "sqs/aws_key_id or sqs/aws_sec_key is missing") {
|
158
|
+
conf = <<"EOS"
|
159
|
+
aws_key_id test_key_id
|
160
|
+
aws_sec_key test_sec_key
|
161
|
+
s3_bucket test_bucket
|
162
|
+
buffer_type memory
|
163
|
+
<sqs>
|
164
|
+
queue_name test_queue
|
165
|
+
endpoint eu-west-1
|
166
|
+
aws_key_id sqs_test_key_id
|
167
|
+
</sqs>
|
168
|
+
EOS
|
169
|
+
create_driver(conf)
|
170
|
+
}
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_sqs_with_invalid_aws_keys_missing_key_id
|
174
|
+
assert_raise(Fluent::ConfigError, "sqs/aws_key_id or sqs/aws_sec_key is missing") {
|
175
|
+
conf = <<"EOS"
|
176
|
+
aws_key_id test_key_id
|
177
|
+
aws_sec_key test_sec_key
|
178
|
+
s3_bucket test_bucket
|
179
|
+
buffer_type memory
|
180
|
+
<sqs>
|
181
|
+
queue_name test_queue
|
182
|
+
endpoint eu-west-1
|
183
|
+
aws_sec_key sqs_test_sec_key
|
184
|
+
</sqs>
|
185
|
+
EOS
|
186
|
+
create_driver(conf)
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_sqs_with_valid_aws_keys_complete_pair
|
191
|
+
conf = <<"EOS"
|
192
|
+
aws_key_id test_key_id
|
193
|
+
aws_sec_key test_sec_key
|
194
|
+
s3_bucket test_bucket
|
195
|
+
buffer_type memory
|
196
|
+
<sqs>
|
197
|
+
queue_name test_queue
|
198
|
+
endpoint eu-west-1
|
199
|
+
aws_key_id sqs_test_key_id
|
200
|
+
aws_sec_key sqs_test_sec_key
|
201
|
+
</sqs>
|
202
|
+
EOS
|
203
|
+
d = create_driver(conf)
|
204
|
+
assert_equal 'sqs_test_key_id', d.instance.sqs.aws_key_id
|
205
|
+
assert_equal 'sqs_test_sec_key', d.instance.sqs.aws_sec_key
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_with_invalid_aws_keys_missing_secret_key
|
209
|
+
assert_raise(Fluent::ConfigError, "aws_key_id or aws_sec_key is missing") {
|
210
|
+
conf = <<"EOS"
|
211
|
+
aws_key_id test_key_id
|
212
|
+
s3_bucket test_bucket
|
213
|
+
buffer_type memory
|
214
|
+
<sqs>
|
215
|
+
queue_name test_queue
|
216
|
+
endpoint eu-west-1
|
217
|
+
</sqs>
|
218
|
+
EOS
|
219
|
+
create_driver(conf)
|
220
|
+
}
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_with_invalid_aws_keys_missing_key_id
|
224
|
+
assert_raise(Fluent::ConfigError, "aws_key_id or aws_sec_key is missing") {
|
225
|
+
conf = <<"EOS"
|
226
|
+
aws_sec_key test_sec_key
|
227
|
+
s3_bucket test_bucket
|
228
|
+
buffer_type memory
|
229
|
+
<sqs>
|
230
|
+
queue_name test_queue
|
231
|
+
endpoint eu-west-1
|
232
|
+
</sqs>
|
233
|
+
EOS
|
234
|
+
create_driver(conf)
|
235
|
+
}
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_with_valid_aws_keys_complete_pair
|
239
|
+
conf = <<"EOS"
|
240
|
+
aws_key_id test_key_id
|
241
|
+
aws_sec_key test_sec_key
|
242
|
+
s3_bucket test_bucket
|
243
|
+
buffer_type memory
|
244
|
+
<sqs>
|
245
|
+
queue_name test_queue
|
246
|
+
endpoint eu-west-1
|
247
|
+
</sqs>
|
248
|
+
EOS
|
249
|
+
d = create_driver(conf)
|
250
|
+
assert_equal 'test_key_id', d.instance.aws_key_id
|
251
|
+
assert_equal 'test_sec_key', d.instance.aws_sec_key
|
252
|
+
end
|
253
|
+
|
156
254
|
Struct.new("StubResponse", :queue_url)
|
157
255
|
Struct.new("StubMessage", :message_id, :receipt_handle, :body)
|
158
256
|
|
data/test/test_out_s3.rb
CHANGED
@@ -52,102 +52,147 @@ class S3OutputTest < Test::Unit::TestCase
|
|
52
52
|
end.configure(conf)
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
def test_s3_endpoint_with_valid_endpoint
|
71
|
-
d = create_driver(CONFIG + 's3_endpoint riak-cs.example.com')
|
72
|
-
assert_equal 'riak-cs.example.com', d.instance.s3_endpoint
|
73
|
-
end
|
74
|
-
|
75
|
-
data('US West (Oregon)' => 's3-us-west-2.amazonaws.com',
|
76
|
-
'EU (Frankfurt)' => 's3.eu-central-1.amazonaws.com',
|
77
|
-
'Asia Pacific (Tokyo)' => 's3-ap-northeast-1.amazonaws.com')
|
78
|
-
def test_s3_endpoint_with_invalid_endpoint(endpoint)
|
79
|
-
assert_raise(Fluent::ConfigError, "s3_endpoint parameter is not supported, use s3_region instead. This parameter is for S3 compatible services") {
|
80
|
-
create_driver(CONFIG + "s3_endpoint #{endpoint}")
|
81
|
-
}
|
82
|
-
end
|
55
|
+
sub_test_case "configure" do
|
56
|
+
def test_configure
|
57
|
+
d = create_driver
|
58
|
+
assert_equal 'test_key_id', d.instance.aws_key_id
|
59
|
+
assert_equal 'test_sec_key', d.instance.aws_sec_key
|
60
|
+
assert_equal 'test_bucket', d.instance.s3_bucket
|
61
|
+
assert_equal 'log', d.instance.path
|
62
|
+
assert_equal 'gz', d.instance.instance_variable_get(:@compressor).ext
|
63
|
+
assert_equal 'application/x-gzip', d.instance.instance_variable_get(:@compressor).content_type
|
64
|
+
assert_equal false, d.instance.force_path_style
|
65
|
+
assert_equal nil, d.instance.compute_checksums
|
66
|
+
assert_equal nil, d.instance.signature_version
|
67
|
+
assert_equal true, d.instance.check_bucket
|
68
|
+
assert_equal true, d.instance.check_object
|
69
|
+
end
|
83
70
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
assert_equal 'json', d.instance.instance_variable_get(:@compressor).ext
|
89
|
-
assert_equal 'application/json', d.instance.instance_variable_get(:@compressor).content_type
|
90
|
-
end
|
71
|
+
def test_s3_endpoint_with_valid_endpoint
|
72
|
+
d = create_driver(CONFIG + 's3_endpoint riak-cs.example.com')
|
73
|
+
assert_equal 'riak-cs.example.com', d.instance.s3_endpoint
|
74
|
+
end
|
91
75
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
76
|
+
data('US West (Oregon)' => 's3-us-west-2.amazonaws.com',
|
77
|
+
'EU (Frankfurt)' => 's3.eu-central-1.amazonaws.com',
|
78
|
+
'Asia Pacific (Tokyo)' => 's3-ap-northeast-1.amazonaws.com')
|
79
|
+
def test_s3_endpoint_with_invalid_endpoint(endpoint)
|
80
|
+
assert_raise(Fluent::ConfigError, "s3_endpoint parameter is not supported, use s3_region instead. This parameter is for S3 compatible services") {
|
81
|
+
create_driver(CONFIG + "s3_endpoint #{endpoint}")
|
82
|
+
}
|
83
|
+
end
|
99
84
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
# TODO: replace code with disable lzop command
|
108
|
-
assert(e.is_a?(Fluent::ConfigError))
|
109
|
-
end
|
85
|
+
def test_configure_with_mime_type_json
|
86
|
+
conf = CONFIG.clone
|
87
|
+
conf << "\nstore_as json\n"
|
88
|
+
d = create_driver(conf)
|
89
|
+
assert_equal 'json', d.instance.instance_variable_get(:@compressor).ext
|
90
|
+
assert_equal 'application/json', d.instance.instance_variable_get(:@compressor).content_type
|
91
|
+
end
|
110
92
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
93
|
+
def test_configure_with_mime_type_text
|
94
|
+
conf = CONFIG.clone
|
95
|
+
conf << "\nstore_as text\n"
|
96
|
+
d = create_driver(conf)
|
97
|
+
assert_equal 'txt', d.instance.instance_variable_get(:@compressor).ext
|
98
|
+
assert_equal 'text/plain', d.instance.instance_variable_get(:@compressor).content_type
|
99
|
+
end
|
117
100
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
101
|
+
def test_configure_with_mime_type_lzo
|
102
|
+
conf = CONFIG.clone
|
103
|
+
conf << "\nstore_as lzo\n"
|
104
|
+
d = create_driver(conf)
|
105
|
+
assert_equal 'lzo', d.instance.instance_variable_get(:@compressor).ext
|
106
|
+
assert_equal 'application/x-lzop', d.instance.instance_variable_get(:@compressor).content_type
|
107
|
+
rescue => e
|
108
|
+
# TODO: replace code with disable lzop command
|
109
|
+
assert(e.is_a?(Fluent::ConfigError))
|
110
|
+
end
|
124
111
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
create_driver(conf
|
112
|
+
def test_configure_with_path_style
|
113
|
+
conf = CONFIG.clone
|
114
|
+
conf << "\nforce_path_style true\n"
|
115
|
+
d = create_driver(conf)
|
116
|
+
assert d.instance.force_path_style
|
129
117
|
end
|
130
|
-
|
131
|
-
|
118
|
+
|
119
|
+
def test_configure_with_compute_checksums
|
120
|
+
conf = CONFIG.clone
|
121
|
+
conf << "\ncompute_checksums false\n"
|
122
|
+
d = create_driver(conf)
|
123
|
+
assert_equal false, d.instance.compute_checksums
|
132
124
|
end
|
133
|
-
end
|
134
125
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
126
|
+
def test_configure_with_hex_random_length
|
127
|
+
conf = CONFIG.clone
|
128
|
+
assert_raise Fluent::ConfigError do
|
129
|
+
create_driver(conf + "\nhex_random_length 17\n")
|
130
|
+
end
|
131
|
+
assert_nothing_raised do
|
132
|
+
create_driver(conf + "\nhex_random_length 16\n")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_configure_with_no_check_on_s3
|
137
|
+
conf = CONFIG.clone
|
138
|
+
conf << "\ncheck_bucket false\ncheck_object false\n"
|
139
|
+
d = create_driver(conf)
|
140
|
+
assert_equal false, d.instance.check_bucket
|
141
|
+
assert_equal false, d.instance.check_object
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_configure_with_grant
|
145
|
+
conf = CONFIG.clone
|
146
|
+
conf << "\grant_full_control id='0123456789'\ngrant_read id='1234567890'\ngrant_read_acp id='2345678901'\ngrant_write_acp id='3456789012'\n"
|
147
|
+
d = create_driver(conf)
|
148
|
+
assert_equal "id='0123456789'", d.instance.grant_full_control
|
149
|
+
assert_equal "id='1234567890'", d.instance.grant_read
|
150
|
+
assert_equal "id='2345678901'", d.instance.grant_read_acp
|
151
|
+
assert_equal "id='3456789012'", d.instance.grant_write_acp
|
152
|
+
end
|
142
153
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
154
|
+
CONFIG_WITH_OBJECTKEY_DEFAULT = %[
|
155
|
+
s3_object_key_format "%{path}%{time_slice}_%{index}.%{file_extension}"
|
156
|
+
aws_key_id test_key_id
|
157
|
+
aws_sec_key test_sec_key
|
158
|
+
s3_bucket test_bucket
|
159
|
+
path log
|
160
|
+
utc
|
161
|
+
buffer_type memory
|
162
|
+
time_slice_format %Y%m%d-%H
|
163
|
+
]
|
164
|
+
|
165
|
+
CONFIG_WITH_OBJECTKEY_FIXED_FOR_MULTI_THEAD = %[
|
166
|
+
s3_object_key_format "%{path}%{time_slice}_${chunk_id}.%{file_extension}"
|
167
|
+
aws_key_id test_key_id
|
168
|
+
aws_sec_key test_sec_key
|
169
|
+
s3_bucket test_bucket
|
170
|
+
path log
|
171
|
+
utc
|
172
|
+
buffer_type memory
|
173
|
+
time_slice_format %Y%m%d-%H
|
174
|
+
]
|
175
|
+
|
176
|
+
data("non_objectkey", {"expected_warning_num" => 1, "conf" => CONFIG, "workers" => 1, "with_multi_buffers" => false})
|
177
|
+
data("non_objectkey-multi_buffer", {"expected_warning_num" => 2, "conf" => CONFIG, "workers" => 1, "with_multi_buffers" => true})
|
178
|
+
data("non_objectkey-multi_worker", {"expected_warning_num" => 2, "conf" => CONFIG, "workers" => 2, "with_multi_buffers" => false})
|
179
|
+
data("default_objectkey", {"expected_warning_num" => 0, "conf" => CONFIG_WITH_OBJECTKEY_DEFAULT, "workers" => 1, "with_multi_buffers" => false})
|
180
|
+
data("default_objectkey-multi_buffer", {"expected_warning_num" => 1, "conf" => CONFIG_WITH_OBJECTKEY_DEFAULT, "workers" => 1, "with_multi_buffers" => true})
|
181
|
+
data("default_objectkey-multi_worker", {"expected_warning_num" => 1, "conf" => CONFIG_WITH_OBJECTKEY_DEFAULT, "workers" => 2, "with_multi_buffers" => false})
|
182
|
+
data("fixed_objectkey", {"expected_warning_num" => 0, "conf" => CONFIG_WITH_OBJECTKEY_FIXED_FOR_MULTI_THEAD, "workers" => 1, "with_multi_buffers" => false})
|
183
|
+
data("fixed_objectkey-multi_buffer", {"expected_warning_num" => 0, "conf" => CONFIG_WITH_OBJECTKEY_FIXED_FOR_MULTI_THEAD, "workers" => 1, "with_multi_buffers" => true})
|
184
|
+
data("fixed_objectkey-multi_worker", {"expected_warning_num" => 0, "conf" => CONFIG_WITH_OBJECTKEY_FIXED_FOR_MULTI_THEAD, "workers" => 2, "with_multi_buffers" => false})
|
185
|
+
def test_configure_warning_on_parallel(data)
|
186
|
+
conf = data["conf"].clone
|
187
|
+
if data["with_multi_buffers"]
|
188
|
+
conf << "\n<buffer>\n@type memory\nflush_thread_count 2\n</buffer>\n"
|
189
|
+
end
|
190
|
+
assert_rr do
|
191
|
+
d = Fluent::Test::Driver::Output.new(Fluent::Plugin::S3Output, opts: {"workers": data["workers"]})
|
192
|
+
mock(d.instance.log).warn(anything).times(data["expected_warning_num"])
|
193
|
+
d.configure(conf)
|
194
|
+
end
|
195
|
+
end
|
151
196
|
end
|
152
197
|
|
153
198
|
def test_format
|
@@ -517,9 +562,9 @@ EOC
|
|
517
562
|
|
518
563
|
def test_assume_role_credentials
|
519
564
|
expected_credentials = Aws::Credentials.new("test_key", "test_secret")
|
520
|
-
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
|
521
|
-
|
522
|
-
|
565
|
+
mock(Aws::AssumeRoleCredentials).new({ role_arn: "test_arn",
|
566
|
+
role_session_name: "test_session",
|
567
|
+
client: anything }){
|
523
568
|
expected_credentials
|
524
569
|
}
|
525
570
|
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
|
@@ -540,9 +585,9 @@ EOC
|
|
540
585
|
expected_credentials = Aws::Credentials.new("test_key", "test_secret")
|
541
586
|
sts_client = Aws::STS::Client.new(region: 'ap-northeast-1')
|
542
587
|
mock(Aws::STS::Client).new(region: 'ap-northeast-1'){ sts_client }
|
543
|
-
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
|
544
|
-
|
545
|
-
|
588
|
+
mock(Aws::AssumeRoleCredentials).new({ role_arn: "test_arn",
|
589
|
+
role_session_name: "test_session",
|
590
|
+
client: sts_client }){
|
546
591
|
expected_credentials
|
547
592
|
}
|
548
593
|
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
|
@@ -565,9 +610,9 @@ EOC
|
|
565
610
|
sts_client = Aws::STS::Client.new(region: 'ap-northeast-1', credentials: expected_credentials)
|
566
611
|
mock(Aws::Credentials).new("test_key_id", "test_sec_key") { expected_credentials }
|
567
612
|
mock(Aws::STS::Client).new(region: 'ap-northeast-1', credentials: expected_credentials){ sts_client }
|
568
|
-
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
|
569
|
-
|
570
|
-
|
613
|
+
mock(Aws::AssumeRoleCredentials).new({ role_arn: "test_arn",
|
614
|
+
role_session_name: "test_session",
|
615
|
+
client: sts_client } ){
|
571
616
|
expected_credentials
|
572
617
|
}
|
573
618
|
config = CONFIG_TIME_SLICE
|
@@ -592,10 +637,10 @@ EOC
|
|
592
637
|
expected_sts_http_proxy = 'http://example.com'
|
593
638
|
sts_client = Aws::STS::Client.new(region: expected_region, http_proxy: expected_sts_http_proxy)
|
594
639
|
mock(Aws::STS::Client).new(region:expected_region, http_proxy: expected_sts_http_proxy){ sts_client }
|
595
|
-
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
|
596
|
-
|
597
|
-
|
598
|
-
|
640
|
+
mock(Aws::AssumeRoleCredentials).new({ role_arn: "test_arn",
|
641
|
+
role_session_name: "test_session",
|
642
|
+
client: sts_client,
|
643
|
+
sts_http_proxy: expected_sts_http_proxy }){
|
599
644
|
expected_credentials
|
600
645
|
}
|
601
646
|
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
|
@@ -619,10 +664,10 @@ EOC
|
|
619
664
|
expected_sts_http_proxy = 'http://example.com'
|
620
665
|
sts_client = Aws::STS::Client.new(region: "us-east-1", http_proxy: expected_sts_http_proxy)
|
621
666
|
mock(Aws::STS::Client).new(region: "us-east-1", http_proxy: expected_sts_http_proxy){ sts_client }
|
622
|
-
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
|
623
|
-
|
624
|
-
|
625
|
-
|
667
|
+
mock(Aws::AssumeRoleCredentials).new({ role_arn: "test_arn",
|
668
|
+
role_session_name: "test_session",
|
669
|
+
client: sts_client,
|
670
|
+
sts_http_proxy: expected_sts_http_proxy }){
|
626
671
|
expected_credentials
|
627
672
|
}
|
628
673
|
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
|
@@ -645,10 +690,10 @@ EOC
|
|
645
690
|
expected_sts_endpoint_url = 'http://example.com'
|
646
691
|
sts_client = Aws::STS::Client.new(region: "us-east-1", endpoint: expected_sts_endpoint_url)
|
647
692
|
mock(Aws::STS::Client).new(region: "us-east-1", endpoint: expected_sts_endpoint_url){ sts_client }
|
648
|
-
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
|
649
|
-
|
650
|
-
|
651
|
-
|
693
|
+
mock(Aws::AssumeRoleCredentials).new({ role_arn: "test_arn",
|
694
|
+
role_session_name: "test_session",
|
695
|
+
client: sts_client,
|
696
|
+
sts_endpoint_url: expected_sts_endpoint_url }){
|
652
697
|
expected_credentials
|
653
698
|
}
|
654
699
|
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
|
@@ -671,9 +716,9 @@ EOC
|
|
671
716
|
expected_sts_region = 'ap-south-1'
|
672
717
|
sts_client = Aws::STS::Client.new(region: expected_sts_region)
|
673
718
|
mock(Aws::STS::Client).new(region: expected_sts_region){ sts_client }
|
674
|
-
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
|
675
|
-
|
676
|
-
|
719
|
+
mock(Aws::AssumeRoleCredentials).new({ role_arn: "test_arn",
|
720
|
+
role_session_name: "test_session",
|
721
|
+
client: sts_client }){
|
677
722
|
expected_credentials
|
678
723
|
}
|
679
724
|
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
|
@@ -694,10 +739,12 @@ EOC
|
|
694
739
|
def test_web_identity_credentials
|
695
740
|
expected_credentials = Aws::Credentials.new("test_key", "test_secret")
|
696
741
|
mock(Aws::AssumeRoleWebIdentityCredentials).new(
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
742
|
+
{
|
743
|
+
role_arn: "test_arn",
|
744
|
+
role_session_name: "test_session",
|
745
|
+
web_identity_token_file: "test_file",
|
746
|
+
client: anything
|
747
|
+
}
|
701
748
|
){
|
702
749
|
expected_credentials
|
703
750
|
}
|
@@ -722,10 +769,12 @@ EOC
|
|
722
769
|
sts_client = Aws::STS::Client.new(region: 'us-east-1')
|
723
770
|
mock(Aws::STS::Client).new(region: 'us-east-1'){ sts_client }
|
724
771
|
mock(Aws::AssumeRoleWebIdentityCredentials).new(
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
772
|
+
{
|
773
|
+
role_arn: "test_arn",
|
774
|
+
role_session_name: "test_session",
|
775
|
+
web_identity_token_file: "test_file",
|
776
|
+
client: sts_client
|
777
|
+
}
|
729
778
|
){
|
730
779
|
expected_credentials
|
731
780
|
}
|
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.
|
4
|
+
version: 1.7.0
|
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:
|
12
|
+
date: 2022-06-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|
@@ -115,6 +115,20 @@ dependencies:
|
|
115
115
|
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
|
+
- !ruby/object:Gem::Dependency
|
119
|
+
name: rexml
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
type: :development
|
126
|
+
prerelease: false
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
118
132
|
description: Amazon S3 output plugin for Fluentd event collector
|
119
133
|
email: frsyuki@gmail.com
|
120
134
|
executables: []
|
@@ -172,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
186
|
- !ruby/object:Gem::Version
|
173
187
|
version: '0'
|
174
188
|
requirements: []
|
175
|
-
rubygems_version: 3.
|
189
|
+
rubygems_version: 3.3.7
|
176
190
|
signing_key:
|
177
191
|
specification_version: 4
|
178
192
|
summary: Amazon S3 output plugin for Fluentd event collector
|