azure-armrest 0.2.3 → 0.2.4

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: 46e8ae9e1b26fc145c1e030083f6a37ec0873e68
4
- data.tar.gz: 23c5fbe41693e3e7d9ba42d91c3fa9da85692e0d
3
+ metadata.gz: 8323690e6c42f0a6ce2ed910bf933d6f8eb6bc9a
4
+ data.tar.gz: e8603030d496cb30d6e99e813c4cd32d05e118e6
5
5
  SHA512:
6
- metadata.gz: c4211477e10c08afe35c587f1f7d6d95505f58ac1f3bcb56b44582459f75cecd2dae7456bb5e78ceca2e2beaa1f21617f4ae530049faa909a50ff7b29d7e2f82
7
- data.tar.gz: c2550408054f12e2ecf56204f5413892d2de5c1501b69ce819cc8c28930cc72b27508f9e617f48ec68f039ddfcc91fa0b14d5a659940b6e411c9e73143461162
6
+ metadata.gz: 90aee7872a99f54b922e8252517e603208f5df62b53c0707687872df69beda6f01867b5ff8d06ad80285ed14eaebb75a3b6ffbe9f1fc2ef6da27565a00e6a35a
7
+ data.tar.gz: 7c280d3c7c302b21ebf4a2975aa613ce0e65b4c7d2417cad77f04e01283e8badc89dbab5649322aa6b8b59dfefff0c6baf97a45e8400158601d41895589059ff
data/CHANGES CHANGED
@@ -1,3 +1,14 @@
1
+ = 0.2.4 - 4-Apr-2016
2
+ * The ArmrestCollection#skip_token method was renamed to "continuation_token".
3
+ * Added the ArmrestService.log and ArmrestService.log= methods. These are just
4
+ thin wrappers around RestClient.log and RestClient.log= methods.
5
+ * Fixed the StorageAccount#table_data method, and added support for
6
+ continuation tokens.
7
+ * Fixed a bug in the BaseModel's method generation code where an all-caps
8
+ key would create strange results.
9
+ * Dealt with a bug in the StorageAccountService#create method caused by
10
+ a potentially empty response.
11
+
1
12
  = 0.2.3 - 29-Mar-2016
2
13
  * Fixed the VirtualMachineImageService class.
3
14
  * Added an Insights::MetricsService class and support models.
@@ -3,7 +3,7 @@
3
3
  module Azure
4
4
  module Armrest
5
5
  class ArmrestCollection < Array
6
- attr_accessor :skip_token
6
+ attr_accessor :continuation_token
7
7
  end
8
8
  end
9
9
  end
@@ -113,21 +113,24 @@ module Azure
113
113
  # - ssl_verify
114
114
  # - ssl_version
115
115
  #
116
- # Of these, you should include a client_id, client_key and tenant_id.
116
+ # Of these, you should include a :client_id, :client_key and :tenant_id.
117
117
  # The resource_group can be specified here, but many methods allow you
118
118
  # to specify a resource group if you prefer flexibility.
119
119
  #
120
- # If no subscription_id is provided then this method will attempt to find
120
+ # If no :subscription_id is provided then this method will attempt to find
121
121
  # a list of associated subscriptions and use the first one it finds as
122
122
  # the default. If no associated subscriptions are found, an ArgumentError
123
123
  # is raised.
124
124
  #
125
- # The other options (grant_type, content_type, accept, token,
126
- # token_expirationand api_version) should generally NOT be set by you
127
- # except in specific circumstances. Setting them explicitly will likely
128
- # cause breakage. Token and token_expiration must be set in pair.
129
- # Token_expiration is of local system time.
130
- # The api_version will typically be overridden on a per-provider/resource
125
+ # The other options (:grant_type, :content_type, :accept, :token,
126
+ # :token_expiration and :api_version) should generally NOT be set by you
127
+ # except in specific circumstances. Setting them explicitly will likely
128
+ # cause breakage.
129
+ #
130
+ # The :token and :token_expiration options must be set in pair. The
131
+ # :token_expiration should be set in local system time.
132
+ #
133
+ # The :api_version will typically be overridden on a per-provider/resource
131
134
  # basis within subclasses anyway.
132
135
  #
133
136
  # You may need to associate your application with a subscription using
@@ -339,6 +342,19 @@ module Azure
339
342
  JSON.parse(resp.body)['value'].map{ |hash| Azure::Armrest::Tenant.new(hash) }
340
343
  end
341
344
 
