azure-armrest 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b38ce81faf1e7a3998d3d6cd13eb2b0355ba74a5
4
- data.tar.gz: bed848faad0986fbaf58291d40786064ece38bbf
3
+ metadata.gz: c69e270a5d35df9198153455a690ada22d513f4c
4
+ data.tar.gz: 67ef3824766ab4ebf5a8b5926acf58a4d34fed8b
5
5
  SHA512:
6
- metadata.gz: 3d3c9da030fd7fbd38a255569898effe664a5018ebde842c2b174cd9a68cecdac89346098190ad052e4439afc461ac4a529a6b9e7c7c73910834b19abb644b3c
7
- data.tar.gz: 015da585475887f7b3e223dbcf798608555de9b277f05aab3af95d9b23b024946b46bd0ef0ff930f4d87940d22df78b7c6b2d4519bc497ab099892cbf720ccfe
6
+ metadata.gz: 08513ba9e0ae24282d58be10bf04b5ae9aa1a98bffee330d0678de5c4afd7ec4bd3be5b83ca12c02aabe5dd13a132155ba91df17cf049b6b4ae2ac64424b35d0
7
+ data.tar.gz: c21f1908abb2d89055db2aea97a57cdac1c080789e844538aa406e20cd8bce853e745f1efa024f13632a0ba17432506573352092c63301f7bb4dba999c2d69ac
data/CHANGES CHANGED
@@ -1,3 +1,10 @@
1
+ = 0.2.1 - 15-Mar-2016
2
+ * The ssl_version and ssl_verify options are now supported by, and
3
+ automatically passed on to, StorageAccount model objects.
4
+ * Added the get_blob_raw method to get at raw blob data. Use wisely.
5
+ * Nested model objects are now named based on the attribute name rather
6
+ than anonymous.
7
+
1
8
  = 0.2.0 - 10-Mar-2016
2
9
  * The Armrest.configure method now supports the :ssl_verify and :ssl_version
3
10
  options. By default, the ssl_version option is set to TLSv1 instead of
@@ -46,12 +46,9 @@ module Azure
46
46
  # Find the exclusion list for the model of next level (@embed_model)
47
47
  # '#' is the separator between levels. Remove attributes
48
48
  # before the first separator.
49
- child_excl_list = self.class.send(:excl_list).map do |e|
49
+ @child_excl_list = self.class.send(:excl_list).map do |e|
50
50
  e.index('#') ? e[e.index('#') + 1..-1] : ''
51
51
  end
52
- @embed_model = Class.new(BaseModel) do
53
- attr_hash(*child_excl_list)
54
- end
55
52
 
56
53
  if json.kind_of?(Hash)
57
54
  @hash = json
@@ -136,10 +133,10 @@ module Azure
136
133
  snake = snake_case(key)
137
134
  unless excl_list.include?(snake) # Must deal with nested models
138
135
  if value.kind_of?(Array)
139
- newval = value.map { |elem| elem.kind_of?(Hash) ? @embed_model.new(elem) : elem }
136
+ newval = value.map { |elem| elem.kind_of?(Hash) ? nested_object(snake.camelize.singularize, elem) : elem }
140
137
  obj[key] = newval
141
138
  elsif value.kind_of?(Hash)
142
- obj[key] = @embed_model.new(value)
139
+ obj[key] = nested_object(snake.camelize, value)
143
140
  end
144
141
  end
145
142
 
@@ -147,6 +144,14 @@ module Azure
147
144
  end
148
145
  end
149
146
 
147
+ def nested_object(klass_name, value)
148
+ unless self.class.const_defined?(klass_name)
149
+ child_excl_list = @child_excl_list
150
+ self.class.const_set(klass_name, Class.new(BaseModel) { attr_hash(*child_excl_list) })
151
+ end
152
+ self.class.const_get(klass_name).new(value)
153
+ end
154
+
150
155
  def add_accessor_methods(method, key)
151
156
  method.prepend('_') if methods.include?(method.to_sym)
