mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Add secrets flag in vcp config and modify vcp to use nodemanger connect method
This commit is contained in:
parent
21a7e9b1cb
commit
6c9558334e
@ -61,6 +61,18 @@ var datastoreFolderIDMap = make(map[string]map[string]string)
|
|||||||
var cleanUpRoutineInitLock sync.Mutex
|
var cleanUpRoutineInitLock sync.Mutex
|
||||||
var cleanUpDummyVMLock sync.RWMutex
|
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.
|
// VSphere is an implementation of cloud provider Interface for VSphere.
|
||||||
type VSphere struct {
|
type VSphere struct {
|
||||||
cfg *VSphereConfig
|
cfg *VSphereConfig
|
||||||
@ -68,8 +80,9 @@ type VSphere struct {
|
|||||||
// Maps the VSphere IP address to VSphereInstance
|
// Maps the VSphere IP address to VSphereInstance
|
||||||
vsphereInstanceMap map[string]*VSphereInstance
|
vsphereInstanceMap map[string]*VSphereInstance
|
||||||
// Responsible for managing discovery of k8s node, their location etc.
|
// Responsible for managing discovery of k8s node, their location etc.
|
||||||
nodeManager *NodeManager
|
nodeManager *NodeManager
|
||||||
vmUUID string
|
vmUUID string
|
||||||
|
isSecretInfoProvided bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Represents a vSphere instance where one or more kubernetes nodes are running.
|
// 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.
|
// Combining the WorkingDir and VMName can form a unique InstanceID.
|
||||||
// When vm-name is set, no username/password is required on worker nodes.
|
// When vm-name is set, no username/password is required on worker nodes.
|
||||||
VMName string `gcfg:"vm-name"`
|
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
|
VirtualCenter map[string]*VirtualCenterConfig
|
||||||
@ -217,6 +234,18 @@ func (vs *VSphere) SetInformers(informerFactory informers.SharedInformerFactory)
|
|||||||
return
|
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.
|
// Only on controller node it is required to register listeners.
|
||||||
// Register callbacks for node updates
|
// Register callbacks for node updates
|
||||||
glog.V(4).Infof("Setting up node informers for vSphere Cloud Provider")
|
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,
|
DeleteFunc: vs.NodeDeleted,
|
||||||
})
|
})
|
||||||
glog.V(4).Infof("Node informers in vSphere cloud provider initialized")
|
glog.V(4).Infof("Node informers in vSphere cloud provider initialized")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates new worker node interface and returns
|
// Creates new worker node interface and returns
|
||||||
@ -247,19 +277,40 @@ func newWorkerNode() (*VSphere, error) {
|
|||||||
|
|
||||||
func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance, error) {
|
func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance, error) {
|
||||||
vsphereInstanceMap := make(map[string]*VSphereInstance)
|
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
|
// Check if the vsphere.conf is in old format. In this
|
||||||
// format the cfg.VirtualCenter will be nil or empty.
|
// format the cfg.VirtualCenter will be nil or empty.
|
||||||
if cfg.VirtualCenter == nil || len(cfg.VirtualCenter) == 0 {
|
if cfg.VirtualCenter == nil || len(cfg.VirtualCenter) == 0 {
|
||||||
glog.V(4).Infof("Config is not per virtual center and is in old format.")
|
glog.V(4).Infof("Config is not per virtual center and is in old format.")
|
||||||
if cfg.Global.User == "" {
|
if !isSecretInfoProvided {
|
||||||
glog.Error("Global.User is empty!")
|
if cfg.Global.User == "" {
|
||||||
return nil, errors.New("Global.User is empty!")
|
glog.Error("Global.User is empty!")
|
||||||
}
|
return nil, ErrUsernameMissing
|
||||||
if cfg.Global.Password == "" {
|
}
|
||||||
glog.Error("Global.Password is empty!")
|
if cfg.Global.Password == "" {
|
||||||
return nil, errors.New("Global.Password is empty!")
|
glog.Error("Global.Password is empty!")
|
||||||
|
return nil, ErrPasswordMissing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Global.WorkingDir == "" {
|
if cfg.Global.WorkingDir == "" {
|
||||||
glog.Error("Global.WorkingDir is empty!")
|
glog.Error("Global.WorkingDir is empty!")
|
||||||
return nil, errors.New("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,
|
RoundTripperCount: cfg.Global.RoundTripperCount,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: If secrets info is provided username and password will be populated
|
||||||
|
// once secret is created.
|
||||||
vSphereConn := vclib.VSphereConnection{
|
vSphereConn := vclib.VSphereConnection{
|
||||||
Username: vcConfig.User,
|
Username: vcConfig.User,
|
||||||
Password: vcConfig.Password,
|
Password: vcConfig.Password,
|
||||||
@ -305,31 +358,44 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance
|
|||||||
glog.Error(msg)
|
glog.Error(msg)
|
||||||
return nil, errors.New(msg)
|
return nil, errors.New(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
for vcServer, vcConfig := range cfg.VirtualCenter {
|
for vcServer, vcConfig := range cfg.VirtualCenter {
|
||||||
glog.V(4).Infof("Initializing vc server %s", vcServer)
|
glog.V(4).Infof("Initializing vc server %s", vcServer)
|
||||||
if vcServer == "" {
|
if vcServer == "" {
|
||||||
glog.Error("vsphere.conf does not have the VirtualCenter IP address specified")
|
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")
|
return nil, errors.New("vsphere.conf does not have the VirtualCenter IP address specified")
|
||||||
}
|
}
|
||||||
if vcConfig.User == "" {
|
|
||||||
vcConfig.User = cfg.Global.User
|
if !isSecretInfoProvided {
|
||||||
}
|
if vcConfig.User == "" {
|
||||||
if vcConfig.Password == "" {
|
vcConfig.User = cfg.Global.User
|
||||||
vcConfig.Password = cfg.Global.Password
|
if vcConfig.User == "" {
|
||||||
}
|
glog.Errorf("vcConfig.User is empty for vc %s!", vcServer)
|
||||||
if vcConfig.User == "" {
|
return nil, ErrUsernameMissing
|
||||||
msg := fmt.Sprintf("vcConfig.User is empty for vc %s!", vcServer)
|
}
|
||||||
glog.Error(msg)
|
}
|
||||||
return nil, errors.New(msg)
|
if vcConfig.Password == "" {
|
||||||
}
|
vcConfig.Password = cfg.Global.Password
|
||||||
if vcConfig.Password == "" {
|
if vcConfig.Password == "" {
|
||||||
msg := fmt.Sprintf("vcConfig.Password is empty for vc %s!", vcServer)
|
glog.Errorf("vcConfig.Password is empty for vc %s!", vcServer)
|
||||||
glog.Error(msg)
|
return nil, ErrPasswordMissing
|
||||||
return nil, errors.New(msg)
|
}
|
||||||
|
}
|
||||||
|
} 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 == "" {
|
if vcConfig.VCenterPort == "" {
|
||||||
vcConfig.VCenterPort = cfg.Global.VCenterPort
|
vcConfig.VCenterPort = cfg.Global.VCenterPort
|
||||||
}
|
}
|
||||||
|
|
||||||
if vcConfig.Datacenters == "" {
|
if vcConfig.Datacenters == "" {
|
||||||
if cfg.Global.Datacenters != "" {
|
if cfg.Global.Datacenters != "" {
|
||||||
vcConfig.Datacenters = cfg.Global.Datacenters
|
vcConfig.Datacenters = cfg.Global.Datacenters
|
||||||
@ -342,6 +408,8 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance
|
|||||||
vcConfig.RoundTripperCount = cfg.Global.RoundTripperCount
|
vcConfig.RoundTripperCount = cfg.Global.RoundTripperCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: If secrets info is provided username and password will be populated
|
||||||
|
// once secret is created.
|
||||||
vSphereConn := vclib.VSphereConnection{
|
vSphereConn := vclib.VSphereConnection{
|
||||||
Username: vcConfig.User,
|
Username: vcConfig.User,
|
||||||
Password: vcConfig.Password,
|
Password: vcConfig.Password,
|
||||||
@ -365,7 +433,30 @@ var getVMUUID = GetVMUUID
|
|||||||
|
|
||||||
// Creates new Controller node interface and returns
|
// Creates new Controller node interface and returns
|
||||||
func newControllerNode(cfg VSphereConfig) (*VSphere, error) {
|
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 == "" {
|
if cfg.Disk.SCSIControllerType == "" {
|
||||||
cfg.Disk.SCSIControllerType = vclib.PVSCSIControllerType
|
cfg.Disk.SCSIControllerType = vclib.PVSCSIControllerType
|
||||||
@ -394,20 +485,9 @@ func newControllerNode(cfg VSphereConfig) (*VSphere, error) {
|
|||||||
nodeInfoMap: make(map[string]*NodeInfo),
|
nodeInfoMap: make(map[string]*NodeInfo),
|
||||||
registeredNodes: make(map[string]*v1.Node),
|
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
|
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))
|
return nil, errors.New(fmt.Sprintf("Cannot find node %q in vsphere configuration map", vcServer))
|
||||||
}
|
}
|
||||||
// Ensure client is logged in and session is valid
|
// Ensure client is logged in and session is valid
|
||||||
err := vsphereIns.conn.Connect(ctx)
|
err := vs.nodeManager.vcConnect(ctx, vsphereIns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("failed connecting to vcServer %q with error %+v", vcServer, err)
|
glog.Errorf("failed connecting to vcServer %q with error %+v", vcServer, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -519,7 +599,7 @@ func (vs *VSphere) NodeAddresses(ctx context.Context, nodeName k8stypes.NodeName
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Ensure client is logged in and session is valid
|
// Ensure client is logged in and session is valid
|
||||||
err = vsi.conn.Connect(ctx)
|
err = vs.nodeManager.vcConnect(ctx, vsi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -634,7 +714,7 @@ func (vs *VSphere) InstanceID(ctx context.Context, nodeName k8stypes.NodeName) (
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
// Ensure client is logged in and session is valid
|
// Ensure client is logged in and session is valid
|
||||||
err = vsi.conn.Connect(ctx)
|
err = vs.nodeManager.vcConnect(ctx, vsi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -725,7 +805,7 @@ func (vs *VSphere) AttachDisk(vmDiskPath string, storagePolicyName string, nodeN
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
// Ensure client is logged in and session is valid
|
// Ensure client is logged in and session is valid
|
||||||
err = vsi.conn.Connect(ctx)
|
err = vs.nodeManager.vcConnect(ctx, vsi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -792,7 +872,7 @@ func (vs *VSphere) DetachDisk(volPath string, nodeName k8stypes.NodeName) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Ensure client is logged in and session is valid
|
// Ensure client is logged in and session is valid
|
||||||
err = vsi.conn.Connect(ctx)
|
err = vs.nodeManager.vcConnect(ctx, vsi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -847,7 +927,7 @@ func (vs *VSphere) DiskIsAttached(volPath string, nodeName k8stypes.NodeName) (b
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
// Ensure client is logged in and session is valid
|
// Ensure client is logged in and session is valid
|
||||||
err = vsi.conn.Connect(ctx)
|
err = vs.nodeManager.vcConnect(ctx, vsi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user