azure-armrest 0.1.0 → 0.1.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: bfd3dade5a1dad37a43cb98080c1509d58d9bd31
4
- data.tar.gz: b3aeb02c6b2ee98cb38a4bda0f71f6e221c81789
3
+ metadata.gz: 1e916135112c85ebd2e061a02e63091e8eb6a629
4
+ data.tar.gz: a3c229e0a8fdf72bd06f81da392273548d5cb62a
5
5
  SHA512:
6
- metadata.gz: b9268be1252d095820a642cf5c20adf895d67555ad4354f6ad78fc35b381c26b693efd3ec1802fbd8cbbb7e9f897889509b9cb28c8cdbb363752325d404bde17
7
- data.tar.gz: cd67fb3c615bd1d8e83644152e28826b816b1f17586c4b84a314a976fde879ea76cb3b620bbb9fbe0bbbb755ad2dc3cf763bdea3c7e3ccbc4739b75a96a2861a
6
+ metadata.gz: bbdbea8e75c851b6ada07023ad9b6e4cce25a6cae9f14ab4e579030538518fd7489a86ae318786bfca0f512a951090fa9059ca2a2b772859b98fd1fcd6756a6f
7
+ data.tar.gz: b327fa9ceea6ebda436f4f51aa5bf4db18d75735f884a1566c48d835a807201f0e31492dca373e709ad49585dceebaaf4e46bb9737163be2a773b327f05453e9
data/CHANGES CHANGED
@@ -1,3 +1,15 @@
1
+ = 0.1.1 - 26-Feb-2016
2
+ * Added proxy support for both the storage model and main configure method.
3
+ * Added the SqlDatabaseService and SqlServerService classes.
4
+ * Added the ResourceGroupBaseedSubservice abstract base class.
5
+ * When fetching a default subscription, enabled subscriptions are chosen
6
+ before disabled subscriptions. If only a disabled subscription can be
7
+ found then a warning is issued.
8
+ * You can now create blobs and blob snapshots with the storage model.
9
+ Thanks go to Alexandre Lamandé and Nguyễn Tấn Tài and for their patches.
10
+ * Some internal refactoring to use our own helper methods for various
11
+ RestClient methods, and other cleanup.
12
+
1
13
  = 0.1.0 - 26-Jan-2015
2
14
  * Refactored the ArmrestService class api_version and provider handling.
3
15
  * The ArmrestService class no longer uses "preview" api versions by default.
data/lib/azure/armrest.rb CHANGED
@@ -24,6 +24,7 @@ require 'azure/armrest/version'
24
24
  require 'azure/armrest/exception'
25
25
  require 'azure/armrest/armrest_service'
26
26
  require 'azure/armrest/resource_group_based_service'
27
+ require 'azure/armrest/resource_group_based_subservice'
27
28
  require 'azure/armrest/storage_account_service'
28
29
  require 'azure/armrest/availability_set_service'
29
30
  require 'azure/armrest/virtual_machine_service'
@@ -43,6 +44,8 @@ require 'azure/armrest/network/virtual_network_service'
43
44
  require 'azure/armrest/network/subnet_service'
44
45
  require 'azure/armrest/role/assignment_service'
45
46
  require 'azure/armrest/role/definition_service'
47
+ require 'azure/armrest/sql/sql_server_service'
48
+ require 'azure/armrest/sql/sql_database_service'
46
49
 
47
50
  # JSON wrapper classes. The service classes should require their own
48
51
  # wrappers from this point on.
@@ -15,7 +15,8 @@ module Azure
15
15
  :content_type,
16
16
  :accept,
17
17
  :token,
18
- :token_expiration # token expiration local system date
18
+ :token_expiration, # token expiration local system date
19
+ :proxy
19
20
  ) do
20
21
  @@tokens = Hash.new([])
21
22
 
@@ -35,13 +36,19 @@ module Azure
35
36
  def fetch_token
36
37
  token_url = Azure::Armrest::AUTHORITY + tenant_id + "/oauth2/token"
37
38
 
38
- response = JSON.parse(ArmrestService.rest_post(
39
- token_url,
40
- :grant_type => grant_type,
41
- :client_id => client_id,
42
- :client_secret => client_key,
43
- :resource => Azure::Armrest::RESOURCE
44
- ))
39
+ response = JSON.parse(
40
+ ArmrestService.rest_post(
41
+ :url => token_url,
42
+ :proxy => proxy,
43
+ :payload => {
44
+ :grant_type => grant_type,
45
+ :client_id => client_id,
46
+ :client_secret => client_key,
47
+ :resource => Azure::Armrest::RESOURCE
48
+ }
49
+ )
50
+ )
51
+
45
52
  token = 'Bearer ' + response['access_token']
46
53
  @@tokens[as_cache_key] = [token, Time.now + response['expires_in'].to_i]
47
54
  end
