fluent-plugin-s3 1.6.1 → 1.7.0

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 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