345
+ # The name of the file or handle used to log requests.
346
+ #
347
+ def self.log
348
+ file = RestClient.log.instance_variable_get("@target_file")
349
+ file || RestClient.log
350
+ end
351
+
352
+ # Sets the log to +output+, which can be a file or a handle.
353
+ #
354
+ def self.log=(output)
355
+ RestClient.log = output
356
+ end
357
+
342
358
  def self.rest_execute(options, http_method = :get)
343
359
  RestClient::Request.execute(options.merge(:method => http_method))
344
360
  rescue RestClient::Exception => e
@@ -59,11 +59,11 @@ module Azure
59
59
  end
60
60
  )
61
61
 
62
- events.skip_token = parse_skip_token(json_response)
62
+ events.continuation_token = parse_skip_token(json_response)
63
63
 
64
- if options[:all] && events.skip_token
65
- events.push(*list(options.merge(:skip_token => events.skip_token)))
66
- events.skip_token = nil # Clear when finished
64
+ if options[:all] && events.continuation_token
65
+ events.push(*list(options.merge(:skip_token => events.continuation_token)))
66
+ events.continuation_token = nil # Clear when finished
67
67
  end
68
68
 
69
69
  events
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
1
3
  module Azure
2
4
  module Armrest
3
5
  # Base class for JSON wrapper classes. Each Service class should have
@@ -114,7 +116,7 @@ module Azure
114
116
  __getobj__[key] = val
115
117
 
116
118
  return if key_exists
117
- add_accessor_methods(snake_case(key), key)
119
+ add_accessor_methods(key.to_s.underscore, key)
118
120
  end
119
121
 
120
122
  protected
@@ -130,7 +132,8 @@ module Azure
130
132
  @hashobj = obj
131
133
  excl_list = self.class.send(:excl_list)
132
134
  obj.each do |key, value|
133
- snake = snake_case(key)
135
+ snake = key.to_s.underscore
136
+
134
137
  unless excl_list.include?(snake) # Must deal with nested models
135
138
  if value.kind_of?(Array)
136
139
  newval = value.map { |elem| elem.kind_of?(Hash) ? nested_object(snake.camelize.singularize, elem) : elem }
@@ -153,14 +156,10 @@ module Azure
153
156
  end
154
157
 
155
158
  def add_accessor_methods(method, key)
156
- method.prepend('_') if methods.include?(method.to_sym)
159
+ method = "_#{method}" if methods.include?(method.to_sym)
157
160
  instance_eval { define_singleton_method(method) { __getobj__[key] } }
158
161
  instance_eval { define_singleton_method("#{method}=") { |val| __getobj__[key] = val } }
159
162
  end
160
-
161
- def snake_case(name)
162
- name.to_s.gsub(/(.)([A-Z])/, '\1_\2').downcase
163
- end
164
163
  end
165
164
 
166
165
  # Initial class definitions. Reopen these classes as needed.
@@ -64,27 +64,55 @@ module Azure
64
64
  # account +key+. The exact nature of the TableData object depends on the
65
65
  # type of table that it is.
66
66
  #
67
+ # You may specify :filter, :select or :top as options to restrict your
68
+ # result set.
69
+ #
70
+ # By default you will receive a maximum of 1000 records. If you wish to
71
+ # receive more records, you will need to use the continuation token. You
72
+ # may also set the :all option to true if you want all records, though we
73
+ # recommend using a filter as well if you use that option as there can
74
+ # be thousands of results.
75
+ #
76
+ # You may also specify a :NextRowKey, :NextPartitionKey or :NextTableset
77
+ # explicitly for paging. Normally you would just pass the
78
+ # collection's continuation_token, however. See below for an example.
79
+ #
80
+ # When using continuation tokens, you should retain your original
81
+ # filtering as well, or you may get unexpected results.
82
+ #
83
+ # Examples:
84
+ #
85
+ # # Get the first 10 rows of data from the last 3 days
86
+ # date = (Time.now - (86400 * 3)).iso8601
87
+ # my_filter = "timestamp ge datetime'#{date}'"
88
+ # options = {:top => 10, :filter => my_filter}
89
+ #
90
+ # results = storage_account.table_data(table, key, options)
91
+ #
92
+ # # Now get the next 10 records
93
+ # if results.continuation_token
94
+ # options[:continuation_token] = results.continuation_token
95
+ # more_results = storage_account.table_data(table, key, options)
96
+ # end
97
+ #
67
98
  def table_data(name, key = nil, options = {})
68
99
  key ||= properties.key1
69
100
 
70
- query = ""
101
+ query = build_query(options)
71
102
 
72
- hash = {
73
- "$filter=" => options[:filter],
74
- "$select=" => options[:select],
75
- "$top=" => options[:top]
76
- }
103
+ response = table_response(key, query, name)
104
+ json_response = JSON.parse(response.body)
77
105
 