@@ -61,6 +68,9 @@ module Azure
61
68
  # The api-version string used for each request.
62
69
  attr_accessor :api_version
63
70
 
71
+ # The http proxy used for each request. Uses ENV['http_proxy'] if set.
72
+ attr_accessor :proxy
73
+
64
74
  @@providers_hash = {} # Set in constructor
65
75
 
66
76
  @@tokens = {} # token caches
@@ -120,26 +130,40 @@ module Azure
120
130
  configuration.content_type ||= 'application/json'
121
131
  configuration.accept ||= 'application/json'
122
132
  configuration.subscription_id ||= fetch_subscription_id(configuration)
133
+ configuration.proxy ||= ENV['http_proxy']
123
134
 
124
135
  configuration
125
136
  end
126
137
 
138
+ # Find the first enabled subscription if one isn't provided or cached.
139
+ #
127
140
  def self.fetch_subscription_id(config)
128
141
  return @@subscriptions[config.as_cache_key] if @@subscriptions.has_key?(config.as_cache_key)
129
142
 
130
143
  url = File.join(Azure::Armrest::RESOURCE, "subscriptions?api-version=#{config.api_version}")
131
144
 
132
145
  response = rest_get(
133
- url,
134
- :content_type => config.content_type,
135
- :authorization => config.token
146
+ :url => url,
147
+ :proxy => config.proxy,
148
+ :headers => {
149
+ :content_type => config.content_type,
150
+ :authorization => config.token
151
+ }
136
152
  )
137
153
 
138
- hash = JSON.parse(response)["value"].first
154
+ array = JSON.parse(response)["value"]
155
+
156
+ if array.nil? || array.empty?
157
+ raise ArgumentError, "No associated subscription found"
158
+ end
159
+
160
+ # Look for the first enabled subscription, otherwise just take the first subscription found.
161
+ hash = array.find{ |h| h['state'] == 'Enabled' } || array.first
139
162
 
140
- raise ArgumentError, "No associated subscription found" if hash.empty?
163
+ id = hash.fetch('subscriptionId')
164
+
165
+ warn "Warning: subscription #{id} is not enabled" unless hash['state'] == 'Enabled'
141
166
 
142
- id = hash.fetch("subscriptionId")
143
167
  @@subscriptions[config.as_cache_key] = id
144
168
  end
145
169
 
@@ -287,34 +311,34 @@ module Azure
287
311
  JSON.parse(resp.body)['value'].map{ |hash| Azure::Armrest::Tenant.new(hash) }
288
312
  end
289
313
 
290
- def self.rest_get(url, headers = {})
291
- RestClient.get(url, headers)
314
+ def self.rest_execute(options, http_method = :get)
315
+ RestClient::Request.execute(options.merge(:method => http_method))
292
316
  rescue RestClient::Exception => e
293
317
  raise_api_exception(e)
294
318
  end
295
319
 
296
- def self.rest_post(url, body, headers = {})
297
- RestClient.post(url, body, headers)
298
- rescue RestClient::Exception => e
299
- raise_api_exception(e)
320
+ def self.rest_get(options)
321
+ rest_execute(options, :get)
300
322
  end
301
323
 
302
- def self.rest_patch(url, body, headers = {})
303
- RestClient.patch(url, body, headers)
304
- rescue RestClient::Exception => e
305
- raise_api_exception(e)
324
+ def self.rest_post(options)
325
+ rest_execute(options, :post)
306
326
  end
307
327
 
308
- def self.rest_delete(url, headers = {})
309
- RestClient.delete(url, headers)
310
- rescue RestClient::Exception => e
311
- raise_api_exception(e)
328
+ def self.rest_patch(options)
329
+ rest_execute(options, :patch)
312
330
  end
313
331
 
314
- def self.rest_put(url, body, headers = {})
315
- RestClient.put(url, body, headers)
316
- rescue RestClient::Exception => e
317
- raise_api_exception(e)
332
+ def self.rest_delete(options)
333
+ rest_execute(options, :delete)
334
+ end
335
+
336
+ def self.rest_put(options)
337
+ rest_execute(options, :put)
338
+ end
339
+
340
+ def self.rest_head(options)
341
+ rest_execute(options, :head)
318
342
  end
319
343
 
320
344
  def self.raise_api_exception(e)
@@ -350,52 +374,44 @@ module Azure
350
374
 
351
375
  # REST verb methods
352
376
 
377
+ def rest_execute(url, body = nil, http_method = :get)
378
+ options = {
379
+ :url => url,
380
+ :proxy => armrest_configuration.proxy,
381
+ :headers => {
382
+ :accept => armrest_configuration.accept,
383
+ :content_type => armrest_configuration.content_type,
384
+ :authorization => armrest_configuration.token
385
+ }
386
+ }
387
+
388
+ options[:payload] = body if body
389
+
390
+ self.class.rest_execute(options, http_method)
391
+ end
392
+
353
393
  def rest_get(url)
