#!/usr/bin/ruby require 'rbvmomi' require 'redis' require 'yaml' $:.unshift( File.dirname( __FILE__ ) ) require 'lib/require_relative' require 'lib/vsphere_helper' vsphere_helper = VsphereHelper.new Dir.chdir( File.dirname( __FILE__ ) ) # Load the configuration file config_file = File.expand_path( 'vmware-host-pooler.yaml' ) pools = YAML.load_file( config_file )[:pools] vsphere = YAML.load_file( config_file )[:vsphere] # Connect to vSphere $vim = RbVmomi::VIM.connect( :host => vsphere['server'], :user => vsphere['username'], :password => vsphere['password'], :ssl => true, :insecure => true, :rev => '5.1' ) # Connect to Redis $redis = Redis.new # Update loop loop do pools.each do |pool| total = 0 # Locate the resource pool datacenter = $vim.serviceInstance.find_datacenter base = vsphere_helper.find_pool(pool['pool']) # Count the number of VMs and correlate Redis inventory inventory = {} base.vm.each do |vm| if ! $redis.sismember('vmware_host_pool-'+pool['name'], vm['name']) $redis.sadd('vmware_host_pool-'+pool['name'], vm['name']) end inventory[vm['name']] = 1 total = total + 1 end $redis.smembers('vmware_host_pool-'+pool['name']).each do |vm| if ! inventory[vm] $redis.srem('vmware_host_pool-'+pool['name'], vm) end end # Bring the pool up to the desired size if total < pool['size'] # Provision VMs (1..(pool['size']-total)).each { |i| vm = {} if pool['template'] =~ /\// templatefolders = pool['template'].split('/') vm['template'] = templatefolders.pop end if templatefolders vm[vm['template']] = vsphere_helper.find_folder(templatefolders.join('/')).find(vm['template']) else raise "Please provide a full path to the template" end if vm['template'].length == 0 raise "Unable to find template '#{h['template']}'!" end # Generate a randomized hostname o = [('a'..'z'),('0'..'9')].map{|r| r.to_a}.flatten vm['hostname'] = o[rand(25)]+(0...14).map{o[rand(o.length)]}.join # Put the VM in the specified folder and resource pool relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec( :datastore => vsphere_helper.find_datastore(pool['datastore']), :pool => vsphere_helper.find_pool(pool['pool']), :diskMoveType => :moveChildMostDiskBacking ) # Create a clone spec spec = RbVmomi::VIM.VirtualMachineCloneSpec( :location => relocateSpec, :powerOn => true, :template => false ) puts '[+] '+vm.inspect # Clone the VM vm[vm['template']].CloneVM_Task( :folder => vsphere_helper.find_folder(pool['folder']), :name => vm['hostname'], :spec => spec ).wait_for_completion # Add VM to Redis inventory $redis.sadd('vmware_host_pool-'+pool['name'], vm['hostname']) } end # ZZZzzz... sleep(5) end end