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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbb79ec06cc2a084f5043825a68b9e15b3d3eed9008f0906ff6fedede8659a22
4
- data.tar.gz: '09eb263937f9f5dd397296579426a744f701eee6ba45d4a2b05b0f5c7990fe5b'
3
+ metadata.gz: db01fa7706627c40baf9e272644c4449c47e4adac7c67ae336099c1c65021e04
4
+ data.tar.gz: d74f9c06bcce4606b62d06ba416f934824213e42b508cf49dc093392c34692fe
5
5
  SHA512:
6
- metadata.gz: 5a0685a1d250f12608bf432c4157d6a1b9cd7a627161cf2278c703ae07cce9fe858d5468bbe5056d060f40914570ea9ec39bbec04828c1dbf193737edf72193a
7
- data.tar.gz: 0caf64221c557536e5e3d1d6f21f28cfdce5fc865a4a4d5b55ec490fd716701675b49999faf81b9e030348abbd68e265df690154f2aac155613efbfcf4ba144d
6
+ metadata.gz: 920c6ddc28b300bf9b00c2a21005d4adfeefc2e6c59ddb9afffedb2fcd45145baf70e2f7ec01997c12380d7b31def2289ece915a3099d0045b086314c914a555
7
+ data.tar.gz: eb84c4fc47ad9840fb375d65f532f7f5df701ce733b8959c6e037ffd45010548555ae5695b9e0839d4af60967ec791b5cb4cd049e103653b7b441a4f2bf54209
@@ -1,14 +1,16 @@
1
1
  name: linux
2
2
  on:
3
- - push
4
- - pull_request
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: [ '2.4', '2.5', '2.6', '2.7' ]
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.6.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
@@ -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
@@ -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
@@ -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
- if (@buffer_config.flush_thread_count > 1) && ['${chunk_id}', '%{uuid_flush}'].none? { |key| @s3_object_key_format.include?(key) }
465
- log.warn "No ${chunk_id} or %{uuid_flush} in s3_object_key_format with multiple flush threads. Recommend to set ${chunk_id} or %{uuid_flush} to avoid data lost by object conflict"
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::ConfigError) do
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
- def test_configure
56
- d = create_driver
57
- assert_equal 'test_key_id', d.instance.aws_key_id
58
- assert_equal 'test_sec_key', d.instance.aws_sec_key
59
- assert_equal 'test_bucket', d.instance.s3_bucket
60
- assert_equal 'log', d.instance.path
61
- assert_equal 'gz', d.instance.instance_variable_get(:@compressor).ext
62
- assert_equal 'application/x-gzip', d.instance.instance_variable_get(:@compressor).content_type
63
- assert_equal false, d.instance.force_path_style
64
- assert_equal nil, d.instance.compute_checksums
65
- assert_equal nil, d.instance.signature_version
66
- assert_equal true, d.instance.check_bucket
67
- assert_equal true, d.instance.check_object
68
- end
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
- def test_configure_with_mime_type_json
85
- conf = CONFIG.clone
86
- conf << "\nstore_as json\n"
87
- d = create_driver(conf)
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
- def test_configure_with_mime_type_text
93
- conf = CONFIG.clone
94
- conf << "\nstore_as text\n"
95
- d = create_driver(conf)
96
- assert_equal 'txt', d.instance.instance_variable_get(:@compressor).ext
97
- assert_equal 'text/plain', d.instance.instance_variable_get(:@compressor).content_type
98
- end
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
- def test_configure_with_mime_type_lzo
101
- conf = CONFIG.clone
102
- conf << "\nstore_as lzo\n"
103
- d = create_driver(conf)
104
- assert_equal 'lzo', d.instance.instance_variable_get(:@compressor).ext
105
- assert_equal 'application/x-lzop', d.instance.instance_variable_get(:@compressor).content_type
106
- rescue => e
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
- def test_configure_with_path_style
112
- conf = CONFIG.clone
113
- conf << "\nforce_path_style true\n"
114
- d = create_driver(conf)
115
- assert d.instance.force_path_style
116
- end
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
- def test_configure_with_compute_checksums
119
- conf = CONFIG.clone
120
- conf << "\ncompute_checksums false\n"
121
- d = create_driver(conf)
122
- assert_equal false, d.instance.compute_checksums
123
- end
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
- def test_configure_with_hex_random_length
126
- conf = CONFIG.clone
127
- assert_raise Fluent::ConfigError do
128
- create_driver(conf + "\nhex_random_length 17\n")
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
- assert_nothing_raised do
131
- create_driver(conf + "\nhex_random_length 16\n")
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
- def test_configure_with_no_check_on_s3
136
- conf = CONFIG.clone
137
- conf << "\ncheck_bucket false\ncheck_object false\n"
138
- d = create_driver(conf)
139
- assert_equal false, d.instance.check_bucket
140
- assert_equal false, d.instance.check_object
141
- end
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
- def test_configure_with_grant
144
- conf = CONFIG.clone
145
- conf << "\grant_full_control id='0123456789'\ngrant_read id='1234567890'\ngrant_read_acp id='2345678901'\ngrant_write_acp id='3456789012'\n"
146
- d = create_driver(conf)
147
- assert_equal "id='0123456789'", d.instance.grant_full_control
148
- assert_equal "id='1234567890'", d.instance.grant_read
149
- assert_equal "id='2345678901'", d.instance.grant_read_acp
150
- assert_equal "id='3456789012'", d.instance.grant_write_acp
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
- role_session_name: "test_session",
522
- client: anything){
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
- role_session_name: "test_session",
545
- client: sts_client){
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
- role_session_name: "test_session",
570
- client: sts_client){
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
- role_session_name: "test_session",
597
- client: sts_client,
598
- sts_http_proxy: expected_sts_http_proxy){
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
- role_session_name: "test_session",
624
- client: sts_client,
625
- sts_http_proxy: expected_sts_http_proxy){
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
- role_session_name: "test_session",
650
- client: sts_client,
651
- sts_endpoint_url: expected_sts_endpoint_url){
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
- role_session_name: "test_session",
676
- client: sts_client){
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
- role_arn: "test_arn",
698
- role_session_name: "test_session",
699
- web_identity_token_file: "test_file",
700
- client: anything
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
- role_arn: "test_arn",
726
- role_session_name: "test_session",
727
- web_identity_token_file: "test_file",
728
- client: sts_client
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.6.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: 2021-08-19 00:00:00.000000000 Z
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.1.6
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