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 +4 -4
- data/CHANGES +12 -0
- data/lib/azure/armrest.rb +3 -0
- data/lib/azure/armrest/armrest_service.rb +81 -65
- data/lib/azure/armrest/model/base_model.rb +5 -0
- data/lib/azure/armrest/model/storage_account.rb +89 -12
- data/lib/azure/armrest/network/network_security_rule_service.rb +3 -38
- data/lib/azure/armrest/network/subnet_service.rb +3 -48
- data/lib/azure/armrest/resource_group_based_service.rb +78 -73
- data/lib/azure/armrest/resource_group_based_subservice.rb +60 -0
- data/lib/azure/armrest/sql/sql_database_service.rb +11 -0
- data/lib/azure/armrest/sql/sql_server_service.rb +11 -0
- data/lib/azure/armrest/storage_account_service.rb +2 -2
- data/lib/azure/armrest/template_deployment_service.rb +34 -32
- data/lib/azure/armrest/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e916135112c85ebd2e061a02e63091e8eb6a629
|
4
|
+
data.tar.gz: a3c229e0a8fdf72bd06f81da392273548d5cb62a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
:
|
135
|
-
:
|
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
|
-
|
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
|
-
|
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.
|
291
|
-
RestClient.
|
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.
|
297
|
-
|
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.
|
303
|
-
|
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.
|
309
|
-
|
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.
|
315
|
-
|
316
|
-
|
317
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
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.
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 <
|
6
|
-
|
7
|
-
|
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 <
|
6
|
-
|
7
|
-
|
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
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
15
|
+
alias update create
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
def list(rgroup = armrest_configuration.resource_group)
|
18
|
+
validate_resource_group(rgroup)
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
33
|
+
def get(name, rgroup = armrest_configuration.resource_group)
|
34
|
+
validate_resource_group(rgroup)
|
35
|
+
validate_resource(name)
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
43
|
+
def delete(name, rgroup = armrest_configuration.resource_group)
|
44
|
+
validate_resource_group(rgroup)
|
45
|
+
validate_resource(name)
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
55
|
+
def validate_resource_group(name)
|
56
|
+
raise ArgumentError, "must specify resource group" unless name
|
57
|
+
end
|
68
58
|
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
74
|
+
def model_class
|
75
|
+
@model_class ||= Object.const_get(self.class.to_s.sub(/Service$/, ''))
|
76
|
+
end
|
82
77
|
|
83
|
-
|
84
|
-
|
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
|
-
|
93
|
+
threads.each(&:join)
|
90
94
|
|
91
|
-
|
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
|
@@ -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
|
-
|
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
|
-
|
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
|
2
|
-
|
3
|
-
|
1
|
+
module Azure
|
2
|
+
module Armrest
|
3
|
+
# Base class for managing templates and deployments
|
4
|
+
class TemplateDeploymentService < ResourceGroupBasedService
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
# Get all deployments for the current subscription
|
18
|
+
def list_all
|
19
|
+
list_in_all_groups
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
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
|
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.
|
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-
|
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
|