azure-armrest 0.7.5 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES +12 -0
- data/lib/azure/armrest/armrest_service.rb +14 -4
- data/lib/azure/armrest/model/base_model.rb +1 -0
- data/lib/azure/armrest/model/storage_account.rb +405 -30
- data/lib/azure/armrest/storage/image_service.rb +1 -1
- data/lib/azure/armrest/version.rb +1 -1
- data/lib/azure/armrest/virtual_machine_image_service.rb +29 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8132014956246e577b66ccaf5a59e002e1dc06d3
|
4
|
+
data.tar.gz: f15ad3108839654399c954bb0f4460499de319cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ca343728c62c77096e320d04ea0bfdeb0e6d9ce3aadbc0ea53935053335d1b20089004591915cf031fa380bd16009f89e7acdea0db4cb08b8098274d7dc3276
|
7
|
+
data.tar.gz: b0185801ee3a2c6cf1079f5f8040ca143402109659b991504b40d2a6e06fa294452163086c00094fdaddca1553738af3278ac0464115f502652894684901c6af
|
data/CHANGES
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
= 0.8.0 - 20-Jul-2017
|
2
|
+
* The StorageAccount#create_blob and StorageAccount#create_blob_snapshot methods
|
3
|
+
were heavily revamped and now return a ResponseHeaders object.
|
4
|
+
* Added support for storage file services to the Storage model, so you can
|
5
|
+
now create, delete or query files or directories on storage accounts.
|
6
|
+
* Added the list_all instance method to the VirtualMachineImageService class.
|
7
|
+
Thanks go to Tyler Gregory for the patch.
|
8
|
+
* Added the ArmestService#list_locations method. This returns an array of
|
9
|
+
Location objects. The ArmrestService#locations method still returns just
|
10
|
+
an array of strings, but is now deprecated.
|
11
|
+
* The StorageAccount#all_blobs method now accepts an options argument.
|
12
|
+
|
1
13
|
= 0.7.5 - 27-Jun-2017
|
2
14
|
* Added the ContainerService service class.
|
3
15
|
* Added the StorageAccount#access_key accessor. If set, this is now used as
|
@@ -77,17 +77,27 @@ module Azure
|
|
77
77
|
# +provider+. If you do not specify a provider, then the locations for
|
78
78
|
# all providers will be returned.
|
79
79
|
#
|
80
|
-
# If you need individual details on a per-provider basis, use the
|
81
|
-
#
|
82
|
-
|
80
|
+
# If you need individual details on a per-provider basis, use the methods
|
81
|
+
# of the ResourceProviderService instead.
|
82
|
+
#
|
83
|
+
# Deprecated.
|
83
84
|
#
|
84
85
|
def locations(provider = nil)
|
85
86
|
list = configuration.providers
|
86
87
|
list = list.select { |rp| rp.namespace.casecmp(provider) == 0 } if provider
|
87
|
-
|
88
88
|
list.collect { |rp| rp.resource_types.map(&:locations) }.flatten.uniq.sort
|
89
89
|
end
|
90
90
|
|
91
|
+
deprecate :locations, :list_locations, 2019, 1
|
92
|
+
|
93
|
+
# Returns a list of Location objects for the current subscription.
|
94
|
+
#
|
95
|
+
def list_locations
|
96
|
+
url = url_with_api_version(configuration.api_version, base_url, 'locations')
|
97
|
+
response = rest_get(url)
|
98
|
+
Azure::Armrest::ArmrestCollection.create_from_response(response, Location)
|
99
|
+
end
|
100
|
+
|
91
101
|
# Returns a list of subscriptions for the current tenant.
|
92
102
|
def list_subscriptions
|
93
103
|
Azure::Armrest::SubscriptionService.new(configuration).list
|
@@ -191,6 +191,7 @@ module Azure
|
|
191
191
|
class Container < BaseModel; end
|
192
192
|
class Event < BaseModel; end
|
193
193
|
class ImageVersion < BaseModel; end
|
194
|
+
class Location < BaseModel; end
|
194
195
|
class Offer < BaseModel; end
|
195
196
|
class Publisher < BaseModel; end
|
196
197
|
class Resource < BaseModel; end
|
@@ -20,6 +20,10 @@ module Azure
|
|
20
20
|
class Table < BaseModel; end
|
21
21
|
class TableData < BaseModel; end
|
22
22
|
|
23
|
+
# Classes used to wrap file shares
|
24
|
+
class ShareDirectory < BaseModel; end
|
25
|
+
class ShareFile < BaseModel; end
|
26
|
+
|
23
27
|
# The version string used in headers sent as part any internal http
|
24
28
|
# request. The default is 2016-05-31.
|
25
29
|
attr_accessor :storage_api_version
|
@@ -50,7 +54,7 @@ module Azure
|
|
50
54
|
def tables(key = access_key)
|
51
55
|
raise ArgumentError, "No access key specified" unless key
|
52
56
|
response = table_response(key, nil, "Tables")
|
53
|
-
JSON.parse(response.body)['value'].map{ |t| Table.new(t) }
|
57
|
+
JSON.parse(response.body)['value'].map { |t| Table.new(t) }
|
54
58
|
end
|
55
59
|
|
56
60
|
# Return information about a single table for the given storage
|
@@ -119,6 +123,280 @@ module Azure
|
|
119
123
|
data
|
120
124
|
end
|
121
125
|
|
126
|
+
### Files and Directories
|
127
|
+
|
128
|
+
# Create a new directory under the specified +share+ or parent directory.
|
129
|
+
#
|
130
|
+
# The only supported option at this time is a "timeout" option.
|
131
|
+
#
|
132
|
+
def create_directory(share, directory, key = access_key, options = {})
|
133
|
+
raise ArgumentError, "No access key specified" unless key
|
134
|
+
|
135
|
+
query = {:restype => 'directory'}.merge(options).to_query
|
136
|
+
|
137
|
+
response = file_response(key, query, 'put', '', File.join(share, directory))
|
138
|
+
|
139
|
+
Azure::Armrest::ResponseHeaders.new(response.headers).tap do |rh|
|
140
|
+
rh.response_code = response.code
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Delete the specified +share+ or parent directory.
|
145
|
+
#
|
146
|
+
# The only supported option at this time is a "timeout" option.
|
147
|
+
#
|
148
|
+
def delete_directory(share, directory, key = access_key, options = {})
|
149
|
+
raise ArgumentError, "No access key specified" unless key
|
150
|
+
|
151
|
+
query = {:restype => 'directory'}.merge(options).to_query
|
152
|
+
|
153
|
+
response = file_response(key, query, 'delete', '', File.join(share, directory))
|
154
|
+
|
155
|
+
Azure::Armrest::ResponseHeaders.new(response.headers).tap do |rh|
|
156
|
+
rh.response_code = response.code
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Get properties for the specified +share+ or parent directory.
|
161
|
+
#
|
162
|
+
# The only supported option at this time is a "timeout" option.
|
163
|
+
#
|
164
|
+
def directory_properties(share, directory, key = access_key, options = {})
|
165
|
+
raise ArgumentError, "No access key specified" unless key
|
166
|
+
|
167
|
+
query = {:restype => 'directory'}.merge(options).to_query
|
168
|
+
|
169
|
+
response = file_response(key, query, 'get', '', File.join(share, directory))
|
170
|
+
|
171
|
+
ShareDirectory.new(response.headers)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Get metadata for the specified +share+ or parent directory.
|
175
|
+
#
|
176
|
+
# The only supported option at this time is a "timeout" option.
|
177
|
+
#
|
178
|
+
def directory_metadata(share, directory, key = access_key, options = {})
|
179
|
+
raise ArgumentError, "No access key specified" unless key
|
180
|
+
|
181
|
+
query = {:restype => 'directory', :comp => 'metadata'}.merge(options).to_query
|
182
|
+
|
183
|
+
response = file_response(key, query, 'head', '', File.join(share, directory))
|
184
|
+
|
185
|
+
ShareDirectory.new(response.headers)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Returns a list of files for the specified file-share. You may also
|
189
|
+
# optionally specify a +directory+ in "share/directory" format.
|
190
|
+
#
|
191
|
+
# You may specify multiple +options+ to limit the result set. The
|
192
|
+
# possible options are:
|
193
|
+
#
|
194
|
+
# * prefix
|
195
|
+
# * marker
|
196
|
+
# * maxresults
|
197
|
+
# * timeout
|
198
|
+
#
|
199
|
+
def files(share, key = access_key, options = {})
|
200
|
+
raise ArgumentError, "No access key specified" unless key
|
201
|
+
|
202
|
+
query = {:restype => 'directory', :comp => 'list'}.merge(options).to_query
|
203
|
+
|
204
|
+
response = file_response(key, query, 'get', nil, share)
|
205
|
+
|
206
|
+
doc = Nokogiri::XML(response.body)
|
207
|
+
results = []
|
208
|
+
|
209
|
+
doc.xpath('//EnumerationResults/Entries').each do |element|
|
210
|
+
element.xpath('//Directory').each do |dir|
|
211
|
+
results << ShareDirectory.new(Hash.from_xml(dir.to_s)['Directory'])
|
212
|
+
end
|
213
|
+
element.xpath('//File').each do |file|
|
214
|
+
results << ShareFile.new(Hash.from_xml(file.to_s)['File'])
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
results.concat(next_marker_results(doc, :files, key, options))
|
219
|
+
|
220
|
+
results
|
221
|
+
end
|
222
|
+
|
223
|
+
# Returns the raw contents of the specified file.
|
224
|
+
#
|
225
|
+
# The only supported option at this time is a "timeout" option.
|
226
|
+
#
|
227
|
+
def file_content(share, file, key = access_key, options = {})
|
228
|
+
raise ArgumentError, "No access key specified" unless key
|
229
|
+
|
230
|
+
query = options.to_query
|
231
|
+
|
232
|
+
response = file_response(key, query, 'get', '', File.join(share, file))
|
233
|
+
response.body
|
234
|
+
end
|
235
|
+
|
236
|
+
# Returns the raw contents of the specified file.
|
237
|
+
#
|
238
|
+
# The only supported option at this time is a "timeout" option.
|
239
|
+
#
|
240
|
+
def file_properties(share, file, key = access_key, options = {})
|
241
|
+
raise ArgumentError, "No access key specified" unless key
|
242
|
+
|
243
|
+
query = options.to_query
|
244
|
+
|
245
|
+
response = file_response(key, query, 'head', '', File.join(share, file))
|
246
|
+
|
247
|
+
Azure::Armrest::ResponseHeaders.new(response.headers).tap do |rh|
|
248
|
+
rh.response_code = response.code
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# Create the specified share file. You may specify any of the following
|
253
|
+
# options:
|
254
|
+
#
|
255
|
+
# * cache_control
|
256
|
+
# * content_disposition
|
257
|
+
# * content_length (default: 0)
|
258
|
+
# * content_encoding
|
259
|
+
# * content_language
|
260
|
+
# * content_md5
|
261
|
+
# * content_type (default: application/octet-stream)
|
262
|
+
# * meta_name
|
263
|
+
# * timeout
|
264
|
+
# * version
|
265
|
+
#
|
266
|
+
# Note that this does not set the content of the file, it only creates
|
267
|
+
# in the file share.
|
268
|
+
#
|
269
|
+
def create_file(share, file, key = access_key, options = {})
|
270
|
+
raise ArgumentError, "No access key specified" unless key
|
271
|
+
|
272
|
+
timeout = options.delete(:timeout) # Part of request
|
273
|
+
|
274
|
+
url = File.join(properties.primary_endpoints.file, share, file)
|
275
|
+
url += "?timeout=#{timeout}" if timeout
|
276
|
+
|
277
|
+
hash = options.transform_keys.each { |okey| 'x-ms-' + okey.to_s.tr('_', '-') }
|
278
|
+
|
279
|
+
hash['verb'] = 'PUT'
|
280
|
+
|
281
|
+
# Mandatory and/or sane defaults
|
282
|
+
hash['x-ms-type'] = 'file'
|
283
|
+
hash['x-ms-content-length'] ||= 0
|
284
|
+
hash['x-ms-content-type'] ||= 'application/octet-stream'
|
285
|
+
|
286
|
+
headers = build_headers(url, key, :file, hash)
|
287
|
+
|
288
|
+
response = ArmrestService.send(
|
289
|
+
:rest_put,
|
290
|
+
:url => url,
|
291
|
+
:payload => '',
|
292
|
+
:headers => headers,
|
293
|
+
:proxy => proxy,
|
294
|
+
:ssl_version => ssl_version,
|
295
|
+
:ssl_verify => ssl_verify
|
296
|
+
)
|
297
|
+
|
298
|
+
Azure::Armrest::ResponseHeaders.new(response.headers).tap do |rh|
|
299
|
+
rh.response_code = response.code
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
# Delete the specified share file.
|
304
|
+
#
|
305
|
+
# The only supported option at this time is a "timeout" option.
|
306
|
+
#
|
307
|
+
def delete_file(share, file, key = access_key, options = {})
|
308
|
+
raise ArgumentError, "No access key specified" unless key
|
309
|
+
|
310
|
+
query = options.to_query
|
311
|
+
|
312
|
+
response = file_response(key, query, 'delete', '', File.join(share, file))
|
313
|
+
|
314
|
+
Azure::Armrest::ResponseHeaders.new(response.headers).tap do |rh|
|
315
|
+
rh.response_code = response.code
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# Copy a +src_file+ to a destination +dst_file+ within the same storage account.
|
320
|
+
#
|
321
|
+
def copy_file(src_container, src_file, dst_container = src_container, dst_file = nil, key = access_key)
|
322
|
+
raise ArgumentError, "No access key specified" unless key
|
323
|
+
|
324
|
+
dst_file ||= File.basename(src_blob)
|
325
|
+
|
326
|
+
dst_url = File.join(properties.primary_endpoints.file, dst_container, dst_file)
|
327
|
+
src_url = File.join(properties.primary_endpoints.file, src_container, src_file)
|
328
|
+
|
329
|
+
options = {'x-ms-copy-source' => src_url, :verb => 'PUT'}
|
330
|
+
|
331
|
+
headers = build_headers(dst_url, key, :file, options)
|
332
|
+
|
333
|
+
response = ArmrestService.send(
|
334
|
+
:rest_put,
|
335
|
+
:url => dst_url,
|
336
|
+
:payload => '',
|
337
|
+
:headers => headers,
|
338
|
+
:proxy => proxy,
|
339
|
+
:ssl_version => ssl_version,
|
340
|
+
:ssl_verify => ssl_verify
|
341
|
+
)
|
342
|
+
|
343
|
+
Azure::Armrest::ResponseHeaders.new(response.headers).tap do |rh|
|
344
|
+
rh.response_code = response.code
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
# Add content to +file+ on +share+. The +options+ hash supports
|
349
|
+
# three options, :content, :timeout and :write.
|
350
|
+
#
|
351
|
+
# The :content option is just a string, i.e. the content you want
|
352
|
+
# to add to the file. Azure allows you to add a maximum of 4mb worth
|
353
|
+
# of content per request.
|
354
|
+
#
|
355
|
+
# The :timeout option is nil by default. The :write option defaults to
|
356
|
+
# 'update'. If you want to clear a file, set it to 'clear'.
|
357
|
+
#
|
358
|
+
def add_file_content(share, file, key = access_key, options = {})
|
359
|
+
raise ArgumentError, "No access key specified" unless key
|
360
|
+
|
361
|
+
timeout = options.delete(:timeout)
|
362
|
+
content = options.delete(:content)
|
363
|
+
|
364
|
+
url = File.join(properties.primary_endpoints.file, share, file) + "?comp=range"
|
365
|
+
url += "&timeout=#{timeout}" if timeout
|
366
|
+
|
367
|
+
hash = options.transform_keys.each { |okey| 'x-ms-' + okey.to_s.tr('_', '-') }
|
368
|
+
|
369
|
+
hash['verb'] = 'PUT'
|
370
|
+
hash['x-ms-write'] ||= 'update'
|
371
|
+
|
372
|
+
if hash['x-ms-write'] == 'clear'
|
373
|
+
hash['content-length'] = 0
|
374
|
+
hash['x-ms-range'] = "bytes=0-"
|
375
|
+
else
|
376
|
+
range = 0..(content.size - 1)
|
377
|
+
hash['content-length'] = content.size
|
378
|
+
hash['x-ms-range'] = "bytes=#{range.min}-#{range.max}"
|
379
|
+
end
|
380
|
+
|
381
|
+
headers = build_headers(url, key, :file, hash)
|
382
|
+
|
383
|
+
response = ArmrestService.send(
|
384
|
+
:rest_put,
|
385
|
+
:url => url,
|
386
|
+
:payload => content,
|
387
|
+
:headers => headers,
|
388
|
+
:proxy => proxy,
|
389
|
+
:ssl_version => ssl_version,
|
390
|
+
:ssl_verify => ssl_verify
|
391
|
+
)
|
392
|
+
|
393
|
+
Azure::Armrest::ResponseHeaders.new(response.headers).tap do |rh|
|
394
|
+
rh.response_code = response.code
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
### Containers
|
399
|
+
|
122
400
|
# Return a list of container names for the given storage account +key+.
|
123
401
|
# If no key is provided, it is assumed that the StorageAccount object
|
124
402
|
# includes the access_key property.
|
@@ -237,9 +515,7 @@ module Azure
|
|
237
515
|
|
238
516
|
url = File.join(properties.primary_endpoints.blob, container, blob) + "?comp=properties"
|
239
517
|
|
240
|
-
hash = options.transform_keys
|
241
|
-
"x-ms-blob-" + okey.to_s.tr('_', '-')
|
242
|
-
end
|
518
|
+
hash = options.transform_keys { |okey| "x-ms-blob-" + okey.to_s.tr('_', '-') }
|
243
519
|
|
244
520
|
hash['verb'] = 'PUT'
|
245
521
|
|
@@ -306,9 +582,11 @@ module Azure
|
|
306
582
|
results.concat(next_marker_results(doc, :blobs, container, key, options))
|
307
583
|
end
|
308
584
|
|
309
|
-
# Returns an array of all blobs for all containers.
|
585
|
+
# Returns an array of all blobs for all containers. The +options+ hash
|
586
|
+
# may contain the same arguments that a call to StorageAccount#blobs
|
587
|
+
# would accept.
|
310
588
|
#
|
311
|
-
def all_blobs(key = access_key, max_threads = 10)
|
589
|
+
def all_blobs(key = access_key, max_threads = 10, options = {})
|
312
590
|
raise ArgumentError, "No access key specified" unless key
|
313
591
|
|
314
592
|
array = []
|
@@ -316,7 +594,7 @@ module Azure
|
|
316
594
|
|
317
595
|
Parallel.each(containers(key), :in_threads => max_threads) do |container|
|
318
596
|
begin
|
319
|
-
mutex.synchronize { array.concat(blobs(container.name, key)) }
|
597
|
+
mutex.synchronize { array.concat(blobs(container.name, key, options)) }
|
320
598
|
rescue Errno::ECONNREFUSED, Azure::Armrest::TimeoutException => err
|
321
599
|
msg "Unable to gather blob information for #{container.name}: #{err}"
|
322
600
|
log('warn', msg)
|
@@ -404,7 +682,8 @@ module Azure
|
|
404
682
|
blob
|
405
683
|
end
|
406
684
|
|
407
|
-
# Delete the given +blob+ found in +container+.
|
685
|
+
# Delete the given +blob+ found in +container+. Pass a :date option
|
686
|
+
# if you wish to delete a snapshot.
|
408
687
|
#
|
409
688
|
def delete_blob(container, blob, key = access_key, options = {})
|
410
689
|
raise ArgumentError, "No access key specified" unless key
|
@@ -431,43 +710,113 @@ module Azure
|
|
431
710
|
|
432
711
|
# Create new blob for a container.
|
433
712
|
#
|
434
|
-
# The
|
713
|
+
# The options parameter is a hash that contains information used
|
714
|
+
# when creating the blob:
|
435
715
|
#
|
436
|
-
#
|
437
|
-
# # - Required. Specifies the type of blob to create: block, page or append.
|
716
|
+
# * type - "BlockBlob", "PageBlob" or "AppendBlob". Mandatory.
|
438
717
|
#
|
439
|
-
#
|
440
|
-
#
|
441
|
-
#
|
442
|
-
|
718
|
+
# * content_disposition
|
719
|
+
# * content_encoding
|
720
|
+
# * content_language
|
721
|
+
# * content_md5
|
722
|
+
# * content_type
|
723
|
+
# * cache_control
|
724
|
+
# * lease_id
|
725
|
+
# * payload (block blobs only)
|
726
|
+
# * sequence_number (page blobs only)
|
727
|
+
# * timeout (part of the request)
|
728
|
+
#
|
729
|
+
# Returns a ResponseHeaders object since this method is asynchronous.
|
730
|
+
#
|
731
|
+
def create_blob(container, blob, key = access_key, options = {})
|
443
732
|
raise ArgumentError, "No access key specified" unless key
|
444
733
|
|
734
|
+
timeout = options.delete(:timeout)
|
735
|
+
payload = options.delete(:payload) || ''
|
736
|
+
|
445
737
|
url = File.join(properties.primary_endpoints.blob, container, blob)
|
738
|
+
url += "&timeout=#{timeout}" if timeout
|
446
739
|
|
447
|
-
|
448
|
-
|
449
|
-
|
740
|
+
hash = options.transform_keys do |okey|
|
741
|
+
if okey.to_s =~ /^if/i
|
742
|
+
okey.to_s.tr('_', '-')
|
743
|
+
elsif %w[date meta_name lease_id version].include?(okey.to_s)
|
744
|
+
'x-ms-' + okey.to_s.tr('_', '-')
|
745
|
+
else
|
746
|
+
'x-ms-blob-' + okey.to_s.tr('_', '-')
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
750
|
+
unless hash['x-ms-blob-type']
|
751
|
+
raise ArgumentError, "The :type option must be specified"
|
752
|
+
end
|
753
|
+
|
754
|
+
hash['x-ms-date'] ||= Time.now.httpdate
|
755
|
+
hash['x-ms-version'] ||= @storage_api_version
|
756
|
+
hash['verb'] = 'PUT'
|
757
|
+
|
758
|
+
# Content length must be 0 (blank) for Page or Append blobs
|
759
|
+
if %w[pageblob appendblob].include?(hash['x-ms-blob-type'].downcase)
|
760
|
+
hash['content-length'] = ''
|
761
|
+
else
|
762
|
+
hash['content-length'] ||= hash['x-ms-blob-content-length']
|
763
|
+
end
|
764
|
+
|
765
|
+
# Override the default empty string
|
766
|
+
hash['content-type'] ||= hash['x-ms-blob-content-type'] || 'application/octet-stream'
|
767
|
+
|
768
|
+
headers = build_headers(url, key, :blob, hash)
|
450
769
|
|
451
770
|
response = ArmrestService.send(
|
452
771
|
:rest_put,
|
453
772
|
:url => url,
|
454
|
-
:payload =>
|
773
|
+
:payload => payload,
|
455
774
|
:headers => headers,
|
456
775
|
:proxy => proxy,
|
457
776
|
:ssl_version => ssl_version,
|
458
777
|
:ssl_verify => ssl_verify
|
459
778
|
)
|
460
779
|
|
461
|
-
|
780
|
+
resp_headers = Azure::Armrest::ResponseHeaders.new(response.headers)
|
781
|
+
resp_headers.response_code = response.code
|
782
|
+
|
783
|
+
resp_headers
|
462
784
|
end
|
463
785
|
|
464
|
-
|
786
|
+
# Create a read-only snapshot of a blob.
|
787
|
+
#
|
788
|
+
# Possible options are:
|
789
|
+
#
|
790
|
+
# * meta_name
|
791
|
+
# * lease_id
|
792
|
+
# * client_request_id
|
793
|
+
# * if_modified_since
|
794
|
+
# * if_unmodified_since
|
795
|
+
# * if_match
|
796
|
+
# * if_none_match
|
797
|
+
# * timeout
|
798
|
+
#
|
799
|
+
# Returns a ResponseHeaders object since this is an asynchronous method.
|
800
|
+
#
|
801
|
+
def create_blob_snapshot(container, blob, key = access_key, options = {})
|
465
802
|
raise ArgumentError, "No access key specified" unless key
|
466
803
|
|
467
|
-
|
468
|
-
|
804
|
+
timeout = options.delete(:timeout) # Part of request
|
805
|
+
|
806
|
+
url = File.join(properties.primary_endpoints.blob, container, blob) + "?comp=snapshot"
|
807
|
+
url += "&timeout=#{timeout}" if timeout
|
808
|
+
|
809
|
+
hash = options.transform_keys do |okey|
|
810
|
+
if okey.to_s =~ /^if/i
|
811
|
+
okey.to_s.tr('_', '-')
|
812
|
+
else
|
813
|
+
'x-ms-blob-' + okey.to_s.tr('_', '-')
|
814
|
+
end
|
815
|
+
end
|
469
816
|
|
470
|
-
|
817
|
+
hash['verb'] = 'PUT'
|
818
|
+
|
819
|
+
headers = build_headers(url, key, :blob, hash)
|
471
820
|
|
472
821
|
response = ArmrestService.send(
|
473
822
|
:rest_put,
|
@@ -479,11 +828,10 @@ module Azure
|
|
479
828
|
:ssl_verify => ssl_verify
|
480
829
|
)
|
481
830
|
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
)
|
831
|
+
headers = Azure::Armrest::ResponseHeaders.new(response.headers)
|
832
|
+
headers.response_code = response.code
|
833
|
+
|
834
|
+
headers
|
487
835
|
end
|
488
836
|
|
489
837
|
# Get the contents of the given +blob+ found in +container+ using the
|
@@ -612,6 +960,31 @@ module Azure
|
|
612
960
|
)
|
613
961
|
end
|
614
962
|
|
963
|
+
# Using the file primary endpoint as a base, join any arguments to the
|
964
|
+
# the url and submit an http request.
|
965
|
+
#
|
966
|
+
def file_response(key, query, request_type = 'get', payload = '', *args)
|
967
|
+
url = File.join(properties.primary_endpoints.file, *args)
|
968
|
+
url += "?#{query}" if query && !query.empty?
|
969
|
+
request_method = "rest_#{request_type}".to_sym
|
970
|
+
|
971
|
+
headers = build_headers(url, key, :file, :verb => request_type.to_s.upcase)
|
972
|
+
|
973
|
+
params = {
|
974
|
+
:url => url,
|
975
|
+
:headers => headers,
|
976
|
+
:proxy => proxy,
|
977
|
+
:ssl_version => ssl_version,
|
978
|
+
:ssl_verify => ssl_verify,
|
979
|
+
}
|
980
|
+
|
981
|
+
if %w[put post].include?(request_type.to_s.downcase)
|
982
|
+
params[:payload] = payload
|
983
|
+
end
|
984
|
+
|
985
|
+
ArmrestService.send(request_method, params)
|
986
|
+
end
|
987
|
+
|
615
988
|
# Using the blob primary endpoint as a base, join any arguments to the
|
616
989
|
# the url and submit an http request.
|
617
990
|
def table_response(key, query = nil, *args)
|
@@ -644,8 +1017,10 @@ module Azure
|
|
644
1017
|
# RestClient will set the Content-Type to application/x-www-form-urlencoded.
|
645
1018
|
# We must override this setting or the request will fail in some cases.
|
646
1019
|
|
1020
|
+
content_type = additional_headers['content-type'] || ''
|
1021
|
+
|
647
1022
|
headers = {
|
648
|
-
'content-type' =>
|
1023
|
+
'content-type' => content_type,
|
649
1024
|
'x-ms-date' => Time.now.httpdate,
|
650
1025
|
'x-ms-version' => @storage_api_version,
|
651
1026
|
'auth_string' => true
|
@@ -6,7 +6,7 @@ module Azure
|
|
6
6
|
module Storage
|
7
7
|
# Base class for managing images.
|
8
8
|
class ImageService < ResourceGroupBasedService
|
9
|
-
# Create and return a new
|
9
|
+
# Create and return a new ImageService instance.
|
10
10
|
#
|
11
11
|
def initialize(configuration, options = {})
|
12
12
|
super(configuration, 'images', 'Microsoft.Compute', options)
|
@@ -22,6 +22,35 @@ module Azure
|
|
22
22
|
@publisher = options[:publisher]
|
23
23
|
end
|
24
24
|
|
25
|
+
# Return a list of all VM image offers from the given +location+.
|
26
|
+
#
|
27
|
+
# Example:
|
28
|
+
#
|
29
|
+
# vmis.list_all('eastus')
|
30
|
+
#
|
31
|
+
def list_all(location = @location)
|
32
|
+
raise ArgumentError, "No location specified" unless location
|
33
|
+
|
34
|
+
images = []
|
35
|
+
publishers(location).each do |publisher|
|
36
|
+
offers(location, publisher.name).each do |offer|
|
37
|
+
skus(offer.name, location, publisher.name).each do |sku|
|
38
|
+
versions(sku.name, offer.name, location, publisher.name).each do |version|
|
39
|
+
images << Azure::Armrest::VirtualMachineImage.new(
|
40
|
+
:location => version.location,
|
41
|
+
:publisher => publisher.name,
|
42
|
+
:offer => offer.name,
|
43
|
+
:sku => sku.name,
|
44
|
+
:version => version.name,
|
45
|
+
:id => "#{publisher.name}:#{offer.name}:#{sku.name}:#{version.name}"
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
images
|
52
|
+
end
|
53
|
+
|
25
54
|
# Return a list of VM image offers from the given +publisher+ and +location+.
|
26
55
|
#
|
27
56
|
# Example:
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: azure-armrest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-
|
14
|
+
date: 2017-07-20 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: json
|
@@ -300,7 +300,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
300
300
|
version: '0'
|
301
301
|
requirements: []
|
302
302
|
rubyforge_project:
|
303
|
-
rubygems_version: 2.
|
303
|
+
rubygems_version: 2.6.12
|
304
304
|
signing_key:
|
305
305
|
specification_version: 4
|
306
306
|
summary: An interface for ARM/JSON Azure REST API
|