354
- self.class.rest_get(
355
- url,
356
- :accept => armrest_configuration.accept,
357
- :content_type => armrest_configuration.content_type,
358
- :authorization => armrest_configuration.token,
359
- )
394
+ rest_execute(url)
360
395
  end
361
396
 
362
397
  def rest_put(url, body = '')
363
- self.class.rest_put(
364
- url,
365
- body,
366
- :accept => armrest_configuration.accept,
367
- :content_type => armrest_configuration.content_type,
368
- :authorization => armrest_configuration.token,
369
- )
398
+ rest_execute(url, body, :put)
370
399
  end
371
400
 
372
401
  def rest_post(url, body = '')
373
- self.class.rest_post(
374
- url,
375
- body,
376
- :accept => armrest_configuration.accept,
377
- :content_type => armrest_configuration.content_type,
378
- :authorization => armrest_configuration.token,
379
- )
402
+ rest_execute(url, body, :post)
380
403
  end
381
404
 
382
405
  def rest_patch(url, body = '')
383
- self.class.rest_patch(
384
- url,
385
- body,
386
- :accept => armrest_configuration.accept,
387
- :content_type => armrest_configuration.content_type,
388
- :authorization => armrest_configuration.token,
389
- )
406
+ rest_execute(url, body, :patch)
390
407
  end
391
408
 
392
409
  def rest_delete(url)
393
- self.class.rest_delete(
394
- url,
395
- :accept => armrest_configuration.accept,
396
- :content_type => armrest_configuration.content_type,
397
- :authorization => armrest_configuration.token,
398
- )
410
+ rest_execute(url, nil, :delete)
411
+ end
412
+
413
+ def rest_head(url)
414
+ rest_execute(url, nil, :head)
399
415
  end
400
416
 
401
417
  # Take an array of URI elements and join the together with the API version.
@@ -200,6 +200,11 @@ module Azure
200
200
  class Assignment < BaseModel; end
201
201
  class Definition < BaseModel; end
202
202
  end
203
+
204
+ module Sql
205
+ class SqlServer < BaseModel; end
206
+ class SqlDatabase < BaseModel; end
207
+ end
203
208
  end
204
209
  end
205
210
 
@@ -14,6 +14,7 @@ module Azure
14
14
  class BlobServiceProperty < BaseModel; end
15
15
  class BlobServiceStat < BaseModel; end
16
16
  class BlobMetadata < BaseModel; end
17
+ class BlobSnapshot < Blob; end
17
18
 
18
19
  # Classes used to wrap table information
19
20
  class Table < BaseModel; end
@@ -23,9 +24,13 @@ module Azure
23
24
  # request. The default is 2015-02-21.
24
25
  attr_accessor :storage_api_version
25
26
 
27
+ # An http proxy to use per request. Defaults to ENV['http_proxy'] if set.
28
+ attr_accessor :proxy
29
+
26
30
  def initialize(json)
27
31
  super
28
32
  @storage_api_version = '2015-02-21'
33
+ @proxy = ENV['http_proxy']
29
34
  end
30
35
 
31
36
  # Returns a list of tables for the given storage account +key+. Note
@@ -127,7 +132,12 @@ module Azure
127
132
  url += "?snapshot=" + options[:date] if options[:date]
128
133
 
129
134
  headers = build_headers(url, key, :blob, :verb => 'HEAD')
130
- response = RestClient.head(url, headers)
135
+
136
+ response = ArmrestService.rest_head(
137
+ :url => url,
138
+ :headers => headers,
139
+ :proxy => proxy
140
+ )
131
141
 
132
142
  BlobProperty.new(response.headers)
133
143
  end
@@ -135,19 +145,26 @@ module Azure
135
145
  # Return a list of blobs for the given +container+ using the given +key+
136
146
  # or the key1 property of the StorageAccount object.
137
147
  #
138
- def blobs(container, key = nil)
148
+ def blobs(container, key = nil, include_snapshot = false)
139
149
  key ||= properties.key1
140
150
 
141
151
  url = File.join(properties.primary_endpoints.blob, container)
142
152
  url += "?restype=container&comp=list"
153
+ url += "&include=snapshots" if include_snapshot
143
154
 
144
155
  headers = build_headers(url, key)
145
- response = RestClient.get(url, headers)
156
+
157
+ response = ArmrestService.rest_get(
158
+ :url => url,
159
+ :headers => headers,
160
+ :proxy => proxy
161
+ )
162
+
146
163
  doc = Nokogiri::XML(response.body)
147
164
 
148
165
  doc.xpath('//Blobs/Blob').map do |node|
149
166
  hash = Hash.from_xml(node.to_s)['Blob'].merge(:container => container)
150
- Blob.new(hash)
167
+ hash.key?('Snapshot') ? BlobSnapshot.new(hash) : Blob.new(hash)
151
168
  end
