Attach storage to OpenStack VM


#1

Hi MIQ,

I’m currently developing a service catalogue item to provision an OpenStack VM.

The service catalogue dialog elements are populated dynamically using ManageIQ objects. Eg, to find the networks for a tenant, I do the following:

  group = $evm.root['miq_group']      

  groupProvScopeTags = group.filters["managed"][0]
  
  dialog_hash = {}

  groupProvScopeTags.each do |groupTag|
    tenants = $evm.vmdb(:cloud_tenant).find_tagged_with(:all => "#{groupTag}", :ns => "*")
    tenants.each do |tenant|
      tenant.cloud_networks.each do |network|
        dialog_hash[network.id] = "#{network.name} on #{tenant.name}"
      end
    end
  end

Per Peter McGowan’s excellent book on automation, the selected VM properties are then passed to the $evm.execute(‘create_provision_request’) method in array of args. The example shown below is for the placement properties (including the tenant network):

args << {'cloud_tenant' => "#{$evm.root['dialog_l_tenants']}",
             'cloud_network' => "#{$evm.root['dialog_l_network']}",
             'security_group' => "#{$evm.root['dialog_l_security_group']}",
             'floating_ip' => "#{$evm.root['dialog_l_floatingip']}"}

Finally, I find the associated MiqAeService* object in my openstack_CustomizeRequest method:

def find_object_for(rsc_class, id_or_name)
  if /\d{13}/.match(id_or_name.to_s)
    obj = $evm.vmdb(rsc_class, id_or_name.to_s)
  else
    obj = $evm.vmdb(rsc_class).find_by_name(id_or_name.to_s)
  end
  $evm.log(:warn, "Couldn\'t find an object of class #{rsc_class} \
              with an ID or name matching \'#{id_or_name}\'") if obj.nil?
  obj
end

prov = $evm.root["miq_provision"]
ws_values = prov.options.fetch(:ws_values, {})

if ws_values.has_key?(:floating_ip)
  unless ws_values[:floating_ip] == "no_float_ip"
    floating_ip = find_object_for('FloatingIp', ws_values[:floating_ip])
      prov.set_floating_ip_address(floating_ip)
  end
end
if ws_values.has_key?(:cloud_network)
  cloud_network = find_object_for('CloudNetwork', ws_values[:cloud_network])
  prov.set_cloud_network(cloud_network)
end
if ws_values.has_key?(:cloud_tenant)
  cloud_tenant = find_object_for('CloudTenant', ws_values[:cloud_tenant])
  prov.set_cloud_tenant(cloud_tenant)
end
if ws_values.has_key?(:security_group)
  security_group = find_object_for('SecurityGroup', ws_values[:security_group])
  prov.set_security_group(security_group)
end

Does anyone know if I can use this same logic to attach a storage volume to an OpenStack VM during provisioning? Ie; find the available storage volumes, add these to the dialog, pass the selected storage volume ID to the $evm.execute(‘create_provision_request’), and find a MiqAeService* object (MiqAeServiceStorage?).

I’ve had a look at the ManageIQ::Providers::Openstack::CloudManager::CloudTenant object, however it doesn’t seem to expose storage volumes, only the following through its associations:

  • cloud_networks
  • cloud_resource_quotas
  • ext_management_system
  • floating_ips
  • miq_templates
  • security_groups
  • vms
  • vms_and_templates

Additionally, doing a $evm.vmdb(‘Storage’).find(:all) doesn’t seem to identify any MiqAeServiceStorage objects.

I know I can use the fog gem to list the storage volumes directly from OpenStack, though I’d prefer to use ManageIQ objects if I can.

Does anyone have any ideas?

Any assistance is greatly appreciated!

Shane


#2

@gmccullough can you review this question from @jockey10 and forward to a SME if necessary.


#3

@jockey10 this feature is currently being added here https://github.com/ManageIQ/manageiq/pull/7742


#4

Thanks very much @jprause and @Ladas, that PR looks exactly like what I was after!