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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5eafec5e5c9b51f1e01cd36f55872192579cf838
4
- data.tar.gz: 80dfaca5f2bec22dcdea5567295248e3a12b254f
3
+ metadata.gz: 8132014956246e577b66ccaf5a59e002e1dc06d3
4
+ data.tar.gz: f15ad3108839654399c954bb0f4460499de319cd
5
5
  SHA512:
6
- metadata.gz: 1f4dcb334ccb37db304d216ffeae044944724f1b517e317a1ea3d4393840203af5b665640806e07f8a5564fa723d66a0c4b3eb7bb802d66de1b6a85d2f0cefa8
7
- data.tar.gz: d0d956239b40e8ca6e59cecfa47650c1334c3b79dae481bef71d8a0485d9e14ada0cce04dba882ad045ef9acc3ddbbc9e8e10d6f52d3b04bb9f6dd721431592d
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
- # provider_info method instead.
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 do |okey|
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 +data+ parameter is a hash that contains the blob's information:
713
+ # The options parameter is a hash that contains information used
714
+ # when creating the blob:
435
715
  #
436
- # data['x-ms-blob-type']
437
- # # - Required. Specifies the type of blob to create: block, page or append.
716
+ # * type - "BlockBlob", "PageBlob" or "AppendBlob". Mandatory.
438
717
  #
439
- # data['x-ms-blob-content-encoding']
440
- # # - Optional. Set the blob’s content encoding.
441
- # ...
442
- def create_blob(container, blob, data, key = access_key)
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
- options = {:verb => 'PUT'}
448
- options = options.merge(data)
449
- headers = build_headers(url, key, :blob, options)
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
- Blob.new(response.headers)
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
- def create_blob_snapshot(container, blob, key = access_key)
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
- url = File.join(properties.primary_endpoints.blob, container, blob)
468
- url += "?comp=snapshot"
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
- headers = build_headers(url, key, :blob, :verb => 'PUT')
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
- BlobSnapshot.new(
483
- 'name' => blob,
484
- 'last_modified' => response.headers.fetch(:last_modified),
485
- 'snapshot' => response.headers.fetch(:x_ms_snapshot)
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 DiskService instance.
9
+ # Create and return a new ImageService instance.
10
10
  #
11
11
  def initialize(configuration, options = {})
12
12
  super(configuration, 'images', 'Microsoft.Compute', options)
@@ -1,6 +1,6 @@
1
1
  module Azure
2
2
  module Armrest
3
3
  # The version of the azure-armrest library.
4
- VERSION = '0.7.5'.freeze
4
+ VERSION = '0.8.0'.freeze
5
5
  end
6
6
  end
@@ -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.7.5
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-06-27 00:00:00.000000000 Z
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.5.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