azure-armrest 0.0.1 → 0.0.2

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.
@@ -3,12 +3,12 @@ module Azure
3
3
  # Armrest namespace
4
4
  module Armrest
5
5
  # Base class for managing subnets
6
- class SubnetManager < VirtualNetworkManager
6
+ class SubnetService < VirtualNetworkService
7
7
 
8
- # Create and return a new SubnetManager instance. Most methods for a
9
- # SubnetManager instance will return one or Subnet instances.
8
+ # Create and return a new SubnetService instance. Most methods for a
9
+ # SubnetService instance will return one or Subnet instances.
10
10
  #
11
- def initialize(options = {})
11
+ def initialize(_armrest_configuration, _options = {})
12
12
  super
13
13
 
14
14
  @base_url += "/subnets"
@@ -0,0 +1,97 @@
1
+ module Azure::Armrest
2
+ # Base class for managing templates and deployments
3
+ class TemplateDeploymentService < ArmrestService
4
+
5
+ def initialize(_armrest_configuration, _options = {})
6
+ super
7
+
8
+ # has to be hard coded for now
9
+ set_service_api_version({'api_version' => '2014-04-01-preview'}, '')
10
+ end
11
+
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 {|e| e['name']}
15
+ end
16
+
17
+ # Get all deployments in a resource group
18
+ # If the resource group is nil, then return deployments in all groups
19
+ def list(resource_group = armrest_configuration.resource_group)
20
+ if resource_group
21
+ url = build_deployment_url(resource_group)
22
+ JSON.parse(rest_get(url))['value']
23
+ else
24
+ threads = []
25
+ array = []
26
+ mutex = Mutex.new
27
+
28
+ resource_groups.each do |rg|
29
+ threads << Thread.new(rg['name']) do |group|
30
+ url = build_deployment_url(group)
31
+ results = JSON.parse(rest_get(url))['value']
32
+ if results && !results.empty?
33
+ mutex.synchronize {
34
+ results.each { |hash| hash['resourceGroup'] = group }
35
+ array << results
36
+ }
37
+ end
38
+ end
39
+ end
40
+
41
+ threads.each(&:join)
42
+ array.flatten
43
+ end
44
+ end
45
+
46
+ # Get the deployment in a resource group
47
+ def get(deploy_name, resource_group = armrest_configuration.resource_group)
48
+ url = build_deployment_url(resource_group, deploy_name)
49
+ JSON.parse(rest_get(url))
50
+ end
51
+
52
+ # Get all operations of a deployment in a resource group
53
+ def list_deployment_operations(deploy_name, resource_group = armrest_configuration.resource_group)
54
+ url = build_deployment_url(resource_group, deploy_name, 'operations')
55
+ JSON.parse(rest_get(url))['value']
56
+ end
57
+
58
+ # Get the operation of a deployment in a resource group
59
+ def get_deployment_operation(deploy_name, op_id, resource_group = armrest_configuration.resource_group)
60
+ url = build_deployment_url(resource_group, deploy_name, 'operations', op_id)
61
+ JSON.parse(rest_get(url))
62
+ end
63
+
64
+ # Create a template deployment
65
+ # The template and parameters should be provided through the options hash
66
+ def create(deploy_name, options, resource_group = armrest_configuration.resource_group)
67
+ url = build_deployment_url(resource_group, deploy_name)
68
+ body = options.has_key?('properties') ? options.to_json : {'properties' => options}.to_json
69
+ JSON.parse(rest_put(url, body))
70
+ end
71
+
72
+ # Delete a deployment
73
+ def delete(deploy_name, resource_group = armrest_configuration.resource_group)
74
+ url = build_deployment_url(resource_group, deploy_name)
75
+ rest_delete(url)
76
+ end
77
+
78
+ private
79
+
80
+
81
+ # Builds a URL based on subscription_id an resource_group and any other
82
+ # arguments provided, and appends it with the api_version.
83
+ #
84
+ def build_deployment_url(resource_group, *args)
85
+ url = File.join(
86
+ Azure::Armrest::COMMON_URI,
87
+ armrest_configuration.subscription_id,
88
+ 'resourceGroups',
89
+ resource_group,
90
+ 'deployments',
91
+ )
92
+
93
+ url = File.join(url, *args) unless args.empty?
94
+ url << "?api-version=#{@api_version}"
95
+ end
96
+ end
97
+ end
@@ -1,5 +1,5 @@
1
1
  module Azure
