azure-armrest 0.1.0 → 0.1.1

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: 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