clean up client version negotiation to handle no legacy API

This commit is contained in:
deads2k
2016-10-28 13:01:32 -04:00
parent 1cba31af40
commit bae940df5c
3 changed files with 104 additions and 106 deletions

View File

@@ -17,6 +17,8 @@ limitations under the License.
package util
import (
"sync"
fed_clientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered"
@@ -43,51 +45,75 @@ type ClientCache struct {
clientsets map[unversioned.GroupVersion]*internalclientset.Clientset
fedClientSets map[unversioned.GroupVersion]fed_clientset.Interface
configs map[unversioned.GroupVersion]*restclient.Config
defaultConfig *restclient.Config
// TODO this is only ever read. It should be moved to initialization at some point.
discoveryClient discovery.DiscoveryInterface
matchVersion bool
matchVersion bool
defaultConfigLock sync.Mutex
defaultConfig *restclient.Config
discoveryClient discovery.DiscoveryInterface
}
// also looks up the discovery client. We can't do this during init because the flags won't have been set
// because this is constructed pre-command execution before the command tree is even set up
func (c *ClientCache) getDefaultConfig() (restclient.Config, discovery.DiscoveryInterface, error) {
c.defaultConfigLock.Lock()
defer c.defaultConfigLock.Unlock()
if c.defaultConfig != nil && c.discoveryClient != nil {
return *c.defaultConfig, c.discoveryClient, nil
}
config, err := c.loader.ClientConfig()
if err != nil {
return restclient.Config{}, nil, err
}
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
return restclient.Config{}, nil, err
}
if c.matchVersion {
if err := discovery.MatchesServerVersion(discoveryClient); err != nil {
return restclient.Config{}, nil, err
}
}
c.defaultConfig = config
c.discoveryClient = discoveryClient
return *c.defaultConfig, c.discoveryClient, nil
}
// ClientConfigForVersion returns the correct config for a server
func (c *ClientCache) ClientConfigForVersion(version *unversioned.GroupVersion) (*restclient.Config, error) {
if c.defaultConfig == nil {
config, err := c.loader.ClientConfig()
if err != nil {
return nil, err
}
c.defaultConfig = config
if c.matchVersion {
if err := discovery.MatchesServerVersion(c.discoveryClient, config); err != nil {
return nil, err
}
}
func (c *ClientCache) ClientConfigForVersion(requiredVersion *unversioned.GroupVersion) (*restclient.Config, error) {
// TODO: have a better config copy method
config, discoveryClient, err := c.getDefaultConfig()
if err != nil {
return nil, err
}
if version != nil {
if config, ok := c.configs[*version]; ok {
if requiredVersion == nil && config.GroupVersion != nil {
// if someone has set the values via flags, our config will have the groupVersion set
// that means it is required.
requiredVersion = config.GroupVersion
}
// required version may still be nil, since config.GroupVersion may have been nil. Do the check
// before looking up from the cache
if requiredVersion != nil {
if config, ok := c.configs[*requiredVersion]; ok {
return config, nil
}
}
// TODO: have a better config copy method
config := *c.defaultConfig
// TODO these fall out when we finish the refactor
var preferredGV *unversioned.GroupVersion
if version != nil {
versionCopy := *version
preferredGV = &versionCopy
}
oldclient.SetKubernetesDefaults(&config)
negotiatedVersion, err := discovery.NegotiateVersion(c.discoveryClient, &config, preferredGV, registered.EnabledVersions())
negotiatedVersion, err := discovery.NegotiateVersion(discoveryClient, requiredVersion, registered.EnabledVersions())
if err != nil {
return nil, err
}
config.GroupVersion = negotiatedVersion
if version != nil {
c.configs[*version] = &config
// TODO this isn't what we want. Each clientset should be setting defaults as it sees fit.
oldclient.SetKubernetesDefaults(&config)
if requiredVersion != nil {
c.configs[*requiredVersion] = &config
}
// `version` does not necessarily equal `config.Version`. However, we know that we call this method again with
@@ -100,13 +126,13 @@ func (c *ClientCache) ClientConfigForVersion(version *unversioned.GroupVersion)
// ClientSetForVersion initializes or reuses a clientset for the specified version, or returns an
// error if that is not possible
func (c *ClientCache) ClientSetForVersion(version *unversioned.GroupVersion) (*internalclientset.Clientset, error) {
if version != nil {
if clientset, ok := c.clientsets[*version]; ok {
func (c *ClientCache) ClientSetForVersion(requiredVersion *unversioned.GroupVersion) (*internalclientset.Clientset, error) {
if requiredVersion != nil {
if clientset, ok := c.clientsets[*requiredVersion]; ok {
return clientset, nil
}
}
config, err := c.ClientConfigForVersion(version)
config, err := c.ClientConfigForVersion(requiredVersion)
if err != nil {
return nil, err
}
@@ -120,13 +146,13 @@ func (c *ClientCache) ClientSetForVersion(version *unversioned.GroupVersion) (*i
// `version` does not necessarily equal `config.Version`. However, we know that if we call this method again with
// `version`, we should get a client based on the same config we just found. There's no guarantee that a client
// is copiable, so create a new client and save it in the cache.
if version != nil {
if requiredVersion != nil {
configCopy := *config
clientset, err := internalclientset.NewForConfig(&configCopy)
if err != nil {
return nil, err
}
c.clientsets[*version] = clientset
c.clientsets[*requiredVersion] = clientset
}
return clientset, nil