bfs-s3 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e4e2d75bba619dbe3e7a68ff669b91cb5e031acbac453683f6197d11a7cc98d
4
- data.tar.gz: 1b92cdd4b1cf3bfbd2b173498de47d7b27528f590010fe5ab5256f6bd391d373
3
+ metadata.gz: 4d6df20270797fc308401a911b078872076ce9cb248bec9fd7c725fec0d034a3
4
+ data.tar.gz: 27cc25f8e2d2f4a854d83decf3fffdff7771c67b9bd69c41d87f0b23a79903fd
5
5
  SHA512:
6
- metadata.gz: d5848551c6fe1b2cc699c3d0cdb47010e2806296cc3cb7734c8a40ede206b566d49855110e70fca2917b65cd92f943497e6acec00b6c17713f3f7a04efb7142d
7
- data.tar.gz: 4e410ead67a7cf7886b14224d216311f759f1be92dc42d85e4ccf11772c935e22fbd723db3f26274f729ac445b15cb56f847c76fa3444799e5d80b7e9cfed398
6
+ metadata.gz: 3c370605ebd6d535da63e198dfc5141e7343eb1b3a55ee3d34c9714d7a83157d2a922089cc875f84b369e6e87181849c1a3ab3ec22b35bcda168614329cfa982
7
+ data.tar.gz: ad263a8e5ee1c2e6423d476b7a65b7d2d227a39002c6d495d8d672bdb22a909bc50c802b306e6ef1a2c7f45ba45246fe24de7daf070a26524319b05f4da07dd9
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
@@ -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.8.0
4
+ version: 0.9.0
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-12-01 00:00:00.000000000 Z
11
+ date: 2021-06-29 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.8.0
33
+ version: 0.9.0
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.8.0
40
+ version: 0.9.0
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.4
70
+ rubygems_version: 3.2.15
71
71
  signing_key:
72
72
  specification_version: 4
73
73
  summary: S3 bucket adapter for bfs