Class: Azure::VirtualMachineManagement::VirtualMachineManagementService

Inherits:
BaseManagementService
  • Object
show all
Defined in:
lib/azure/virtual_machine_management/virtual_machine_management_service.rb

Instance Method Summary collapse

Constructor Details

#initializeVirtualMachineManagementService

Returns a new instance of VirtualMachineManagementService.



21
22
23
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 21

def initialize
  super()
end

Instance Method Details

#add_data_disk(vm_name, cloud_service_name, options = {}) ⇒ Object

Public: adds a data disk to a virtual machine.

Attributes

  • cloud_service_name - String. Cloud service name.

  • vm_name - String. Virtual machine name.

  • options - Hash. Optional parameters.

Options

Accepted key/value pairs in options parameter are:

  • :import - Boolean. if true, then allows to use an existing

disk by disk name. if false, then create and attach new data disk.
  • :disk_name - String. Specifies the name of the disk. Reqruied if using existing disk.

  • :host_caching - String. Specifies the caching behavior of data disk The default is ReadOnly. Possible values are: None, ReadOnly, ReadWrite

  • :disk_label - String. Specifies the description of the data disk.

  • :disk_size - String. Specifies the size of disk in GB

See msdn.microsoft.com/en-us/library/windowsazure/jj157199.aspx

Returns None



480
481
482
483
484
485
486
487
488
489
490
491
492
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 480

def add_data_disk(vm_name, cloud_service_name, options = {})
  options[:import] ||= false
  vm = get_virtual_machine(vm_name, cloud_service_name)
  if vm
    path = "/services/hostedservices/#{cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm_name}/DataDisks"
    body = Serialization.add_data_disk_to_xml(vm, options)
    Loggerx.info "Adding data disk to virtual machine #{vm_name} ..."
    request = ManagementHttpRequest.new(:post, path, body)
    request.call
  else
    Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
  end
end

#add_role(params, options = {}) ⇒ Object

Public: Add a new role to a cloud service. Atleast one deployment should exist before you can add a role.

Attributes

  • params - Hash. parameters.

  • options - Hash. Optional parameters.

==== Params

Accepted key/value pairs are:

  • :vm_name - String. Name of virtual machine.

  • :vm_user - String. User name for the virtual machine instance.

  • :password - String. A description for the hosted service.

  • :image - String. Name of the disk image to use to create the virtual machine.

  • :cloud_service_name - String. Name of cloud service.

==== Options

Accepted key/value pairs are:

  • :storage_account_name - String. Name of storage account.

  • :tcp_endpoints - String. Specifies the internal port and external/public port separated by a colon. You can map multiple internal and external ports by separating them with a comma.

  • :ssh_private_key_file - String. Path of private key file.

  • :ssh_certificate_file - String. Path of certificate file.

  • :ssh_port - Integer. Specifies the SSH port number.

  • +:winrm_http_port - Integer. Specifies the WinRM HTTP port number.

  • +:winrm_https_port - Integer. Specifies the WinRM HTTPS port number.

  • :vm_size - String. Specifies the size of the virtual machine instance.

  • :winrm_transport - Array. Specifies WINRM transport protocol.

Returns Azure::VirtualMachineManagement::VirtualMachine objects of newly created instance.

See: msdn.microsoft.com/en-us/library/windowsazure/jj157186.aspx



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 192

