bfs-s3 0.7.6 → 0.8.4

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: c7b0a87bb99ee39fefb3d297a891b96c740793529a187a8f19a3a9f37219b1e5
4
- data.tar.gz: 4d38e77a1b7f0a1f3a9591dfd4f00a038aec0c43f9dda60203049d9036df8004
3
+ metadata.gz: 759ac37f6057cd72d3a8126cbd2e733745efd8d2a5e0845b0fe1ffa7e4555eba
4
+ data.tar.gz: f988f4496cc91538a70326eba61896b2309b18e70a52604d7389a4857df22a2c
5
5
  SHA512:
6
- metadata.gz: d79da1d49939071bd04072e3120d4e4d4dd7c35c78cae2eba0010e6e7a0900052cc92970ba6e56c17bb1b6595b0a5553d3d5fb274140429fd47ca9b57ba5eb17
7
- data.tar.gz: 38831316b1684be8981982309b4d85e03b2c57e6ec29ed6e245cb8ddaa042166b5a4ca0479af621e5fa56eb0cf2740d2274029d8a4311a658428074e62f699c5
6
+ metadata.gz: 0db4458fc49076e9c9780c69864d53b21298f286360b4441635210162ad47be74e0c537faac51060a00aaca033aeae063909e84b8a519e0bea5dc47fab56d293
7
+ data.tar.gz: a44ed9a7876cca15c41209207dd8045666bd691f120573d8a04e98b41e40b3911c7766c794e2db21fe9cf4de64bc7037c5a36cf21ad5bfe6117f3b1dcb5cf944
data/lib/bfs/bucket/s3.rb CHANGED
@@ -33,22 +33,19 @@ module BFS
33
33
 
34
34
  # Lists the contents of a bucket using a glob pattern
35
35
  def ls(pattern = '**/*', **opts)
36
- prefix = pattern[%r{^[^*?\{\}\[\]]+/}]
37
- prefix = File.join(*[@prefix, prefix].compact) if @prefix
38
-
39
- opts = opts.merge(bucket: name, prefix: @prefix)
40
- opts[:prefix] = prefix if prefix
36
+ Enumerator.new do |acc|
37
+ walk(pattern, **opts) do |path, _|
38
+ acc << path
39
+ end
40
+ end
41
+ end
41
42
 
42
- next_token = nil
43
- Enumerator.new do |y|
44
- loop do
45
- resp = @client.list_objects_v2 opts.merge(continuation_token: next_token)
46
- resp.contents.each do |obj|
47
- name = trim_prefix(obj.key)
48
- y << name if File.fnmatch?(pattern, name, File::FNM_PATHNAME)
49
- end
50
- next_token = resp.next_continuation_token.to_s
51
- break if next_token.empty?
43
+ # Iterates over the contents of a bucket using a glob pattern
44
+ def glob(pattern = '**/*', **opts)
45
+ Enumerator.new do |acc|
46
+ walk(pattern, **opts) do |path, obj|
47
+ info = BFS::FileInfo.new(path: path, size: obj.size, mtime: obj.last_modified)
48
+ acc << info
52
49
  end
53
50
  end
54
51
  end
@@ -60,7 +57,7 @@ module BFS
60
57
  info = @client.head_object(**opts)
61
58
  raise BFS::FileNotFound, path unless info
62
59
 
63
- BFS::FileInfo.new(path: path, size: info.content_length, mtime: info.last_modified, content_type: info.content_type, metadata: norm_meta(info.metadata))
60
+ BFS::FileInfo.new path: path, size: info.content_length, mtime: info.last_modified, content_type: info.content_type, metadata: norm_meta(info.metadata)
64
61
  rescue Aws::S3::Errors::NoSuchKey, Aws::S3::Errors::NoSuchBucket, Aws::S3::Errors::NotFound
65
62
  raise BFS::FileNotFound, path
66
63
  end
@@ -82,7 +79,7 @@ module BFS
82
79
  opts[:server_side_encryption] ||= @sse if @sse
83
80
  opts[:storage_class] ||= @storage_class if @storage_class
84
81
 
85
- BFS::TempWriter.new(path, encoding: encoding, perm: perm) do |t|
82
+ BFS::Writer.new(path, encoding: encoding, perm: perm) do |t|
86
83
  File.open(t, encoding: encoding) do |file|
87
84
  @client.put_object(opts.merge(body: file))
88
85
  end
@@ -144,9 +141,38 @@ module BFS
144
141
  config[:credentials] = opts[:credentials] if opts[:credentials]
145
142
  config[:credentials] ||= Aws::Credentials.new(opts[:access_key_id].to_s, opts[:secret_access_key].to_s) if opts[:access_key_id]
