Posts Tagged ‘cloudforms’

IE 11 and CloudForms Certificate Issues

May 16th, 2016 No comments

We were receiving an error when using IE 11 against a CloudForms appliance: “Error: Name is required”. It appears to be due to IE’s handling of Self-Signed certificates.

Since we’re using IPA as the authentication source for CloudForms, I figured we’d just use that to generate certs for the appliance and then we can trust the CA from IPA. Here’s a gist of the shell script I whipped up to do that. It should be run from the CF Appliance that’s already joined to the IPA realm.

Packaging VMware VDDK 6.0.x RPM for CloudForms

April 27th, 2016 No comments


Here’s a SPEC file I came up with to package the VMware VDDK as an RPM for CloudForms/ManageIQ appliances. VDDK 5.x came with an install script, but 6.x does not. It’s probably better packaged as an RPM anyway. This is based off of the instructions available at (for paying Red Hat customers).

The latest versions will be available at


This is packaged as a nosrc.rpm since VMware-vix-disklib can’t be distributed. To build, run the following:

yum install rpmdevtools

Download the VMware-vix-disklib-6.0.2-3566099.x86_64.tar.gz to ~/rpmbuild/SOURCES
Download the vmware-vix-disklib.spec to ~/rpmbuild/SPECS

rpmbuild -ba ~/rpmbuild/SPECS/vmware-vix-disklib.spec

SPEC file

