-
Notifications
You must be signed in to change notification settings - Fork 39.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added ability for vSphere to reconnect on secret update #90836
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ import ( | |
"os" | ||
"path" | ||
"path/filepath" | ||
"reflect" | ||
"runtime" | ||
"strings" | ||
"sync" | ||
|
@@ -98,6 +99,7 @@ type VSphere struct { | |
nodeManager *NodeManager | ||
vmUUID string | ||
isSecretInfoProvided bool | ||
isSecretManaged bool | ||
} | ||
|
||
// Represents a vSphere instance where one or more kubernetes nodes are running. | ||
|
@@ -175,6 +177,8 @@ type VSphereConfig struct { | |
SecretName string `gcfg:"secret-name"` | ||
// Secret Namespace where secret will be present that has vCenter credentials. | ||
SecretNamespace string `gcfg:"secret-namespace"` | ||
// Secret changes being ingnored for cloud resources | ||
SecretNotManaged bool `gcfg:"secret-not-managed"` | ||
} | ||
|
||
VirtualCenter map[string]*VirtualCenterConfig | ||
|
@@ -276,6 +280,15 @@ func (vs *VSphere) SetInformers(informerFactory informers.SharedInformerFactory) | |
VirtualCenter: make(map[string]*Credential), | ||
}, | ||
} | ||
if vs.isSecretManaged { | ||
klog.V(4).Infof("Setting up secret informers for vSphere Cloud Provider") | ||
secretInformer := informerFactory.Core().V1().Secrets().Informer() | ||
secretInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ | ||
AddFunc: vs.SecretAdded, | ||
UpdateFunc: vs.SecretUpdated, | ||
}) | ||
klog.V(4).Infof("Secret informers in vSphere cloud provider initialized") | ||
} | ||
vs.nodeManager.UpdateCredentialManager(secretCredentialManager) | ||
} | ||
|
||
|
@@ -530,6 +543,7 @@ func buildVSphereFromConfig(cfg VSphereConfig) (*VSphere, error) { | |
registeredNodes: make(map[string]*v1.Node), | ||
}, | ||
isSecretInfoProvided: isSecretInfoProvided, | ||
isSecretManaged: !cfg.Global.SecretNotManaged, | ||
cfg: &cfg, | ||
} | ||
return &vs, nil | ||
|
@@ -1502,6 +1516,54 @@ func (vs *VSphere) NodeDeleted(obj interface{}) { | |
} | ||
} | ||
|
||
// Notification handler when credentials secret is added. | ||
func (vs *VSphere) SecretAdded(obj interface{}) { | ||
secret, ok := obj.(*v1.Secret) | ||
if secret == nil || !ok { | ||
klog.Warningf("Unrecognized secret object %T", obj) | ||
return | ||
} | ||
|
||
if secret.Name != vs.cfg.Global.SecretName || | ||
secret.Namespace != vs.cfg.Global.SecretNamespace { | ||
return | ||
} | ||
|
||
klog.V(4).Infof("secret added: %+v", obj) | ||
vs.refreshNodesForSecretChange() | ||
} | ||
|
||
// Notification handler when credentials secret is updated. | ||
func (vs *VSphere) SecretUpdated(obj interface{}, newObj interface{}) { | ||
oldSecret, ok := obj.(*v1.Secret) | ||
if oldSecret == nil || !ok { | ||
klog.Warningf("Unrecognized secret object %T", obj) | ||
return | ||
} | ||
|
||
secret, ok := newObj.(*v1.Secret) | ||
if secret == nil || !ok { | ||
klog.Warningf("Unrecognized secret object %T", newObj) | ||
return | ||
} | ||
|
||
if secret.Name != vs.cfg.Global.SecretName || | ||
secret.Namespace != vs.cfg.Global.SecretNamespace || | ||
reflect.DeepEqual(secret.Data, oldSecret.Data) { | ||
return | ||
} | ||
|
||
klog.V(4).Infof("secret updated: %+v", newObj) | ||
vs.refreshNodesForSecretChange() | ||
} | ||
|
||
func (vs *VSphere) refreshNodesForSecretChange() { | ||
err := vs.nodeManager.refreshNodes() | ||
if err != nil { | ||
klog.Errorf("failed to rediscover nodes: %v", err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. returning here without retry means a single node lookup failure will leave the remaining nodes in the list with stale credentials, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having and error here means that it failed during couple of retries while trying to (re)discover node, and update VM state, so this logic is already handled. |
||
} | ||
} | ||
|
||
func (vs *VSphere) NodeManager() (nodeManager *NodeManager) { | ||
if vs == nil { | ||
return nil | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all informers will get an added event at startup, which means we'll always trigger RediscoverNodes... is that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the issue faced by QE at some point. If some of the configuration is dedicated to the secret content, and there is another manager resource updating cluster configuration on config's content change, this part was left over, as nothing would recognize the secret being
added/updated/deleted