152
169
  end
153
170
 
@@ -226,11 +243,11 @@ module Azure
226
243
 
227
244
  headers = build_headers(dst_url, key, :blob, options)
228
245
 
229
- # RestClient will set the Content-Type to application/x-www-form-urlencoded.
230
- # We must override this setting or the request will fail.
231
- headers['Content-Type'] = ''
232
-
233
- response = RestClient.put(dst_url, '', headers)
246
+ response = ArmrestService.rest_put(
247
+ :url => dst_url,
248
+ :payload => '',
249
+ :headers => headers
250
+ )
234
251
 
235
252
  Blob.new(response.headers)
236
253
  end
@@ -244,11 +261,67 @@ module Azure
244
261
  url += "?snapshot=" + options[:date] if options[:date]
245
262
 
246
263
  headers = build_headers(url, key, :blob, :verb => 'DELETE')
247
- response = RestClient.delete(url, headers)
264
+
265
+ response = ArmrestService.rest_delete(
266
+ :url => url,
267
+ :headers => headers,
268
+ :proxy => proxy
269
+ )
248
270
 
249
271
  true
250
272
  end
251
273
 
274
+ # Create new blob for a container.
275
+ #
276
+ # The +data+ parameter is a hash that contains the blob's information:
277
+ #
278
+ # data['x-ms-blob-type']
279
+ # # - Required. Specifies the type of blob to create: block, page or append.
280
+ #
281
+ # data['x-ms-blob-content-encoding']
282
+ # # - Optional. Set the blob’s content encoding.
283
+ # ...
284
+ def create_blob(container, blob, data, key = nil)
285
+ key ||= properties.key1
286
+
287
+ url = File.join(properties.primary_endpoints.blob, container, blob)
288
+
289
+ options = {:verb => 'PUT'}
290
+ options = options.merge(data)
291
+ headers = build_headers(url, key, :blob, options)
292
+
293
+ response = ArmrestService.rest_put(
294
+ :url => url,
295
+ :payload => '',
296
+ :headers => headers,
297
+ :proxy => proxy
298
+ )
299
+
300
+ Blob.new(response.headers)
301
+ end
302
+
303
+ def create_blob_snapshot(container, blob, key = nil)
304
+ key ||= properties.key1
305
+
306
+ url = File.join(properties.primary_endpoints.blob, container, blob)
307
+ url += "?comp=snapshot"
308
+
309
+ headers = build_headers(url, key, :blob, :verb => 'PUT')
310
+
311
+ response = ArmrestService.rest_put(
312
+ :url => url,
313
+ :payload => '',
314
+ :headers => headers,
315
+ :proxy => proxy
316
+ )
317
+
318
+ BlobSnapshot.new(
319
+ 'name' => blob,
320
+ 'last_modified' => response.headers.fetch(:last_modified),
321
+ 'snapshot' => response.headers.fetch(:x_ms_snapshot)
322
+ )
323
+ end
324
+
252
325
  private
253
326
 
254
327
  # Using the blob primary endpoint as a base, join any arguments to the
@@ -257,7 +330,7 @@ module Azure
257
330
  def blob_response(key, query, *args)
258
331
  url = File.join(properties.primary_endpoints.blob, *args) + "?#{query}"
259
332
  headers = build_headers(url, key, 'blob')
260
- RestClient.get(url, headers)
333
+ ArmrestService.rest_get(:url => url, :headers => headers, :proxy => proxy)
261
334
  end
262
335
 
263
336
  # Using the blob primary endpoint as a base, join any arguments to the
@@ -270,7 +343,7 @@ module Azure
270
343
 
271
344
  url << "?#{query}" if query # Must happen after headers are built
272
345
 
273
- RestClient.get(url, headers)
346
+ ArmrestService.rest_get(:url => url, :headers => headers, :proxy => proxy)
274
347
  end
275
348
 
276
349
  # Set the headers needed, including the Authorization header.
@@ -279,7 +352,11 @@ module Azure
279
352
  sig = Signature.new(url, key)
280
353
  sig_type ||= 'blob'
281
354
 
