mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-22 18:50:08 +03:00
Feature #3306: Add Distributed Network support for vCenter
Add VLAN retrieval
This commit is contained in:
parent
547bc6c8a5
commit
256d8a73db
@ -214,4 +214,95 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
exit 0
|
||||
end
|
||||
|
||||
network_desc = <<-EOT.unindent
|
||||
Import vCenter networks into OpenNebula
|
||||
EOT
|
||||
|
||||
command :networks, network_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"\
|
||||
" vCenter networks:\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 vCenter networks..."
|
||||
|
||||
rs = vc.vcenter_networks
|
||||
|
||||
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 Networks found in #{dc}...\n\n"
|
||||
next
|
||||
end
|
||||
|
||||
tmps.each{ |n|
|
||||
print_str = "\n * Network found:\n"\
|
||||
" - Name : #{n[:name]}\n"\
|
||||
" - Type : #{n[:type]}\n"
|
||||
print_str += " - VLAN ID : #{n[:vlan]}\n" if n[:vlan]
|
||||
print_str += " Import this Network [y/n]? "
|
||||
|
||||
STDOUT.print print_str
|
||||
|
||||
next if STDIN.gets.strip.downcase != 'y'
|
||||
|
||||
STDOUT.print " How many VMs are you planning"\
|
||||
" to fit into this network [255]? "
|
||||
|
||||
size = STDIN.gets.strip
|
||||
|
||||
size = "255" if size.to_i.to_s != size
|
||||
|
||||
one_vn = ::OpenNebula::VirtualNetwork.new(
|
||||
::OpenNebula::Template.build_xml, vc.one)
|
||||
|
||||
vnet_template = "NAME=\"#{n[:name]}\"\n" +
|
||||
"BRIDGE=\"#{n[:name]}\"\n" +
|
||||
"VCENTER_TYPE=\"#{n[:type]}\"" +
|
||||
"AR=[\n" +
|
||||
" TYPE = \"ETHER\"\n," +
|
||||
" SIZE = \"#{size.to_i}\"\n]"
|
||||
|
||||
vnet_template += "VLAN=\"YES\"\nVLAN_ID=#{n[:vlan]}" if n[:vlan]
|
||||
|
||||
rc = one_vn.allocate(vnet_template)
|
||||
|
||||
if ::OpenNebula.is_error?(rc)
|
||||
STDOUT.puts " Error creating virtual network: " +
|
||||
" #{rc.message}\n"
|
||||
else
|
||||
STDOUT.puts " OpenNebula virtual network " +
|
||||
"#{one_vn.id} created with size #{size}!\n"
|
||||
end
|
||||
}
|
||||
}
|
||||
rescue Exception => e
|
||||
STDOUT.puts "error: #{e.message}"
|
||||
exit -1
|
||||
end
|
||||
|
||||
exit 0
|
||||
end
|
||||
end
|
||||
|
@ -129,7 +129,7 @@ class VIClient
|
||||
|
||||
########################################################################
|
||||
# Initialize a VIConnection based just on the VIM parameters. The
|
||||
# OpenNebula client is also initilialize
|
||||
# OpenNebula client is also initilialized
|
||||
########################################################################
|
||||
def self.new_connection(user_opts)
|
||||
|
||||
@ -166,6 +166,23 @@ class VIClient
|
||||
end
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Searches the associated vmFolder of the DataCenter for the current
|
||||
# connection. Returns a RbVmomi::VIM::VirtualMachine or nil if not found
|
||||
# @param vm_name [String] the UUID of the VM or VM Template
|
||||
########################################################################
|
||||
def find_vm(vm_name)
|
||||
vms = get_entities(@dc.vmFolder, 'VirtualMachine')
|
||||
|
||||
return vms.find do |v|
|
||||
begin
|
||||
v.name == vm_name
|
||||
rescue ManagedObjectNotFound
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Builds a hash with the DataCenter / ClusterComputeResource hierarchy
|
||||
# for this VCenter.
|
||||
@ -219,6 +236,63 @@ class VIClient
|
||||
return vm_templates
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Builds a hash with the Datacenter / CCR (Distributed)Networks
|
||||
# for this VCenter
|
||||
# @return [Hash] in the form
|
||||
# { dc_name [String] => Networks [Array] }
|
||||
########################################################################
|
||||
def vcenter_networks
|
||||
vcenter_networks = {}
|
||||
|
||||
datacenters = get_entities(@root, 'Datacenter')
|
||||
|
||||
datacenters.each { |dc|
|
||||
networks = get_entities(dc.networkFolder, 'Network' )
|
||||
one_nets = []
|
||||
|
||||
networks.each { |n|
|
||||
one_nets << {:name => n.name,
|
||||
:bridge => n.name,
|
||||
:type => "Port Group"}
|
||||
}
|
||||
|
||||
vcenter_networks[dc.name] = one_nets
|
||||
|
||||
networks = get_entities(dc.networkFolder,
|
||||
'DistributedVirtualPortgroup' )
|
||||
one_nets = []
|
||||
|
||||
networks.each { |n|
|
||||
one_net = {:name => n.name,
|
||||
:bridge => n.name,
|
||||
:type=> "Distributed Port Group"}
|
||||
|
||||
vlan = n.config.defaultPortConfig.vlan.vlanId
|
||||
|
||||
if vlan != 0
|
||||
if vlan.is_a? Array
|
||||
vlan_str = ""
|
||||
vlan.each{|v|
|
||||
vlan_str += v.start + ".." + v.end + ","
|
||||
}
|
||||
vlan_str.chop!
|
||||
else
|
||||
vlan_str = vlan.to_s
|
||||
end
|
||||
|
||||
one_net[:vlan] = vlan_str
|
||||
end
|
||||
|
||||
one_nets << one_net
|
||||
}
|
||||
|
||||
vcenter_networks[dc.name] += one_nets
|
||||
}
|
||||
|
||||
return vcenter_networks
|
||||
end
|
||||
|
||||
def self.translate_hostname(hostname)
|
||||
host_pool = OpenNebula::HostPool.new(::OpenNebula::Client.new())
|
||||
rc = host_pool.info
|
||||
@ -820,7 +894,9 @@ private
|
||||
# Returns the spec to reconfig a VM and add a NIC
|
||||
########################################################################
|
||||
def self.calculate_addnic_spec(vm, mac, bridge, model)
|
||||
model = model.nil? ? nil : model.downcase
|
||||
network = vm.runtime.host.network.select{|n| n.name==bridge}
|
||||
backing = nil
|
||||
|
||||
if network.empty?
|
||||
raise "Network #{bridge} not found in host #{vm.runtime.host.name}"
|
||||
@ -836,8 +912,6 @@ private
|
||||
end
|
||||
}
|
||||
|
||||
model = model.nil? ? nil : model.downcase
|
||||
|
||||
nic_card = case model
|
||||
when "virtuale1000"
|
||||
RbVmomi::VIM::VirtualE1000
|
||||
@ -857,9 +931,19 @@ private
|
||||
RbVmomi::VIM::VirtualE1000
|
||||
end
|
||||
|
||||
backing = RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(
|
||||
:deviceName => bridge,
|
||||
:network => network)
|
||||
if network.class == RbVmomi::VIM::Network
|
||||
backing = RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(
|
||||
:deviceName => bridge,
|
||||
:network => network)
|
||||
else
|
||||
port = RbVmomi::VIM::DistributedVirtualSwitchPortConnection(
|
||||
:switchUuid =>
|
||||
network.config.distributedVirtualSwitch.uuid,
|
||||
:portgroupKey => network.key)
|
||||
backing =
|
||||
RbVmomi::VIM.VirtualEthernetCardDistributedVirtualPortBackingInfo(
|
||||
:port => port)
|
||||
end
|
||||
|
||||
return {:operation => :add,
|
||||
:device => nic_card.new(
|
||||
@ -920,10 +1004,22 @@ private
|
||||
:powerOn => false,
|
||||
:template => false)
|
||||
|
||||
vm = vc_template.CloneVM_Task(
|
||||
:folder => vc_template.parent,
|
||||
:name => "one-#{vmid}",
|
||||
:spec => clone_spec).wait_for_completion
|
||||
begin
|
||||
vm = vc_template.CloneVM_Task(
|
||||
:folder => vc_template.parent,
|
||||
:name => "one-#{vmid}",
|
||||
:spec => clone_spec).wait_for_completion
|
||||
rescue Exception => e
|
||||
if e.message.start_with?('DuplicateName')
|
||||
vm = connection.find_vm("one-#{vmid}")
|
||||
vm.Destroy_Task.wait_for_completion
|
||||
vm = vc_template.CloneVM_Task(
|
||||
:folder => vc_template.parent,
|
||||
:name => "one-#{vmid}",
|
||||
:spec => clone_spec).wait_for_completion
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
vm_uuid = vm.config.uuid
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user