class Fog::Storage::AzureRM::Real

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls. This is to make this library compatible with CarrierWave.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implementation for service calls. msdn.microsoft.com/en-us/library/azure/dd135734.aspx

This class provides the actual implementation for service calls. msdn.microsoft.com/en-us/library/azure/dd179352.aspx

This class provides the actual implementation for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implemention for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

This class provides the actual implementation for service calls.

Constants

BLOCK_SIZE

Public Class Methods

new(options) click to toggle source
# File lib/fog/azurerm/storage.rb, line 82
def initialize(options)
  begin
    require 'azure/storage/common'
    require 'azure/storage/blob'
    require 'securerandom'
    @debug = ENV['DEBUG'] || options[:debug]
    require 'azure/core/http/debug_filter' if @debug
  rescue LoadError => e
    retry if require('rubygems')
    raise e.message
  end

  options[:environment] = 'AzureCloud' if options[:environment].nil?

  @tenant_id = options[:tenant_id]
  @client_id = options[:client_id]
  @client_secret = options[:client_secret]
  @subscription_id = options[:subscription_id]
  @environment = options[:environment]

  credentials = Fog::Credentials::AzureRM.get_credentials(@tenant_id, @client_id, @client_secret, @environment)
  telemetry = "gitlab-fog-azure-rm/#{Fog::AzureRM::VERSION}"

  return unless @azure_storage_account_name != options[:azure_storage_account_name] ||
                @azure_storage_access_key != options[:azure_storage_access_key]

  @azure_storage_account_name = options[:azure_storage_account_name]
  @azure_storage_access_key = options[:azure_storage_access_key]
  @azure_storage_domain = options[:azure_storage_domain]

  domain =
    if @azure_storage_domain.nil? || @azure_storage_domain.empty?
      get_blob_endpoint(@azure_storage_account_name, true, @environment)
    else
      get_blob_endpoint_with_domain(@azure_storage_account_name, true, @azure_storage_domain)
    end

  azure_client = Azure::Storage::Common::Client.create(storage_account_name: @azure_storage_account_name,
                                                       storage_access_key: @azure_storage_access_key,
                                                       storage_blob_host: domain)
  @blob_client = Azure::Storage::Blob::BlobService.new(client: azure_client)
  @blob_client.with_filter(Azure::Storage::Common::Core::Filter::ExponentialRetryPolicyFilter.new)
  @blob_client.with_filter(Azure::Core::Http::DebugFilter.new) if @debug
  @signature_client = Azure::Storage::Common::Core::Auth::SharedAccessSignature.new(@azure_storage_account_name,
                                                                                    @azure_storage_access_key)
end

Public Instance Methods

