Class: Azure::VirtualMachineManagement::VirtualMachineManagementService

Inherits:
BaseManagement::BaseManagementService show all
Includes:
Core::Utility
Defined in:
lib/azure/virtual_machine_management/virtual_machine_management_service.rb

Instance Attribute Summary

Attributes inherited from BaseManagement::BaseManagementService

#client

Instance Method Summary collapse

Methods inherited from BaseManagement::BaseManagementService

#create_affinity_group, #delete_affinity_group, #get_affinity_group, #initialize, #list_affinity_groups, #list_locations, #list_role_sizes, #update_affinity_group, #validate_configuration!

Constructor Details

This class inherits a constructor from Azure::BaseManagement::BaseManagementService

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/azure/jj157199.aspx

Returns None



453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 453

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)
    Azure::Loggerx.info "Adding data disk to virtual machine #{vm_name} ..."
    request = client.management_request(:post, path, body: body)
    request.call
  else
    Azure::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_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/azure/jj157186.aspx



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 173

def add_role(params, options = {})
  image = get_image(params[:image])
  options[:os_type] = image.os_type
  validate_deployment_params(params, options, true)
  cloud_services = client.cloud_service_management
  cloud_service = cloud_services.get_cloud_service_properties(params[:cloud_service_name])
  deployment_name = cloud_service.deployment_name
  Azure::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])
    client.storage_management.(options[:storage_account_name], others)
  end
  Azure::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
  cloud_services.upload_certificate(options[:cloud_service_name], params[:certificate]) unless params[:certificate].empty?
  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"
  Azure::Loggerx.info 'Deployment in progress...'
  request = client.management_request(:post, path, body)
  request.call
  get_virtual_machine(params[:vm_name], cloud_service.name)
end

#create_virtual_machine(params, options = {}) ⇒ Azure::VirtualMachineManagement::VirtualMachine

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

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.

  • :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_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.

  • :reserved_ip_name - String. Specifies the reserved IP name.



95
96
97
98
99
100
101
102
103
104
105
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
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 95

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]
  Azure::Loggerx.info 'Creating deployment...'

  options[:cloud_service_name] ||= generate_cloud_service_name(params[:vm_name])
  options[:storage_account_name] ||= (params[:vm_name])
  optionals = {}
  if options[:virtual_network_name]
    virtual_network_service = client.network_management
    virtual_networks = virtual_network_service.list_virtual_networks.select { |x| x.name == options[:virtual_network_name] }
    if virtual_networks.empty?
      Azure::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 = client.cloud_service_management
  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])
    client.storage_management.(options[:storage_account_name], optionals)
  end
  body = Serialization.deployment_to_xml(params, image, options)
  path = "/services/hostedservices/#{options[:cloud_service_name]}/deployments"
  Azure::Loggerx.info 'Deployment in progress...'
  request = client.management_request(:post, path, body)
  request.call
  get_virtual_machine(params[:vm_name], options[:cloud_service_name])
rescue Exception => e
  Azure::Loggerx.error_with_exit "Failed to create virtual machine : "+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/azure/jj157187.aspx

Returns NONE



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

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 = client.management_request(:put, path, body: body)
    Azure::Loggerx.info "Deleting virtual machine endpoint #{endpoint_name} ..."
    request.call
  else
    Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
  end
end

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

Public: Deletes the deployment, cloud service and disk.

Attributes

  • vm_name - String. Virtual machine name.

  • cloud_service_name - String. Cloud service name.

==== Options

Accepted key/value pairs are:

  • delete_vhd - Boolean. To delete the associated VHD from the blob storage location.

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

Returns NONE



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 224

def delete_virtual_machine(vm_name, cloud_service_name, options={})
  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 = client.cloud_service_management
      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}"
      Azure::Loggerx.info "Deleting virtual machine #{vm_name}. \n"
      request = client.management_request(:delete, path)
      request.call
    end
    Azure::Loggerx.info "Waiting for disk to be released.\n"
    disk_name = vm.disk_name
    disk_management_service = client.vm_disk_management
    # Wait for 180s for disk to be released.
    disk = nil
    18.times do
      Azure::Loggerx.info '# '
      disk = disk_management_service.get_virtual_machine_disk(disk_name)
      unless disk.attached
        Azure::Loggerx.info "Disk released.\n"
        break
      end
      sleep 10
    end
    if disk.attached
      Azure::Loggerx.error "\nCannot delete disk #{disk_name}."
    else
      disk_management_service.delete_virtual_machine_disk(disk_name, options)
    end
  else
    Azure::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.



51
52
53
54
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 51

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.



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

def list_virtual_machines(*cloud_service_names)
  roles = []
  cloud_service_names.flatten!
  if cloud_service_names.empty?
    cloud_service = client.cloud_service_management
    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 = client.management_request(: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/azure/jj157197.aspx

Returns NONE



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

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
    Azure::Loggerx.info "Restarting virtual machine \"#{vm.vm_name}\" ..."
    request = client.management_request(:post, path, body: body)
    request.call
  else
    Azure::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/azure/jj157195.aspx

Returns NONE



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 273

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)
      Azure::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
      Azure::Loggerx.info "Shutting down virtual machine \"#{vm.vm_name}\" ..."
      request = client.management_request(:post, path, body)
      request.call
    else
      Azure::Loggerx.error 'Cannot perform the shutdown operation on a stopped deployment.'
    end
  else
    Azure::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/azure/jj157189.aspx

Returns NONE



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 302

def start_virtual_machine(vm_name, cloud_service_name)
  vm = get_virtual_machine(vm_name, cloud_service_name)
  if vm
    if vm.status == 'ReadyRole'
      Azure::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
      Azure::Loggerx.info "Starting virtual machine \"#{vm.vm_name}\" ..."
      request = client.management_request(:post, path, body: body)
      request.call
    end
  else
    Azure::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/azure/jj157187.aspx

Returns NONE



385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/azure/virtual_machine_management/virtual_machine_management_service.rb', line 385

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 = client.management_request(:put, path, body: body)
    Azure::Loggerx.info "Updating endpoints of virtual machine #{vm.vm_name} ..."
    request.call
  else
    Azure::Loggerx.error "Cannot find virtual machine \"#{vm_name}\" under cloud service \"#{cloud_service_name}\"."
  end
end