2
2
  module Armrest
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -3,7 +3,11 @@ module Azure
3
3
  # Armrest namespace
4
4
  module Armrest
5
5
  # Base class for managing virtual machine extensions
6
- class VirtualMachineExtensionManager < VirtualMachineManager
6
+ class VirtualMachineExtensionService < VirtualMachineService
7
+
8
+ def initialize(_armrest_configuration, _options = {})
9
+ super
10
+ end
7
11
 
8
12
  # Creates a new virtual machine extension for +vmname+ with the given
9
13
  # +extension_name+, and the given +options+. Possible options are:
@@ -20,7 +24,7 @@ module Azure
20
24
  #type = options.fetch(:type)
21
25
  #type_handler_version = options.fetch(:type_handler_version)
22
26
 
23
- url = @uri + "/#{vmname}/extensions/#{extension_name}?#{api_version}"
27
+ url = @uri + "/#{vmname}/extensions/#{extension_name}?#{@api_version}"
24
28
  url
25
29
  end
26
30
 
@@ -31,7 +35,7 @@ module Azure
31
35
  # DELETE
32
36
  #
33
37
  def delete(vmname, extension_name)
34
- url = @uri + "/#{vmname}/extensions/#{extension_name}?#{api_version}"
38
+ url = @uri + "/#{vmname}/extensions/#{extension_name}?#{@api_version}"
35
39
  url
36
40
  end
37
41
 
@@ -43,7 +47,7 @@ module Azure
43
47
  def get(vmname, instance_view = false)
44
48
  url = @uri + "/#{vmname}/extensions/#{extension_name}?"
45
49
  url += "$expand=instanceView," if instance_view
46
- url += "#{api_version}"
50
+ url += "#{@api_version}"
47
51
  url
48
52
  end
49
53
 
@@ -51,7 +55,7 @@ module Azure
51
55
  def list(vmname, instance_view = false)
52
56
  url = @uri + "/#{vmname}/extensions"
53
57
  url += "$expand=instanceView," if instance_view
54
- url += "#{api_version}"
58
+ url += "#{@api_version}"
55
59
  url
56
60
  end
57
61
  end
@@ -3,7 +3,7 @@ module Azure
3
3
  # Armrest namespace
4
4
  module Armrest
5
5
  # Base class for managing virtual machine images
6
- class VirtualMachineImageManager < ArmrestManager
6
+ class VirtualMachineImageService < ArmrestService
7
7
  # The location used in requests when gathering VM image information.
8
8
  attr_accessor :location
9
9
 
@@ -13,23 +13,20 @@ module Azure
13
13
  # The publisher used in requests when gathering VM image information.
14
14
  attr_accessor :publisher
15
15
 
16
- # Create and return a new VirtualMachineImageManager (VMIM) instance.
16
+ # Create and return a new VirtualMachineImageService (VMIM) instance.
17
17
  #
18
18
  # This subclass accepts the additional :location, :provider, and
19
19
  # :publisher options as well. The default provider is set to
20
20
  # 'Microsoft.Compute'.
21
21
  #
22
- def initialize(options = {})
22
+ def initialize(_armrest_configuration, options = {})
23
23
  super
24
24
 
25
25
  @location = options[:location]
26
26
  @provider = options[:provider] || 'Microsoft.Compute'
27
27
  @publisher = options[:publisher]
28
28
 
29
- # Typically only empty in testing.
30
- unless @@providers.empty?
31
- @api_version = @@providers[@provider]['locations/publishers']['api_version']
32
- end
29
+ set_service_api_version(options, 'locations/publishers')
33
30
  end
34
31
 
35
32
  # Set a new provider to use the default for other methods. This may alter
