diff --git a/src/cli/onevcenter b/src/cli/onevcenter index 78f99b0c7f..c42313e867 100644 --- a/src/cli/onevcenter +++ b/src/cli/onevcenter @@ -94,20 +94,20 @@ cmd=CommandParser::CmdParser.new(ARGV) do end begin - STDOUT.print "Connecting to vCenter: #{options[:vcenter]}..." + STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..." vc = VCenterDriver::VIClient.new_connection( :user => options[:vuser], :password => options[:vpass], :host => options[:vcenter]) - STDOUT.puts "done!" + STDOUT.print "done!\n\n" STDOUT.print "Exploring vCenter resources..." rs = vc.hierarchy - STDOUT.puts "done!" + STDOUT.print "done!\n\n" rs.each {|dc, cluster| STDOUT.print "Do you want to process datacenter #{dc} [y/n]? " @@ -142,6 +142,76 @@ cmd=CommandParser::CmdParser.new(ARGV) do end exit 0 - #h = VCenterDriver::VCenterHost.to_one(vc) + end + + templates_desc = <<-EOT.unindent + Import vCenter VM Templates into OpenNebula + EOT + + command :templates, templates_desc, :options=>[ VCENTER, USER, PASS ] do + if options[:vuser].nil? || + options[:vpass].nil? || + options[:vcenter].nil? + STDERR.puts "vCenter connection parameters are mandatory to import"\ + " VM templates:\n"\ + "\t --vcenter vCenter hostname\n"\ + "\t --vuser username to login in vcenter\n"\ + "\t --vpass password for the user" + exit -1 + end + + begin + STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..." + + vc = VCenterDriver::VIClient.new_connection( + :user => options[:vuser], + :password => options[:vpass], + :host => options[:vcenter]) + + STDOUT.print "done!\n\n" + + STDOUT.print "Looking for VM Templates..." + + rs = vc.vm_templates + + STDOUT.print "done!\n" + + rs.each {|dc, tmps| + STDOUT.print "\nDo you want to process datacenter #{dc} [y/n]? " + + next if STDIN.gets.strip.downcase != 'y' + + if tmps.empty? + STDOUT.print " No VM Templates found in #{dc}...\n\n" + next + end + + tmps.each{ |t| + STDOUT.print "\n * VM Template found:\n"\ + " - Name : #{t[:name]}\n"\ + " - UUID : #{t[:uuid]}\n"\ + " - Cluster: #{t[:host]}\n"\ + " Import this VM template [y/n]? " + + next if STDIN.gets.strip.downcase != 'y' + + one_t = ::OpenNebula::Template.new( + ::OpenNebula::Template.build_xml, vc.one) + + rc = one_t.allocate(t[:one]) + + if ::OpenNebula.is_error?(rc) + STDOUT.puts " Error creating template: #{rc.message}\n" + else + STDOUT.puts " OpenNebula template #{one_t.id} created!\n" + end + } + } + rescue Exception => e + STDOUT.puts "error: #{e.message}" + exit -1 + end + + exit 0 end end diff --git a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb index 255e0a676e..90a842b2dd 100644 --- a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb +++ b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb @@ -42,7 +42,6 @@ module VCenterDriver - ################################################################################ # This class represents a VCenter connection and an associated OpenNebula client # The connection is associated to the VCenter backing a given OpenNebula host. @@ -128,7 +127,7 @@ # Builds a hash with the DataCenter / ClusterComputeResource hierarchy # for this VCenter. # @return [Hash] in the form - # { dc_name [String] => ClusterComputeResources [Array] } + # {dc_name [String] => ClusterComputeResources Names [Array - String]} ######################################################################## def hierarchy vc_hosts = {} @@ -144,6 +143,39 @@ return vc_hosts end + ######################################################################## + # Builds a hash with the Datacenter / VM Templates for this VCenter + # @return [Hash] in the form + # { dc_name [String] => } + ######################################################################## + def vm_templates + vm_templates = {} + + @root.childEntity.each { |dc| + + vms = dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine) + + tmp = vms.select { |v| v.config.template == true } + + one_tmp = [] + + tmp.each { |t| + vi_tmp = VCenterVm.new(self, t) + + one_tmp << { + :name => vi_tmp.vm.name, + :uuid => vi_tmp.vm.config.uuid, + :host => vi_tmp.vm.runtime.host.parent.name, + :one => vi_tmp.to_one + } + } + + vm_templates[dc.name] = one_tmp + } + + return vm_templates + end + def self.translate_hostname(hostname) host_pool = OpenNebula::HostPool.new(::OpenNebula::Client.new()) rc = host_pool.info @@ -365,6 +397,8 @@ ################################################################################ class VCenterVm + attr_reader :vm + ############################################################################ # Creates a new VIVm using a RbVmomi::VirtualMachine object # @param vm_vi [RbVmomi::VirtualMachine] it will be used if not nil @@ -631,6 +665,23 @@ str_info << "NETTX=" << @net_tx.to_s end + ######################################################################## + # Generates an OpenNebula Template for this VCenterVm + # + # + ######################################################################## + def to_one + str = "NAME = \"#{@vm.name}\"\n"\ + "CPU = \"#{@vm.config.hardware.numCPU}\"\n"\ + "vCPU = \"#{@vm.config.hardware.numCPU}\"\n"\ + "MEMORY = \"#{@vm.config.hardware.memoryMB}\"\n"\ + "PUBLIC_CLOUD = [\n"\ + " TYPE =\"vcenter\",\n"\ + " VM_TEMPLATE =\"#{@vm.config.uuid}\"\n"\ + "]\n"\ + "SCHED_REQUIREMENTS=\"NAME=\\\"#{@vm.runtime.host.parent.name}\\\"\"\n" + end + private ########################################################################