78
- hash.each do |key, value|
79
- if query.include?("$")
80
- query << "&#{key}#{value}" if value
81
- else
82
- query << "#{key}#{value}" if value
83
- end
106
+ data = ArmrestCollection.new(json_response['value'].map { |t| TableData.new(t) })
107
+ data.continuation_token = parse_continuation_tokens(response)
108
+
109
+ if options[:all] && data.continuation_token
110
+ options[:continuation_token] = data.continuation_token
111
+ data.push(*table_data(name, key, options))
112
+ data.continuation_token = nil # Clear when finished
84
113
  end
85
114
 
86
- response = table_response(key, query, name)
87
- JSON.parse(response.body)['value'].map{ |t| TableData.new(t) }
115
+ data
88
116
  end
89
117
 
90
118
  # Return a list of container names for the given storage account +key+.
@@ -415,6 +443,42 @@ module Azure
415
443
 
416
444
  private
417
445
 
446
+ # Build a query string from a hash of options.
447
+ #
448
+ def build_query(options)
449
+ array = []
450
+
451
+ options.each do |key, value|
452
+ next if key == :all
453
+ if [:filter, :select, :top].include?(key)
454
+ array << "$#{key}=#{value}" if value
455
+ elsif key == :continuation_token
456
+ value.each { |k, token| array << "#{k}=#{token}" if token }
457
+ else
458
+ array << "#{key}=#{value}" if value
459
+ end
460
+ end
461
+
462
+ array.join('&')
463
+ end
464
+
465
+ # Get the continuation tokens from the response headers for paging results.
466
+ #
467
+ def parse_continuation_tokens(response)
468
+ headers = response.headers
469
+
470
+ token = {
471
+ :NextPartitionKey => headers[:x_ms_continuation_nextpartitionkey],
472
+ :NextRowKey => headers[:x_ms_continuation_nextrowkey],
473
+ :NextTableName => headers[:x_ms_continuation_nexttablename]
474
+ }
475
+
476
+ # If there are no continuation values at all, then return nil
477
+ token = nil if token.all? { |_key, value| value.nil? }
478
+
479
+ token
480
+ end
481
+
418
482
  # Using the blob primary endpoint as a base, join any arguments to the
419
483
  # the url and submit an http request.
420
484
  #
@@ -439,7 +503,10 @@ module Azure
439
503
  headers = build_headers(url, key, 'table')
440
504
  headers['Accept'] = 'application/json;odata=fullmetadata'
441
505
 
442
- url << "?#{query}" if query # Must happen after headers are built
506
+ # Must happen after headers are built
507
+ unless query.nil? || query.empty?
508
+ url << "?#{query}"
509
+ end
443
510
 
444
511
  ArmrestService.rest_get(
445
512
  :url => url,
@@ -79,8 +79,8 @@ module Azure
79
79
  # sas = Azure::Armrest::StorageAccountService(config)
80
80
  #
81
81
  # sas.create(
82
- # "yourstorageaccount1",
83
- # "yourresourcegroup",
82
+ # "your_storage_account",
83
+ # "your_resource_group",
84
84
  # {
85
85
  # :location => "West US",
86
86
  # :properties => {:accountType => "Standard_ZRS"},
@@ -88,14 +88,24 @@ module Azure
88
88
  # }
89
89
  # )
90
90
  #
91
- def create(account_name, rgroup = configuration.resource_group, options = {})
91
+ def create(account_name, rgroup = configuration.resource_group, options)
92
92
  validating = options.delete(:validating)
93
93
  validate_account_type(options[:properties][:accountType])
94
94
  validate_account_name(account_name)
95
95
 
96
- super(account_name, rgroup, options) do |url|
96
+ acct = super(account_name, rgroup, options) do |url|
97
97
  url << "&validating=" << validating if validating
98
- end.tap { |m| m.proxy = configuration.proxy }
98
+ end
99
+
100
+ # An initial create call will return nil because the response body is
101
+ # empty. In that case, make another call to get the object properties.
102
+ acct = get(account_name, rgroup) unless acct
103
+
104
+ acct.proxy = configuration.proxy
105
+ acct.ssl_version = configuration.ssl_version
106
+ acct.ssl_verify = configuration.ssl_verify
107
+
108
+ acct
99
109
  end
100
110
 
101
111
  # Returns the primary and secondary access keys for the given
@@ -1,5 +1,5 @@
1
1
  module Azure
2
2
  module Armrest
3
- VERSION = '0.2.3'
3
+ VERSION = '0.2.4'
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.3
4
+ version: 0.2.4
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-29 00:00:00.000000000 Z
14
+ date: 2016-04-04 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: json