Skip to content
This repository has been archived by the owner on Mar 21, 2023. It is now read-only.

Commit

Permalink
Add Fog Support for Azure Stack (fog#386)
Browse files Browse the repository at this point in the history
Add Fog Support for Azure Stack
  • Loading branch information
bingosummer authored and wichru committed Mar 21, 2023
1 parent 68ea3f7 commit 1d8f26e
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 20 deletions.
2 changes: 1 addition & 1 deletion fog-azure-rm.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'azure_mgmt_traffic_manager', '~> 0.9.0'
spec.add_dependency 'azure_mgmt_sql', '~> 0.9.0'
spec.add_dependency 'azure_mgmt_key_vault', '~> 0.9.0'
spec.add_dependency 'azure-storage', '= 0.11.5.preview'
spec.add_dependency 'azure-storage', '>= 0.11.5.preview', '< 1.0'
spec.add_dependency 'vhd', '0.0.4'
spec.add_dependency 'mime-types', '~> 3.0'
end
1 change: 1 addition & 0 deletions lib/fog/azurerm/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
ENVIRONMENT_AZURE_CHINA_CLOUD = 'AzureChinaCloud'.freeze
ENVIRONMENT_AZURE_US_GOVERNMENT = 'AzureUSGovernment'.freeze
ENVIRONMENT_AZURE_GERMAN_CLOUD = 'AzureGermanCloud'.freeze
ENVIRONMENT_AZURE_STACK = 'AzureStack'.freeze

# MsRestAzure::AzureOperationError class Error Codes
ERROR_CODE_RESOURCE_NOT_FOUND = 'ResourceNotFound'.freeze
Expand Down
17 changes: 14 additions & 3 deletions lib/fog/azurerm/storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class AzureRM < Fog::Service
# Recognizes when creating data client
recognizes :azure_storage_account_name
recognizes :azure_storage_access_key
recognizes :azure_storage_dns_suffix
recognizes :debug

request_path 'fog/azurerm/requests/storage'
Expand Down Expand Up @@ -121,10 +122,20 @@ def initialize(options)

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

azure_client = Azure::Storage::Client.create(storage_account_name: @azure_storage_account_name,
storage_access_key: @azure_storage_access_key)
azure_client.storage_blob_host = get_blob_endpoint(@azure_storage_account_name, true, @environment)
client_options = {
storage_account_name: @azure_storage_account_name,
storage_access_key: @azure_storage_access_key,
user_agent_prefix: telemetry
}
client_options[:storage_dns_suffix] = if @environment == ENVIRONMENT_AZURE_STACK
@azure_storage_dns_suffix.nil? ? 'local.azurestack.external' : @azure_storage_dns_suffix
else
storage_endpoint_suffix(@environment)[1..-1]
end

azure_client = Azure::Storage::Client.create(client_options)
@blob_client = azure_client.blob_client
@blob_client.with_filter(Azure::Storage::Core::Filter::ExponentialRetryPolicyFilter.new)
@blob_client.with_filter(Azure::Core::Http::DebugFilter.new) if @debug
Expand Down
17 changes: 12 additions & 5 deletions test/integration/blob.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@

azure_credentials = YAML.load_file(File.expand_path('credentials/azure.yml', __dir__))

location = azure_credentials['location']

rs = Fog::Resources::AzureRM.new(
tenant_id: azure_credentials['tenant_id'],
client_id: azure_credentials['client_id'],
client_secret: azure_credentials['client_secret'],
subscription_id: azure_credentials['subscription_id']
subscription_id: azure_credentials['subscription_id'],
environment: azure_credentials['environment']
)

storage = Fog::Storage::AzureRM.new(
Expand Down Expand Up @@ -40,23 +43,27 @@
begin
resource_group = rs.resource_groups.create(
name: resource_group_name,
location: LOCATION
location: location
)

storage_account = storage.storage_accounts.create(
name: storage_account_name,
location: LOCATION,
location: location,
resource_group: resource_group_name
)

access_key = storage_account.get_access_keys[0].value
Fog::Logger.debug access_key.inspect
storage_data = Fog::Storage.new(

options = {
provider: 'AzureRM',
azure_storage_account_name: storage_account.name,
azure_storage_access_key: access_key,
environment: azure_credentials['environment']
)
}
options[:storage_dns_suffix] = azure_credentials['azure_storage_dns_suffix'] unless azure_credentials['azure_storage_dns_suffix'].nil?

storage_data = Fog::Storage.new(options)

########################################################################################################################
###################### Create Container ######################
Expand Down
277 changes: 277 additions & 0 deletions test/integration/blob_azure_stack.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
require 'fog/azurerm'
require 'yaml'

########################################################################################################################
###################### Services object required by all actions ######################
###################### Keep it Uncommented! ######################
########################################################################################################################

azure_credentials = YAML.load_file(File.expand_path('credentials/azure-stack-storage.yml', __dir__))

########################################################################################################################
###################### Resource names #####################
########################################################################################################################

time = current_time
storage_account_name = azure_credentials['storage_account_name']
access_key = azure_credentials['storage_account_access_key']
container_name = "con#{time}"
test_container_name = "tcon#{time}"

########################################################################################################################
###################### Prerequisites ######################
########################################################################################################################

begin
options = {
provider: 'AzureRM',
azure_storage_account_name: storage_account_name,
azure_storage_access_key: access_key,
environment: azure_credentials['environment']
}
options[:azure_storage_dns_suffix] = azure_credentials['storage_dns_suffix'] unless azure_credentials['storage_dns_suffix'].nil?

storage_data = Fog::Storage.new(options)

########################################################################################################################
###################### Create Container ######################
########################################################################################################################

storage_data.directories.create(
key: container_name,
public: true
)

storage_data.directories.create(
key: test_container_name,
public: false
)

########################################################################################################################
###################### Get container ######################
########################################################################################################################

container = storage_data.directories.get(container_name)
test_container = storage_data.directories.get(test_container_name)

########################################################################################################################
###################### Create a small block blob ######################
########################################################################################################################

small_blob_name = 'small_test_file.dat'
content = Array.new(1024 * 1024) { [*'0'..'9', *'a'..'z'].sample }.join

options = {
key: small_blob_name,
body: content
}
blob = container.files.create(options)
puts "Created small block blob: #{blob.key}"

########################################################################################################################
###################### Create a large block blob ######################
########################################################################################################################

large_blob_name = 'large_test_file.dat'
begin
large_blob_file_name = '/tmp/large_test_file.dat'
File.open(large_blob_file_name, 'w') do |large_file|
33.times do
large_file.puts(content)
end
end

File.open(large_blob_file_name) do |file|
options = {
key: large_blob_name,
body: file
}
blob = container.files.create(options)
puts "Created large block blob: #{blob.key}"
end
ensure
File.delete(large_blob_file_name) if File.exist?(large_blob_file_name)
end

########################################################################################################################
###################### Create a small page blob ######################
########################################################################################################################

small_page_blob_name = 'small_test_file.vhd'
content = Array.new(1024 * 1024 + 512) { [*'0'..'9', *'a'..'z'].sample }.join

options = {
key: small_page_blob_name,
body: content,
blob_type: 'PageBlob'
}
blob = container.files.create(options)
puts "Created small page blob: #{blob.key}"

########################################################################################################################
###################### Create a large page blob ######################
########################################################################################################################

begin
large_page_blob_file_name = '/tmp/large_test_file.vhd'
large_page_blob_name = 'large_test_file.vhd'
File.open(large_page_blob_file_name, 'w') do |large_file|
content = Array.new(1024 * 1024) { [*'0'..'9', *'a'..'z'].sample }.join
33.times do
large_file.puts(content)
end
content = Array.new(512) { [*'0'..'9', *'a'..'z'].sample }.join
large_file.puts(content)
large_file.truncate(33 * 1024 * 1024 + 512)
end

File.open(large_page_blob_file_name) do |file|
options = {
key: large_page_blob_name,
body: file,
blob_type: 'PageBlob'
}
blob = container.files.create(options)
puts "Created large page blob: #{blob.key}"
end
ensure
File.delete(large_page_blob_file_name) if File.exist?(large_page_blob_file_name)
end

########################################################################################################################
###################### Copy Blob ########################
########################################################################################################################

puts "Copy blob: #{container.files.head(small_blob_name).copy(test_container_name, small_blob_name)}"

########################################################################################################################
###################### Get a public URL ######################
########################################################################################################################

blob_uri = container.files.head(large_blob_name).public_url
puts "Get blob public uri: #{blob_uri}"

########################################################################################################################
###################### Copy Blob from URI ########################
########################################################################################################################

copied_blob = test_container.files.new(key: 'small_blob_name')
puts "Copy blob from uri: #{copied_blob.copy_from_uri(blob_uri)}"

########################################################################################################################
###################### Update blob ######################
########################################################################################################################

copied_blob.content_encoding = 'utf-8'
copied_blob.metadata = { 'owner' => 'azure' }
copied_blob.save(update_body: false)

temp = test_container.files.head(small_blob_name)
puts 'Updated blob'
Fog::Logger.debug temp.content_encoding
Fog::Logger.debug temp.metadata

########################################################################################################################
###################### Compare Blob #####################
########################################################################################################################

puts "Compare blobs: #{storage_data.compare_container_blobs(container_name, test_container_name)}"

########################################################################################################################
###################### Blob Exist #####################
########################################################################################################################

puts 'Blob exist' if container.files.head(small_blob_name)

########################################################################################################################
###################### Blob Count in a Container #####################
########################################################################################################################

puts "Blob count in a container: #{container.files.all.length}"

########################################################################################################################
###################### List Blobs in a Container #####################
########################################################################################################################

puts 'List blobs in a container:'
container.files.each do |temp_file|
puts temp_file.key
end

########################################################################################################################
###################### Download a small blob ######################
########################################################################################################################

begin
downloaded_file_name = '/tmp/downloaded_' + small_blob_name
blob = container.files.get(small_blob_name)
File.open(downloaded_file_name, 'wb') do |file|
file.write(blob.body)
end
puts 'Downloaded small blob'
ensure
File.delete(downloaded_file_name) if File.exist?(downloaded_file_name)
end

########################################################################################################################
###################### Download a large blob ######################
########################################################################################################################

begin
downloaded_file_name = '/tmp/downloaded_' + large_blob_name
File.open(downloaded_file_name, 'wb') do |file|
container.files.get(large_blob_name) do |chunk, remaining_bytes, total_bytes|
Fog::Logger.debug "remaining_bytes: #{remaining_bytes}, total_bytes: #{total_bytes}"
file.write(chunk)
end
end
puts 'Downloaded large blob'
ensure
File.delete(downloaded_file_name) if File.exist?(downloaded_file_name)
end

########################################################################################################################
###################### Get a https URL with expires ######################
########################################################################################################################

test_blob = test_container.files.head(small_blob_name)
puts "Get https URL with expires: #{test_blob.public?}, #{test_blob.url(Time.now + 3600)}"
Fog::Logger.debug test_blob.public?
Fog::Logger.debug test_blob.url(Time.now + 3600)

########################################################################################################################
###################### Get a http URL with expires ######################
########################################################################################################################

puts "Get a http URL with expires: #{test_blob.url(Time.now + 3600, scheme: 'http')}"

########################################################################################################################
###################### Lease Blob ######################
########################################################################################################################

lease_id_blob = storage_data.acquire_blob_lease(container_name, large_blob_name)
puts 'Leased blob'

########################################################################################################################
###################### Release Leased Blob ######################
########################################################################################################################

storage_data.release_blob_lease(container_name, large_blob_name, lease_id_blob)
puts 'Release Leased Blob'

########################################################################################################################
###################### Delete Blob ######################
########################################################################################################################

blob = container.files.head(large_blob_name)
puts "Deleted blob: #{blob.destroy}"

########################################################################################################################
###################### Deleted Container ######################
########################################################################################################################

puts "Deleted container: #{container.destroy}"
puts "Deleted test container: #{test_container.destroy}"
rescue => ex
puts "Integration Test for blob is failing: #{ex.inspect}\n#{ex.backtrace.join("\n")}"
end
Loading

0 comments on commit 1d8f26e

Please sign in to comment.