Add secrets flag in vcp config and modify vcp to use nodemanger connect method
This commit is contained in:
		| @@ -61,6 +61,18 @@ var datastoreFolderIDMap = make(map[string]map[string]string) | ||||
| var cleanUpRoutineInitLock sync.Mutex | ||||
| var cleanUpDummyVMLock sync.RWMutex | ||||
|  | ||||
| // Error Messages | ||||
| const ( | ||||
| 	MissingUsernameErrMsg = "Username is missing" | ||||
| 	MissingPasswordErrMsg = "Password is missing" | ||||
| ) | ||||
|  | ||||
| // Error constants | ||||
| var ( | ||||
| 	ErrUsernameMissing = errors.New(MissingUsernameErrMsg) | ||||
| 	ErrPasswordMissing = errors.New(MissingPasswordErrMsg) | ||||
| ) | ||||
|  | ||||
| // VSphere is an implementation of cloud provider Interface for VSphere. | ||||
| type VSphere struct { | ||||
| 	cfg      *VSphereConfig | ||||
| @@ -68,8 +80,9 @@ type VSphere struct { | ||||
| 	// Maps the VSphere IP address to VSphereInstance | ||||
| 	vsphereInstanceMap map[string]*VSphereInstance | ||||
| 	// Responsible for managing discovery of k8s node, their location etc. | ||||
| 	nodeManager *NodeManager | ||||
| 	vmUUID      string | ||||
| 	nodeManager          *NodeManager | ||||
| 	vmUUID               string | ||||
| 	isSecretInfoProvided bool | ||||
| } | ||||
|  | ||||
| // Represents a vSphere instance where one or more kubernetes nodes are running. | ||||
| @@ -131,6 +144,10 @@ type VSphereConfig struct { | ||||
| 		// Combining the WorkingDir and VMName can form a unique InstanceID. | ||||
| 		// When vm-name is set, no username/password is required on worker nodes. | ||||
| 		VMName string `gcfg:"vm-name"` | ||||
| 		// Name of the secret were vCenter credentials are present. | ||||
| 		SecretName string `gcfg:"secret-name"` | ||||
| 		// Secret Namespace where secret will be present that has vCenter credentials. | ||||
| 		SecretNamespace string `gcfg:"secret-namespace"` | ||||
| 	} | ||||
|  | ||||
| 	VirtualCenter map[string]*VirtualCenterConfig | ||||
| @@ -217,6 +234,18 @@ func (vs *VSphere) SetInformers(informerFactory informers.SharedInformerFactory) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if vs.isSecretInfoProvided { | ||||
| 		secretCredentialManager := &SecretCredentialManager{ | ||||
| 			SecretName:      vs.cfg.Global.SecretName, | ||||
| 			SecretNamespace: vs.cfg.Global.SecretNamespace, | ||||
| 			SecretLister:    informerFactory.Core().V1().Secrets().Lister(), | ||||
| 			Cache: &SecretCache{ | ||||
| 				VirtualCenter: make(map[string]*Credential), | ||||
| 			}, | ||||
| 		} | ||||
| 		vs.nodeManager.UpdateCredentialManager(secretCredentialManager) | ||||
| 	} | ||||
|  | ||||
| 	// Only on controller node it is required to register listeners. | ||||
| 	// Register callbacks for node updates | ||||
| 	glog.V(4).Infof("Setting up node informers for vSphere Cloud Provider") | ||||
| @@ -226,6 +255,7 @@ func (vs *VSphere) SetInformers(informerFactory informers.SharedInformerFactory) | ||||
| 		DeleteFunc: vs.NodeDeleted, | ||||
| 	}) | ||||
| 	glog.V(4).Infof("Node informers in vSphere cloud provider initialized") | ||||
|  | ||||
| } | ||||
|  | ||||
| // Creates new worker node interface and returns | ||||
| @@ -247,19 +277,40 @@ func newWorkerNode() (*VSphere, error) { | ||||
|  | ||||
| func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance, error) { | ||||
| 	vsphereInstanceMap := make(map[string]*VSphereInstance) | ||||
| 	isSecretInfoProvided := true | ||||
|  | ||||
| 	if cfg.Global.SecretName == "" || cfg.Global.SecretNamespace == "" { | ||||
| 		glog.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 != "" { | ||||
| 			glog.Warning("Global.User and Secret info provided. VCP will use secret to get credentials") | ||||
| 			cfg.Global.User = "" | ||||
| 		} | ||||
| 		if cfg.Global.Password != "" { | ||||
| 			glog.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 { | ||||
| 		glog.V(4).Infof("Config is not per virtual center and is in old format.") | ||||
| 		if cfg.Global.User == "" { | ||||
| 			glog.Error("Global.User is empty!") | ||||
| 			return nil, errors.New("Global.User is empty!") | ||||
| 		} | ||||
| 		if cfg.Global.Password == "" { | ||||
| 			glog.Error("Global.Password is empty!") | ||||
| 			return nil, errors.New("Global.Password is empty!") | ||||
| 		if !isSecretInfoProvided { | ||||
| 			if cfg.Global.User == "" { | ||||
| 				glog.Error("Global.User is empty!") | ||||
| 				return nil, ErrUsernameMissing | ||||
| 			} | ||||
| 			if cfg.Global.Password == "" { | ||||
| 				glog.Error("Global.Password is empty!") | ||||
| 				return nil, ErrPasswordMissing | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if cfg.Global.WorkingDir == "" { | ||||
| 			glog.Error("Global.WorkingDir is empty!") | ||||
| 			return nil, errors.New("Global.WorkingDir is empty!") | ||||
| @@ -285,6 +336,8 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance | ||||
| 			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, | ||||
| @@ -305,31 +358,44 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance | ||||
| 			glog.Error(msg) | ||||
| 			return nil, errors.New(msg) | ||||
| 		} | ||||
|  | ||||
| 		for vcServer, vcConfig := range cfg.VirtualCenter { | ||||
| 			glog.V(4).Infof("Initializing vc server %s", vcServer) | ||||
| 			if vcServer == "" { | ||||
| 				glog.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 vcConfig.User == "" { | ||||
| 				vcConfig.User = cfg.Global.User | ||||
| 			} | ||||
| 			if vcConfig.Password == "" { | ||||
| 				vcConfig.Password = cfg.Global.Password | ||||
| 			} | ||||
| 			if vcConfig.User == "" { | ||||
| 				msg := fmt.Sprintf("vcConfig.User is empty for vc %s!", vcServer) | ||||
| 				glog.Error(msg) | ||||
| 				return nil, errors.New(msg) | ||||
| 			} | ||||
| 			if vcConfig.Password == "" { | ||||
| 				msg := fmt.Sprintf("vcConfig.Password is empty for vc %s!", vcServer) | ||||
| 				glog.Error(msg) | ||||
| 				return nil, errors.New(msg) | ||||
|  | ||||
| 			if !isSecretInfoProvided { | ||||
| 				if vcConfig.User == "" { | ||||
| 					vcConfig.User = cfg.Global.User | ||||
| 					if vcConfig.User == "" { | ||||
| 						glog.Errorf("vcConfig.User is empty for vc %s!", vcServer) | ||||
| 						return nil, ErrUsernameMissing | ||||
| 					} | ||||
| 				} | ||||
| 				if vcConfig.Password == "" { | ||||
| 					vcConfig.Password = cfg.Global.Password | ||||
| 					if vcConfig.Password == "" { | ||||
| 						glog.Errorf("vcConfig.Password is empty for vc %s!", vcServer) | ||||
| 						return nil, ErrPasswordMissing | ||||
| 					} | ||||
| 				} | ||||
| 			} else { | ||||
| 				if vcConfig.User != "" { | ||||
| 					glog.Warningf("vcConfig.User for server %s and Secret info provided. VCP will use secret to get credentials", vcServer) | ||||
| 					vcConfig.User = "" | ||||
| 				} | ||||
| 				if vcConfig.Password != "" { | ||||
| 					glog.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 | ||||
| @@ -342,6 +408,8 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance | ||||
| 				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, | ||||
| @@ -365,7 +433,30 @@ var getVMUUID = GetVMUUID | ||||
|  | ||||
| // Creates new Controller node interface and returns | ||||
| func newControllerNode(cfg VSphereConfig) (*VSphere, error) { | ||||
| 	var err error | ||||
| 	vs, err := buildVSphereFromConfig(cfg) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	vs.hostName, err = os.Hostname() | ||||
| 	if err != nil { | ||||
| 		glog.Errorf("Failed to get hostname. err: %+v", err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	vs.vmUUID, err = getVMUUID() | ||||
| 	if err != nil { | ||||
| 		glog.Errorf("Failed to get uuid. err: %+v", err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	runtime.SetFinalizer(vs, logout) | ||||
| 	return vs, nil | ||||
| } | ||||
|  | ||||
| // Initializes vSphere from vSphere CloudProvider Configuration | ||||
| func buildVSphereFromConfig(cfg VSphereConfig) (*VSphere, error) { | ||||
| 	isSecretInfoProvided := false | ||||
| 	if cfg.Global.SecretName != "" && cfg.Global.SecretNamespace != "" { | ||||
| 		isSecretInfoProvided = true | ||||
| 	} | ||||
|  | ||||
| 	if cfg.Disk.SCSIControllerType == "" { | ||||
| 		cfg.Disk.SCSIControllerType = vclib.PVSCSIControllerType | ||||
| @@ -394,20 +485,9 @@ func newControllerNode(cfg VSphereConfig) (*VSphere, error) { | ||||
| 			nodeInfoMap:        make(map[string]*NodeInfo), | ||||
| 			registeredNodes:    make(map[string]*v1.Node), | ||||
| 		}, | ||||
| 		cfg: &cfg, | ||||
| 		isSecretInfoProvided: isSecretInfoProvided, | ||||
| 		cfg:                  &cfg, | ||||
| 	} | ||||
|  | ||||
| 	vs.hostName, err = os.Hostname() | ||||
| 	if err != nil { | ||||
| 		glog.Errorf("Failed to get hostname. err: %+v", err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	vs.vmUUID, err = getVMUUID() | ||||
| 	if err != nil { | ||||
| 		glog.Errorf("Failed to get uuid. err: %+v", err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	runtime.SetFinalizer(&vs, logout) | ||||
| 	return &vs, nil | ||||
| } | ||||
|  | ||||
| @@ -480,7 +560,7 @@ func (vs *VSphere) getVSphereInstanceForServer(vcServer string, ctx context.Cont | ||||
| 		return nil, errors.New(fmt.Sprintf("Cannot find node %q in vsphere configuration map", vcServer)) | ||||
| 	} | ||||
| 	// Ensure client is logged in and session is valid | ||||
| 	err := vsphereIns.conn.Connect(ctx) | ||||
| 	err := vs.nodeManager.vcConnect(ctx, vsphereIns) | ||||
| 	if err != nil { | ||||
| 		glog.Errorf("failed connecting to vcServer %q with error %+v", vcServer, err) | ||||
| 		return nil, err | ||||
| @@ -519,7 +599,7 @@ func (vs *VSphere) NodeAddresses(ctx context.Context, nodeName k8stypes.NodeName | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// Ensure client is logged in and session is valid | ||||
| 	err = vsi.conn.Connect(ctx) | ||||
| 	err = vs.nodeManager.vcConnect(ctx, vsi) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -634,7 +714,7 @@ func (vs *VSphere) InstanceID(ctx context.Context, nodeName k8stypes.NodeName) ( | ||||
| 			return "", err | ||||
| 		} | ||||
| 		// Ensure client is logged in and session is valid | ||||
| 		err = vsi.conn.Connect(ctx) | ||||
| 		err = vs.nodeManager.vcConnect(ctx, vsi) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| @@ -725,7 +805,7 @@ func (vs *VSphere) AttachDisk(vmDiskPath string, storagePolicyName string, nodeN | ||||
| 			return "", err | ||||
| 		} | ||||
| 		// Ensure client is logged in and session is valid | ||||
| 		err = vsi.conn.Connect(ctx) | ||||
| 		err = vs.nodeManager.vcConnect(ctx, vsi) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
| @@ -792,7 +872,7 @@ func (vs *VSphere) DetachDisk(volPath string, nodeName k8stypes.NodeName) error | ||||
| 			return err | ||||
| 		} | ||||
| 		// Ensure client is logged in and session is valid | ||||
| 		err = vsi.conn.Connect(ctx) | ||||
| 		err = vs.nodeManager.vcConnect(ctx, vsi) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -847,7 +927,7 @@ func (vs *VSphere) DiskIsAttached(volPath string, nodeName k8stypes.NodeName) (b | ||||
| 			return false, err | ||||
| 		} | ||||
| 		// Ensure client is logged in and session is valid | ||||
| 		err = vsi.conn.Connect(ctx) | ||||
| 		err = vs.nodeManager.vcConnect(ctx, vsi) | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Abrar Shivani
					Abrar Shivani