152
157
  instance_eval { define_singleton_method(method) { __getobj__[key] } }
@@ -27,10 +27,18 @@ module Azure
27
27
  # An http proxy to use per request. Defaults to ENV['http_proxy'] if set.
28
28
  attr_accessor :proxy
29
29
 
30
+ # The SSL version to use per request. Defaults to TLSv1.
31
+ attr_accessor :ssl_version
32
+
33
+ # The SSL verification method used for each request. The default is VERIFY_PEER.
34
+ attr_accessor :ssl_verify
35
+
30
36
  def initialize(json)
31
37
  super
32
38
  @storage_api_version = '2015-02-21'
33
39
  @proxy = ENV['http_proxy']
40
+ @ssl_version = 'TLSv1'
41
+ @ssl_verify = nil
34
42
  end
35
43
 
36
44
  # Returns a list of tables for the given storage account +key+. Note
@@ -134,9 +142,11 @@ module Azure
134
142
  headers = build_headers(url, key, :blob, :verb => 'HEAD')
135
143
 
136
144
  response = ArmrestService.rest_head(
137
- :url => url,
138
- :headers => headers,
139
- :proxy => proxy
145
+ :url => url,
146
+ :headers => headers,
147
+ :proxy => proxy,
148
+ :ssl_version => ssl_version,
149
+ :ssl_verify => ssl_verify
140
150
  )
141
151
 
142
152
  BlobProperty.new(response.headers)
@@ -155,9 +165,11 @@ module Azure
155
165
  headers = build_headers(url, key)
156
166
 
157
167
  response = ArmrestService.rest_get(
158
- :url => url,
159
- :headers => headers,
160
- :proxy => proxy
168
+ :url => url,
169
+ :headers => headers,
170
+ :proxy => proxy,
171
+ :ssl_version => ssl_version,
172
+ :ssl_verify => ssl_verify
161
173
  )
162
174
 
163
175
  doc = Nokogiri::XML(response.body)
@@ -244,10 +256,12 @@ module Azure
244
256
  headers = build_headers(dst_url, key, :blob, options)
245
257
 
246
258
  response = ArmrestService.rest_put(
247
- :url => dst_url,
248
- :payload => '',
249
- :headers => headers,
250
- :proxy => proxy
259
+ :url => dst_url,
260
+ :payload => '',
261
+ :headers => headers,
262
+ :proxy => proxy,
263
+ :ssl_version => ssl_version,
264
+ :ssl_verify => ssl_verify
251
265
  )
252
266
 
253
267
  Blob.new(response.headers)
@@ -264,9 +278,11 @@ module Azure
264
278
  headers = build_headers(url, key, :blob, :verb => 'DELETE')
265
279
 
266
280
  response = ArmrestService.rest_delete(
267
- :url => url,
268
- :headers => headers,
269
- :proxy => proxy
281
+ :url => url,
282
+ :headers => headers,
283
+ :proxy => proxy,
284
+ :ssl_version => ssl_version,
285
+ :ssl_verify => ssl_verify
270
286
  )
271
287
 
272
288
  true
@@ -292,10 +308,12 @@ module Azure
292
308
  headers = build_headers(url, key, :blob, options)
293
309
 
294
310
  response = ArmrestService.rest_put(
295
- :url => url,
296
- :payload => '',
297
- :headers => headers,
298
- :proxy => proxy
311
+ :url => url,
312
+ :payload => '',
313
+ :headers => headers,
314
+ :proxy => proxy,
315
+ :ssl_version => ssl_version,
316
+ :ssl_verify => ssl_verify
299
317
  )
300
318
 
301
319
  Blob.new(response.headers)
@@ -310,10 +328,12 @@ module Azure
310
328
  headers = build_headers(url, key, :blob, :verb => 'PUT')
311
329
 
312
330
  response = ArmrestService.rest_put(
313
- :url => url,
314
- :payload => '',
315
- :headers => headers,
316
- :proxy => proxy
331
+ :url => url,
332
+ :payload => '',
333
+ :headers => headers,
334
+ :proxy => proxy,
335
+ :ssl_version => ssl_version,
336
+ :ssl_verify => ssl_verify
317
337
  )
