fluent-plugin-s3 1.6.0 → 1.7.1

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: 155f0d28d700caf2e5c817843abec96a26f301404d2bf521c6cd383068fdeb47
4
- data.tar.gz: '0701182695128c6812b28179685658a8b570332a2f747146e157e859d61d0898'
3
+ metadata.gz: fe9afa0a2351dfffc6ea9afa0c2f3598a29b19a55fbfa22f58f3d17b606a3113
4
+ data.tar.gz: e5813910a178d16ed61c2a8782e2adeb394d0d256acfbcfdbead05069d789163
5
5
  SHA512:
6
- metadata.gz: 47460a080d212895f1a121da9dc547b08281df9c9ae1c2644dce582c63cad4b971aeefcf287553bf8f983dd4b2e628acfd6119b2dd3b725e5d0125e58fe5c043
7
- data.tar.gz: a10f906a8db7c81f80dad1257a1aaf38a9a432ede35f12df6e21df2e138fd6662668192c6382cba9b647dd4e8427c9697f8b4188acef5280fd0278f24ef87b26
6
+ metadata.gz: e3ca35df25975b7b57244c88d3145ab8fb5521054b863e030846a867bae6cbc9a69343f586f01b3a29d233eea787cf0ab540ff77edc0423d583394e29a192a7c
7
+ data.tar.gz: d46deabb1425e03250c9bc24578ad8dacef71cc445335ac9e4122b11c6ad91cf7a73f92b63d3688848ff35d427cb6371777f0011c94c45a898a6063edc1e3d9c
@@ -0,0 +1,72 @@
1
+ name: Bug Report
2
+ description: Create a report with a procedure for reproducing the bug
3
+ body:
4
+ - type: markdown
5
+ attributes:
6
+ value: |
7
+ Check [README](https://github.com/fluent/fluent-plugin-s3#readme) first and here is the list to help us investigate the problem.
8
+ - type: textarea
9
+ id: description
10
+ attributes:
11
+ label: Describe the bug
12
+ description: A clear and concise description of what the bug is
13
+ validations:
14
+ required: true
15
+ - type: textarea
16
+ id: reproduce
17
+ attributes:
18
+ label: To Reproduce
19
+ description: Steps to reproduce the behavior
20
+ validations:
21
+ required: true
22
+ - type: textarea
23
+ id: expected
24
+ attributes:
25
+ label: Expected behavior
26
+ description: A clear and concise description of what you expected to happen
27
+ validations:
28
+ required: true
29
+ - type: textarea
30
+ id: environment
31
+ attributes:
32
+ label: Your Environment
33
+ description: |
34
+ - Fluentd or td-agent version: `fluentd --version` or `td-agent --version`
35
+ - Operating system: `cat /etc/os-release`
36
+ - Kernel version: `uname -r`
37
+
38
+ Tip: If you hit the problem with older fluentd version, try latest version first.
39
+ value: |
40
+ - Fluentd version:
41
+ - TD Agent version:
42
+ - fluent-plugin-s3 version:
43
+ - aws-sdk-s3 version:
44
+ - aws-sdk-sqs version:
45
+ - Operating system:
46
+ - Kernel version:
47
+ render: markdown
48
+ validations:
49
+ required: true
50
+ - type: textarea
51
+ id: configuration
52
+ attributes:
53
+ label: Your Configuration
54
+ description: |
55
+ Write your configuration here. Minimum reproducible fluentd.conf is recommended.
56
+ validations:
57
+ required: true
58
+ - type: textarea
59
+ id: logs
60
+ attributes:
61
+ label: Your Error Log
62
+ description: Write your ALL error log here
63
+ render: shell
64
+ validations:
65
+ required: true
66
+ - type: textarea
67
+ id: addtional-context
68
+ attributes:
69
+ label: Additional context
70
+ description: Add any other context about the problem here.
71
+ validations:
72
+ required: false
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Ask a Question
4
+ url: https://discuss.fluentd.org/
5
+ about: I have questions about fluent-plugin-kafka. Please ask and answer questions at https://discuss.fluentd.org/.
@@ -0,0 +1,38 @@
1
+ name: Feature request
2
+ description: Suggest an idea for this project
3
+ body:
4
+ - type: markdown
5
+ attributes:
6
+ value: |
7
+ Check [README.md](https://github.com/fluent/fluent-plugin-s3/blob/master/README.md) first and here is the list to help us investigate the problem.
8
+ - type: textarea
9
+ id: description
10
+ attributes:
11
+ label: Is your feature request related to a problem? Please describe.
12
+ description: |
13
+ A clear and concise description of what the problem is.
14
+ Ex. I'm always frustrated when [...]
15
+ validations:
16
+ required: true
17
+ - type: textarea
18
+ id: solution
19
+ attributes:
20
+ label: Describe the solution you'd like
21
+ description: A clear and concise description of what you want to happen.
22
+ validations:
23
+ required: true
24
+ - type: textarea
25
+ id: alternative
26
+ attributes:
27
+ label: Describe alternatives you've considered
28
+ description: A clear and concise description of any alternative solutions or features you've considered.
29
+ validations:
30
+ required: true
31
+ - type: textarea
32
+ id: addtional-context
33
+ attributes:
34
+ label: Additional context
35
+ description: Add any other context or screenshots about the feature request here.
36
+ validations:
37
+ required: false
38
+
@@ -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 }}
@@ -0,0 +1,22 @@
1
+ name: "Mark or close stale issues and PRs"
2
+ on:
3
+ schedule:
4
+ - cron: "00 10 * * *"
5
+
6
+ jobs:
7
+ stale:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/stale@v3
11
+ with:
12
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
13
+ days-before-stale: 90
14
+ days-before-close: 30
15
+ stale-issue-message: "This issue has been automatically marked as stale because it has been open 90 days with no activity. Remove stale label or comment or this issue will be closed in 30 days"
16
+ stale-pr-message: "This PR has been automatically marked as stale because it has been open 90 days with no activity. Remove stale label or comment or this PR will be closed in 30 days"
17
+ close-issue-message: "This issue was automatically closed because of stale in 30 days"
18
+ close-pr-message: "This PR was automatically closed because of stale in 30 days"
19
+ stale-pr-label: "stale"
20
+ stale-issue-label: "stale"
21
+ exempt-issue-labels: "bug,help wanted,enhancement"
22
+ exempt-pr-labels: "bug,help wanted,enhancement"
data/ChangeLog CHANGED
@@ -1,3 +1,19 @@
1
+ Release 1.7.1 - 2022/07/15
2
+
3
+ * in_s3: Add `match_regexp` parameter to selectively download S3 files based on the object key
4
+ * out_s3: Support `ssl_ca_bundle` and `ssl_ca_directory` parameter
5
+
6
+ Release 1.7.0 - 2022/06/14
7
+
8
+ * in_s3: Allow multi workers
9
+ * in_s3: Support alternative AWS key ID and secret for SQS
10
+ * out_s3: Add warning for multi workers
11
+ * out_s3: Support object tagging
12
+
13
+ Release 1.6.1 - 2021/08/19
14
+
15
+ * in_s3/out_s3: Don't raise error when s3_endpoint is used for VPC endpoint (GitHub: #384)
16
+
1
17
  Release 1.6.0 - 2021/04/08