Name:           vmware-vix-disklib
Version:        6.0.2
Release:        1%{?dist}
Summary:        The Virtual Disk Development Kit (VDDK) is a collection of C libraries, code samples, utilities, and documentation to help you create or access VMware virtual disk storage.
License:        Proprietary
Source0:        VMware-vix-disklib-6.0.2-3566099.x86_64.tar.gz
NoSource:	0
BuildRequires:  coreutils
The Virtual Disk Development Kit (VDDK) is a collection of C libraries, code samples, utilities, and documentation to help you create or access VMware virtual disk storage. The kit includes:
* The Virtual Disk and Disk Mount libraries, sets of C function calls to manipulate virtual disk files. C++ code samples that you can build with either Visual Studio or the GNU C compiler
* Documentation about the VDDK libraries and the command-line utilities
* The Disk Mount utility to access files and file systems in offline virtual disks on Windows or Linux guest virtual machines
* The Virtual Disk Manager utility to manipulate offline virtual disk on Windows or Linux (clone, create, relocate, rename, grow, shrink, or defragment)
%setup -n %{name}-distrib
%__mkdir_p %{buildroot}/usr/lib/vmware-vix-disklib
%__cp -r bin64 include lib64 %{buildroot}/usr/lib/%{name}
%__ln_s /usr/lib/vmware-vix-disklib/lib64/ %{buildroot}/usr/lib/
%__ln_s /usr/lib/vmware-vix-disklib/lib64/ %{buildroot}/usr/lib/
%doc doc/*
* Wed Apr 27 2016 Matt Hyclak <> 6.0.2-1
Initial Build

Delaying VM Deletion during Retirement in CFME 5.4

September 29th, 2015 No comments

At $DAYJOB we would like to be able to “un-retire” a VM, especially in those cases where a customer retires it and “didn’t know that’s what it would do” or similar. To meet these requirements, I’ve introduced a delay in processing the full retirement by overriding the default pre_retirement.rb method. Here’s the gist of things:

# Description: This method powers-off the VM on the provider and waits for Retirement Delay to pass before continuing
require 'miq_dev_util'
@logger =$evm, 'pre_retirement')
vm = $evm.root['vm']
customer_id = $evm.instantiate('/Configuration/Methods/get_customer_identifier')['return_value']
retirement_delay = $evm.instantiate("/Infrastructure/VM/Retirement/Configuration/RetirementDelay/#{customer_id}")['retirement_delay'].gsub(' ', '.')
#TODO: Figure out a way to ensure retirement_delay is valid
@logger.log('info', "Found Customer #{customer_id} with retirement delay #{retirement_delay}")
# Power off the VM
unless vm.nil? || vm.attributes['power_state'] == 'off'
  ems = vm.ext_management_system
  @logger.log('info', "Powering Off VM <#{}> in provider <#{ems.try(:name)}>")
# If we don't have a delay, continue on
if retirement_delay.nil?
  @logger.log('info', "No retirement delay requested. Continuing with the process")
# Otherwise process the delay
  if vm.retirement_state == 'retiring'
    @logger.log('info', "Delaying #{retirement_delay} before finishing retirement for #{}")
    # The VM isn't really retired here, but for display purposes lets see what happens
    # The retirement date isn't set, so that may be a way to differentiate if we need to
    vm['retired'] = true # Because exposing the retired= method is too hard?
    vm.retirement_state = 'delaying'
    $evm.root['ae_result']         = 'retry'
    $evm.root['ae_retry_interval'] = "#{retirement_delay}"
  elsif vm.retirement_state == 'delaying'
    @logger.log('info', "Retirement delay reached. Continuing with the process.")
    vm['retired'] = false # Have to set this back so finish_retirement doesn't bomb later.
    vm.retirement_state = 'retiring'

Some items of note:

  1. I’m using the miq_dev_util module written by my colleague that provides a couple of nice utility functions. In this case I’m only using the logging, so swapping that out would be no big deal.
  2. The VM gets “retired” very early on so that the VM shows up with an ‘R’ for an icon and it is obvious it’s been retired – even though it hasn’t been deleted. During this time, the Retirement Status is set to “Delaying”.
  3. We take advantage of the retry capabilities of the state machine to perform the delay for us.
  4. customer_identifier is something internal to us. You can use whatever key you like to search for the appropriate instance of RetirementDelay. Eventually, retirement_delay should contain a ruby-valid time statement, such as ’60.minutes’ or ‘7.days’

Hope you find this useful!

CloudForms VMware Tools Upgrade method

May 14th, 2015 No comments

I wrote a method a while back to allow me to upgrade VMware tools from within the CloudForms interface. I thought I would share it. I usually create a VM button to call the method, but it could probably be used elsewhere with some tweaking.

For the button, create it with System/Process/Request, Message create and Request upgrade_vmware_tools.

Screen Shot 2015-05-14 at 10.31.33 AM

Next, create an instance under /System/Process/Request called upgrade_vmware_tools that has a relationship field pointing to the location of your method. In my case, I chose /Infrastructure/VM/Operations/Methods/upgrade_vmware_tools

Screen Shot 2015-05-14 at 10.32.56 AM

Finally, you can create your instance and method.

Screen Shot 2015-05-14 at 10.33.32 AM

Here’s the code for what I wrote:

# CFME Automate Method: upgrade_vmware_tools
# Inputs: $evm.root['vm']
  # Method for logging
  def log(level, message)
    @method = 'upgrade_vmware_tools'
    $evm.log(level, "#{@method} - #{message}")
  def dump_attributes(my_object, my_object_name)
    $evm.log(:info, "Begin #{my_object_name}.attributes")
    my_object.attributes.sort.each { |k, v| $evm.log(:info, "#{my_object_name} Attribute - #{k}: #{v}")}
    $evm.log(:info, "End #{my_object_name}.attributes")
    $evm.log(:info, "")
  def dump_associations(my_object, my_object_name)
    $evm.log(:info, "Begin #{my_object_name}.associations")
    my_object.associations.sort.each { |a| $evm.log(:info, "#{my_object_name} Association - #{a}")}
    $evm.log(:info, "End #{my_object_name}.associations")
    $evm.log(:info, "")
  def dump_virtual_columns(my_object, my_object_name)
    $evm.log(:info, "Begin #{my_object_name}.virtual_columns")
    my_object.virtual_column_names.sort.each { |vcn| $evm.log(:info, "#{my_object_name} Virtual Column - #{vcn}")}
    $evm.log(:info, "End #{my_object_name}.virtual_columns")
    $evm.log(:info, "")
  log(:info, "CFME Automate Method Started")
  # Log information 
  #dump_attributes($evm.root, "$evm.root")
  #dump_associations($evm.root['vm'], "vm")
  #dump_virtual_columns($evm.root, "$evm.root")
  def find_vm(dc, name)
    vm = {}
    dc.datastoreFolder.childEntity.collect do |datastore|
      vm[:instance] = datastore.vm.find { |x| == name }
      if vm[:instance]
        vm[:datastore] =
  def upg_tools(vm)
    if vm[:instance][:guest][:guestFamily] == 'windowsGuest'
      instopts = '/s /v "/qn REBOOT=ReallySuppress"'
      instopts = nil
    $evm.log(:info, "Upgrading VMware Tools on #{vm[:instance][:name]}")
    upgtask = vm[:instance].UpgradeTools_Task(:installerOptions => instopts).wait_for_completion
  require 'rbvmomi'
  VIM = RbVmomi::VIM
  rvm  = $evm.root['vm']
  ems = rvm.ext_management_system()
  credentials = { :host => ems['hostname'], :user => ems.authentication_userid(), :password => ems.authentication_password(), :insecure => true }
  vim = VIM.connect credentials
  dc = vim.serviceInstance.find_datacenter
  vm = find_vm(dc,
  rc = upg_tools(vm)
  # Exit method
  log(:info, "CFME Automate Method Ended")
  exit MIQ_OK
  # Ruby rescue 
rescue => err
  log(:error, "[#{err}]\n#{err.backtrace.join("\n")}")
  exit MIQ_ABORT

Using the CloudForms SOAP API for daily provision reports

May 7th, 2015 No comments

For several reasons, we are currently unable to integrate directly from CloudForms to our CMDB. The current workaround is to send a CSV with the pertinent information to the group responsible for creating CIs in the CMDB. We implemented this originally as part of the Automation workflow – but after talking with this group, they indicated that the volume of individual CSV files would be overwhelming.

Read more…