def add_role(params, options = {})
  image = get_image(params[:image])
  options[:os_type] = image.os_type
  validate_deployment_params(params, options, true)
  cloud_service = Azure::CloudServiceManagementService.new
  cloud_service = cloud_service.get_cloud_service_properties(params[:cloud_service_name])
  deployment_name = cloud_service.deployment_name
  Loggerx.error_with_exit "Deployment doesn't exists." if cloud_service && deployment_name.empty?
  others = {}
  if cloud_service.location
    others[:location] = cloud_service.location
  elsif cloud_service.affinity_group
    others[:affinity_group_name] = cloud_service.affinity_group
  end
  unless image.category == 'User'
    options[:storage_account_name] ||= (params[:vm_name])
    Azure::StorageManagementService.new.(options[:storage_account_name], others)
  end
  Loggerx.info 'Deployment exists, adding role...'
  existing_ports = []
  cloud_service.virtual_machines[deployment_name.to_sym].each do |vm|
    vm.tcp_endpoints.each do |endpoint|
      existing_ports << endpoint[:public_port]
    end
  end
  options[:existing_ports] = existing_ports
  body = Serialization.role_to_xml(params, image, options).to_xml
  path = "/services/hostedservices/#{cloud_service.name}/deployments/#{deployment_name}/roles"
  Loggerx.info 'Deployment in progress...'
  request = ManagementHttpRequest.new(:post, path, body)
  request.call

  vm = get_virtual_machine(params[:vm_name], cloud_service.name)

  # if this is a User image, a second call is required to set the endpoints, this is because
  # according to https://msdn.microsoft.com/en-us/library/azure/jj157186.aspx all 
  # ConfigurationSets parameters (including the NetworkConfiguration type) are ignored
  # when the VMImageName is set 
  if image.category == 'User'
    Serialization.endpoints_from_xml(Nokogiri::XML(body), vm)
    update_endpoints(vm.vm_name, cloud_service.name, vm.tcp_endpoints + vm.udp_endpoints)
  end

  vm
  rescue Exception => e
  e.message
end

#create_virtual_machine(params, options = {}) ⇒ Object

Public: Provisions a virtual machine based on the supplied configuration.

Attributes

  • params - Hash. parameters.

  • options - Hash. Optional parameters.

  • add_role - true/false. Optional Parameter. Default is false

==== Params

Accepted key/value pairs are:

  • :vm_name - String. Name of virtual machine.

  • :vm_user - String. User name for the virtual machine instance.

  • :password - String. A description for the hosted service.

  • :image - String. Name of the disk image to use to create the virtual machine.

  • :location - String. The location where the virtual machine will be created.

  • +:affinity_group_name - String. The affinity group name to be used

for the cloud service and the storage account if these do not exist.

==== Options

Accepted key/value pairs are:

  • :storage_account_name - String. Name of storage account.

  • :cloud_service_name - String. Name of cloud service.

  • :deployment_name - String. A name for the deployment.

  • :tcp_endpoints - String. Specifies the internal port and external/public port separated by a colon. You can map multiple internal and external ports by separating them with a comma.

  • :ssh_private_key_file - String. Path of private key file.

  • :ssh_certificate_file - String. Path of certificate file.

  • :ssh_port - Integer. Specifies the SSH port number.

  • +:winrm_http_port - Integer. Specifies the WinRM HTTP port number.

  • +:winrm_https_port - Integer. Specifies the WinRM HTTPS port number.

  • :vm_size - String. Specifies the size of the virtual machine instance.

  • :winrm_transport - Array. Specifies WINRM transport protocol.

  • :availability_set_name - String. Specifies the availability set name.

==== add_role

Accepted values are:

  • false - Will add a new deployment in a cloud service.

  • true - Will add a new role to a cloud service. Atleast one

deployment should exist before you can add a role.

Returns Azure::VirtualMachineManagement::VirtualMachine objects of newly created instance.

See: msdn.microsoft.com/en-us/library/windowsazure/jj157194.aspx msdn.microsoft.com/en-us/library/windowsazure/jj157186.aspx



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 106