2
18
 
3
19
  * out_s3: Add support for Parquet compressor. Use `<compress>` section to configure columnify command behavior.
data/README.md CHANGED
@@ -20,6 +20,8 @@ the former one is stored in "20110102.gz" file, and latter one in
20
20
  SQS queue on the region same as S3 bucket.
21
21
  We must setup SQS queue and S3 event notification before use this plugin.
22
22
 
23
+ :warning: Be sure to keep a close eye on S3 costs, as a few user have reported [unexpectedly high costs](https://github.com/fluent/fluent-plugin-s3/issues/160).
24
+
23
25
  ## Requirements
24
26
 
25
27
  | fluent-plugin-s3 | fluentd | ruby |
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.6.0
1
+ 1.7.1
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.
@@ -77,6 +82,14 @@ SQS queue name. Need to create SQS queue on the region same as S3 bucket.
77
82
 
78
83
  SQS Owner Account ID
79
84
 
85
+ ### aws_key_id
86
+
87
+ Alternative aws key id for SQS
88
+
89
+ ### aws_sec_key
90
+
91
+ Alternative aws key secret for SQS
92
+
80
93
  ### skip_delete
81
94
 
82
95
  When true, messages are not deleted after polling block. Default is false.
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.
@@ -152,6 +160,8 @@ NOTE: ${hostname} placeholder is deprecated since v0.8. You can get same result
152
160
 
153
161
  Above two configurations are same. The important point is wrapping `""` is needed for `#{Socket.gethostname}`.
154
162
 
163
+ NOTE: If `check_object` is set to `false`, Ensure the value of `s3_object_key_format` must be unique in each write, If not, existing file will be overwritten.
164
+
155
165
  ## force_path_style
156
166
 
157
167
  :force_path_style (Boolean) — default: false — When set to true, the
@@ -322,6 +332,8 @@ Use UTC instead of local time.
322
332
 
323
333
  Set storage class. Possible values are `STANDARD`, `REDUCED_REDUNDANCY`, `STANDARD_IA` from [Ruby SDK](http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#storage_class-instance_method).
324
334
 
335
+ Note that reduced redundancy is [not reccomended](https://serverfault.com/a/1010951/512362).
336
+
325
337
  ## reduced_redundancy
326
338
 
327
339
  Use S3 reduced redundancy storage for 33% cheaper pricing. Default is
@@ -434,6 +446,10 @@ It would be useful when you use S3 compatible storage that accepts only signatur
434
446
 
435
447
  Given a threshold to treat events as delay, output warning logs if delayed events were put into s3.
436
448
 
449
+ ## tagging
450
+
451
+ The S3 tag-set for the object. The tag-set must be encoded as URL Query parameters. (For example, "Key1=Value1").
452
+
437
453
  ## \<bucket_lifecycle_rule\> section
438
454
 
439
455
  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
@@ -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"
@@ -98,6 +100,10 @@ module Fluent::Plugin
98
100
  config_param :queue_owner_aws_account_id, :string, default: nil
99
101
  desc "Use 's3_region' instead"
100
102
  config_param :endpoint, :string, default: nil
103
+ desc "AWS access key id for SQS user"
104
+ config_param :aws_key_id, :string, default: nil, secret: true
105
+ desc "AWS secret key for SQS user."
106
+ config_param :aws_sec_key, :string, default: nil, secret: true
101
107
  desc "Skip message deletion"
102
108
  config_param :skip_delete, :bool, default: false
103
109
  desc "The long polling interval."
@@ -115,10 +121,15 @@ module Fluent::Plugin
115
121
 
116
122
  attr_reader :bucket
117
123
 
124
+ def reject_s3_endpoint?
125
+ @s3_endpoint && !@s3_endpoint.end_with?('vpce.amazonaws.com') &&
126
+ @s3_endpoint.end_with?('amazonaws.com') && !['fips', 'gov'].any? { |e| @s3_endpoint.include?(e) }
127
+ end
128
+
118
129
  def configure(conf)
119
130
  super
120
131
 
121
- if @s3_endpoint && (@s3_endpoint.end_with?('amazonaws.com') && !['fips', 'gov'].any? { |e| @s3_endpoint.include?(e) })
132
+ if reject_s3_endpoint?
122
133
  raise Fluent::ConfigError, "s3_endpoint parameter is not supported for S3, use s3_region instead. This parameter is for S3 compatible services"
123
134
  end
124
135
 
@@ -131,6 +142,14 @@ module Fluent::Plugin
131
142
  raise Fluent::ConfigError, "sqs/queue_name is required"
132
143
  end
133
144
 
145
+ if !!@aws_key_id ^ !!@aws_sec_key
146
+ raise Fluent::ConfigError, "aws_key_id or aws_sec_key is missing"
147
+ end
148
+
149
+ if !!@sqs.aws_key_id ^ !!@sqs.aws_sec_key
150
+ raise Fluent::ConfigError, "sqs/aws_key_id or sqs/aws_sec_key is missing"
151
+ end
152
+
134
153
  Aws.use_bundled_cert! if @use_bundled_cert
135
154
 
136
155
  @extractor = EXTRACTOR_REGISTRY.lookup(@store_as).new(log: log)
@@ -139,6 +158,10 @@ module Fluent::Plugin
139
158
  @parser = parser_create(conf: parser_config, default_type: DEFAULT_PARSE_TYPE)
140
159
  end
141
160
 
161
+ def multi_workers_ready?
162
+ true
163
+ end
164
+
142
165
  def start
143
166
  super
144
167
 
@@ -183,7 +206,12 @@ module Fluent::Plugin
183
206
  body = Yajl.load(message.body)
184
207
  log.debug(body)
185
208
  next unless body["Records"] # skip test queue
186
-
209
+ if @match_regexp
210
+ s3 = body["Records"].first["s3"]
211
+ raw_key = s3["object"]["key"]
212
+ key = CGI.unescape(raw_key)
213
+ next unless @match_regexp.match?(key)
214
+ end
187
215
  process(body)
188
216
  rescue => e
189
217
  log.warn(error: e)
@@ -270,6 +298,10 @@ module Fluent::Plugin
270
298
  options[:region] = @s3_region if @s3_region
271
299
  options[:endpoint] = @sqs.endpoint if @sqs.endpoint
272
300
  options[:http_proxy] = @proxy_uri if @proxy_uri
301
+ if @sqs.aws_key_id && @sqs.aws_sec_key
302
+ options[:access_key_id] = @sqs.aws_key_id
303
+ options[:secret_access_key] = @sqs.aws_sec_key
304
+ end
273
305
  log.on_trace do
274
306
  options[:http_wire_trace] = true
275
307
  options[:logger] = log
@@ -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"
@@ -147,6 +151,8 @@ module Fluent::Plugin
147
151
  config_param :signature_version, :string, default: nil # use nil to follow SDK default configuration
148
152
  desc "Given a threshold to treat events as delay, output warning logs if delayed events were put into s3"
149
153
  config_param :warn_for_delay, :time, default: nil
154
+ desc "Arbitrary S3 tag-set for the object"
155
+ config_param :tagging, :string, default: nil
150
156
  desc "Arbitrary S3 metadata headers to set for the object"
151
157
  config_param :s3_metadata, :hash, default: nil
152
158
  config_section :bucket_lifecycle_rule, param_name: :bucket_lifecycle_rules, multi: true do
@@ -173,6 +179,11 @@ module Fluent::Plugin
173
179
 
174
180
  MAX_HEX_RANDOM_LENGTH = 16
175
181
 
182
+ def reject_s3_endpoint?
183
+ @s3_endpoint && !@s3_endpoint.end_with?('vpce.amazonaws.com') &&
184
+ @s3_endpoint.end_with?('amazonaws.com') && !['fips', 'gov'].any? { |e| @s3_endpoint.include?(e) }
185
+ end
186
+
176
187
  def configure(conf)
177
188
  compat_parameters_convert(conf, :buffer, :formatter, :inject)
178
189
 
@@ -180,7 +191,7 @@ module Fluent::Plugin
180
191
 
181
192
  Aws.use_bundled_cert! if @use_bundled_cert
182
193
 
183
- if @s3_endpoint && (@s3_endpoint.end_with?('amazonaws.com') && !['fips', 'gov'].any? { |e| @s3_endpoint.include?(e) })
194
+ if reject_s3_endpoint?
184
195
  raise Fluent::ConfigError, "s3_endpoint parameter is not supported for S3, use s3_region instead. This parameter is for S3 compatible services"
185
196
  end
186
197
 
@@ -242,6 +253,8 @@ module Fluent::Plugin
242
253
  options[:compute_checksums] = @compute_checksums unless @compute_checksums.nil?
243
254
  options[:signature_version] = @signature_version unless @signature_version.nil?
244
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
245
258
  log.on_trace do
246
259
  options[:http_wire_trace] = true
247
260
  options[:logger] = log
@@ -355,6 +368,7 @@ module Fluent::Plugin
355
368
  put_options[:grant_read] = @grant_read if @grant_read
356
369
  put_options[:grant_read_acp] = @grant_read_acp if @grant_read_acp
357
370
  put_options[:grant_write_acp] = @grant_write_acp if @grant_write_acp
371
+ put_options[:tagging] = @tagging if @tagging
358
372
 
359
373
  if @s3_metadata
360
374
  put_options[:metadata] = {}
@@ -456,8 +470,9 @@ module Fluent::Plugin
456
470
  log.warn "The default value of s3_object_key_format will use ${chunk_id} instead of %{index} to avoid object conflict in v2"
457
471
  end
458
472
 
459
- if (@buffer_config.flush_thread_count > 1) && ['${chunk_id}', '%{uuid_flush}'].none? { |key| @s3_object_key_format.include?(key) }
460
- 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"
473
+ is_working_on_parallel = @buffer_config.flush_thread_count > 1 || system_config.workers > 1
474
+ if is_working_on_parallel && ['${chunk_id}', '%{uuid_flush}'].none? { |key| @s3_object_key_format.include?(key) }
475
+ 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"
461
476
  end
462
477
  end
463
478
 
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
@@ -115,14 +115,19 @@ class S3InputTest < Test::Unit::TestCase
115
115
  end
116
116
 
117
117
 
118
- def test_s3_endpoint_with_valid_endpoint
119
- d = create_driver(CONFIG + 's3_endpoint riak-cs.example.com')
120
- assert_equal 'riak-cs.example.com', d.instance.s3_endpoint
118
+ data('Normal endpoint' => 'riak-cs.example.com',
119
+ 'VPCE endpoint' => 'vpce.amazonaws.com',
120
+ 'FIPS endpoint' => 'fips.xxx.amazonaws.com',
121
+ 'GOV endpoint' => 'gov.xxx.amazonaws.com')
122
+ def test_s3_endpoint_with_valid_endpoint(endpoint)
123
+ d = create_driver(CONFIG + "s3_endpoint #{endpoint}")
124
+ assert_equal endpoint, d.instance.s3_endpoint
121
125
  end
122
126
 
123
127
  data('US West (Oregon)' => 's3-us-west-2.amazonaws.com',
124
128
  'EU (Frankfurt)' => 's3.eu-central-1.amazonaws.com',
125
- 'Asia Pacific (Tokyo)' => 's3-ap-northeast-1.amazonaws.com')
129
+ 'Asia Pacific (Tokyo)' => 's3-ap-northeast-1.amazonaws.com',
130
+ 'Invalid VPCE' => 'vpce.xxx.amazonaws.com')
126
131
  def test_s3_endpoint_with_invalid_endpoint(endpoint)
127
132
  assert_raise(Fluent::ConfigError, "s3_endpoint parameter is not supported, use s3_region instead. This parameter is for S3 compatible services") {
128
133
  create_driver(CONFIG + "s3_endpoint #{endpoint}")
@@ -148,6 +153,104 @@ EOS
148
153
  }
149
154
  end
150
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
+
151
254
  Struct.new("StubResponse", :queue_url)
152
255
  Struct.new("StubMessage", :message_id, :receipt_handle, :body)
153
256
 
@@ -510,4 +613,68 @@ EOS
510
613
  ]
511
614
  assert_equal(expected_records, events.map {|_tag, _time, record| record })
512
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
513
680
  end
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.0
4
+ version: 1.7.1
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-04-09 00:00:00.000000000 Z
12
+ date: 2022-07-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fluentd
@@ -115,13 +115,31 @@ 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: []
121
135
  extensions: []
122
136
  extra_rdoc_files: []
123
137
  files:
138
+ - ".github/ISSUE_TEMPLATE/bug_report.yaml"
139
+ - ".github/ISSUE_TEMPLATE/config.yml"
140
+ - ".github/ISSUE_TEMPLATE/feature_request.yaml"
124
141
  - ".github/workflows/linux.yml"
142
+ - ".github/workflows/stale-actions.yml"
125
143
  - ".gitignore"
126
144
  - AUTHORS
127
145
  - ChangeLog
@@ -168,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
186
  - !ruby/object:Gem::Version
169
187
  version: '0'
170
188
  requirements: []
171
- rubygems_version: 3.1.2
189
+ rubygems_version: 3.3.7
172
190
  signing_key:
173
191
  specification_version: 4
174
192
  summary: Amazon S3 output plugin for Fluentd event collector