in pkg/common/connectionmanager/search.go [47:230]
func (cm *ConnectionManager) WhichVCandDCByNodeID(ctx context.Context, nodeID string, searchBy FindVM) (*VMDiscoveryInfo, error) {
if nodeID == "" {
klog.V(3).Info("WhichVCandDCByNodeID called but nodeID is empty")
return nil, errors.New("nodeID is empty")
}
type vmSearch struct {
tenantRef string
vc string
datacenter *vclib.Datacenter
}
var mutex = &sync.Mutex{}
var globalErrMutex = &sync.Mutex{}
var queueChannel chan *vmSearch
var wg sync.WaitGroup
var globalErr *error
queueChannel = make(chan *vmSearch, QueueSize)
myNodeID := nodeID
switch searchBy {
case FindVMByUUID:
klog.V(3).Info("WhichVCandDCByNodeID by UUID")
myNodeID = strings.TrimSpace(strings.ToLower(nodeID))
case FindVMByIP:
klog.V(3).Info("WhichVCandDCByNodeID by IP")
default:
klog.V(3).Info("WhichVCandDCByNodeID by Name")
}
klog.V(2).Info("WhichVCandDCByNodeID nodeID: ", myNodeID)
vmFound := false
globalErr = nil
setGlobalErr := func(err error) {
globalErrMutex.Lock()
globalErr = &err
globalErrMutex.Unlock()
}
setVMFound := func(found bool) {
mutex.Lock()
vmFound = found
mutex.Unlock()
}
getVMFound := func() bool {
mutex.Lock()
found := vmFound
mutex.Unlock()
return found
}
go func() {
for _, vsi := range cm.VsphereInstanceMap {
var datacenterObjs []*vclib.Datacenter
if getVMFound() {
break
}
var err error
for i := 0; i < NumConnectionAttempts; i++ {
err = cm.Connect(ctx, vsi)
if err == nil {
break
}
time.Sleep(time.Duration(RetryAttemptDelaySecs) * time.Second)
}
if err != nil {
klog.Error("WhichVCandDCByNodeID error vc:", err)
setGlobalErr(err)
continue
}
if vsi.Cfg.Datacenters == "" {
datacenterObjs, err = vclib.GetAllDatacenter(ctx, vsi.Conn)
if err != nil {
klog.Error("WhichVCandDCByNodeID error dc:", err)
setGlobalErr(err)
continue
}
} else {
datacenters := strings.Split(vsi.Cfg.Datacenters, ",")
for _, dc := range datacenters {
dc = strings.TrimSpace(dc)
if dc == "" {
continue
}
datacenterObj, err := vclib.GetDatacenter(ctx, vsi.Conn, dc)
if err != nil {
klog.Error("WhichVCandDCByNodeID error dc:", err)
setGlobalErr(err)
continue
}
datacenterObjs = append(datacenterObjs, datacenterObj)
}
}
for _, datacenterObj := range datacenterObjs {
if getVMFound() {
break
}
klog.V(4).Infof("Finding node %s in vc=%s and datacenter=%s", myNodeID, vsi.Cfg.VCenterIP, datacenterObj.Name())
queueChannel <- &vmSearch{
tenantRef: vsi.Cfg.TenantRef,
vc: vsi.Cfg.VCenterIP,
datacenter: datacenterObj,
}
}
}
close(queueChannel)
}()
var vmInfo *VMDiscoveryInfo
for i := 0; i < PoolSize; i++ {
wg.Add(1)
go func() {
for res := range queueChannel {
var vm *vclib.VirtualMachine
var err error
switch searchBy {
case FindVMByUUID:
vm, err = res.datacenter.GetVMByUUID(ctx, myNodeID)
case FindVMByIP:
vm, err = res.datacenter.GetVMByIP(ctx, myNodeID)
default:
vm, err = res.datacenter.GetVMByDNSName(ctx, myNodeID)
}
if err != nil {
klog.Errorf("Error while looking for vm=%s(%s) in vc=%s and datacenter=%s: %v",
myNodeID, searchBy, res.vc, res.datacenter.Name(), err)
if err != vclib.ErrNoVMFound {
setGlobalErr(err)
} else {
klog.V(2).Infof("Did not find node %s in vc=%s and datacenter=%s",
myNodeID, res.vc, res.datacenter.Name())
}
continue
}
var oVM mo.VirtualMachine
err = vm.Properties(ctx, vm.Reference(), []string{"config", "summary", "guest"}, &oVM)
if err != nil {
klog.Errorf("Error collecting properties for vm=%+v in vc=%s and datacenter=%s: %v",
vm, res.vc, res.datacenter.Name(), err)
continue
}
hostName := oVM.Guest.HostName
if searchBy == FindVMByIP {
klog.V(2).Infof("WhichVCandDCByNodeID by IP. Overriding VMName from=%s to to=%s", oVM.Guest.HostName, myNodeID)
hostName = myNodeID
}
UUID := strings.ToLower(strings.TrimSpace(oVM.Summary.Config.Uuid))
klog.V(2).Infof("Found node %s as vm=%+v in vc=%s and datacenter=%s",
nodeID, vm, res.vc, res.datacenter.Name())
klog.V(2).Infof("Hostname: %s, UUID: %s", hostName, UUID)
vmInfo = &VMDiscoveryInfo{TenantRef: res.tenantRef, DataCenter: res.datacenter, VM: vm, VcServer: res.vc,
UUID: UUID, NodeName: hostName}
setVMFound(true)
break
}
wg.Done()
}()
}
wg.Wait()
if vmFound {
return vmInfo, nil
}
if globalErr != nil {
return nil, *globalErr
}
klog.V(4).Infof("WhichVCandDCByNodeID: %q vm not found", myNodeID)
return nil, vclib.ErrNoVMFound
}