Chapter 20. The Options Hash

A user starts the virtual machine provisioning workflow by clicking on the Lifecycle → Provision VMs button in the Virtual Machines toolbar of the WebUI. After selecting a template to provision from, the requesting user completes the provisioning dialog and enters all of the details that are required to create the virtual machine—the number of CPUs, memory, network to connect to, and hard disk format, for example. Somehow this information collected from the WebUI must be added to the Automate provisioning workflow.

Provisioning a virtual machine or instance is a complex operation that, as we have just seen, involves an approval stage. We saw in Chapter 12 that an automation operation involving an approval stage is split into two parts, the request and the task. In the case of a virtual machine provisioning operation, the request is represented by an miq_provision_request object, and the task is represented by an miq_provision object.

The inputs and options selected from the provisioning dialog are added to the miq_provision_request object as key/value pairs in a data structure known as the options hash. When we write our custom Ruby methods to interact with the provisioning workflow, we frequently read from and write to the options hash.

If the provisioning request is approved, the options hash from the request object is propagated to the task object, but there are slight differences between the two hashes. We’ll examine these next.

Request Object (miq_provision_request)

The contents of the request object’s options hash varies slightly between provisioning targets (VMware, OpenStack, RHEV, etc.) and target VM operating system (Linux, Windows, etc.), but a typical hash for a Linux virtual machine provision to an RHEV provider is:

request.options[:addr_mode] = ["static", "Static"]   (type: Array)
request.options[:cluster_filter] = [nil, nil]   (type: Array)
request.options[:cores_per_socket] = [1, "1"]   (type: Array)
request.options[:current_tab_key] = customize   (type: Symbol)
request.options[:customization_template_script] = nil
request.options[:customize_enabled] = ["disabled"]   (type: Array)
request.options[:delivered_on] = 2015-06-05 07:33:20 UTC   (type: Time)
request.options[:disk_format] = ["default", "Default"]   (type: Array)
request.options[:initial_pass] = true   (type: TrueClass)
request.options[:ip_addr] = nil
request.options[:linked_clone] = [nil, nil]   (type: Array)
request.options[:mac_address] = nil
request.options[:miqrequestdialog_name] = miq_provision_redhat_dialogs_template
request.options[:network_adapters] = [1, "1"]   (type: Array)
request.options[:number_of_sockets] = [1, "1"]   (type: Array)
request.options[:number_of_vms] = [1, "1"]   (type: Array)
request.options[:owner_email] = pemcg@bit63.com   (type: String)
request.options[:owner_first_name] = Peter   (type: String)
request.options[:owner_last_name] = McGowan   (type: String)
request.options[:pass] = 1   (type: Fixnum)
request.options[:placement_auto] = [false, 0]   (type: Array)
request.options[:placement_cluster_name] = [1000000000001, "Production"]
request.options[:placement_dc_name] = [1000000000002, "Default"]   (type: Array)
request.options[:placement_ds_name] = [1000000000001, "Data"]   (type: Array)
request.options[:placement_host_name] = [1000000000001, "rhevh12.bit63.net"]
request.options[:provision_type] = ["native_clone", "Native Clone"]
request.options[:retirement] = [0, "Indefinite"]   (type: Array)
request.options[:retirement_warn] = [604800, "1 Week"]   (type: Array)
request.options[:root_password] = nil
request.options[:schedule_time] = 2015-06-06 00:00:00 UTC   (type: Time)
request.options[:schedule_type] = ["immediately", "Immediately on Approval"]
request.options[:src_ems_id] = [1000000000001, "RHEV"]   (type: Array)
request.options[:src_vm_id] = [1000000000004, "rhel7-generic"]   (type: Array)
request.options[:start_date] = 6/6/2015   (type: String)
request.options[:start_hour] = 00   (type: String)
request.options[:start_min] = 00   (type: String)
request.options[:stateless] = [false, 0]   (type: Array)
request.options[:subnet_mask] = nil
request.options[:vlan] = ["public", "public"]   (type: Array)
request.options[:vm_auto_start] = [false, 0]   (type: Array)
request.options[:vm_description] = nil
request.options[:vm_memory] = ["2048", "2048"]   (type: Array)
request.options[:vm_name] = rhel7srv002   (type: String)
request.options[:vm_prefix] = nil
request.options[:vm_tags] = []   (type: Array)

When we work with our own methods that interact with the VM provisioning process, we can read any of the options hash keys using the miq_provision_request.get_option method, like so:

memory_in_request = miq_provision_request.get_option(:vm_memory).to_i

We can also set most options using the miq_provision_request.set_option method, as follows:

miq_provision_request.set_option(:subnet_mask,'255.255.254.0')

Several options hash keys have their own set method, listed in Table 20-1, which we should use in place of request.set_option.

Table 20-1. Options hash keys set methods
Options hash key set method

:vm_notes

request.set_vm_notes

:vlan

request.set_vlan

:dvs

request.set_dvs

:addr_mode

