func populateVsphereInstanceMap()

in vsphere/vsphere.go [329:489]


func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance, error) {
	vsphereInstanceMap := make(map[string]*VSphereInstance)
	isSecretInfoProvided := true

	if cfg.Global.SecretName == "" || cfg.Global.SecretNamespace == "" {
		klog.Warningf("SecretName and/or SecretNamespace is not provided. " +
			"VCP will use username and password from config file")
		isSecretInfoProvided = false
	}

	if isSecretInfoProvided {
		if cfg.Global.User != "" {
			klog.Warning("Global.User and Secret info provided. VCP will use secret to get credentials")
			cfg.Global.User = ""
		}
		if cfg.Global.Password != "" {
			klog.Warning("Global.Password and Secret info provided. VCP will use secret to get credentials")
			cfg.Global.Password = ""
		}
	}

	// Check if the vsphere.conf is in old format. In this
	// format the cfg.VirtualCenter will be nil or empty.
	if cfg.VirtualCenter == nil || len(cfg.VirtualCenter) == 0 {
		klog.V(4).Infof("Config is not per virtual center and is in old format.")
		if !isSecretInfoProvided {
			if cfg.Global.User == "" {
				klog.Error("Global.User is empty!")
				return nil, ErrUsernameMissing
			}
			if cfg.Global.Password == "" {
				klog.Error("Global.Password is empty!")
				return nil, ErrPasswordMissing
			}
		}

		if cfg.Global.WorkingDir == "" {
			klog.Error("Global.WorkingDir is empty!")
			return nil, errors.New("Global.WorkingDir is empty!")
		}
		if cfg.Global.VCenterIP == "" {
			klog.Error("Global.VCenterIP is empty!")
			return nil, errors.New("Global.VCenterIP is empty!")
		}
		if cfg.Global.Datacenter == "" {
			klog.Error("Global.Datacenter is empty!")
			return nil, errors.New("Global.Datacenter is empty!")
		}
		cfg.Workspace.VCenterIP = cfg.Global.VCenterIP
		cfg.Workspace.Datacenter = cfg.Global.Datacenter
		cfg.Workspace.Folder = cfg.Global.WorkingDir
		cfg.Workspace.DefaultDatastore = cfg.Global.DefaultDatastore

		vcConfig := VirtualCenterConfig{
			User:              cfg.Global.User,
			Password:          cfg.Global.Password,
			VCenterPort:       cfg.Global.VCenterPort,
			Datacenters:       cfg.Global.Datacenter,
			RoundTripperCount: cfg.Global.RoundTripperCount,
			Thumbprint:        cfg.Global.Thumbprint,
		}

		// Note: If secrets info is provided username and password will be populated
		// once secret is created.
		vSphereConn := vclib.VSphereConnection{
			Username:          vcConfig.User,
			Password:          vcConfig.Password,
			Hostname:          cfg.Global.VCenterIP,
			Insecure:          cfg.Global.InsecureFlag,
			RoundTripperCount: vcConfig.RoundTripperCount,
			Port:              vcConfig.VCenterPort,
			CACert:            cfg.Global.CAFile,
			Thumbprint:        cfg.Global.Thumbprint,
		}

		vsphereIns := VSphereInstance{
			conn: &vSphereConn,
			cfg:  &vcConfig,
		}
		vsphereInstanceMap[cfg.Global.VCenterIP] = &vsphereIns
	} else {
		if cfg.Workspace.VCenterIP == "" || cfg.Workspace.Folder == "" || cfg.Workspace.Datacenter == "" {
			msg := fmt.Sprintf("All fields in workspace are mandatory."+
				" vsphere.conf does not have the workspace specified correctly. cfg.Workspace: %+v", cfg.Workspace)
			klog.Error(msg)
			return nil, errors.New(msg)
		}
		if len(cfg.VirtualCenter) > 1 {
			klog.Warning("Multi vCenter support is deprecated. vSphere CSI Driver does not support Kubernetes nodes spread across multiple vCenter servers. Please consider moving all Kubernetes nodes to single vCenter server")
		}

		for vcServer, vcConfig := range cfg.VirtualCenter {
			klog.V(4).Infof("Initializing vc server %s", vcServer)
			if vcServer == "" {
				klog.Error("vsphere.conf does not have the VirtualCenter IP address specified")
				return nil, errors.New("vsphere.conf does not have the VirtualCenter IP address specified")
			}

			if !isSecretInfoProvided {
				if vcConfig.User == "" {
					vcConfig.User = cfg.Global.User
					if vcConfig.User == "" {
						klog.Errorf("vcConfig.User is empty for vc %s!", vcServer)
						return nil, ErrUsernameMissing
					}
				}
				if vcConfig.Password == "" {
					vcConfig.Password = cfg.Global.Password
					if vcConfig.Password == "" {
						klog.Errorf("vcConfig.Password is empty for vc %s!", vcServer)
						return nil, ErrPasswordMissing
					}
				}
			} else {
				if vcConfig.User != "" {
					klog.Warningf("vcConfig.User for server %s and Secret info provided. VCP will use secret to get credentials", vcServer)
					vcConfig.User = ""
				}
				if vcConfig.Password != "" {
					klog.Warningf("vcConfig.Password for server %s and Secret info provided. VCP will use secret to get credentials", vcServer)
					vcConfig.Password = ""
				}
			}

			if vcConfig.VCenterPort == "" {
				vcConfig.VCenterPort = cfg.Global.VCenterPort
			}

			if vcConfig.Datacenters == "" {
				if cfg.Global.Datacenters != "" {
					vcConfig.Datacenters = cfg.Global.Datacenters
				} else {
					// cfg.Global.Datacenter is deprecated, so giving it the last preference.
					vcConfig.Datacenters = cfg.Global.Datacenter
				}
			}
			if vcConfig.RoundTripperCount == 0 {
				vcConfig.RoundTripperCount = cfg.Global.RoundTripperCount
			}

			// Note: If secrets info is provided username and password will be populated
			// once secret is created.
			vSphereConn := vclib.VSphereConnection{
				Username:          vcConfig.User,
				Password:          vcConfig.Password,
				Hostname:          vcServer,
				Insecure:          cfg.Global.InsecureFlag,
				RoundTripperCount: vcConfig.RoundTripperCount,
				Port:              vcConfig.VCenterPort,
				CACert:            cfg.Global.CAFile,
				Thumbprint:        vcConfig.Thumbprint,
			}
			vsphereIns := VSphereInstance{
				conn: &vSphereConn,
				cfg:  vcConfig,
			}
			vsphereInstanceMap[vcServer] = &vsphereIns
		}
	}
	return vsphereInstanceMap, nil
}