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