355
+ # RestClient will set the Content-Type to application/x-www-form-urlencoded.
356
+ # We must override this setting or the request will fail in some cases.
357
+
282
358
  headers = {
359
+ 'Content-Type' => '',
283
360
  'x-ms-date' => Time.now.httpdate,
284
361
  'x-ms-version' => @storage_api_version,
285
362
  :auth_string => true
@@ -2,44 +2,9 @@ module Azure
2
2
  module Armrest
3
3
  module Network
4
4
  # Base class for managing securityRules
5
- class NetworkSecurityRuleService < NetworkSecurityGroupService
6
- # Creates a new +rule_name+ on +security_group+ using the given +options+.
7
- def create(rule_name, security_group, resource_group = armrest_configuration.resource_group, options = {})
8
- super(combine(security_group, rule_name), resource_group, options)
9
- end
10
-
11
- alias update create
12
-
13
- # Deletes the given +rule_name+ in +security_group+.
14
- #
15
- def delete(rule_name, security_group, resource_group = armrest_configuration.resource_group)
16
- super(combine(security_group, rule_name), resource_group)
17
- end
18
-
19
- # Retrieves information for the provided +rule_name+ in +security_group+ for
20
- # the current subscription.
21
- #
22
- def get(rule_name, security_group, resource_group = armrest_configuration.resource_group)
23
- super(combine(security_group, rule_name), resource_group)
24
- end
25
-
26
- # List available security rules on +security_group+ for the given +resource_group+.
27
- #
28
- def list(security_group, resource_group = armrest_configuration.resource_group)
29
- raise ArgumentError, "must specify resource group" unless resource_group
30
- raise ArgumentError, "must specify name of the resource" unless security_group
31
-
32
- url = build_url(resource_group, security_group, 'securityRules')
33
- response = rest_get(url)
34
- JSON.parse(response)['value'].map{ |hash| model_class.new(hash) }
35
- end
36
-
37
- alias list_all list
38
-
39
- private
40
-
41
- def combine(virtual_network, subnet)
42
- File.join(virtual_network, 'securityRules', subnet)
5
+ class NetworkSecurityRuleService < ResourceGroupBasedSubservice
6
+ def initialize(armrest_configuration, options = {})
7
+ super(armrest_configuration, 'networkSecurityGroups', 'securityRules', 'Microsoft.Network', options)
43
8
  end
44
9
  end
45
10
  end # Network
@@ -2,54 +2,9 @@ module Azure
2
2
  module Armrest
3
3
  module Network
4
4
  # Base class for managing subnets
5
- class SubnetService < VirtualNetworkService
6
- # Creates a new +subnet_name+ on +virtual_network+ using the given
7
- # +options+. The +options+ argument is a hash that supports the
8
- # following keys and subkeys.
9
- #
10
- # - :properties
11
- # - :addressPrefix
12
- # - :networkSecurityGroup
13
- # - :id
14
- # - :routeTable
15
- # - :id
16
- #
17
- def create(subnet_name, virtual_network, resource_group = armrest_configuration.resource_group, options = {})
18
- super(combine(virtual_network, subnet_name), resource_group, options)
19
- end
20
-
21
- alias update create
22
-
23
- # Deletes the given +subnet_name+ in +virtual_network+.
24
- #
25
- def delete(subnet_name, virtual_network, resource_group = armrest_configuration.resource_group)
26
- super(combine(virtual_network, subnet_name), resource_group)
27
- end
28
-
29
- # Retrieves information for the provided +subnet_name+ in +virtual_network+ for
30
- # the current subscription.
31
- #
32
- def get(subnet_name, virtual_network, resource_group = armrest_configuration.resource_group)
33
- super(combine(virtual_network, subnet_name), resource_group)
34
- end
35
-
36
- # List available subnets on +virtual_network+ for the given +resource_group+.
37
- #
38
- def list(virtual_network, resource_group = armrest_configuration.resource_group)
39
- raise ArgumentError, "must specify resource group" unless resource_group
40
- raise ArgumentError, "must specify name of the resource" unless virtual_network
41
-
42
- url = build_url(resource_group, virtual_network, 'subnets')
43
- response = rest_get(url)
44
- JSON.parse(response)['value'].map{ |hash| model_class.new(hash) }
45
- end
46
-
47
- alias list_all list
48
-
49
- private
50
-
51
- def combine(virtual_newtork, subnet)
52
- File.join(virtual_newtork, 'subnets', subnet)
5
+ class SubnetService < ResourceGroupBasedSubservice
6
+ def initialize(armrest_configuration, options = {})
7
+ super(armrest_configuration, 'virtualNetworks', 'subnets', 'Microsoft.Network', options)
53
8
  end
54
9
  end
55
10
  end # Network
@@ -1,94 +1,99 @@
1
- module Azure::Armrest
2
- # Base class for services that needs to run in a resource group
3
- class ResourceGroupBasedService < ArmrestService
4
- def create(name, rgroup = armrest_configuration.resource_group, options = {})
5
- raise ArgumentError, "must specify resource group" unless rgroup
6
- raise ArgumentError, "must specify name of the resource" unless name
7
-
8
- url = build_url(rgroup, name)
9
- url = yield(url) || url if block_given?
10
- response = rest_put(build_url(rgroup, name), options.to_json)
11
- model_class.new(response) unless response.empty?
12
- end
1
+ module Azure
2
+ module Armrest
3
+ # Base class for services that need to run in a resource group
4
+ class ResourceGroupBasedService < ArmrestService
5
+ def create(name, rgroup = armrest_configuration.resource_group, options = {})
6
+ validate_resource_group(rgroup)
7
+ validate_resource(name)
8
+
9
+ url = build_url(rgroup, name)
10
+ url = yield(url) || url if block_given?
11
+ response = rest_put(url, options.to_json)
12
+ model_class.new(response) unless response.empty?
13
+ end
13
14
 
14
- alias update create
15
+ alias update create
15
16
 
16
- def list(rgroup = armrest_configuration.resource_group)
17
- raise ArgumentError, "must specify resource group" unless rgroup
17
+ def list(rgroup = armrest_configuration.resource_group)
18
+ validate_resource_group(rgroup)
18
19
 
19
- url = build_url(rgroup)
20
- url = yield(url) || url if block_given?
21
- response = rest_get(url)
22
- JSON.parse(response)['value'].map{ |hash| model_class.new(hash) }
23
- end
20
+ url = build_url(rgroup)
21
+ url = yield(url) || url if block_given?
22
+ response = rest_get(url)
23
+ JSON.parse(response)['value'].map { |hash| model_class.new(hash) }
24
+ end
24
25
 
25
- def list_all
26
- url = build_url
27
- url = yield(url) || url if block_given?
28
- response = rest_get(url)
29
- JSON.parse(response)['value'].map{ |hash| model_class.new(hash) }
30
- end
26
+ def list_all
27
+ url = build_url
28
+ url = yield(url) || url if block_given?
29
+ response = rest_get(url)
30
+ JSON.parse(response)['value'].map { |hash| model_class.new(hash) }
31
+ end
31
32
 
32
- def get(name, rgroup = armrest_configuration.resource_group)
33
- raise ArgumentError, "must specify resource group" unless rgroup
34
- raise ArgumentError, "must specify name of the resource" unless name
33
+ def get(name, rgroup = armrest_configuration.resource_group)
34
+ validate_resource_group(rgroup)
35
+ validate_resource(name)
35
36
 
36
- url = build_url(rgroup, name)
37
- url = yield(url) || url if block_given?
38
- response = rest_get(url)
39
- model_class.new(response)
40
- end
37
+ url = build_url(rgroup, name)
38
+ url = yield(url) || url if block_given?
39
+ response = rest_get(url)
40
+ model_class.new(response)
41
+ end
41
42
 
42
- def delete(name, rgroup= armrest_configuration.resource_group)
43
- raise ArgumentError, "must specify resource group" unless rgroup
44
- raise ArgumentError, "must specify name of the resource" unless name
43
+ def delete(name, rgroup = armrest_configuration.resource_group)
44
+ validate_resource_group(rgroup)
45
+ validate_resource(name)
45
46
 
46
- url = build_url(rgroup, name)
47
- url = yield(url) || url if block_given?
48
- rest_delete(url)
49
- nil
50
- end
47
+ url = build_url(rgroup, name)
48
+ url = yield(url) || url if block_given?
49
+ rest_delete(url)
50
+ nil
51
+ end
51
52
 
52
- private
53
-
54
- # Builds a URL based on subscription_id an resource_group and any other
55
- # arguments provided, and appends it with the api_version.
56
- #
57
- def build_url(resource_group = nil, *args)
58
- url = File.join(Azure::Armrest::COMMON_URI, armrest_configuration.subscription_id)
59
- url = File.join(url, 'resourceGroups', resource_group) if resource_group
60
- url = File.join(url, 'providers', @provider, @service_name)
61
- url = File.join(url, *args) unless args.empty?
62
- url << "?api-version=#{@api_version}"
63
- end
53
+ private
64
54
 
65
- def model_class
66
- @model_class ||= Object.const_get(self.class.to_s.sub(/Service$/, ''))
67
- end
55
+ def validate_resource_group(name)
56
+ raise ArgumentError, "must specify resource group" unless name
57
+ end
68
58
 
69
- # Aggregate resources from each group
70
- # To be used in the case that API does not support list_all with one call
71
- def list_in_all_groups
72
- array = []
73
- threads = []
74
- mutex = Mutex.new
59
+ def validate_resource(name)
60
+ raise ArgumentError, "must specify #{@service_name.singularize.underscore.humanize}" unless name
61
+ end
75
62
 
76
- resource_groups.each do |rg|
77
- threads << Thread.new(rg['name']) do |group|
78
- url = build_url(group)
79
- response = rest_get(url)
63
+ # Builds a URL based on subscription_id an resource_group and any other
64
+ # arguments provided, and appends it with the api_version.
65
+ #
66
+ def build_url(resource_group = nil, *args)
67
+ url = File.join(Azure::Armrest::COMMON_URI, armrest_configuration.subscription_id)
68
+ url = File.join(url, 'resourceGroups', resource_group) if resource_group
69
+ url = File.join(url, 'providers', @provider, @service_name)
70
+ url = File.join(url, *args) unless args.empty?
71
+ url << "?api-version=#{@api_version}"
72
+ end
80
73
 
81
- results = JSON.parse(response)['value'].map { |hash| model_class.new(hash) }
74
+ def model_class
75
+ @model_class ||= Object.const_get(self.class.to_s.sub(/Service$/, ''))
76
+ end
82
77
 
83
- if results && !results.empty?
84
- mutex.synchronize{ array << results }
78
+ # Aggregate resources from each group
79
+ # To be used in the case that API does not support list_all with one call
80
+ def list_in_all_groups
81
+ array = []
82
+ threads = []
83
+ mutex = Mutex.new
84
+
85
+ resource_groups.each do |rg|
86
+ threads << Thread.new(rg['name']) do |group|
87
+ response = rest_get(build_url(group))
88
+ results = JSON.parse(response)['value'].map { |hash| model_class.new(hash) }
89
+ mutex.synchronize { array << results } unless results.blank?
85
90
  end
86
91
  end
87
- end
88
92
 
89
- threads.each(&:join)
93
+ threads.each(&:join)
90
94
 
91
- array.flatten
95
+ array.flatten
96
+ end
92
97
  end
93
98
  end
94
99
  end
@@ -0,0 +1,60 @@
1
+ module Azure
2
+ module Armrest
3
+ # Base class for services that have two levels in the path and need to run in a resource group
4
+ class ResourceGroupBasedSubservice < ResourceGroupBasedService
5
+ # Do not instantiate directly. This is an abstract base class from which
6
+ # all other service classes should subclass, and call super within their
7
+ # own constructors.
8
+ #
9
+ def initialize(armrest_configuration, service_name, subservice_name, default_provider, options)
10
+ @subservice_name = subservice_name
11
+ super(armrest_configuration, service_name, default_provider, options)
12
+ end
13
+
14
+ def create(resource, subresource, rgroup = armrest_configuration.resource_group, options = {})
15
+ validate_resource_group(rgroup)
16
+ validate_resource(resource)
17
+ validate_subresource(subresource)
18
+ super(combine(resource, subresource), rgroup, options)
19
+ end
20
+
21
+ alias update create
22
+
23
+ def list(resource, rgroup = armrest_configuration.resource_group)
24
+ validate_resource_group(rgroup)
25
+ validate_resource(resource)
26
+
27
+ url = build_url(rgroup, resource, @subservice_name)
28
+ url = yield(url) || url if block_given?
29
+ response = rest_get(url)
30
+ JSON.parse(response)['value'].map { |hash| model_class.new(hash) }
31
+ end
32
+
33
+ alias list_all list
34
+
35
+ def get(resource, subresource, rgroup = armrest_configuration.resource_group)
36
+ validate_resource_group(rgroup)
37
+ validate_resource(resource)
38
+ validate_subresource(subresource)
39
+ super(combine(resource, subresource), rgroup)
40
+ end
41
+
42
+ def delete(resource, subresource, rgroup = armrest_configuration.resource_group)
43
+ validate_resource_group(rgroup)
44
+ validate_resource(resource)
45
+ validate_subresource(subresource)
46
+ super(combine(resource, subresource), rgroup)
47
+ end
48
+
49
+ private
50
+
51
+ def validate_subresource(name)
52
+ raise ArgumentError, "must specify #{@subservice_name.singularize.underscore.humanize}" unless name
53
+ end
54
+
55
+ def combine(resource, subresource)
56
+ File.join(resource, @subservice_name, subresource)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,11 @@
1
+ module Azure
2
+ module Armrest
3
+ module Sql
4
+ class SqlDatabaseService < ResourceGroupBasedSubservice
5
+ def initialize(armrest_configuration, options = {})
6
+ super(armrest_configuration, 'servers', 'databases', 'Microsoft.Sql', options)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Azure
2
+ module Armrest
3
+ module Sql
4
+ class SqlServerService < ResourceGroupBasedService
5
+ def initialize(armrest_configuration, options = {})
6
+ super(armrest_configuration, 'servers', 'Microsoft.Sql', options)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -71,7 +71,7 @@ module Azure
71
71
  # storage account as a hash.
72
72
  #
73
73
  def list_account_keys(account_name, group = armrest_configuration.resource_group)
74
- raise ArgumentError, "must specify resource group" unless group
74
+ validate_resource_group(group)
75
75
 
76
76
  url = build_url(group, account_name, 'listKeys')
77
77
  response = rest_post(url)
@@ -87,7 +87,7 @@ module Azure
87
87
  # }
88
88
  #
89
89
  def regenerate_storage_account_keys(account_name, group = armrest_configuration.resource_group, options)
90
- raise ArgumentError, "must specify resource group" unless group
90
+ validate_resource_group(group)
91
91
 
92
92
  url = build_url(group, account_name, 'regenerateKey')
93
93
  response = rest_post(url, options.to_json)
@@ -1,42 +1,44 @@
1
- module Azure::Armrest
2
- # Base class for managing templates and deployments
3
- class TemplateDeploymentService < ResourceGroupBasedService
1
+ module Azure
2
+ module Armrest
3
+ # Base class for managing templates and deployments
4
+ class TemplateDeploymentService < ResourceGroupBasedService
4
5
 
5
- def initialize(armrest_configuration, options = {})
6
- # Has to be hard coded for now
7
- options = {'api_version' => '2014-04-01-preview'}.merge(options)
8
- super(armrest_configuration, 'deployments', 'Microsoft.Resources', options)
9
- end
6
+ def initialize(armrest_configuration, options = {})
7
+ # Has to be hard coded for now
8
+ options = {'api_version' => '2014-04-01-preview'}.merge(options)
9
+ super(armrest_configuration, 'deployments', 'Microsoft.Resources', options)
10
+ end
10
11
 
11
- # Get names of all deployments in a resource group
12
- def list_names(resource_group = armrest_configuration.resource_group)
13
- list(resource_group).map(&:name)
14
- end
12
+ # Get names of all deployments in a resource group
13
+ def list_names(resource_group = armrest_configuration.resource_group)
14
+ list(resource_group).map(&:name)
15
+ end
15
16
 
16
- # Get all deployments for the current subscription
17
- def list_all
18
- list_in_all_groups
19
- end
17
+ # Get all deployments for the current subscription
18
+ def list_all
19
+ list_in_all_groups
20
+ end
20
21
 
21
- # Get all operations of a deployment in a resource group
22
- def list_deployment_operations(deploy_name, resource_group = armrest_configuration.resource_group)
23
- raise ArgumentError, "must specify resource group" unless resource_group
24
- raise ArgumentError, "must specify name of the resource" unless deploy_name
22
+ # Get all operations of a deployment in a resource group
23
+ def list_deployment_operations(deploy_name, resource_group = armrest_configuration.resource_group)
24
+ validate_resource_group(resource_group)
25
+ validate_resource(deploy_name)
25
26
 
26
- url = build_url(resource_group, deploy_name, 'operations')
27
- response = rest_get(url)
28
- JSON.parse(response)['value'].map{ |hash| TemplateDeploymentOperation.new(hash) }
29
- end
27
+ url = build_url(resource_group, deploy_name, 'operations')
28
+ response = rest_get(url)
29
+ JSON.parse(response)['value'].map { |hash| TemplateDeploymentOperation.new(hash) }
30
+ end
30
31
 
31
- # Get the operation of a deployment in a resource group
32
- def get_deployment_operation(op_id, deploy_name, resource_group = armrest_configuration.resource_group)
33
- raise ArgumentError, "must specify resource group" unless resource_group
34
- raise ArgumentError, "must specify name of the resource" unless deploy_name
35
- raise ArgumentError, "must specify operation id" unless op_id
32
+ # Get the operation of a deployment in a resource group
33
+ def get_deployment_operation(op_id, deploy_name, resource_group = armrest_configuration.resource_group)
34
+ validate_resource_group(resource_group)
35
+ validate_resource(deploy_name)
36
+ raise ArgumentError, "must specify operation id" unless op_id
36
37
 
37
- url = build_url(resource_group, deploy_name, 'operations', op_id)
38
- response = rest_get(url)
39
- TemplateDeploymentOperation.new(response)
38
+ url = build_url(resource_group, deploy_name, 'operations', op_id)
39
+ response = rest_get(url)
40
+ TemplateDeploymentOperation.new(response)
41
+ end
40
42
  end
41
43
  end
42
44
  end
@@ -1,5 +1,5 @@
1
1
  module Azure
2
2
  module Armrest
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.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.1.0
4
+ version: 0.1.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-01-26 00:00:00.000000000 Z
14
+ date: 2016-02-26 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: json
@@ -205,11 +205,14 @@ files:
205
205
  - lib/azure/armrest/network/subnet_service.rb
206
206
  - lib/azure/armrest/network/virtual_network_service.rb
207
207
  - lib/azure/armrest/resource_group_based_service.rb
208
+ - lib/azure/armrest/resource_group_based_subservice.rb
208
209
  - lib/azure/armrest/resource_group_service.rb
209
210
  - lib/azure/armrest/resource_provider_service.rb
210
211
  - lib/azure/armrest/resource_service.rb
211
212
  - lib/azure/armrest/role/assignment_service.rb
212
213
  - lib/azure/armrest/role/definition_service.rb
214
+ - lib/azure/armrest/sql/sql_database_service.rb
215
+ - lib/azure/armrest/sql/sql_server_service.rb
213
216
  - lib/azure/armrest/storage_account_service.rb
214
217
  - lib/azure/armrest/template_deployment_service.rb
215
218
  - lib/azure/armrest/version.rb