Updating the federation cluster controller to use secretRef to contact the server

This commit is contained in:
nikhiljindal 2016-05-23 20:20:27 -07:00
parent 236eb42664
commit 9b604242c6
4 changed files with 87 additions and 14 deletions

View File

@ -17,7 +17,9 @@ limitations under the License.
package cluster package cluster
import ( import (
"fmt"
"net" "net"
"os"
"strings" "strings"
federation_v1alpha1 "k8s.io/kubernetes/federation/apis/federation/v1alpha1" federation_v1alpha1 "k8s.io/kubernetes/federation/apis/federation/v1alpha1"
@ -25,14 +27,17 @@ import (
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/typed/discovery" "k8s.io/kubernetes/pkg/client/typed/discovery"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
utilnet "k8s.io/kubernetes/pkg/util/net" utilnet "k8s.io/kubernetes/pkg/util/net"
) )
const ( const (
UserAgentName = "Cluster-Controller" UserAgentName = "Cluster-Controller"
KubeAPIQPS = 20.0 KubeAPIQPS = 20.0
KubeAPIBurst = 30 KubeAPIBurst = 30
KubeconfigSecretDataKey = "kubeconfig"
) )
type ClusterClient struct { type ClusterClient struct {
@ -59,7 +64,29 @@ func NewClusterClientSet(c *federation_v1alpha1.Cluster) (*ClusterClient, error)
} }
var clusterClientSet = ClusterClient{} var clusterClientSet = ClusterClient{}
if serverAddress != "" { if serverAddress != "" {
clusterConfig, err := clientcmd.BuildConfigFromFlags(serverAddress, "") // Get a client to talk to the k8s apiserver, to fetch secrets from it.
client, err := client.NewInCluster()
if err != nil {
return nil, fmt.Errorf("error in creating in-cluster client: %s", err)
}
kubeconfigGetter := func() (*clientcmdapi.Config, error) {
// Get the namespace this is running in from the env variable.
namespace := os.Getenv("POD_NAMESPACE")
if namespace == "" {
return nil, fmt.Errorf("unexpected: POD_NAMESPACE env var returned empty string")
}
secret, err := client.Secrets(namespace).Get(c.Spec.SecretRef.Name)
if err != nil {
return nil, fmt.Errorf("error in fetching secret: %s", err)
}
data, ok := secret.Data[KubeconfigSecretDataKey]
if !ok {
return nil, fmt.Errorf("secret does not have data with key: %s", KubeconfigSecretDataKey)
}
return clientcmd.Load(data)
}
clusterConfig, err := clientcmd.BuildConfigFromKubeconfigGetter(serverAddress, kubeconfigGetter)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -399,3 +399,12 @@ func BuildConfigFromFlags(masterUrl, kubeconfigPath string) (*restclient.Config,
&ClientConfigLoadingRules{ExplicitPath: kubeconfigPath}, &ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
&ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}}).ClientConfig() &ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}}).ClientConfig()
} }
// BuildConfigFromKubeconfigGetter is a helper function that builds configs from a master
// url and a kubeconfigGetter.
func BuildConfigFromKubeconfigGetter(masterUrl string, kubeconfigGetter KubeconfigGetter) (*restclient.Config, error) {
cc := NewNonInteractiveDeferredLoadingClientConfig(
&ClientConfigGetter{kubeconfigGetter: kubeconfigGetter},
&ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}})
return cc.ClientConfig()
}

View File

