2015-04-07 18:21:25 +00:00
|
|
|
/*
|
2016-06-03 00:25:58 +00:00
|
|
|
Copyright 2014 The Kubernetes Authors.
|
2015-04-07 18:21:25 +00:00
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package util
|
|
|
|
|
|
|
|
import (
|
2016-04-26 14:33:47 +00:00
|
|
|
fed_clientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset"
|
2015-11-13 21:20:54 +00:00
|
|
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
2016-01-13 22:40:56 +00:00
|
|
|
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
2016-09-08 14:24:02 +00:00
|
|
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
2016-02-12 18:58:43 +00:00
|
|
|
"k8s.io/kubernetes/pkg/client/restclient"
|
2015-08-13 19:01:50 +00:00
|
|
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
|
|
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
2015-04-07 18:21:25 +00:00
|
|
|
)
|
|
|
|
|
2015-08-10 20:05:57 +00:00
|
|
|
func NewClientCache(loader clientcmd.ClientConfig) *ClientCache {
|
|
|
|
return &ClientCache{
|
2016-09-08 14:24:02 +00:00
|
|
|
clientsets: make(map[unversioned.GroupVersion]*internalclientset.Clientset),
|
2016-04-26 14:33:47 +00:00
|
|
|
configs: make(map[unversioned.GroupVersion]*restclient.Config),
|
|
|
|
fedClientSets: make(map[unversioned.GroupVersion]fed_clientset.Interface),
|
|
|
|
loader: loader,
|
2015-06-13 02:06:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-10 20:05:57 +00:00
|
|
|
// ClientCache caches previously loaded clients for reuse, and ensures MatchServerVersion
|
2015-04-07 18:21:25 +00:00
|
|
|
// is invoked only once
|
2015-08-10 20:05:57 +00:00
|
|
|
type ClientCache struct {
|
2015-04-07 18:21:25 +00:00
|
|
|
loader clientcmd.ClientConfig
|
2016-09-08 14:24:02 +00:00
|
|
|
clientsets map[unversioned.GroupVersion]*internalclientset.Clientset
|
2016-04-26 14:33:47 +00:00
|
|
|
fedClientSets map[unversioned.GroupVersion]fed_clientset.Interface
|
2016-02-12 18:58:43 +00:00
|
|
|
configs map[unversioned.GroupVersion]*restclient.Config
|
|
|
|
defaultConfig *restclient.Config
|
2015-06-17 03:04:51 +00:00
|
|
|
defaultClient *client.Client
|
2015-04-07 18:21:25 +00:00
|
|
|
matchVersion bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// ClientConfigForVersion returns the correct config for a server
|
2016-02-12 18:58:43 +00:00
|
|
|
func (c *ClientCache) ClientConfigForVersion(version *unversioned.GroupVersion) (*restclient.Config, error) {
|
2015-04-07 18:21:25 +00:00
|
|
|
if c.defaultConfig == nil {
|
|
|
|
config, err := c.loader.ClientConfig()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
c.defaultConfig = config
|
|
|
|
if c.matchVersion {
|
2015-06-17 03:04:51 +00:00
|
|
|
if err := client.MatchesServerVersion(c.defaultClient, config); err != nil {
|
2015-04-07 18:21:25 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-12-08 20:14:38 +00:00
|
|
|
if version != nil {
|
|
|
|
if config, ok := c.configs[*version]; ok {
|
|
|
|
return config, nil
|
|
|
|
}
|
2015-06-13 02:06:18 +00:00
|
|
|
}
|
2015-12-08 20:14:38 +00:00
|
|
|
|
2015-04-07 18:21:25 +00:00
|
|
|
// TODO: have a better config copy method
|
|
|
|
config := *c.defaultConfig
|
2015-11-13 21:20:54 +00:00
|
|
|
|
|
|
|
// TODO these fall out when we finish the refactor
|
|
|
|
var preferredGV *unversioned.GroupVersion
|
2015-12-08 20:14:38 +00:00
|
|
|
if version != nil {
|
|
|
|
versionCopy := *version
|
|
|
|
preferredGV = &versionCopy
|
2015-11-13 21:20:54 +00:00
|
|
|
}
|
|
|
|
|
2016-07-18 14:46:48 +00:00
|
|
|
client.SetKubernetesDefaults(&config)
|
2015-12-19 05:08:34 +00:00
|
|
|
negotiatedVersion, err := client.NegotiateVersion(c.defaultClient, &config, preferredGV, registered.EnabledVersions())
|
2015-06-13 02:06:18 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2015-04-07 18:21:25 +00:00
|
|
|
}
|
2015-11-13 21:20:54 +00:00
|
|
|
config.GroupVersion = negotiatedVersion
|
2015-12-08 20:14:38 +00:00
|
|
|
|
|
|
|
if version != nil {
|
|
|
|
c.configs[*version] = &config
|
|
|
|
}
|
2015-04-07 18:21:25 +00:00
|
|
|
|
2015-11-10 14:16:23 +00:00
|
|
|
// `version` does not necessarily equal `config.Version`. However, we know that we call this method again with
|
2016-08-02 16:51:51 +00:00
|
|
|
// `config.Version`, we should get the config we've just built.
|
2015-11-10 14:16:23 +00:00
|
|
|
configCopy := config
|
2015-12-08 20:14:38 +00:00
|
|
|
c.configs[*config.GroupVersion] = &configCopy
|
2015-11-10 14:16:23 +00:00
|
|
|
|
2015-04-07 18:21:25 +00:00
|
|
|
return &config, nil
|
|
|
|
}
|
|
|
|
|
2016-09-08 14:24:02 +00:00
|
|
|
// 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 {
|
|
|
|
return clientset, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
config, err := c.ClientConfigForVersion(version)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
clientset, err := internalclientset.NewForConfig(config)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
c.clientsets[*config.GroupVersion] = clientset
|
|
|
|
|
|
|
|
// `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 {
|
|
|
|
configCopy := *config
|
|
|
|
clientset, err := internalclientset.NewForConfig(&configCopy)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
c.clientsets[*version] = clientset
|
|
|
|
}
|
|
|
|
|
|
|
|
return clientset, nil
|
|
|
|
}
|
|
|
|
|
2016-04-26 14:33:47 +00:00
|
|
|
func (c *ClientCache) FederationClientSetForVersion(version *unversioned.GroupVersion) (fed_clientset.Interface, error) {
|
|
|
|
if version != nil {
|
|
|
|
if clientSet, found := c.fedClientSets[*version]; found {
|
|
|
|
return clientSet, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
config, err := c.ClientConfigForVersion(version)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: support multi versions of client with clientset
|
|
|
|
clientSet, err := fed_clientset.NewForConfig(config)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
c.fedClientSets[*config.GroupVersion] = clientSet
|
|
|
|
|
|
|
|
if version != nil {
|
|
|
|
configCopy := *config
|
|
|
|
clientSet, err := fed_clientset.NewForConfig(&configCopy)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
c.fedClientSets[*version] = clientSet
|
|
|
|
}
|
|
|
|
|
|
|
|
return clientSet, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ClientCache) FederationClientForVersion(version *unversioned.GroupVersion) (*restclient.RESTClient, error) {
|
|
|
|
fedClientSet, err := c.FederationClientSetForVersion(version)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return fedClientSet.(*fed_clientset.Clientset).FederationClient.RESTClient, nil
|
|
|
|
}
|