1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-16 22:50:10 +03:00

M #-: Refactor get_unimported_networks (#4058)

This commit is contained in:
Angel Luis Moya Gonzalez 2019-12-19 16:51:09 +01:00 committed by Tino Vázquez
parent a1f36e047d
commit 7e4ea10b2e
3 changed files with 229 additions and 213 deletions

View File

@ -96,6 +96,7 @@ class OneVcenterHelper < OpenNebulaHelper::OneHelper
end
def host(arg)
return arg
end
########################

View File

@ -186,7 +186,7 @@ end
get '/vcenter/networks' do
begin
new_vcenter_importer("networks")
opts = {:filter => true}
opts = {:host => params["host"], :filter => true}
[200, $importer.retrieve_resources(opts).to_json]
rescue Exception => e
logger.error("[vCenter] " + e.message)

View File

@ -331,229 +331,244 @@ class DatacenterFolder
{ vcenter_instance_name => template_objects }
end
def get_unimported_networks(npool,vcenter_instance_name, hpool, args)
def cluster_networks(one_host)
ccr_ref = one_host['TEMPLATE/VCENTER_CCR_REF']
cluster = VCenterDriver::ClusterComputeResource
.new_from_ref(ccr_ref, @vi_client)
# cluster = cluster_mob(one_host)
raise "Cluster with ref: #{ccr_ref} not found" if cluster.nil?
networks = cluster.item.network
return networks
end
# Return network type of a given network:
# "Port Group"
# "Distributed Port Group"
# "NSX-V"
# "Opaque Network"
# "Unknown Network"
def identify_network_type(vc_network)
case vc_network
when RbVmomi::VIM::DistributedVirtualPortgroup
if vc_network['name']
.match(/^vxw-dvs-(.*)-virtualwire-(.*)-sid-(.*)/)
VCenterDriver::Network::NETWORK_TYPE_NSXV
else
VCenterDriver::Network::NETWORK_TYPE_DPG
end
when RbVmomi::VIM::OpaqueNetwork
VCenterDriver::Network::NETWORK_TYPE_NSXT
when RbVmomi::VIM::Network
VCenterDriver::Network::NETWORK_TYPE_PG
else
VCenterDriver::Network::NETWORK_TYPE_UNKNOWN
end
end
# Return ONE cluster ID
def one_cluster_id(one_host)
if !one_host || !one_host['CLUSTER_ID']
cluster_id = -1
else
cluster_id = one_host['CLUSTER_ID']
end
cluster_id.to_i
end
# Get vSwitch of Standard PortGroup
# If there is differents vSwitches returns the first.
def vSwitch(vc_pg)
vswitch = []
vc_hosts = vc_pg.host
vc_hosts.each do |vc_host|
host_pgs = vc_host.configManager.networkSystem.networkInfo.portgroup
host_pgs.each do |pg|
if vc_pg.name == pg.spec.name
vswitch << pg.spec.vswitchName
end
end
end
vswitch.uniq!
vswitch << 'Invalid configuration' if vswitch.length > 1
vswitch.join(" / ")
end
# Determine if a network must be excluded from the list
def exclude_network?(vc_network, one_host, args)
# Exclude some networks if filter = true
if args[:filter]
if ( one_host && one_host['TEMPLATE/NSX_STATUS'] != 'OK')
# Only NSX-V and NSX-T can be excluded
network_type = identify_network_type(vc_network)
if network_type == VCenterDriver::Network::NETWORK_TYPE_NSXT ||\
network_type == VCenterDriver::Network::NETWORK_TYPE_NSXV
return true
end
end
# Exclude networks without hosts
if vc_network['host'].empty?
return true
end
# Exclude DVS uplinks
unless vc_network['tag'].empty?
if vc_network['tag'][0][:key] == 'SYSTEM/DVS.UPLINKPG'
return true
end
end
# Exclude portgroup used for VXLAN communication in NSX
if vc_network['name'].match(/^vxw-vmknicPg-dvs-(.*)/)
return true
end
return false
end
return false
end
# Proccess each network
def process_network(vc_network,
vcenter_instance_name,
vcenter_uuid,
hpool,
one_host,
args)
# Initialize network hash
network = {}
# Add name to network hash
network[vc_network._ref] = {'name' => vc_network.name}
# By default no network is excluded
network[vc_network._ref][:excluded] = false
# Initialize opts hash used to inject data into one template
opts = {}
# Add network type to network hash
network_type = identify_network_type(vc_network)
network[vc_network._ref][:network_type] = network_type
# Determine if the network must be excluded
network[vc_network._ref][:excluded] = exclude_network?(vc_network,
one_host,
args)
return nil if network[vc_network._ref][:excluded] == true
case network[vc_network._ref][:network_type]
# Distributed PortGroups
when VCenterDriver::Network::NETWORK_TYPE_DPG
network[vc_network._ref][:sw_name] = \
vc_network.config.distributedVirtualSwitch.name
# For DistributedVirtualPortgroups there is networks and uplinks
network[vc_network._ref][:uplink] = \
vc_network.config.uplink
#network[vc_network._ref][:uplink] = false
# NSX-V PortGroups
when VCenterDriver::Network::NETWORK_TYPE_NSXV
network[vc_network._ref][:sw_name] = \
vc_network.config.distributedVirtualSwitch.name
# For NSX-V ( is the same as DistributedVirtualPortgroups )
# there is networks and uplinks
network[vc_network._ref][:uplink] = \
vc_network.config.uplink
network[vc_network._ref][:uplink] = false
# Standard PortGroups
when VCenterDriver::Network::NETWORK_TYPE_PG
# There is no uplinks for standard portgroups, so all Standard
# PortGroups are networks and no uplinks
network[vc_network._ref][:uplink] = false
network[vc_network._ref][:sw_name] = vSwitch(vc_network)
# NSX-T PortGroups
when VCenterDriver::Network::NETWORK_TYPE_NSXT
network[vc_network._ref][:sw_name] = \
vc_network.summary.opaqueNetworkType
# There is no uplinks for NSX-T networks, so all NSX-T networks
# are networks and no uplinks
network[vc_network._ref][:uplink] = false
else
raise 'Unknown network type: ' \
"#{network[vc_network._ref][:network_type]}"
end
# Multicluster nets support
network[vc_network._ref][:clusters] = {}
network[vc_network._ref][:clusters][:refs] = []
network[vc_network._ref][:clusters][:one_ids] = []
network[vc_network._ref][:clusters][:names] = []
network[vc_network._ref][:processed] = true
# Get hosts
vc_hosts = vc_network.host
vc_hosts.each do |vc_host|
# Get cluster
vc_cluster = vc_host.parent
network[vc_network._ref][:clusters][:refs] << vc_cluster._ref
cluster_id = one_cluster_id(one_host)
network[vc_network._ref][:clusters][:one_ids] << cluster_id
network[vc_network._ref][:clusters][:names] << vc_cluster.name
opts[:dc_name] = vc_cluster.name
end
# Remove duplicate entries
network[vc_network._ref][:clusters][:refs].uniq!
network[vc_network._ref][:clusters][:one_ids].uniq!
network[vc_network._ref][:clusters][:names].uniq!
# General net_info related to datacenter
opts[:vcenter_uuid] = vcenter_uuid
opts[:vcenter_instance_name] = vcenter_instance_name
opts[:network_name] = network[vc_network._ref]['name']
opts[:network_ref] = network.keys.first
opts[:network_type] = network[vc_network._ref][:network_type]
opts[:sw_name] = network[vc_network._ref][:sw_name]
network[vc_network._ref] = \
network[vc_network._ref].merge(VCenterDriver::Network
.to_one_template(opts))
network
end
def get_unimported_networks(npool, vcenter_instance_name, hpool, args)
vcenter_uuid = get_vcenter_instance_uuid
pc = @vi_client.vim.serviceContent.propertyCollector
#Get all port groups and distributed port groups in vcenter instance
view = @vi_client.vim.serviceContent.viewManager.CreateContainerView({
container: @vi_client.vim.rootFolder,
type: ['Network','DistributedVirtualPortgroup','OpaqueNetwork'],
recursive: true
})
filterSpec = RbVmomi::VIM.PropertyFilterSpec(
:objectSet => [
:obj => view,
:skip => true,
:selectSet => [
RbVmomi::VIM.TraversalSpec(
:name => 'traverseEntities',
:type => 'ContainerView',
:path => 'view',
:skip => false
)
]
],
:propSet => [
{ :type => 'Network', :pathSet => ['name'] },
{ :type => 'DistributedVirtualPortgroup', :pathSet => ['name'] },
{ :type => 'OpaqueNetwork', :pathSet => ['name'] }
]
)
result = pc.RetrieveProperties(:specSet => [filterSpec])
networks = {}
result.each do |r|
exist = VCenterDriver::VIHelper.find_by_ref(OpenNebula::VirtualNetworkPool,
"TEMPLATE/VCENTER_NET_REF",
r.obj._ref,
vcenter_uuid,
npool)
# Selected host in OpenNebula
one_client = OpenNebula::Client.new()
one_host = OpenNebula::Host.new_with_id(args[:host], one_client)
rc = one_host.info
raise rc.message if OpenNebula.is_error? rc
# Get all networks in vcenter cluster (one_host)
vc_cluster_networks = cluster_networks(one_host)
# Iterate over vcenter networks
vc_cluster_networks.each do |vc_cluster_network|
exist = VCenterDriver::VIHelper
.find_by_ref(OpenNebula::VirtualNetworkPool,
'TEMPLATE/VCENTER_NET_REF',
vc_cluster_network._ref,
vcenter_uuid,
npool)
next if exist
if args[:filter]
# Exclude networks without hosts
next if r.obj['host'].empty?
network = process_network(vc_cluster_network,
vcenter_instance_name,
vcenter_uuid,
hpool,
one_host,
args)
# Exclude DVS uplinks
unless r.obj['tag'].empty?
next if r.obj['tag'][0][:key] == 'SYSTEM/DVS.UPLINKPG'
end
# Exclude NSX uplinks
next if r.obj['name'].match(/^vxw-vmknicPg-dvs-(.*)/)
end
networks[r.obj._ref] = r.to_hash if r.obj.is_a?(RbVmomi::VIM::DistributedVirtualPortgroup) || r.obj.is_a?(RbVmomi::VIM::Network) || r.obj.is_a?(RbVmomi::VIM::OpaqueNetwork)
if r.obj.is_a?(RbVmomi::VIM::DistributedVirtualPortgroup)
# Here can be NETWORK_TYPE_DPG or NETWORK_TYPE_NSXV
if r['name'].match(/^vxw-dvs-(.*)-virtualwire-(.*)-sid-(.*)/)
networks[r.obj._ref][:network_type] = VCenterDriver::Network::NETWORK_TYPE_NSXV
else
networks[r.obj._ref][:network_type] = VCenterDriver::Network::NETWORK_TYPE_DPG
end
elsif r.obj.is_a?(RbVmomi::VIM::OpaqueNetwork)
networks[r.obj._ref][:network_type] = VCenterDriver::Network::NETWORK_TYPE_NSXT
elsif r.obj.is_a?(RbVmomi::VIM::Network)
networks[r.obj._ref][:network_type] = VCenterDriver::Network::NETWORK_TYPE_PG
else
networks[r.obj._ref][:network_type] = VCenterDriver::Network::NETWORK_TYPE_UNKNOWN
end
networks[r.obj._ref][:uplink] = false
networks[r.obj._ref][:processed] = false
#Multicluster nets support
networks[r.obj._ref][:clusters] = {}
networks[r.obj._ref][:clusters][:refs] = []
networks[r.obj._ref][:clusters][:one_ids] = []
networks[r.obj._ref][:clusters][:names] = []
networks.merge!(network) unless network.nil?
end
view.DestroyView # Destroy the view
#Get datacenters
fetch! if @items.empty?
#Iterate over datacenters
@items.values.each do |dc|
dc_name = dc.item.name
view = @vi_client.vim.serviceContent.viewManager.CreateContainerView({
container: dc.item,
type: ['ClusterComputeResource'],
recursive: true
})
filterSpec = RbVmomi::VIM.PropertyFilterSpec(
:objectSet => [
:obj => view,
:skip => true,
:selectSet => [
RbVmomi::VIM.TraversalSpec(
:name => 'traverseEntities',
:type => 'ContainerView',
:path => 'view',
:skip => false
)
]
],
:propSet => [
{ :type => 'ClusterComputeResource', :pathSet => ['name','network'] }
]
)
result = pc.RetrieveProperties(:specSet => [filterSpec])
clusters = {}
result.each do |r|
browser = r.obj.environmentBrowser || nil
if browser
browser.QueryConfigTarget.distributedVirtualPortgroup.each do |s|
next if !networks.key?(s.portgroupKey) || networks[s.portgroupKey][:processed]
networks[s.portgroupKey][:uplink] = s.uplinkPortgroup
networks[s.portgroupKey][:processed] = true
networks[s.portgroupKey][:sw_name] = s.switchName
end
end
clusters[r.obj._ref] = r.to_hash if r.obj.is_a?(RbVmomi::VIM::ClusterComputeResource)
end
view.DestroyView # Destroy the view
#general net_info related to datacenter
opts = {}
opts[:vcenter_uuid] = vcenter_uuid
opts[:vcenter_instance_name] = vcenter_instance_name
opts[:dc_name] = dc_name
clusters.each do |ref, info|
one_host = VCenterDriver::VIHelper.find_by_ref(OpenNebula::HostPool,
"TEMPLATE/VCENTER_CCR_REF",
ref,
vcenter_uuid,
hpool)
if !one_host || !one_host['CLUSTER_ID']
cluster_id = -1
else
cluster_id = one_host['CLUSTER_ID']
end
# Remove networks except for onevcenter list_all command
if args[:filter]
# Remove NSX networks if NSX_STATUS != "OK"
if one_host && one_host['TEMPLATE/NSX_STATUS'] != 'OK'
networks.delete_if do |_k,v|
v[:network_type] == 'Opaque Network' || \
v[:network_type] == 'NSX-V'
end
end
end
one_cluster = VCenterDriver::ClusterComputeResource.new_from_ref(ref, @vi_client)
location = VCenterDriver::VIHelper.get_location(one_cluster.item)
one_cluster['host'].each do |host|
begin
esx_host = VCenterDriver::ESXHost.new_from_ref(host._ref, @vi_client)
esx_host.lock
pg_inside = esx_host.get_pg_inside
networks.each {|ref, n|
next if networks[ref][:sw_name]
pg_inside.each do |vswitch, network_names|
network_names.each do |name|
if n['name'] == name
networks[ref][:sw_name] = vswitch
end
end
end
}
ensure
esx_host.unlock if esx_host
end
end
network_obj = info['network']
cname = info['name']
network_obj.each do |n|
network_ref = n._ref
next unless networks[network_ref]
if !networks[network_ref][:uplink]
# network can belong to more than 1 cluster
networks[network_ref][:clusters][:refs] << ref
networks[network_ref][:clusters][:one_ids] << cluster_id.to_i
networks[network_ref][:clusters][:names] << cname
networks[network_ref][:vcenter] = vcenter_instance_name
next if networks[network_ref][:clusters][:refs].size > 1
opts[:network_name] = networks[network_ref]['name']
opts[:network_ref] = network_ref
opts[:network_type] = networks[network_ref][:network_type]
opts[:sw_name] = networks[network_ref][:sw_name]
networks[network_ref] = networks[network_ref].merge(VCenterDriver::Network.to_one_template(opts))
else
networks.delete(network_ref)
end
end #networks loop
end #clusters loop
end # datacenters loop
# Added import id
imid = -1
networks.map{ |k,v| v[:import_id] = imid += 1 }
networks.map {|_k, v| v[:import_id] = imid += 1 }
{ vcenter_instance_name => networks }
end
end # class DatatacenterFolder
class Datacenter