Module: Azure::Armrest::Storage::ManagedStorageHelper

Included in:
DiskService, SnapshotService
Defined in:
lib/azure/armrest/storage/managed_disk.rb,
lib/azure/armrest/storage/managed_storage_helper.rb

Overview

Base class for managing managed disks.

Defined Under Namespace

Classes: ManagedDisk

Instance Method Summary collapse

Instance Method Details

#access_token(disk_name, resource_group = configuration.resource_group, options = {}) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/azure/armrest/storage/managed_storage_helper.rb', line 112

def access_token(disk_name, resource_group = configuration.resource_group, options = {})
  validate_resource_group(resource_group)

  post_options = {
    :access            => 'read',                    # Must be 'read'
    :durationInSeconds => options[:duration] || 3600 # 1 hour default
  }

  # This call will give us an operations URL in the headers.
  begin_get_access_url = build_url(resource_group, disk_name, 'BeginGetAccess')
  begin_get_access_response = rest_post(begin_get_access_url, post_options.to_json)

  headers = Azure::Armrest::ResponseHeaders.new(begin_get_access_response.headers)
  status = wait(headers, 120, 1)

  unless status.casecmp('succeeded').zero?
    msg = "Unable to obtain an operations URL for #{disk_name}/#{resource_group}"
    log('debug', "#{msg}: #{begin_get_access_response.headers}")
    raise Azure::Armrest::NotFoundException.new(begin_get_access_response.code, msg, begin_get_access_response.body)
  end

  # Get the SAS URL from the BeginGetAccess call
  op_url = headers.try(:azure_asyncoperation) || headers.location

  # Dig the URL + SAS token URL out of the response
  response = rest_get(op_url)
  body     = Azure::Armrest::ResponseBody.new(response.body)
  body.properties.output.access_sas
end

#close(disk_name, resource_group) ⇒ Object



98
99
100
101
# File 'lib/azure/armrest/storage/managed_storage_helper.rb', line 98

def close(disk_name, resource_group)
  end_url = build_url(resource_group, disk_name, 'EndGetAccess')
  rest_post(end_url)
end

#get_blob_raw(disk_name, resource_group = configuration.resource_group, options = {}) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/azure/armrest/storage/managed_storage_helper.rb', line 103

def get_blob_raw(disk_name, resource_group = configuration.resource_group, options = {})
  managed_disk = open(disk_name, resource_group, options)
  begin
    managed_disk.read(options)
  ensure
    managed_disk.close
  end
end

#open(disk_name, resource_group = configuration.resource_group, options = {}) ⇒ Object

Get the raw blob information for a managed disk. This is similar to the StorageAccount#get_blob_raw method, but applies only to a managed disk or its snapshot, whereas that method applies only to an individual storage account.

As with the Storage#get_blob_raw method, you should pass a :range, :start_byte, :end_byte or :length option. If you want the entire image you must pass the :entire_image option, though this is generally not recommended. Unlike the Storage#get_blob_raw method, this method does not support the :date parameter.

The options are as follows:

:range        => A range of bytes you want, e.g. 0..1023 to get first 1k bytes
:start_byte   => The starting byte number that you want to collect bytes for. Use
                 this in conjunction with :length or :end_byte.
:end_byte     => The ending byte that you want to collect bytes for. Use this
                 in conjunction with :start_byte.
:length       => If given a :start_byte, specifies the number of bytes from the
                 the :start_byte that you wish to collect.
:entire_image => If set, returns the entire image in bytes. This will be a long
                 running request that returns a large number of bytes.

You may also pass a :duration parameter, which indicates how long, in seconds, that the privately generated SAS token should last. This token is used internally by requests that are used to access the requested information. By default it lasts for 1 hour.

Get the information you need using:

  • response.body - blob data (the raw bytes).

  • response.headers - blob metadata (a hash).

Example:

vms = Azure::Armrest::VirtualMachineService.new(conf)
sds = Azure::Armrest::Storage::DiskService.new(conf)

vm = vms.get(vm_name, vm_resource_group)
os_disk = vm.properties.storage_profile.os_disk

disk_id = os_disk.managed_disk.id
disk = sds.get_by_id(disk_id)

# Get the first 1024 bytes
data = sds.get_blob_raw(disk.name, disk.resource_group, :range => 0..1023)

p data.headers
File.open('vm.vhd', 'a'){ |fh| fh.write(data.body) }


53
54
55
# File 'lib/azure/armrest/storage/managed_storage_helper.rb', line 53

def open(disk_name, resource_group = configuration.resource_group, options = {})
  ManagedDisk.new(self, disk_name, resource_group, options)
end

#read(sas_url, options = {}) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/azure/armrest/storage/managed_storage_helper.rb', line 57

def read(sas_url, options = {})
  # The same restrictions that apply to the StorageAccount method also apply here.
  range = options[:range] if options[:range]
  range ||= options[:start_byte]..options[:end_byte] if options[:start_byte] && options[:end_byte]
  range ||= options[:start_byte]..options[:start_byte] + options[:length] - 1 if options[:start_byte] && options[:length]

  range_str = range ? "bytes=#{range.min}-#{range.max}" : nil

  unless range_str || options[:entire_image]
    raise ArgumentError, "must specify byte range or :entire_image flag"
  end

  headers = {}
  headers['x-ms-range'] = range_str if range_str

  # Need to make a raw call since we need to explicitly pass headers,
  # but without encoding the URL or passing our configuration token.
  max_retries           = 5
  retries               = 0

  begin
    RestClient::Request.execute(
      :method      => :get,
      :url         => sas_url,
      :headers     => headers,
      :proxy       => configuration.proxy,
      :ssl_version => configuration.ssl_version,
      :ssl_verify  => configuration.ssl_verify
    )
  rescue Azure::Armrest::ForbiddenException => err
    log('warn', "ManagedStorageHelper.read: #{err}")
    raise err
  rescue RestClient::Exception, Azure::Armrest::Exception => err
    raise err unless retries < max_retries
    log('warn', "ManagedStorageHelper.read: #{err} - retry number #{retries}")
    retries += 1
    sleep 5
    retry
  end
end