146
143
  config[:credentials] ||= Aws::SharedCredentials.new(profile_name: opts[:profile_name]) if opts[:profile_name]
144
+ config[:credentials] = assume_role_credentials(opts[:assume_role], config[:credentials]) if opts[:assume_role]
147
145
 
148
146
  Aws::S3::Client.new(config)
149
147
  end
148
+
149
+ def assume_role_credentials(role_arn, credentials = nil)
150
+ opts = {
151
+ role_arn: role_arn,
152
+ role_session_name: SecureRandom.urlsafe_base64(12),
153
+ }
154
+ opts[:client] = Aws::STS::Client.new(credentials: credentials) if credentials
155
+ Aws::AssumeRoleCredentials.new(**opts)
156
+ end
157
+
158
+ def walk(pattern, **opts)
159
+ prefix = pattern[%r{^[^*?\{\}\[\]]+/}]
160
+ prefix = File.join(*[@prefix, prefix].compact) if @prefix
161
+
162
+ opts = opts.merge(bucket: name, prefix: @prefix)
163
+ opts[:prefix] = prefix if prefix
164
+
165
+ next_token = nil
166
+ loop do
167
+ resp = @client.list_objects_v2 opts.merge(continuation_token: next_token)
168
+ resp.contents.each do |obj|
169
+ path = trim_prefix(obj.key)
170
+ yield(path, obj) if File.fnmatch?(pattern, path, File::FNM_PATHNAME)
171
+ end
172
+ next_token = resp.next_continuation_token.to_s
173
+ break if next_token.empty?
174
+ end
175
+ end
150
176
  end
151
177
  end
152
178
  end
@@ -154,7 +180,7 @@ end
154
180
  BFS.register('s3') do |url, opts, block|
155
181
  prefix = BFS.norm_path(opts[:prefix] || url.path)
156
182
  opts[:prefix] = prefix.empty? ? nil : prefix
157
- opts = opts.slice(:prefix, :region, :sse, :access_key_id, :secret_access_key, :acl, :storage_class, :encoding)
183
+ opts = opts.slice(:prefix, :region, :sse, :access_key_id, :secret_access_key, :acl, :storage_class, :encoding, :assume_role)
158
184
 
159
185
  BFS::Bucket::S3.open url.host, **opts, &block
160
186
  end
@@ -3,20 +3,20 @@ require 'spec_helper'
3
3
  bucket_name = 'bsm-bfs-unittest'
4
4
 
5
5
  RSpec.describe BFS::Bucket::S3, s3: true do
6
- let(:prefix) { "x/#{SecureRandom.uuid}/" }
7
-
8
6
  subject do
9
7
  described_class.new bucket_name, prefix: prefix
10
8
  end
11
9
 
12
- after :all do
13
- bucket = described_class.new bucket_name, prefix: 'x/'
10
+ let(:prefix) { "x/#{SecureRandom.uuid}/" }
11
+
12
+ after do
13
+ bucket = described_class.new bucket_name, prefix: prefix
14
14
  bucket.ls.each {|name| bucket.rm(name) }
15
15
  end
16
16
 
17
17
  it_behaves_like 'a bucket'
18
18
 
19
- it 'should resolve from URL' do
19
+ it 'resolves from URL' do
20
20
  bucket = BFS.resolve("s3://#{bucket_name}/?acl=private&encoding=binary")
21
21
  expect(bucket).to be_instance_of(described_class)
22
22
  expect(bucket.name).to eq(bucket_name)
@@ -32,7 +32,7 @@ RSpec.describe BFS::Bucket::S3, s3: true do
32
32
  bucket.close
33
33
  end
34
34
 
35
- it 'should enumerate over a large number of files' do
35
+ it 'enumerates over a large number of files' do
36
36
  bucket = described_class.new bucket_name, prefix: 'm/'
37
37
  expect(bucket.ls('**/*').count).to eq(2121)
38
38
  bucket.close
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bfs-s3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.6
4
+ version: 0.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitrij Denissenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-10 00:00:00.000000000 Z
11
+ date: 2021-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-s3
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.7.6
33
+ version: 0.8.4
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.7.6
40
+ version: 0.8.4
41
41
  description: https://github.com/bsm/bfs.rb
42
42
  email: dimitrij@blacksquaremedia.com
43
43
  executables: []
@@ -67,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  requirements: []
70
- rubygems_version: 3.1.2
70
+ rubygems_version: 3.2.15
71
71
  signing_key:
72
72
  specification_version: 4
73
73
  summary: S3 bucket adapter for bfs