318
338
 
319
339
  BlobSnapshot.new(
@@ -323,6 +343,76 @@ module Azure
323
343
  )
324
344
  end
325
345
 
346
+ # Get the contents of the given +blob+ found in +container+ using the
347
+ # given +options+. This is a low level method to read a range of bytes
348
+ # from the blob directly. The possible options are:
349
+ #
350
+ # * range - A range of bytes to collect.
351
+ # * start_byte - The starting byte for collection.
352
+ # * end_byte - The end byte for collection. Use this or :length with :start_byte.
353
+ # * length - The number of bytes to collect starting at +start_byte+.
354
+ # * entire_image - Read all bytes for the blob.
355
+ # * md5 - If true, the response headers will include MD5 checksum information.
356
+ # * date - Get the blob snapshot for the given date.
357
+ #
358
+ # If you do not specify a :range or :start_byte, then an error will be
359
+ # raised unless you explicitly set the :entire_image option to true.
360
+ # However, that is not recommended because the blobs can be huge.
361
+ #
362
+ # Unlike other methods, this method returns a raw response object rather
363
+ # than a wrapper model. Get the information you need using:
364
+ #
365
+ # * response.body - blob data.
366
+ # * response.headers - blob metadata.
367
+ #
368
+ # Example:
369
+ #
370
+ # ret = @storage_acct.get_blob(@container, @blob, key, :start_byte => start_byte, :length => length)
371
+ # content_md5 = ret.headers[:content_md5].unpack("m0").first.unpack("H*").first
372
+ # returned_md5 = Digest::MD5.hexdigest(ret.body)
373
+ # raise "Checksum error: #{range_str}, blob: #{@container}/#{@blob}" unless content_md5 == returned_md5
374
+ # return ret.body
375
+ #
376
+ def get_blob_raw(container, blob, key = nil, options = {})
377
+ key ||= properties.key1
378
+
379
+ url = File.join(properties.primary_endpoints.blob, container, blob)
380
+ url += "?snapshot=" + options[:date] if options[:date]
381
+
382
+ additional_headers = {
383
+ 'verb' => 'GET'
384
+ }
385
+
386
+ range_str = nil
387
+ if options[:range]
388
+ range_str = "bytes=#{options[:range].min}-#{options[:range].max}"
389
+ elsif options[:start_byte]
390
+ range_str = "bytes=#{options[:start_byte]}-"
391
+ if options[:end_byte]
392
+ range_str << options[:end_byte].to_s
393
+ elsif options[:length]
394
+ range_str << (options[:start_byte] + options[:length] - 1).to_s
395
+ end
396
+ end
397
+
398
+ if range_str
399
+ additional_headers['x-ms-range'] = range_str
400
+ additional_headers['x-ms-range-get-content-md5'] = true if options[:md5]
401
+ else
402
+ raise ArgumentError, "must specify byte range or entire_image flag" unless options[:entire_image]
403
+ end
404
+
405
+ headers = build_headers(url, key, :blob, additional_headers)
406
+
407
+ ArmrestService.rest_get(
408
+ :url => url,
409
+ :headers => headers,
410
+ :proxy => proxy,
411
+ :ssl_version => ssl_version,
412
+ :ssl_verify => ssl_verify,
413
+ )
414
+ end
415
+
326
416
  private
327
417
 
328
418
  # Using the blob primary endpoint as a base, join any arguments to the
@@ -331,7 +421,14 @@ module Azure
331
421
  def blob_response(key, query, *args)
332
422
  url = File.join(properties.primary_endpoints.blob, *args) + "?#{query}"
333
423
  headers = build_headers(url, key, 'blob')
334
- ArmrestService.rest_get(:url => url, :headers => headers, :proxy => proxy)
424
+
425
+ ArmrestService.rest_get(
426
+ :url => url,
427
+ :headers => headers,
428
+ :proxy => proxy,
429
+ :ssl_version => ssl_version,
430
+ :ssl_verify => ssl_verify,
431
+ )
335
432
  end