@ -63,6 +63,40 @@ func currentMigrationRules() map[string]string {
return migrationRules return migrationRules
} }
type ClientConfigLoader interface {
ConfigAccess
Load() (*clientcmdapi.Config, error)
}
type KubeconfigGetter func() (*clientcmdapi.Config, error)
type ClientConfigGetter struct {
kubeconfigGetter KubeconfigGetter
}
// ClientConfigGetter implements the ClientConfigLoader interface.
var _ ClientConfigLoader = &ClientConfigGetter{}
func (g *ClientConfigGetter) Load() (*clientcmdapi.Config, error) {
return g.kubeconfigGetter()
}
func (g *ClientConfigGetter) GetLoadingPrecedence() []string {
return nil
}
func (g *ClientConfigGetter) GetStartingConfig() (*clientcmdapi.Config, error) {
return nil, nil
}
func (g *ClientConfigGetter) GetDefaultFilename() string {
return ""
}
func (g *ClientConfigGetter) IsExplicitFile() bool {
return false
}
func (g *ClientConfigGetter) GetExplicitFile() string {
return ""
}
// ClientConfigLoadingRules is an ExplicitPath and string slice of specific locations that are used for merging together a Config // ClientConfigLoadingRules is an ExplicitPath and string slice of specific locations that are used for merging together a Config
// Callers can put the chain together however they want, but we'd recommend: // Callers can put the chain together however they want, but we'd recommend:
// EnvVarPathFiles if set (a list of files if set) OR the HomeDirectoryPath // EnvVarPathFiles if set (a list of files if set) OR the HomeDirectoryPath
@ -80,6 +114,9 @@ type ClientConfigLoadingRules struct {
DoNotResolvePaths bool DoNotResolvePaths bool
} }
// ClientConfigLoadingRules implements the ClientConfigLoader interface.
var _ ClientConfigLoader = &ClientConfigLoadingRules{}
// NewDefaultClientConfigLoadingRules returns a ClientConfigLoadingRules object with default fields filled in. You are not required to // NewDefaultClientConfigLoadingRules returns a ClientConfigLoadingRules object with default fields filled in. You are not required to
// use this constructor // use this constructor
func NewDefaultClientConfigLoadingRules() *ClientConfigLoadingRules { func NewDefaultClientConfigLoadingRules() *ClientConfigLoadingRules {

View File

@ -27,13 +27,13 @@ import (
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
) )
// DeferredLoadingClientConfig is a ClientConfig interface that is backed by a set of loading rules // DeferredLoadingClientConfig is a ClientConfig interface that is backed by a client config loader.
// It is used in cases where the loading rules may change after you've instantiated them and you want to be sure that // It is used in cases where the loading rules may change after you've instantiated them and you want to be sure that
// the most recent rules are used. This is useful in cases where you bind flags to loading rule parameters before // the most recent rules are used. This is useful in cases where you bind flags to loading rule parameters before
// the parse happens and you want your calling code to be ignorant of how the values are being mutated to avoid // the parse happens and you want your calling code to be ignorant of how the values are being mutated to avoid
// passing extraneous information down a call stack // passing extraneous information down a call stack
type DeferredLoadingClientConfig struct { type DeferredLoadingClientConfig struct {
loadingRules *ClientConfigLoadingRules loader ClientConfigLoader
overrides *ConfigOverrides overrides *ConfigOverrides
fallbackReader io.Reader fallbackReader io.Reader
@ -42,13 +42,13 @@ type DeferredLoadingClientConfig struct {
} }
// NewNonInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name // NewNonInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name
func NewNonInteractiveDeferredLoadingClientConfig(loadingRules *ClientConfigLoadingRules, overrides *ConfigOverrides) ClientConfig { func NewNonInteractiveDeferredLoadingClientConfig(loader ClientConfigLoader, overrides *ConfigOverrides) ClientConfig {
return &DeferredLoadingClientConfig{loadingRules: loadingRules, overrides: overrides} return &DeferredLoadingClientConfig{loader: loader, overrides: overrides}
} }
// NewInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name and the fallback auth reader // NewInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name and the fallback auth reader
func NewInteractiveDeferredLoadingClientConfig(loadingRules *ClientConfigLoadingRules, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig { func NewInteractiveDeferredLoadingClientConfig(loader ClientConfigLoader, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
return &DeferredLoadingClientConfig{loadingRules: loadingRules, overrides: overrides, fallbackReader: fallbackReader} return &DeferredLoadingClientConfig{loader: loader, overrides: overrides, fallbackReader: fallbackReader}
} }
func (config *DeferredLoadingClientConfig) createClientConfig() (ClientConfig, error) { func (config *DeferredLoadingClientConfig) createClientConfig() (ClientConfig, error) {
@ -57,16 +57,16 @@ func (config *DeferredLoadingClientConfig) createClientConfig() (ClientConfig, e
defer config.loadingLock.Unlock() defer config.loadingLock.Unlock()
if config.clientConfig == nil { if config.clientConfig == nil {
mergedConfig, err := config.loadingRules.Load() mergedConfig, err := config.loader.Load()
if err != nil { if err != nil {
return nil, err return nil, err
} }
var mergedClientConfig ClientConfig var mergedClientConfig ClientConfig
if config.fallbackReader != nil { if config.fallbackReader != nil {
mergedClientConfig = NewInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.fallbackReader, config.loadingRules) mergedClientConfig = NewInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.fallbackReader, config.loader)
} else { } else {
mergedClientConfig = NewNonInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.loadingRules) mergedClientConfig = NewNonInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.loader)
} }
config.clientConfig = mergedClientConfig config.clientConfig = mergedClientConfig
@ -118,5 +118,5 @@ func (config *DeferredLoadingClientConfig) Namespace() (string, bool, error) {
// ConfigAccess implements ClientConfig // ConfigAccess implements ClientConfig
func (config *DeferredLoadingClientConfig) ConfigAccess() ConfigAccess { func (config *DeferredLoadingClientConfig) ConfigAccess() ConfigAccess {
return config.loadingRules return config.loader
} }