@@ -37,8 +34,8 @@ module Azure
37
34
  # 'Microsoft.Compute' or 'Microsoft.ClassicCompute' should be used.
38
35
  #
39
36
  def provider=(name)
40
- @api_version = @@providers[name]['locations/publishers']['api_version']
41
37
  @provider = name
38
+ set_service_api_version({}, 'locations/publishers')
42
39
  end
43
40
 
44
41
  # Return a list of VM image offers from the given +publisher+ and +location+.
@@ -119,7 +116,7 @@ module Azure
119
116
  def build_url(location, *args)
120
117
  url = File.join(
121
118
  Azure::Armrest::COMMON_URI,
122
- subscription_id,
119
+ armrest_configuration.subscription_id,
123
120
  'providers',
124
121
  provider,
125
122
  'locations',
@@ -130,6 +127,6 @@ module Azure
130
127
  url << "?api-version=#{api_version}"
131
128
  end
132
129
 
133
- end # VirtualMachineImageManager
130
+ end # VirtualMachineImageService
134
131
  end # Armrest
135
132
  end # Azure
@@ -3,12 +3,12 @@ module Azure
3
3
  # Armrest namespace
4
4
  module Armrest
5
5
  # Base class for managing virtual machines
6
- class VirtualMachineManager < ArmrestManager
6
+ class VirtualMachineService < ArmrestService
7
7
 
8
8
  # The provider used in requests when gathering VM information.
9
9
  attr_reader :provider
10
10
 
11
- # Create and return a new VirtualMachineManager (VMM) instance. Most
11
+ # Create and return a new VirtualMachineService (VMM) instance. Most
12
12
  # methods for a VMM instance will return one or more VirtualMachine
13
13
  # instances.
14
14
  #
@@ -16,39 +16,34 @@ module Azure
16
16
  # default is 'Microsoft.ClassicCompute'. You may need to set this to
17
17
  # 'Microsoft.Compute' for your purposes.
18
18
  #
19
- def initialize(options = {})
19
+ def initialize(_armrest_configuration, options = {})
20
20
  super
21
-
22
21
  @provider = options[:provider] || 'Microsoft.Compute'
23
-
24
- # Typically only empty in testing.
25
- unless @@providers.empty?
26
- @api_version = @@providers[@provider]['virtualMachines']['api_version']
27
- end
22
+ set_service_api_version(options, 'virtualMachines')
28
23
  end
29
24
 
30
25
  # Set a new provider to use the default for other methods. This may alter
31
26
  # the api_version used for future requests. In practice, only
32
27
  # 'Microsoft.Compute' or 'Microsoft.ClassicCompute' should be used.
33
28
  #
34
- def provider=(name)
35
- @api_version = @@providers[name]['virtualMachines']['api_version']
29
+ def provider=(name, options = {})
36
30
  @provider = name
31
+ set_service_api_version(options, 'virtualMachines')
37
32
  end
38
33
 
39
34
  # Return a list of available VM series (aka sizes, flavors, etc), such
40
35
  # as "Basic_A1", though information is included as well.
41
36
  #
42
37
  def series(location)
43
- unless @@providers[@provider] && @@providers[@provider]['locations/vmSizes']
38
+ unless @@providers_hash[@provider.downcase] && @@providers_hash[@provider.downcase]['locations/vmSizes']
44
39
  raise ArgumentError, "Invalid provider '#{provider}'"
45
40
  end
46
41
 
47
- version = @@providers[@provider]['locations/vmSizes']['api_version']
42
+ version = @@providers_hash[@provider.downcase]['locations/vmSizes']['api_version']
48
43
 
49
44
  url = url_with_api_version(
50
- version, @base_url, 'subscriptions', subscription_id, 'providers',
51
- provider, 'locations', location, 'vmSizes'
45
+ version, @base_url, 'subscriptions', armrest_configuration.subscription_id,
46
+ 'providers', provider, 'locations', location, 'vmSizes'
52
47
  )
53
48
 
54
49
  JSON.parse(rest_get(url))['value']
@@ -72,8 +67,9 @@ module Azure
72
67
  # p JSON.parse(resp.body)["value"][0]["properties"]["hardwareProfile"]
73
68
  # p JSON.parse(resp.body)["value"][0]["properties"]["storageProfile"]
74
69
  #
75
- def list(group = nil)
70
+ def list(group = armrest_configuration.resource_group)
76
71
  array = []
72
+
77
73
  if group
78
74
  url = build_url(group)
79
75
  array << JSON.parse(rest_get(url))['value']
@@ -81,63 +77,67 @@ module Azure
81
77
  threads = []
82
78
  mutex = Mutex.new
83
79
 
84
- resource_groups.each do |group|
85
- url = build_url(group['name'])
86
-
87
- threads << Thread.new(url) do |thread_url|
88
- response = rest_get(thread_url)
80
+ resource_groups.each do |rg|
81
+ threads << Thread.new(rg['name']) do |rgroup|
82
+ response = rest_get(build_url(rgroup))
89
83
  result = JSON.parse(response)['value']
90
- mutex.synchronize{ array << result if result }
84
+ if result
85
+ mutex.synchronize{
86
+ result.each{ |hash| hash['resourceGroup'] = rgroup }
87
+ array << result
88
+ }
89
+ end
91
90
  end
92
91
  end
93
92
 
94
93
  threads.each(&:join)
95
94
 
96
95
  array = array.flatten
96
+
97
+ if provider.downcase == 'microsoft.compute'
98
+ add_network_profile(array)
99
+ add_power_status(array)
100
+ end
97
101
  end
98
102
 
99
- add_network_profile(array)
103
+ array
100
104
  end
101
105
 
102
106
  alias get_vms list
103
107
 
104
- def add_network_profile(vms)
105
- vms.each { |vm|
106
- vm['properties']['networkProfile']['networkInterfaces'].each { |net|
107
- get_nic_profile(net)
108
- }
109
- }
110
- end
111
-
112
- def get_nic_profile(nic)
113
- url = File.join(
114
- Azure::Armrest::RESOURCE,
115
- nic['id'],
116
- "?api-version=#{api_version}"
117
- )
108
+ # Captures the +vmname+ and associated disks into a reusable CSM template.
109
+ # The 3rd argument is a hash of options that supports the following keys:
110
+ #
111
+ # * prefix - The prefix in the name of the blobs.
112
+ # * container - The name of the container inside which the image will reside.
113
+ # * overwrite - Boolean that indicates whether or not to overwrite any VHD's
114
+ # with the same prefix. The default is false.
115
+ #
116
+ # The :prefix and :container options are mandatory. You may optionally
117
+ # specify the :resource_group as an option, or as the 3rd argument, but
118
+ # it is also mandatory if not already set in the constructor.
119
+ #
120
+ # Note that this is a long running operation. You are expected to
121
+ # poll on the client side to check the status of the operation.
122
+ #
123
+ def capture(vmname, options = {}, group = nil)
124
+ prefix = options.fetch(:prefix)
125
+ container = options.fetch(:container)
126
+ overwrite = options[:overwrite] || false
127
+ group ||= options[:resource_group] || armrest_configuration.resource_group
118
128
 
119
- nic['properties'] = JSON.parse(rest_get(url))['properties']['ipConfigurations']
120
- nic['properties'].each do |n|
121
- next if n['properties']['publicIPAddress'].nil?
129
+ raise ArgumentError, "no resource group provided" unless group
122
130
 
123
- # public IP is a URI so we need to make another rest call to get it.
124
- url = File.join(
125
- Azure::Armrest::RESOURCE,
126
- n['properties']['publicIPAddress']['id'],
127
- "?api-version=#{api_version}"
128
- )
131
+ body = {
132
+ :vhdPrefix => prefix,
133
+ :destinationContainer => container,
134
+ :overwriteVhds => overwrite
135
+ }.to_json
129
136
 
130
- public_ip = JSON.parse(rest_get(url))['properties']['ipAddress']
131
- n['properties']['publicIPAddress'] = public_ip
132
- end
133
- end
137
+ url = build_url(group, 'capture')
134
138
 
135
- # Captures the +vmname+ and associated disks into a reusable CSM template.
136
- #--
137
- # POST
138
- def capture(vmname, action = 'capture')
139
- uri = @uri + "/#{vmname}/#{action}?api-version=#{api_version}"
140
- uri
139
+ response = rest_post(url, body)
140
+ response.return!
141
141
  end
142
142
 
143
143
  # Creates a new virtual machine (or updates an existing one). Pass a hash
@@ -202,7 +202,7 @@ module Azure
202
202
  #
203
203
  # Example:
204
204
  #
205
- # vmm = VirtualMachineManager.new(x, y, z)
205
+ # vmm = VirtualMachineService.new(x, y, z)
206
206
  #
207
207
  # vm = vmm.create(
208
208
  # :name => 'test1',
@@ -224,23 +224,16 @@ module Azure
224
224
  # )
225
225
  #--
226
226
  # PUT operation
227
- #
228
- def create(options = {})
229
- #name = options.fetch(:name)
230
- #location = options.fetch(:location)
231
- #tags = option[:tags]
232
- vmsize = options.fetch(:vmsize)
233
-
234
- unless VALID_VM_SIZES.include?(vmsize)
235
- raise ArgumentError, "Invalid vmsize '#{vmsize}'"
236
- end
237
- end
227
+ # TODO: Implement
228
+ #def create(options = {})
229
+ #end
238
230
 
239
- alias update create
231
+ #alias update create
240
232
 
241
233
  # Stop the VM +vmname+ in +group+ and deallocate the tenant in Fabric.
242
234
  #
243
- def deallocate(vmname, group = vmname)
235
+ def deallocate(vmname, group = armrest_configuration.resource_group)
236
+ raise ArgumentError, "no resource group provided" unless group
244
237
  url = build_url(group, vmname, 'deallocate')
245
238
  response = rest_post(url)
246
239
  response.return!
@@ -249,7 +242,8 @@ module Azure
249
242
  # Deletes the +vmname+ in +group+ that you specify. Note that associated
250
243
  # disks are not deleted.
251
244
  #
252
- def delete(vmname, group = vmname)
245
+ def delete(vmname, group = armrest_configuration.resource_group)
246
+ raise ArgumentError, "no resource group provided" unless group
253
247
  url = build_url(group, vmname)
254
248
  response = rest_delete(url)
255
249
  response.return!
@@ -257,7 +251,8 @@ module Azure
257
251
 
258
252
  # Sets the OSState for the +vmname+ in +group+ to 'Generalized'.
259
253
  #
260
- def generalize(vmname, group = vmname)
254
+ def generalize(vmname, group = armrest_configuration.resource_group)
255
+ raise ArgumentError, "no resource group provided" unless group
261
256
  url = build_url(group, vmname, 'generalize')
262
257
  response = rest_post(url)
263
258
  response.return!
@@ -270,7 +265,9 @@ module Azure
270
265
  # parameter is false, it will retrieve an instance view. The difference is
271
266
  # in the details of the information retrieved.
272
267
  #
273
- def get(vmname, group = vmname, model_view = true)
268
+ def get(vmname, group = armrest_configuration.resource_group, model_view = true)
269
+ raise ArgumentError, "no resource group provided" unless group
270
+
274
271
  if model_view
275
272
  url = build_url(group, vmname)
276
273
  else
@@ -283,14 +280,16 @@ module Azure
283
280
  # Convenient wrapper around the get method that retrieves the model view
284
281
  # for +vmname+ in resource_group +group+.
285
282
  #
286
- def get_model_view(vmname, group = vmname)
283
+ def get_model_view(vmname, group = armrest_configuration.resource_group)
284
+ raise ArgumentError, "no resource group provided" unless group
287
285
  get(vmname, group, true)
288
286
  end
289
287
 
290
288
  # Convenient wrapper around the get method that retrieves the instance view
291
289
  # for +vmname+ in resource_group +group+.
292
290
  #
293
- def get_instance_view(vmname, group = vmname)
291
+ def get_instance_view(vmname, group = armrest_configuration.resource_group)
292
+ raise ArgumentError, "no resource group provided" unless group
294
293
  get(vmname, group, false)
295
294
  end
296
295
 
@@ -300,7 +299,8 @@ module Azure
300
299
  # This is an asynchronous operation that returns a response object
301
300
  # which you can inspect, such as response.code or response.headers.
302
301
  #
303
- def restart(vmname, group = vmname)
302
+ def restart(vmname, group = armrest_configuration.resource_group)
303
+ raise ArgumentError, "no resource group provided" unless group
304
304
  url = build_url(group, vmname, 'restart')
305
305
  response = rest_post(url)
306
306
  response.return!
@@ -312,7 +312,8 @@ module Azure
312
312
  # This is an asynchronous operation that returns a response object
313
313
  # which you can inspect, such as response.code or response.headers.
314
314
  #
315
- def start(vmname, group = vmname)
315
+ def start(vmname, group = armrest_configuration.resource_group)
316
+ raise ArgumentError, "no resource group provided" unless group
316
317
  url = build_url(group, vmname, 'start')
317
318
  response = rest_post(url)
318
319
  response.return!
@@ -324,7 +325,8 @@ module Azure
324
325
  # This is an asynchronous operation that returns a response object
325
326
  # which you can inspect, such as response.code or response.headers.
326
327
  #
327
- def stop(vmname, group = vmname)
328
+ def stop(vmname, group = armrest_configuration.resource_group)
329
+ raise ArgumentError, "no resource group provided" unless group
328
330
  url = build_url(group, vmname, 'powerOff')
329
331
  response = rest_post(url)
330
332
  response.return!
@@ -332,6 +334,45 @@ module Azure
332
334
 
333
335
  private
334
336
 
337
+ def add_network_profile(vms)
338
+ vms.each { |vm|
339
+ vm['properties']['networkProfile']['networkInterfaces'].each { |net|
340
+ get_nic_profile(net)
341
+ }
342
+ }
343
+ end
344
+
345
+ def get_nic_profile(nic)
346
+ url = File.join(
347
+ Azure::Armrest::RESOURCE,
348
+ nic['id'],
349
+ "?api-version=#{@api_version}"
350
+ )
351
+
352
+ nic['properties'] = JSON.parse(rest_get(url))['properties']['ipConfigurations']
353
+ nic['properties'].each do |n|
354
+ next if n['properties']['publicIPAddress'].nil?
355
+
356
+ # public IP is a URI so we need to make another rest call to get it.
357
+ url = File.join(
358
+ Azure::Armrest::RESOURCE,
359
+ n['properties']['publicIPAddress']['id'],
360
+ "?api-version=#{@api_version}"
361
+ )
362
+
363
+ public_ip = JSON.parse(rest_get(url))['properties']['ipAddress']
364
+ n['properties']['publicIPAddress'] = public_ip
365
+ end
366
+ end
367
+
368
+ def add_power_status(vms)
369
+ vms.each do |vm|
370
+ i_view = get_instance_view(vm["name"], vm["resourceGroup"])
371
+ powerstatus_hash = i_view["statuses"].find {|h| h["code"].include? "PowerState"}
372
+ vm["powerStatus"] = powerstatus_hash['displayStatus'] unless powerstatus_hash.nil?
373
+ end
374
+ end
375
+
335
376
  # If no default subscription is set, then use the first one found.
336
377
  def set_default_subscription
337
378
  @subscription_id ||= subscriptions.first['subscriptionId']
@@ -343,7 +384,7 @@ module Azure
343
384
  def build_url(resource_group, *args)
344
385
  url = File.join(
345
386
  Azure::Armrest::COMMON_URI,
346
- subscription_id,
387
+ armrest_configuration.subscription_id,
347
388
  'resourceGroups',
348
389
  resource_group,
349
390
  'providers',
@@ -352,7 +393,7 @@ module Azure
352
393
  )
353
394
 
354
395
  url = File.join(url, *args) unless args.empty?
355
- url << "?api-version=#{api_version}"
396
+ url << "?api-version=#{@api_version}"
356
397
  end
357
398
  end
358
399
  end