func()

in pkg/common/connectionmanager/zones.go [127:291]


func (cm *ConnectionManager) getDIFromMultiVCorDC(ctx context.Context,
	zoneLabel string, regionLabel string, zoneLooking string, regionLooking string) (*ZoneDiscoveryInfo, error) {
	klog.V(4).Infof("getDIFromMultiVCorDC called with zone: %s and region: %s", zoneLooking, regionLooking)

	if len(zoneLabel) == 0 || len(regionLabel) == 0 || len(zoneLooking) == 0 || len(regionLooking) == 0 {
		err := ErrMultiVCRequiresZones
		klog.Errorf("%v", err)
		return nil, err
	}

	type zoneSearch struct {
		tenantRef  string
		vc         string
		datacenter *vclib.Datacenter
		host       *object.HostSystem
	}

	var mutex = &sync.Mutex{}
	var globalErrMutex = &sync.Mutex{}
	var queueChannel chan *zoneSearch
	var wg sync.WaitGroup
	var globalErr *error

	queueChannel = make(chan *zoneSearch, QueueSize)

	zoneFound := false
	globalErr = nil

	setGlobalErr := func(err error) {
		globalErrMutex.Lock()
		globalErr = &err
		globalErrMutex.Unlock()
	}

	setZoneFound := func(found bool) {
		mutex.Lock()
		zoneFound = found
		mutex.Unlock()
	}

	getZoneFound := func() bool {
		mutex.Lock()
		found := zoneFound
		mutex.Unlock()
		return found
	}

	go func() {
		for _, vsi := range cm.VsphereInstanceMap {
			var datacenterObjs []*vclib.Datacenter

			if getZoneFound() {
				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("getDIFromMultiVCorDC error vc:", err)
				setGlobalErr(err)
				continue
			}

			if vsi.Cfg.Datacenters == "" {
				datacenterObjs, err = vclib.GetAllDatacenter(ctx, vsi.Conn)
				if err != nil {
					klog.Error("getDIFromMultiVCorDC 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("getDIFromMultiVCorDC error dc:", err)
						setGlobalErr(err)
						continue
					}
					datacenterObjs = append(datacenterObjs, datacenterObj)
				}
			}

			for _, datacenterObj := range datacenterObjs {
				if getZoneFound() {
					break
				}

				finder := find.NewFinder(datacenterObj.Client(), false)
				finder.SetDatacenter(datacenterObj.Datacenter)

				hostList, err := finder.HostSystemList(ctx, "*/*")
				if err != nil {
					klog.Errorf("HostSystemList failed: %v", err)
					continue
				}

				for _, host := range hostList {
					klog.V(3).Infof("Finding zone in vc=%s and datacenter=%s for host: %s", vsi.Cfg.VCenterIP, datacenterObj.Name(), host.Name())
					queueChannel <- &zoneSearch{
						tenantRef:  vsi.Cfg.TenantRef,
						vc:         vsi.Cfg.VCenterIP,
						datacenter: datacenterObj,
						host:       host,
					}
				}
			}
		}
		close(queueChannel)
	}()

	var zoneInfo *ZoneDiscoveryInfo
	for i := 0; i < PoolSize; i++ {
		wg.Add(1)
		go func() {
			for res := range queueChannel {

				klog.V(3).Infof("Checking zones for host: %s", res.host.Name())
				result, err := cm.LookupZoneByMoref(ctx, res.tenantRef, res.host.Reference(), zoneLabel, regionLabel)
				if err != nil {
					klog.Errorf("Failed to find zone: %s and region: %s for host %s", zoneLabel, regionLabel, res.host.Name())
					continue
				}

				if !strings.EqualFold(result[ZoneLabel], zoneLooking) ||
					!strings.EqualFold(result[RegionLabel], regionLooking) {
					klog.V(4).Infof("Does not match region: %s and zone: %s", result[RegionLabel], result[ZoneLabel])
					continue
				}

				klog.Infof("Found zone: %s and region: %s for host %s", zoneLooking, regionLooking, res.host.Name())
				zoneInfo = &ZoneDiscoveryInfo{
					TenantRef:  res.tenantRef,
					VcServer:   res.vc,
					DataCenter: res.datacenter,
				}

				setZoneFound(true)
				break
			}
			wg.Done()
		}()
	}
	wg.Wait()
	if zoneFound {
		return zoneInfo, nil
	}
	if globalErr != nil {
		return nil, *globalErr
	}

	klog.V(4).Infof("getDIFromMultiVCorDC: zone: %s and region: %s not found", zoneLabel, regionLabel)
	return nil, vclib.ErrNoZoneRegionFound
}