Class: Bosh::Blobstore::S3BlobstoreClient
- Inherits:
-
BaseClient
- Object
- Client
- BaseClient
- Bosh::Blobstore::S3BlobstoreClient
- Defined in:
- lib/blobstore_client/s3_blobstore_client.rb
Constant Summary collapse
- ENDPOINT =
'https://s3.amazonaws.com'
- DEFAULT_CIPHER_NAME =
'aes-128-cbc'
Constants inherited from Client
Client::PROVIDER_NAMES, Client::VERSION
Instance Attribute Summary collapse
-
#bucket_name ⇒ Object
readonly
Returns the value of attribute bucket_name.
-
#encryption_key ⇒ Object
readonly
Returns the value of attribute encryption_key.
-
#simple ⇒ Object
readonly
Returns the value of attribute simple.
Instance Method Summary collapse
- #create_file(object_id, file) ⇒ Object
- #delete_object(object_id) ⇒ Object
- #get_file(object_id, file) ⇒ Object
-
#initialize(options) ⇒ S3BlobstoreClient
constructor
Blobstore client for S3 with optional object encryption.
- #object_exists?(object_id) ⇒ Boolean
Methods inherited from BaseClient
#create, #delete, #exists?, #get
Methods inherited from Client
Constructor Details
#initialize(options) ⇒ S3BlobstoreClient
Note:
If access_key_id and secret_access_key are not present, the blobstore client operates in read only mode as a simple_blobstore_client
Blobstore client for S3 with optional object encryption
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/blobstore_client/s3_blobstore_client.rb', line 26 def initialize() super() @bucket_name = @options[:bucket_name] @encryption_key = @options[:encryption_key] = { use_ssl: @options.fetch(:use_ssl, true), s3_port: @options.fetch(:port, 443), s3_endpoint: @options.fetch(:host, URI.parse(S3BlobstoreClient::ENDPOINT).host), s3_force_path_style: @options.fetch(:s3_force_path_style, false), ssl_verify_peer: @options.fetch(:ssl_verify_peer, true), s3_multipart_threshold: @options.fetch(:s3_multipart_threshold, 16_777_216), } .merge!(aws_credentials) # using S3 without credentials is a special case: # it is really the simple blobstore client with a bucket name if read_only? if @encryption_key raise BlobstoreError, "can't use read-only with an encryption key" end unless @options[:bucket_name] || @options[:bucket] raise BlobstoreError, 'bucket name required' end @options[:bucket] ||= @options[:bucket_name] @options[:endpoint] ||= S3BlobstoreClient::ENDPOINT @simple = SimpleBlobstoreClient.new(@options) else @s3 = AWS::S3.new() end rescue AWS::Errors::Base => e raise BlobstoreError, "Failed to initialize S3 blobstore: #{e.}" end |
Instance Attribute Details
#bucket_name ⇒ Object (readonly)
Returns the value of attribute bucket_name.
14 15 16 |
# File 'lib/blobstore_client/s3_blobstore_client.rb', line 14 def bucket_name @bucket_name end |
#encryption_key ⇒ Object (readonly)
Returns the value of attribute encryption_key.
14 15 16 |
# File 'lib/blobstore_client/s3_blobstore_client.rb', line 14 def encryption_key @encryption_key end |
#simple ⇒ Object (readonly)
Returns the value of attribute simple.
14 15 16 |
# File 'lib/blobstore_client/s3_blobstore_client.rb', line 14 def simple @simple end |
Instance Method Details
#create_file(object_id, file) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/blobstore_client/s3_blobstore_client.rb', line 65 def create_file(object_id, file) raise BlobstoreError, 'unsupported action' if @simple object_id ||= generate_object_id file = encrypt_file(file) if @encryption_key # in Ruby 1.8 File doesn't respond to :path path = file.respond_to?(:path) ? file.path : file store_in_s3(path, full_oid_path(object_id)) object_id rescue AWS::Errors::Base => e raise BlobstoreError, "Failed to create object, S3 response error: #{e.}" ensure FileUtils.rm(file) if @encryption_key end |
#delete_object(object_id) ⇒ Object
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/blobstore_client/s3_blobstore_client.rb', line 113 def delete_object(object_id) raise BlobstoreError, 'unsupported action' if @simple object_id = full_oid_path(object_id) object = get_object_from_s3(object_id) raise NotFound, "Object '#{object_id}' is not found" unless object.exists? object.delete rescue AWS::Errors::Base => e raise BlobstoreError, "Failed to delete object '#{object_id}', S3 response error: #{e.}" end |
#get_file(object_id, file) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/blobstore_client/s3_blobstore_client.rb', line 85 def get_file(object_id, file) object_id = full_oid_path(object_id) return @simple.get_file(object_id, file) if @simple if @encryption_key cipher = OpenSSL::Cipher::Cipher.new(DEFAULT_CIPHER_NAME) cipher.decrypt cipher.key = Digest::SHA1.digest(encryption_key)[0..(cipher.key_len - 1)] end object = get_object_from_s3(object_id) object.read do |chunk| if @encryption_key file.write(cipher.update(chunk)) else file.write(chunk) end end file.write(cipher.final) if @encryption_key rescue AWS::S3::Errors::NoSuchKey => e raise NotFound, "S3 object '#{object_id}' not found" rescue AWS::Errors::Base => e raise BlobstoreError, "Failed to find object '#{object_id}', S3 response error: #{e.}" end |
#object_exists?(object_id) ⇒ Boolean
124 125 126 127 128 129 |
# File 'lib/blobstore_client/s3_blobstore_client.rb', line 124 def object_exists?(object_id) object_id = full_oid_path(object_id) return simple.exists?(object_id) if simple get_object_from_s3(object_id).exists? end |