def create_virtual_machine(params, options = {})
  image = get_image(params[:image])
  options[:os_type] = image.os_type
  validate_deployment_params(params, options)
  options[:deployment_name] ||= options[:cloud_service_name]
  Loggerx.info 'Creating deployment...'
  options[:cloud_service_name] ||= generate_cloud_service_name(params[:vm_name])        
  optionals = {}
  if options[:virtual_network_name]
    virtual_network_service = Azure::VirtualNetworkManagementService.new
    virtual_networks = virtual_network_service.list_virtual_networks.select { |x| x.name == options[:virtual_network_name] }
    if virtual_networks.empty?
      Loggerx.error_with_exit "Virtual network #{options[:virtual_network_name]} doesn't exists"
    else
      vnet = virtual_networks.first
      if !vnet.affinity_group.empty?
        options[:affinity_group_name] = vnet.affinity_group
      else
        optionals[:location] = vnet.location
      end
    end
  elsif options[:affinity_group_name]
    optionals[:affinity_group_name] = options[:affinity_group_name]
  else
    optionals[:location] = params[:location]
  end
  cloud_service = Azure::CloudServiceManagementService.new
  cloud_service.create_cloud_service(options[:cloud_service_name], optionals)
  cloud_service.upload_certificate(options[:cloud_service_name], params[:certificate]) unless params[:certificate].empty?
  unless image.category == 'User'
    options[:storage_account_name] ||= (params[:vm_name])
    Azure::StorageManagementService.new.(options[:storage_account_name], optionals)
  end
  body = Serialization.deployment_to_xml(params, image, options)
  path = "/services/hostedservices/#{options[:cloud_service_name]}/deployments"
  Loggerx.info 'Deployment in progress...'
  request = ManagementHttpRequest.new(:post, path, body)
  request.call
  vm = get_virtual_machine(params[:vm_name], options[:cloud_service_name])
  # if this is a User image, a second call is required to set the endpoints, this is because
  # according to https://msdn.microsoft.com/en-us/library/azure/jj157186.aspx all 
  # ConfigurationSets parameters (including the NetworkConfiguration type) are ignored
  # when the VMImageName is set 
  if image.category == 'User'
    Serialization.endpoints_from_xml(Nokogiri::XML(body), vm)
    update_endpoints(vm.vm_name, options[:cloud_service_name], vm.tcp_endpoints + vm.udp_endpoints)
  end
  vm
  rescue Exception => e
  e.message
end

#delete_endpoint(vm_name, cloud_service_name, endpoint_name) ⇒ Object

Public: Delete endpoint of virtual machine.

Attributes

  • name - String. Virtual machine name.

  • cloud_service_name - String. Cloud service name.

  • endpoint_name - String. Name of endpoint.

See msdn.microsoft.com/en-us/library/windowsazure/jj157187.aspx

Returns NONE



442
443
444
445
446
447
448
449
450
451
452
453
454
455
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 442

def delete_endpoint(vm_name, cloud_service_name, endpoint_name)
  vm = get_virtual_machine(vm_name, cloud_service_name)
  if vm
    path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm_name}"
    endpoints = vm.tcp_endpoints + vm.udp_endpoints
    endpoints.delete_if { |ep| endpoint_name.downcase == ep[:name].downcase }
    body = Serialization.update_role_to_xml(endpoints, vm)
    request = ManagementHttpRequest.new(:put, path, body)
    Loggerx.info "Deleting virtual machine endpoint #{endpoint_name} ..."
    request.call
  else
    Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
  end
end

#delete_virtual_machine(vm_name, cloud_service_name) ⇒ Object

Public: Deletes the deployment, cloud service and disk.

Attributes

  • vm_name - String. Virtual machine name.

  • cloud_service_name - String. Cloud service name.

See msdn.microsoft.com/en-us/library/windowsazure/gg441305.aspx See msdn.microsoft.com/en-us/library/windowsazure/jj157179.aspx

Returns NONE



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 251