336
433
 
337
434
  # Using the blob primary endpoint as a base, join any arguments to the
@@ -344,7 +441,13 @@ module Azure
344
441
 
345
442
  url << "?#{query}" if query # Must happen after headers are built
346
443
 
347
- ArmrestService.rest_get(:url => url, :headers => headers, :proxy => proxy)
444
+ ArmrestService.rest_get(
445
+ :url => url,
446
+ :headers => headers,
447
+ :proxy => proxy,
448
+ :ssl_version => ssl_version,
449
+ :ssl_verify => ssl_verify,
450
+ )
348
451
  end
349
452
 
350
453
  # Set the headers needed, including the Authorization header.
@@ -23,19 +23,31 @@ module Azure
23
23
  # Same as other resource based get methods, but also sets the proxy on the model object.
24
24
  #
25
25
  def get(name, resource_group = configuration.resource_group)
26
- super.tap { |m| m.proxy = configuration.proxy }
26
+ super.tap do |m|
27
+ m.proxy = configuration.proxy
28
+ m.ssl_version = configuration.ssl_version
29
+ m.ssl_verify = configuration.ssl_verify
30
+ end
27
31
  end
28
32
 
29
33
  # Same as other resource based list methods, but also sets the proxy on each model object.
30
34
  #
31
35
  def list(resource_group = configuration.resource_group)
32
- super.each { |m| m.proxy = configuration.proxy }
36
+ super.each do |m|
37
+ m.proxy = configuration.proxy
38
+ m.ssl_version = configuration.ssl_version
39
+ m.ssl_verify = configuration.ssl_verify
40
+ end
33
41
  end
34
42
 
35
43
  # Same as other resource based list_all methods, but also sets the proxy on each model object.
36
44
  #
37
45
  def list_all
38
- super.each { |m| m.proxy = configuration.proxy }
46
+ super.each do |m|
47
+ m.proxy = configuration.proxy
48
+ m.ssl_version = configuration.ssl_version
49
+ m.ssl_verify = configuration.ssl_verify
50
+ end
39
51
  end
40
52
 
41
53
  # Creates a new storage account, or updates an existing account with the
@@ -156,6 +168,38 @@ module Azure
156
168
  results.flatten
157
169
  end
158
170
 
171
+ def accounts_by_name
172
+ @accounts_by_name ||= list_all.each_with_object({}) { |sa, sah| sah[sa.name] = sa }
173
+ end
174
+
175
+ def parse_uri(uri)
176
+ uri = URI.parse(uri)
177
+ host_components = uri.host.split('.')
178
+
179
+ rh = {
180
+ :scheme => uri.scheme,
181
+ :account_name => host_components[0],
182
+ :service_name => host_components[1],
183
+ :resource_path => uri.path
184
+ }
185
+
186
+ # TODO: support other service types.
187
+ return rh unless rh[:service_name] == "blob"
188
+
189
+ blob_components = uri.path.split('/', 3)
190
+ if blob_components[2]
191
+ rh[:container] = blob_components[1]
192
+ rh[:blob] = blob_components[2]
193
+ else
194
+ rh[:container] = '$root'
195
+ rh[:blob] = blob_components[1]
196
+ end
197
+
198
+ return rh unless uri.query && uri.query.start_with?("snapshot=")
199
+ rh[:snapshot] = uri.query.split('=', 2)[1]
200
+ rh
201
+ end
202
+
159
203
  private
160
204
 
161
205
  def validate_account_type(account_type)
@@ -1,5 +1,5 @@
1
1
  module Azure
2
2
  module Armrest
3
- VERSION = "0.2.0"
3
+ VERSION = '0.2.1'
4
4
  end
5
5
  end
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.2.0
4
+ version: 0.2.1
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: 2016-03-10 00:00:00.000000000 Z
14
+ date: 2016-03-15 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: json