fluent-plugin-s3 1.5.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.
@@ -0,0 +1,83 @@
1
+ require "open3"
2
+
3
+ module Fluent::Plugin
4
+ class S3Output
5
+ class ParquetCompressor < Compressor
6
+ S3Output.register_compressor("parquet", self)
7
+
8
+ config_section :compress, multi: false do
9
+ desc "parquet compression codec"
10
+ config_param :parquet_compression_codec, :enum, list: [:uncompressed, :snappy, :gzip, :lzo, :brotli, :lz4, :zstd], default: :snappy
11
+ desc "parquet file page size"
12
+ config_param :parquet_page_size, :size, default: 8192
13
+ desc "parquet file row group size"
14
+ config_param :parquet_row_group_size, :size, default: 128 * 1024 * 1024
15
+ desc "record data format type"
16
+ config_param :record_type, :enum, list: [:avro, :csv, :jsonl, :msgpack, :tsv, :json], default: :msgpack
17
+ desc "schema type"
18
+ config_param :schema_type, :enum, list: [:avro, :bigquery], default: :avro
19
+ desc "path to schema file"
20
+ config_param :schema_file, :string
21
+ end
22
+
23
+ def configure(conf)
24
+ super
25
+ check_command("columnify", "-h")
26
+
27
+ if [:lzo, :brotli, :lz4].include?(@compress.parquet_compression_codec)
28
+ raise Fluent::ConfigError, "unsupported compression codec: #{@compress.parquet_compression_codec}"
29
+ end
30
+
31
+ @parquet_compression_codec = @compress.parquet_compression_codec.to_s.upcase
32
+ if @compress.record_type == :json
33
+ @record_type = :jsonl
34
+ else
35
+ @record_type = @compress.record_type
36
+ end
37
+ end
38
+
39
+ def ext
40
+ "parquet".freeze
41
+ end
42
+
43
+ def content_type
44
+ "application/octet-stream".freeze
45
+ end
46
+
47
+ def compress(chunk, tmp)
48
+ chunk_is_file = @buffer_type == "file"
49
+ path = if chunk_is_file
50
+ chunk.path
51
+ else
52
+ w = Tempfile.new("chunk-parquet-tmp")
53
+ w.binmode
54
+ chunk.write_to(w)
55
+ w.close
56
+ w.path
57
+ end
58
+ stdout, stderr, status = columnify(path, tmp.path)
59
+ unless status.success?
60
+ raise Fluent::UnrecoverableError, "failed to execute columnify command. stdout=#{stdout} stderr=#{stderr} status=#{status.inspect}"
61
+ end
62
+ ensure
63
+ unless chunk_is_file
64
+ w.close(true) rescue nil
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def columnify(src_path, dst_path)
71
+ Open3.capture3("columnify",
72
+ "-parquetCompressionCodec", @parquet_compression_codec,
73
+ "-parquetPageSize", @compress.parquet_page_size.to_s,
74
+ "-parquetRowGroupSize", @compress.parquet_row_group_size.to_s,
75
+ "-recordType", @record_type.to_s,
76
+ "-schemaType", @compress.schema_type.to_s,
77
+ "-schemaFile", @compress.schema_file,
78
+ "-output", dst_path,
79
+ src_path)
80
+ end
81
+ end
82
+ end
83
+ end
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
 
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.5.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-02-16 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,15 +115,32 @@ 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
- - ".travis.yml"
127
144
  - AUTHORS
128
145
  - ChangeLog
129
146
  - Gemfile
@@ -132,6 +149,11 @@ files:
132
149
  - Rakefile
133
150
  - VERSION
134
151
  - appveyor.yml
152
+ - docs/credentials.md
153
+ - docs/howto.md
154
+ - docs/input.md
155
+ - docs/output.md
156
+ - docs/v0.12.md
135
157
  - fluent-plugin-s3.gemspec
136
158
  - lib/fluent/log-ext.rb
137
159
  - lib/fluent/plugin/in_s3.rb
@@ -139,6 +161,7 @@ files:
139
161
  - lib/fluent/plugin/s3_compressor_gzip_command.rb
140
162
  - lib/fluent/plugin/s3_compressor_lzma2.rb
141
163
  - lib/fluent/plugin/s3_compressor_lzo.rb
164
+ - lib/fluent/plugin/s3_compressor_parquet.rb
142
165
  - lib/fluent/plugin/s3_extractor_gzip_command.rb
143
166
  - lib/fluent/plugin/s3_extractor_lzma2.rb
144
167
  - lib/fluent/plugin/s3_extractor_lzo.rb
@@ -163,10 +186,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
163
186
  - !ruby/object:Gem::Version
164
187
  version: '0'
165
188
  requirements: []
166
- rubygems_version: 3.1.4
189
+ rubygems_version: 3.3.7
167
190
  signing_key:
168
191
  specification_version: 4
169
192
  summary: Amazon S3 output plugin for Fluentd event collector
170
- test_files:
171
- - test/test_in_s3.rb
172
- - test/test_out_s3.rb
193
+ test_files: []