request.set_network_address_mode

:placement_host_name

request.set_host

:placement_ds_name

request.set_storage

:placement_cluster_name

request.set_cluster

:placement_rp_name

request.set_resource_pool

:placement_folder_name

request.set_folder

:pxe_server_id

request.set_pxe_server

:pxe_image_id (Linux server provision)

request.set_pxe_image

:pxe_image_id (Windows server provision)

request.set_windows_image

:customization_template_id

request.set_customization_template

:iso_image_id

request.set_iso_image

:placement_availability_zone

request.set_availability_zone

:cloud_tenant

request.set_cloud_tenant

:cloud_network

request.set_cloud_network

:cloud_subnet

request.set_cloud_subnet

:security_groups

request.set_security_group

:floating_ip_address

request.set_floating_ip_address

:instance_type

request.set_instance_type

:guest_access_key_pair

request.set_guest_access_key_pair

All but the first four of the set methods just listed perform a validity check to verify that the value we’re setting is an eligible resource for the provisioning instance. They also take an object as an argument, rather than a text string—for example:

cloud_network = $evm.vmdb('CloudNetwork', '1000000000012')
prov.set_cloud_network(cloud_network)
Tip

Use one of the techniques discussed in Chapter 10 to find out what key/value pairs are in the options hash to manipulate.

Task Object (miq_provision)

The options hash from the request object is propagated to each task object, where it is subsequently extended by task-specific methods such as those handling VM naming and placement:

miq_provision.options[:dest_cluster] = [1000000000001, "Default"]
miq_provision.options[:dest_host] = [1000000000001, "rhelh03.bit63.net"]
miq_provision.options[:dest_storage] = [1000000000001, "Data"]
miq_provision.options[:vm_target_hostname] = rhel7srv002
miq_provision.options[:vm_target_name] = rhel7srv002

Some options hash keys, such as :number_of_vms, have no effect if changed in the task object; they are relevant only for the request.

Adding Network Adapters

There are two additional methods that we can call on an miq_provision object, to add further network adapters. These are .set_nic_settings and .set_network_adapter:

idx = 1
miq_provision.set_network_adapter(idx,
                         {
                          :network => 'VM Network',
                          :devicetype => 'VirtualVmxnet3',
                          :is_dvs => false
                         })

miq_provision.set_nic_settings(idx,
                          {
                           :ip_addr => '10.2.1.23',
                           :subnet_mask => '255.255.255.0',
                           :addr_mode => ['static', 'Static']
                          })

Correlation with the Provisioning Dialog

The key/value pairs that make up the options hash initially come from the provisioning dialog. If we look at an extract from one of the provisioning dialog YAML files, we see the dialog definitions for the number_of_sockets and cores_per_socket options:

      :number_of_sockets:
        :values:
          1: '1'
          2: '2'
          4: '4'
          8: '8'
        :description: Number of Sockets
        :required: false
        :display: :edit
        :default: 1
        :data_type: :integer
      :cores_per_socket:
        :values:
          1: '1'
          2: '2'
          4: '4'
          8: '8'
        :description: Cores per Socket
        :required: false
        :display: :edit
        :default: 1
        :data_type: :integer

These correspond to:

miq_provision_request.options[:cores_per_socket]
miq_provision_request.options[:number_of_sockets]

Adding Our Own Options: The ws_values Hash

Sometimes we wish to add our own custom key/value pairs to the request or task object, so that they can be used in a subsequent stage in the VM provision state machine for custom processing. An example might be the size and mount point for a secondary disk to be added as part of the provisioning workflow. Although we could add our own key/value pairs directly to the option hash, we risk overwriting a key defined in the core provisioning code (or one added in a later release of CloudForms).

There is an existing options hash key that is intended to be used for this, called ws_values. The value of this key is itself a hash, containing our key/value pairs that we wish to save:

miq_provision.options[:ws_values] = {:disk_dize_gb=>100, :mountpoint=>"/opt"}

The ws_values hash is also used to store custom values that we might supply if we provision a VM programmatically from either the RESTful API or from create_provision_request. One of the arguments for a programmatic call to create a VM is a set of key/value pairs called additional_values (it was originally called additionalValues in the SOAP call). Any key/value pairs supplied with this argument for the automation call will automatically be added to the ws_options hash.

By using the ws_options hash to store our own custom key/value pairs, we make our code compatible with the VM provision request being called programmatically.

Summary

The options hashes in the miq_provision_request and miq_provision objects are some of the most important data structures that we work with. They contain all of the information required to create the new virtual machine or instance, and by setting their key values programmatically we can influence the outcome of the provisioning operation.

As discussed in Chapter 12, the challenge is sometimes knowing whether we should access the options hash in the miq_provision_request or miq_provision objects, particularly when setting values. We need to apply our knowledge of requests and tasks to determine which context we’re working in.

We also need to be aware of which options hash keys have their own set method, as these keys typically require an array formatted in a particular way.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.47.208