def delete_virtual_machine(vm_name, cloud_service_name)
  virtual_machines = list_virtual_machines(cloud_service_name)
  vm = virtual_machines.select { |x| x.vm_name == vm_name }.first
  if vm
    if virtual_machines.size == 1
      cloud_service = Azure::CloudServiceManagementService.new
      cloud_service.delete_cloud_service_deployment(cloud_service_name)
      cloud_service.delete_cloud_service(cloud_service_name)
    else
      path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm.vm_name}"
      Loggerx.info "Deleting virtual machine #{vm_name}. \n"
      request = ManagementHttpRequest.new(:delete, path)
      request.call
    end
    Loggerx.info "Waiting for disk to be released.\n"
    disk_name = vm.disk_name
    disk_management_service = VirtualMachineDiskManagementService.new
    # Wait for 180s for disk to be released.
    disk = nil
    18.times do
      print '# '
      disk = disk_management_service.get_virtual_machine_disk(disk_name)
      unless disk.attached
        print "Disk released.\n"
        break
      end
      sleep 10
    end
    if disk.attached
      Loggerx.error "\nCannot delete disk #{disk_name}."
    else
      disk_management_service.delete_virtual_machine_disk(disk_name)
    end
  else
    Loggerx.error "Cannot find virtual machine #{vm_name} under cloud service #{cloud_service_name}"
  end
rescue
end

#get_virtual_machine(name, cloud_service_name) ⇒ Object

Public: Gets a virtual machine based on the provided name and cloud service name.

Attributes

  • name - String. Virtual machine name.

  • cloud_service_name - String. Cloud service name.

Returns an Azure::VirtualMachineManagement::VirtualMachine instance.



53
54
55
56
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 53

def get_virtual_machine(name, cloud_service_name)
  server = list_virtual_machines(cloud_service_name).select { |x| x.vm_name.casecmp(name) == 0 }
  server.first
end

#list_virtual_machines(*cloud_service_names) ⇒ Object

Public: Get a lists of virtual machines available under the current subscription.

Returns an list of Azure::VirtualMachineManagement::VirtualMachine instances.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 28

def list_virtual_machines(*cloud_service_names)
  roles = []
  cloud_service_names.flatten!
  if cloud_service_names.empty?
    cloud_service = Azure::CloudServiceManagementService.new
    cloud_service_names = cloud_service.list_cloud_services.map(&:name)
  end
  cloud_service_names.each do |cloud_service_name|
    request_path = "/services/hostedservices/#{cloud_service_name}/deploymentslots/production"
    request = ManagementHttpRequest.new(:get, request_path)
    request.warn = true
    response = request.call
    roles << Serialization.virtual_machines_from_xml(response, cloud_service_name)
  end
  roles.flatten.compact
end

#restart_virtual_machine(vm_name, cloud_service_name) ⇒ Object

Public: Restarts the specified virtual machine.

Attributes

  • name - String. Virtual machine name.

  • cloud_service_name - String. Cloud service name.

See msdn.microsoft.com/en-us/library/windowsazure/jj157197.aspx

Returns NONE



356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 356

def restart_virtual_machine(vm_name, cloud_service_name)
  vm = get_virtual_machine(vm_name, cloud_service_name)
  if vm
    path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roleinstances/#{vm.vm_name}/Operations"
    body = Serialization.restart_virtual_machine_to_xml
    Loggerx.info "Restarting virtual machine \"#{vm.vm_name}\" ..."
    request = ManagementHttpRequest.new(:post, path, body)
    request.call
  else
    Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
  end
end

#shutdown_virtual_machine(vm_name, cloud_service_name) ⇒ Object

Public: Shuts down the specified virtual machine.

Attributes

  • name - String. Virtual machine name.

  • cloud_service_name - String. Cloud service name.

See msdn.microsoft.com/en-us/library/windowsazure/jj157195.aspx

Returns NONE



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 300