acquire_blob_lease(container_name, name, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/acquire_blob_lease.rb, line 6
def acquire_blob_lease(container_name, name, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Leasing blob: #{name} of container #{container_name} options: #{options}"
  Fog::Logger.debug msg

  begin
    lease_id = @blob_client.acquire_blob_lease(container_name, name, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Blob #{name} leased successfully."
  lease_id
end
acquire_container_lease(name, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/acquire_container_lease.rb, line 6
def acquire_container_lease(name, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Leasing container: #{name} options: #{options}"
  Fog::Logger.debug msg

  begin
    lease_id = @blob_client.acquire_container_lease(name, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Container #{name} leased successfully."
  lease_id
end
check_container_exists(name) click to toggle source
# File lib/fog/azurerm/requests/storage/check_container_exists.rb, line 6
def check_container_exists(name)
  msg = "Checking container #{name}."
  Fog::Logger.debug msg
  begin
    get_container_properties(name)
    Fog::Logger.debug "Container #{name} exists."
    true
  rescue Exception => e
    if e.message.include? 'NotFound'
      Fog::Logger.debug "The specified container #{name} does not exist."
      false
    end
  end
end
commit_blob_blocks(container_name, blob_name, blocks, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/commit_blob_blocks.rb, line 6
def commit_blob_blocks(container_name, blob_name, blocks, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "commit_blob_blocks: Complete uploading #{blob_name} to the container #{container_name}. options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.commit_blob_blocks(container_name, blob_name, blocks, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Block blob #{blob_name} is uploaded successfully."
  true
end
compare_container_blobs(container1, container2) click to toggle source
# File lib/fog/azurerm/requests/storage/compare_container_blobs.rb, line 6
def compare_container_blobs(container1, container2)
  msg = "Comparing blobs from container #{container1} to container #{container2}"
  Fog::Logger.debug msg
  begin
    identical_blobs = get_identical_blobs_from_containers(container1, container2)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end
  identical_blobs
end
copy_blob(destination_container, destination_blob, source_container, source_blob, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/copy_blob.rb, line 6
def copy_blob(destination_container, destination_blob, source_container, source_blob, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Copying blob: #{source_blob} from container #{source_container} to container #{destination_container} options: #{options}"
  Fog::Logger.debug msg

  begin
    copy_id, copy_status = @blob_client.copy_blob(destination_container, destination_blob, source_container, source_blob, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Copying blob: x-ms-copy-id: #{copy_id}, x-ms-copy-status: #{copy_status}"
  [copy_id, copy_status]
end
copy_blob_from_uri(destination_container, destination_blob, source_blob_uri, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/copy_blob_from_uri.rb, line 6
def copy_blob_from_uri(destination_container, destination_blob, source_blob_uri, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Copying blob: #{source_blob_uri} to container #{destination_container} options: #{options}"
  Fog::Logger.debug msg

  begin
    copy_id, copy_status = @blob_client.copy_blob_from_uri(destination_container, destination_blob, source_blob_uri, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Copying blob: x-ms-copy-id: #{copy_id}, x-ms-copy-status: #{copy_status}"
  [copy_id, copy_status]
end
copy_object(source_container, source_blob, target_container, target_blob, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/copy_object.rb, line 7
def copy_object(source_container, source_blob, target_container, target_blob, options = {})
  copy_blob(target_container, target_blob, source_container, source_blob, options)
end
create_block_blob(container_name, blob_name, body, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/create_block_blob.rb, line 6
def create_block_blob(container_name, blob_name, body, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "create_block_blob #{blob_name} to the container #{container_name}. options: #{options}"
  Fog::Logger.debug msg

  @blob_client.create_block_blob(container_name, blob_name, body, options)
rescue Azure::Core::Http::HTTPError => ex
  raise_azure_exception(ex, msg)
end
create_container(name, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/create_container.rb, line 6
def create_container(name, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Creating container: #{name}. options: #{options}"
  Fog::Logger.debug msg

  begin
    container = @blob_client.create_container(name, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Container #{name} created successfully."
  container
end
create_page_blob(container_name, blob_name, blob_size, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/create_page_blob.rb, line 6
def create_page_blob(container_name, blob_name, blob_size, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "create_page_blob #{blob_name} to the container #{container_name}. blob_size: #{blob_size}, options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.create_page_blob(container_name, blob_name, blob_size, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Page blob #{blob_name} created successfully."
  true
end
delete_blob(container_name, blob_name, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/delete_blob.rb, line 6
def delete_blob(container_name, blob_name, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Deleting blob: #{blob_name} in container #{container_name}. options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.delete_blob(container_name, blob_name, options)
  rescue Azure::Core::Http::HTTPError => ex
    return true if ex.message.include?('(404)')
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Blob #{blob_name} deleted successfully."
  true
end
delete_blob_https_url(container_name, blob_name, expires) click to toggle source

Get a pre-signed URL to delete an object in Azure blob storage

@param container_name [String] Name of container containing blob @param blob_name [String] Name of blob to get expiring url for @param expires [Time] An expiry time for this url

@return [String] - https url for blob

@see docs.microsoft.com/en-us/rest/api/storageservices/delete-blob

# File lib/fog/azurerm/requests/storage/delete_blob_https_url.rb, line 16
def delete_blob_https_url(container_name, blob_name, expires)
  relative_path = "#{container_name}/#{blob_name}"
  params = {
    service: 'b',
    resource: 'b',
    permissions: 'd',
    expiry: expires.utc.iso8601,
    protocol: 'https'
  }
  token = @signature_client.generate_service_sas_token(relative_path, params)
  uri = @blob_client.generate_uri(relative_path, {}, { encode: true })
  "#{uri}?#{token}"
end
delete_container(name) click to toggle source
# File lib/fog/azurerm/requests/storage/delete_container.rb, line 6
def delete_container(name)
  options = { request_id: SecureRandom.uuid }
  msg = "Deleting container: #{name}. options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.delete_container(name, options)
  rescue Azure::Core::Http::HTTPError => ex
    return true if ex.message.include?('(404)')
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Container #{name} deleted successfully."
  true
end
delete_object_url(container_name, blob_name, expires) click to toggle source

Get a pre-signed URL to delete an object in Azure blob storage This is to make this library compatible with CarrierWave.

@param container_name [String] Name of container containing blob @param blob_name [String] Name of blob to get expiring url for @param expires [Time] An expiry time for this url

@return [String] - https url for blob

@see docs.microsoft.com/en-us/rest/api/storageservices/delete-blob

# File lib/fog/azurerm/requests/storage/delete_object_url.rb, line 17
def delete_object_url(container_name, blob_name, expires)
  delete_blob_https_url(container_name, blob_name, expires)
end
get_blob(container_name, blob_name, options = {}, &block) click to toggle source
# File lib/fog/azurerm/requests/storage/get_blob.rb, line 65
def get_blob(container_name, blob_name, options = {}, &block)
  if block_given?
    get_blob_with_block_given(container_name, blob_name, options, &block)
  else
    options[:request_id] = SecureRandom.uuid
    msg = "get_blob blob #{blob_name} in the container #{container_name}. options: #{options}"
    Fog::Logger.debug msg

    begin
      blob, content = @blob_client.get_blob(container_name, blob_name, options)
      Fog::Logger.debug "Get blob #{blob_name} successfully."
      [blob, content]
    rescue Azure::Core::Http::HTTPError => ex
      raise 'NotFound' if ex.message.include?('(404)')
      raise_azure_exception(ex, msg)
    end
  end
end
get_blob_http_url(container_name, blob_name, expires) click to toggle source

Get an expiring http blob url from Azure blob storage

@param container_name [String] Name of container containing blob @param blob_name [String] Name of blob to get expiring url for @param expires [Time] An expiry time for this url

@return [String] - http url for blob

@see msdn.microsoft.com/en-us/library/azure/mt584140.aspx

# File lib/fog/azurerm/requests/storage/get_blob_http_url.rb, line 16
def get_blob_http_url(container_name, blob_name, expires)
  relative_path = "#{container_name}/#{blob_name}"
  relative_path = remove_trailing_periods_from_path_segments(relative_path)
  params = {
    service: 'b',
    resource: 'b',
    permissions: 'r',
    expiry: expires.utc.iso8601
  }
  token = @signature_client.generate_service_sas_token(relative_path, params)
  uri = @blob_client.generate_uri(relative_path, {}, { encode: true })
  url = "#{uri}?#{token}"
  url.gsub('https:', 'http:')
end
get_blob_https_url(container_name, blob_name, expires) click to toggle source

Get an expiring https blob url from Azure blob storage

@param container_name [String] Name of container containing blob @param blob_name [String] Name of blob to get expiring url for @param expires [Time] An expiry time for this url

@return [String] - https url for blob

@see msdn.microsoft.com/en-us/library/azure/mt584140.aspx

# File lib/fog/azurerm/requests/storage/get_blob_https_url.rb, line 16
def get_blob_https_url(container_name, blob_name, expires)
  relative_path = "#{container_name}/#{blob_name}"
  relative_path = remove_trailing_periods_from_path_segments(relative_path)
  params = {
    service: 'b',
    resource: 'b',
    permissions: 'r',
    expiry: expires.utc.iso8601,
    protocol: 'https'
  }
  token = @signature_client.generate_service_sas_token(relative_path, params)
  uri = @blob_client.generate_uri(relative_path, {}, { encode: true })
  "#{uri}?#{token}"
end
get_blob_properties(container_name, name, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/get_blob_properties.rb, line 6
def get_blob_properties(container_name, name, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Get Blob #{name} properties in container #{container_name}, options: #{options}."
  Fog::Logger.debug msg
  begin
    blob = @blob_client.get_blob_properties(container_name, name, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise 'NotFound' if ex.message.include?('(404)')
    raise_azure_exception(ex, msg)
  end
  Fog::Logger.debug "Getting properties of blob #{name} successfully."
  blob
end
get_blob_url(container_name, blob_name, options = {}) click to toggle source

Get a public blob url from Azure blob storage

# File lib/fog/azurerm/requests/storage/get_blob_url.rb, line 7
def get_blob_url(container_name, blob_name, options = {})
  uri = @blob_client.generate_uri("#{container_name}/#{blob_name}", {}, { encode: true })

  if options[:scheme] == 'http'
    uri.to_s.gsub('https:', 'http:')
  else
    uri.to_s
  end
end
get_blob_with_block_given(container_name, blob_name, options, &_block) click to toggle source
# File lib/fog/azurerm/requests/storage/get_blob.rb, line 8
def get_blob_with_block_given(container_name, blob_name, options, &_block)
  options[:request_id] = SecureRandom.uuid
  msg = "get_blob_with_block_given: blob #{blob_name} in the container #{container_name}. options: #{options}"
  Fog::Logger.debug msg

  begin
    blob = @blob_client.get_blob_properties(container_name, blob_name, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise 'NotFound' if ex.message.include?('(404)')
    raise_azure_exception(ex, msg)
  end

  content_length = blob.properties[:content_length]
  if content_length.zero?
    Proc.new.call('', 0, 0)
    return [blob, '']
  end

  start_range = 0
  end_range = content_length - 1
  start_range = options[:start_range] if options[:start_range]
  end_range = options[:end_range] if options[:end_range]
  raise ArgumentError.new(':end_range MUST be greater than :start_range') if start_range > end_range

  if start_range == end_range
    Proc.new.call('', 0, 0)
    return [blob, '']
  end

  buffer_size = BLOCK_SIZE
  buffer_size = options[:block_size] if options[:block_size]
  buffer_start_range = start_range
  total_bytes = end_range - start_range + 1
  params = options.dup

  while buffer_start_range < end_range
    buffer_end_range = [end_range, buffer_start_range + buffer_size - 1].min
    params[:start_range] = buffer_start_range
    params[:end_range] = buffer_end_range
    params[:request_id] = SecureRandom.uuid

    begin
      msg = "get_blob_with_block_given: blob #{blob_name} in the container #{container_name}. options: #{params}"
      Fog::Logger.debug msg
      _, content = @blob_client.get_blob(container_name, blob_name, params)
    rescue Azure::Core::Http::HTTPError => ex
      raise 'NotFound' if ex.message.include?('(404)')
      raise_azure_exception(ex, msg)
    end

    Proc.new.call(content, end_range - buffer_end_range, total_bytes)
    buffer_start_range += buffer_size
  end
  # No need to return content when block is given.
  [blob, '']
end
get_container_acl(container_name, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/get_container_acl.rb, line 6
def get_container_acl(container_name, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Get container ACL: #{container_name}. options: #{options}"
  Fog::Logger.debug msg

  begin
    container, signed_identifiers = @blob_client.get_container_acl(container_name, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Getting ACL of container #{container_name} successfully."
  [container.public_access_level, signed_identifiers]
end
get_container_properties(name, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/get_container_properties.rb, line 6
def get_container_properties(name, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Getting container properties: #{name}, options: #{options}."
  Fog::Logger.debug msg

  begin
    container = @blob_client.get_container_properties(name, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise 'NotFound' if ex.message.include?('(404)')
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Getting properties of container #{name} successfully."
  container
end
get_container_url(container_name, options = {}) click to toggle source

Get a public container url from Azure storage container

@param container_name [String] Name of container

@return [String] - url for container

# File lib/fog/azurerm/requests/storage/get_container_url.rb, line 12
def get_container_url(container_name, options = {})
  query = { 'comp' => 'list', 'restype' => 'container' }
  uri = @blob_client.generate_uri(container_name, query, { encode: true })

  if options[:scheme] == 'http'
    uri.to_s.gsub('https:', 'http:')
  else
    uri.to_s
  end
end
get_object_url(container_name, blob_name, expires) click to toggle source

Get a public blob url from Azure blob storage This is to make this library compatible with CarrierWave.

# File lib/fog/azurerm/requests/storage/get_object_url.rb, line 8
def get_object_url(container_name, blob_name, expires)
  get_blob_https_url(container_name, blob_name, expires)
end
list_blobs(container_name, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/list_blobs.rb, line 7
def list_blobs(container_name, options = {})
  options = options.dup
  options[:metadata] = true
  next_marker = nil
  blobs = []

  msg = nil

  max_results = -1
  max_results = options[:max_results].to_i if options[:max_results]
  begin
    loop do
      options[:request_id] = SecureRandom.uuid
      msg = "Listing blobs in container: #{container_name}, options: #{options}"
      Fog::Logger.debug msg
      temp = @blob_client.list_blobs(container_name, options)
      # Workaround for the issue https://github.com/Azure/azure-storage-ruby/issues/37
      raise temp unless temp.instance_of?(Azure::Storage::Common::Service::EnumerationResults)

      blobs += temp unless temp.empty?
      break if temp.continuation_token.nil? || temp.continuation_token.empty?
      options[:marker] = temp.continuation_token

      next if max_results == -1

      options[:max_results] = max_results - blobs.size
      if options[:max_results].zero?
        next_marker = temp.continuation_token
        break
      end
    end
  rescue Azure::Core::Http::HTTPError => ex
    raise 'NotFound' if ex.message.include?('(404)')
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Listing blobs in container: #{container_name} successfully."
  {
    next_marker: next_marker,
    blobs: blobs
  }
end
list_containers() click to toggle source
# File lib/fog/azurerm/requests/storage/list_containers.rb, line 7
def list_containers
  options = { metadata: true }
  containers = []
  msg = nil

  begin
    loop do
      options[:request_id] = SecureRandom.uuid
      msg = "Listing containers. options: #{options}"
      Fog::Logger.debug msg
      temp = @blob_client.list_containers(options)
      # Workaround for the issue https://github.com/Azure/azure-storage-ruby/issues/37
      raise temp unless temp.instance_of?(Azure::Storage::Common::Service::EnumerationResults)

      containers += temp unless temp.empty?
      break if temp.continuation_token.nil? || temp.continuation_token.empty?
      options[:marker] = temp.continuation_token
    end
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug 'Listing containers successfully.'
  containers
end
put_blob_block(container_name, blob_name, block_id, data, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/put_blob_block.rb, line 6
def put_blob_block(container_name, blob_name, block_id, data, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "put_blob_block block_id: #{block_id} / #{blob_name} to the container #{container_name}. options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.put_blob_block(container_name, blob_name, block_id, data, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "block_id #{block_id} is uploaded successfully."
  true
end
put_blob_https_url(container_name, blob_name, expires) click to toggle source

Generate a pre-signed URL for create an object in an Azure blob storage

@param container_name [String] Name of container containing blob @param blob_name [String] Name of blob to get expiring url for @param expires [Time] An expiry time for this url

@return [String] - https url for blob

@see docs.microsoft.com/en-us/rest/api/storageservices/put-blob

# File lib/fog/azurerm/requests/storage/put_blob_https_url.rb, line 16
def put_blob_https_url(container_name, blob_name, expires)
  relative_path = "#{container_name}/#{blob_name}"
  params = {
    service: 'b',
    resource: 'b',
    permissions: 'c',
    expiry: expires.utc.iso8601,
    protocol: 'https'
  }
  token = @signature_client.generate_service_sas_token(relative_path, params)
  uri = @blob_client.generate_uri(relative_path, {}, { encode: true })
  "#{uri}?#{token}"
end
put_blob_metadata(container_name, name, metadata, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/put_blob_metadata.rb, line 6
def put_blob_metadata(container_name, name, metadata, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Setting Blob #{name} metadata in a container #{container_name}. options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.set_blob_metadata(container_name, name, metadata, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Setting metadata of blob #{name} successfully."
  true
end
put_blob_pages(container_name, blob_name, start_range, end_range, data, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/put_blob_pages.rb, line 6
def put_blob_pages(container_name, blob_name, start_range, end_range, data, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "put_blob_pages [#{start_range}-#{end_range}] / #{blob_name} to the container #{container_name}. options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.put_blob_pages(container_name, blob_name, start_range, end_range, data, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "[#{start_range}-#{end_range}] / #{blob_name} is uploaded successfully."
  true
end
put_blob_properties(container_name, name, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/put_blob_properties.rb, line 6
def put_blob_properties(container_name, name, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Set Blob #{name} properties #{options} in container #{container_name}."
  Fog::Logger.debug msg

  begin
    @blob_client.set_blob_properties(container_name, name, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Setting properties of blob #{name} successfully."
  true
end
put_container_acl(name, acl, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/put_container_acl.rb, line 6
def put_container_acl(name, acl, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Setting Container #{name} acl #{acl.nil? ? 'nil' : acl}. options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.set_container_acl(name, acl, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Setting acl of container #{name} successfully."
  true
end
put_container_metadata(name, metadata, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/put_container_metadata.rb, line 6
def put_container_metadata(name, metadata, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Setting Container #{name} metadata. options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.set_container_metadata(name, metadata, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Setting metadata of container #{name} successfully."
  true
end
put_object_url(bucket_name, object_name, expire_at, _upload_options) click to toggle source

Generate a pre-signed URL for create an object in an Azure blob storage This is to make this library compatible with CarrierWave.

@param container_name [String] Name of container containing blob @param blob_name [String] Name of blob to get expiring url for @param expires [Time] An expiry time for this url

@return [String] - https url for blob

@see docs.microsoft.com/en-us/rest/api/storageservices/put-blob

# File lib/fog/azurerm/requests/storage/put_object_url.rb, line 17
def put_object_url(bucket_name, object_name, expire_at, _upload_options)
  put_blob_https_url(bucket_name, object_name, expire_at)
end
release_blob_lease(container_name, name, lease_id, options = {}) click to toggle source
# File lib/fog/azurerm/requests/storage/release_blob_lease.rb, line 6
def release_blob_lease(container_name, name, lease_id, options = {})
  options[:request_id] = SecureRandom.uuid
  msg = "Releasing blob: #{name} of container #{container_name} having lease_id #{lease_id} options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.release_blob_lease(container_name, name, lease_id, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Blob #{name} released successfully."
  true
end
release_container_lease(name, lease_id, options={}) click to toggle source
# File lib/fog/azurerm/requests/storage/release_container_lease.rb, line 6
def release_container_lease(name, lease_id, options={})
  options[:request_id] = SecureRandom.uuid
  msg = "Releasing container: #{name} having lease_id #{lease_id} options: #{options}"
  Fog::Logger.debug msg

  begin
    @blob_client.release_container_lease(name, lease_id, options)
  rescue Azure::Core::Http::HTTPError => ex
    raise_azure_exception(ex, msg)
  end

  Fog::Logger.debug "Container #{name} released successfully."
  true
end
save_page_blob(container_name, blob_name, body, options) click to toggle source
# File lib/fog/azurerm/requests/storage/save_page_blob.rb, line 57
def save_page_blob(container_name, blob_name, body, options)
  threads_num = options.delete(:worker_thread_num)
  threads_num = UPLOAD_BLOB_WORKER_THREAD_COUNT if threads_num.nil? || !threads_num.is_a?(Integer) || threads_num < 1

  begin
    blob_size = Fog::Storage.get_body_size(body)
    raise "The page blob size must be aligned to a 512-byte boundary. But the file size is #{blob_size}." if (blob_size % 512).nonzero?

    # Initiate the upload
    Fog::Logger.debug "Creating the page blob #{container_name}/#{blob_name}. options: #{options}"
    create_page_blob(container_name, blob_name, blob_size, options)
    options.delete(:content_md5)

    # Uploading content
    iostream = BlobFileStream.new(body)

    threads = []
    threads_num.times do |id|
      thread = Thread.new do
        Fog::Logger.debug "Created upload thread #{id}."
        while (chunk = iostream.read(MAXIMUM_CHUNK_SIZE))
          Fog::Logger.debug "Upload thread #{id} is uploading #{chunk.id}, start_range: #{chunk.start_range}, size: #{chunk.data.size}."
          put_blob_pages(container_name, blob_name, chunk.start_range, chunk.end_range, chunk.data, options) if Digest::MD5.hexdigest(chunk.data) != HASH_OF_4MB_EMPTY_CONTENT
        end
        Fog::Logger.debug "Upload thread #{id} finished."
      end
      thread.abort_on_exception = true
      threads << thread
    end

    threads.each(&:join)
  rescue
    # Abort the upload & reraise
    begin
      delete_blob(container_name, blob_name)
    rescue => ex
      Fog::Logger.debug "Cannot delete the blob: #{container_name}/#{blob_name} after save_page_blob failed. #{ex.inspect}"
    end
    raise
  end

  Fog::Logger.debug "Successfully save the page blob: #{container_name}/#{blob_name}."
  true
end
wait_blob_copy_operation_to_finish(container_name, blob_name, copy_id, copy_status, timeout = nil) click to toggle source
# File lib/fog/azurerm/requests/storage/wait_blob_copy_operation_to_finish.rb, line 6
def wait_blob_copy_operation_to_finish(container_name, blob_name, copy_id, copy_status, timeout = nil)
  begin
    start_time = Time.new
    while copy_status == COPY_STATUS[:PENDING]
      blob = get_blob_properties(container_name, blob_name)
      blob_props = blob.properties
      if !copy_id.nil? && blob_props[:copy_id] != copy_id
        raise "The progress of copying to #{container_name}/#{blob_name} was interrupted by other copy operations."
      end

      copy_status_description = blob_props[:copy_status_description]
      copy_status = blob_props[:copy_status]
      break if copy_status != COPY_STATUS[:PENDING]

      elapse_time = Time.new - start_time
      raise Timeout::Error.new("The copy operation cannot be finished in #{timeout} seconds") if !timeout.nil? && elapse_time >= timeout

      copied_bytes, total_bytes = blob_props[:copy_progress].split('/').map(&:to_i)
      interval = copied_bytes.zero? ? 5 : (total_bytes - copied_bytes).to_f / copied_bytes * elapse_time
      interval = 30 if interval > 30
      interval = 1 if interval < 1
      sleep(interval)
    end

    if copy_status != COPY_STATUS[:SUCCESS]
      raise "Failed to copy to #{container_name}/#{blob_name}: \n\tcopy status: #{copy_status}\n\tcopy description: #{copy_status_description}"
    end
  rescue
    # Abort the copy & reraise
    begin
      delete_blob(container_name, blob_name)
    rescue => ex
      Fog::Logger.debug "Cannot delete the blob: #{container_name}/#{blob_name} after the copy operation failed. #{ex.inspect}"
    end
    raise
  end

  Fog::Logger.debug "Successfully copied the blob: #{container_name}/#{blob_name}."
  true
end

Private Instance Methods

get_identical_blobs_from_containers(container1, container2) click to toggle source
# File lib/fog/azurerm/requests/storage/compare_container_blobs.rb, line 19
def get_identical_blobs_from_containers(container1, container2)
  container1_blobs = list_blobs(container1)
  container2_blobs = list_blobs(container2)

  identical_blobs = []
  container1_blobs[:blobs].each do |container1_blob|
    container2_blobs[:blobs].each do |container2_blob|
      if container1_blob.name == container2_blob.name && container1_blob.properties[:content_md5] == container2_blob.properties[:content_md5]
        identical_blobs.push(container1_blob)
      end
    end
  end
  identical_blobs
end