def shutdown_virtual_machine(vm_name, cloud_service_name)
  vm = get_virtual_machine(vm_name, cloud_service_name)
  if vm
    if %w(StoppedVM StoppedDeallocated).include?(vm.status)
      Loggerx.error 'Cannot perform the shutdown operation on a stopped virtual machine.'
    elsif vm.deployment_status == 'Running'
      path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roleinstances/#{vm.vm_name}/Operations"
      body = Serialization.shutdown_virtual_machine_to_xml
      Loggerx.info "Shutting down virtual machine \"#{vm.vm_name}\" ..."
      request = ManagementHttpRequest.new(:post, path, body)
      request.call
    else
      Loggerx.error 'Cannot perform the shutdown operation on a stopped deployment.'
    end
  else
    Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\". "
  end
end

#start_virtual_machine(vm_name, cloud_service_name) ⇒ Object

Public: Starts the specified virtual machine.

Attributes

  • name - String. Virtual machine name.

  • cloud_service_name - String. Cloud service name.

See msdn.microsoft.com/en-us/library/windowsazure/jj157189.aspx

Returns NONE



329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 329

def start_virtual_machine(vm_name, cloud_service_name)
  vm = get_virtual_machine(vm_name, cloud_service_name)
  if vm
    if vm.status == 'ReadyRole'
      Loggerx.error 'Cannot perform the start operation on started virtual machine.'
    else
      path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roleinstances/#{vm.vm_name}/Operations"
      body = Serialization.start_virtual_machine_to_xml
      Loggerx.info "Starting virtual machine \"#{vm.vm_name}\" ..."
      request = ManagementHttpRequest.new(:post, path, body)
      request.call
    end
  else
    Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
  end
end

#update_endpoints(vm_name, cloud_service_name, *input_endpoints) ⇒ Object

Public: Add/Update endpoints of virtual machine.

Attributes

  • name - String. Virtual machine name.

  • cloud_service_name - String. Cloud service name.

  • input_endpoints - Hash. A hash of the name/value pairs for the endpoint.

Endpoint

Accepted key/value pairs are:

  • :local_port - String. Specifies the internal port on which the Virtual Machine is listening.

  • :public_port - String. Specifies the external port to use for the endpoint.

  • :name - String. Specifies the name of the external endpoint.

  • load_balancer_name - String. Specifies a name for a set of load-balanced endpoints.

  • :protocol - String. Specifies the transport protocol for the endpoint. Possible values are: TCP, UDP

  • :direct_server_return - String. Specifies whether the endpoint uses Direct Server Return. Possible values are: true, false (optional)

  • +:load_balancer - Hash. Contains properties that define the endpoint settings that the load balancer uses to monitor the availability of the Virtual Machine (optional)

Load balancer

Accepted key/value pairs are:

  • :port - String. Specifies the internal port on which the Virtual Machine is listening.

  • :protocol - String. Specifies the protocol to use to inspect the availability status of the virtual machine.

  • :interval - String. Specifies the interval for the load balancer probe in seconds. (optional)

  • :timeout - String. Specifies the timeout for the load balancer probe in seconds. (optional)

  • :path - String. Specifies the relative path to inspect to determine the availability status of the Virtual Machine. (optional)

See msdn.microsoft.com/en-us/library/windowsazure/jj157187.aspx

Returns NONE



412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 412

def update_endpoints(vm_name, cloud_service_name, *input_endpoints)
  input_endpoints.flatten!
  vm = get_virtual_machine(vm_name, cloud_service_name)
  if vm
    path = "/services/hostedservices/#{vm.cloud_service_name}/deployments/#{vm.deployment_name}/roles/#{vm_name}"
    endpoints = vm.tcp_endpoints + vm.udp_endpoints
    input_endpoints.each do |iep|
      endpoints.delete_if { |ep| iep[:name].downcase == ep[:name].downcase }
    end
    endpoints += input_endpoints
    body = Serialization.update_role_to_xml(endpoints, vm)
    request = ManagementHttpRequest.new(:put, path, body)
    Loggerx.info "Updating endpoints of virtual machine #{vm.vm_name} ..."
    request.call
  else
    Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
  end
end