add namespace to kubeconfig file
This commit is contained in:
@@ -83,6 +83,8 @@ type Context struct {
|
||||
AuthInfo string `json:"user"`
|
||||
// Namespace is the default namespace to use on unspecified requests
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
// NamespacePath is the path to a kubernetes ns file (~/.kubernetes_ns)
|
||||
NamespacePath string `json:"namespace-path,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions map[string]runtime.EmbeddedObject `json:"extensions,omitempty"`
|
||||
}
|
||||
|
@@ -83,6 +83,8 @@ type Context struct {
|
||||
AuthInfo string `json:"user"`
|
||||
// Namespace is the default namespace to use on unspecified requests
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
// NamespacePath is the path to a kubernetes ns file (~/.kubernetes_ns)
|
||||
NamespacePath string `json:"namespace-path,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions []NamedExtension `json:"extensions,omitempty"`
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
|
||||
)
|
||||
|
||||
@@ -36,9 +37,12 @@ var (
|
||||
|
||||
// ClientConfig is used to make it easy to get an api server client
|
||||
type ClientConfig interface {
|
||||
// RawConfig returns the merged result of all overrides
|
||||
RawConfig() (clientcmdapi.Config, error)
|
||||
// ClientConfig returns a complete client config
|
||||
ClientConfig() (*client.Config, error)
|
||||
// Namespace returns the namespace resulting from the merged result of all overrides
|
||||
Namespace() (string, error)
|
||||
}
|
||||
|
||||
// DirectClientConfig is a ClientConfig interface that is backed by a clientcmdapi.Config, options overrides, and an optional fallbackReader for auth information
|
||||
@@ -226,6 +230,35 @@ func canIdentifyUser(config client.Config) bool {
|
||||
|
||||
}
|
||||
|
||||
// Namespace implements KubeConfig
|
||||
func (config DirectClientConfig) Namespace() (string, error) {
|
||||
if err := config.ConfirmUsable(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
configContext := config.getContext()
|
||||
|
||||
if len(configContext.Namespace) != 0 {
|
||||
return configContext.Namespace, nil
|
||||
}
|
||||
|
||||
if len(configContext.NamespacePath) != 0 {
|
||||
nsInfo, err := kubectl.LoadNamespaceInfo(configContext.NamespacePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return nsInfo.Namespace, nil
|
||||
}
|
||||
|
||||
// if nothing was specified, try the default file
|
||||
nsInfo, err := kubectl.LoadNamespaceInfo(os.Getenv("HOME") + "/.kubernetes_ns")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return nsInfo.Namespace, nil
|
||||
}
|
||||
|
||||
// ConfirmUsable looks a particular context and determines if that particular part of the config is useable. There might still be errors in the config,
|
||||
// but no errors in the sections requested or referenced. It does not return early so that it can find as many errors as possible.
|
||||
func (config DirectClientConfig) ConfirmUsable() error {
|
||||
@@ -248,21 +281,30 @@ func (config DirectClientConfig) getContextName() string {
|
||||
}
|
||||
|
||||
func (config DirectClientConfig) getAuthInfoName() string {
|
||||
if len(config.overrides.AuthInfoName) != 0 {
|
||||
return config.overrides.AuthInfoName
|
||||
if len(config.overrides.Context.AuthInfo) != 0 {
|
||||
return config.overrides.Context.AuthInfo
|
||||
}
|
||||
return config.getContext().AuthInfo
|
||||
}
|
||||
|
||||
func (config DirectClientConfig) getClusterName() string {
|
||||
if len(config.overrides.ClusterName) != 0 {
|
||||
return config.overrides.ClusterName
|
||||
if len(config.overrides.Context.Cluster) != 0 {
|
||||
return config.overrides.Context.Cluster
|
||||
}
|
||||
return config.getContext().Cluster
|
||||
}
|
||||
|
||||
func (config DirectClientConfig) getContext() clientcmdapi.Context {
|
||||
return config.config.Contexts[config.getContextName()]
|
||||
contexts := config.config.Contexts
|
||||
contextName := config.getContextName()
|
||||
|
||||
var mergedContext clientcmdapi.Context
|
||||
if configContext, exists := contexts[contextName]; exists {
|
||||
mergo.Merge(&mergedContext, configContext)
|
||||
}
|
||||
mergo.Merge(&mergedContext, config.overrides.Context)
|
||||
|
||||
return mergedContext
|
||||
}
|
||||
|
||||
func (config DirectClientConfig) getAuthInfo() clientcmdapi.AuthInfo {
|
||||
|
@@ -48,6 +48,24 @@ func createValidTestConfig() *clientcmdapi.Config {
|
||||
return config
|
||||
}
|
||||
|
||||
func TestMergeContext(t *testing.T) {
|
||||
const namespace = "overriden-namespace"
|
||||
|
||||
config := createValidTestConfig()
|
||||
clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{
|
||||
Context: clientcmdapi.Context{
|
||||
Namespace: namespace,
|
||||
},
|
||||
})
|
||||
|
||||
actual, err := clientBuilder.Namespace()
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
matchStringArg(namespace, actual, t)
|
||||
}
|
||||
|
||||
func TestCreateClean(t *testing.T) {
|
||||
config := createValidTestConfig()
|
||||
clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{})
|
||||
|
@@ -78,3 +78,13 @@ func (config DeferredLoadingClientConfig) ClientConfig() (*client.Config, error)
|
||||
|
||||
return mergedClientConfig.ClientConfig()
|
||||
}
|
||||
|
||||
// Namespace implements KubeConfig
|
||||
func (config DeferredLoadingClientConfig) Namespace() (string, error) {
|
||||
mergedKubeConfig, err := config.createClientConfig()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return mergedKubeConfig.Namespace()
|
||||
}
|
||||
|
@@ -27,10 +27,8 @@ import (
|
||||
type ConfigOverrides struct {
|
||||
AuthInfo clientcmdapi.AuthInfo
|
||||
ClusterInfo clientcmdapi.Cluster
|
||||
Namespace string
|
||||
Context clientcmdapi.Context
|
||||
CurrentContext string
|
||||
ClusterName string
|
||||
AuthInfoName string
|
||||
}
|
||||
|
||||
// ConfigOverrideFlags holds the flag names to be used for binding command line flags. Notice that this structure tightly
|
||||
@@ -38,10 +36,8 @@ type ConfigOverrides struct {
|
||||
type ConfigOverrideFlags struct {
|
||||
AuthOverrideFlags AuthOverrideFlags
|
||||
ClusterOverrideFlags ClusterOverrideFlags
|
||||
Namespace string
|
||||
ContextOverrideFlags ContextOverrideFlags
|
||||
CurrentContext string
|
||||
ClusterName string
|
||||
AuthInfoName string
|
||||
}
|
||||
|
||||
// AuthOverrideFlags holds the flag names to be used for binding command line flags for AuthInfo objects
|
||||
@@ -52,6 +48,14 @@ type AuthOverrideFlags struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
// ContextOverrideFlags holds the flag names to be used for binding command line flags for Cluster objects
|
||||
type ContextOverrideFlags struct {
|
||||
ClusterName string
|
||||
AuthInfoName string
|
||||
Namespace string
|
||||
NamespacePath string
|
||||
}
|
||||
|
||||
// ClusterOverride holds the flag names to be used for binding command line flags for Cluster objects
|
||||
type ClusterOverrideFlags struct {
|
||||
APIServer string
|
||||
@@ -61,18 +65,19 @@ type ClusterOverrideFlags struct {
|
||||
}
|
||||
|
||||
const (
|
||||
FlagClusterName = "cluster"
|
||||
FlagAuthInfoName = "user"
|
||||
FlagContext = "context"
|
||||
FlagNamespace = "namespace"
|
||||
FlagAPIServer = "server"
|
||||
FlagAPIVersion = "api-version"
|
||||
FlagAuthPath = "auth-path"
|
||||
FlagInsecure = "insecure-skip-tls-verify"
|
||||
FlagCertFile = "client-certificate"
|
||||
FlagKeyFile = "client-key"
|
||||
FlagCAFile = "certificate-authority"
|
||||
FlagBearerToken = "token"
|
||||
FlagClusterName = "cluster"
|
||||
FlagAuthInfoName = "user"
|
||||
FlagContext = "context"
|
||||
FlagNamespace = "namespace"
|
||||
FlagNamespacePath = "ns-path"
|
||||
FlagAPIServer = "server"
|
||||
FlagAPIVersion = "api-version"
|
||||
FlagAuthPath = "auth-path"
|
||||
FlagInsecure = "insecure-skip-tls-verify"
|
||||
FlagCertFile = "client-certificate"
|
||||
FlagKeyFile = "client-key"
|
||||
FlagCAFile = "certificate-authority"
|
||||
FlagBearerToken = "token"
|
||||
)
|
||||
|
||||
// RecommendedAuthOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
|
||||
@@ -100,10 +105,18 @@ func RecommendedConfigOverrideFlags(prefix string) ConfigOverrideFlags {
|
||||
return ConfigOverrideFlags{
|
||||
AuthOverrideFlags: RecommendedAuthOverrideFlags(prefix),
|
||||
ClusterOverrideFlags: RecommendedClusterOverrideFlags(prefix),
|
||||
Namespace: prefix + FlagNamespace,
|
||||
ContextOverrideFlags: RecommendedContextOverrideFlags(prefix),
|
||||
CurrentContext: prefix + FlagContext,
|
||||
ClusterName: prefix + FlagClusterName,
|
||||
AuthInfoName: prefix + FlagAuthInfoName,
|
||||
}
|
||||
}
|
||||
|
||||
// RecommendedContextOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
|
||||
func RecommendedContextOverrideFlags(prefix string) ContextOverrideFlags {
|
||||
return ContextOverrideFlags{
|
||||
ClusterName: prefix + FlagClusterName,
|
||||
AuthInfoName: prefix + FlagAuthInfoName,
|
||||
Namespace: prefix + FlagNamespace,
|
||||
NamespacePath: prefix + FlagNamespacePath,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,9 +142,14 @@ func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, f
|
||||
func BindOverrideFlags(overrides *ConfigOverrides, flags *pflag.FlagSet, flagNames ConfigOverrideFlags) {
|
||||
BindAuthInfoFlags(&overrides.AuthInfo, flags, flagNames.AuthOverrideFlags)
|
||||
BindClusterFlags(&overrides.ClusterInfo, flags, flagNames.ClusterOverrideFlags)
|
||||
// TODO not integrated yet
|
||||
// flags.StringVar(&overrides.Namespace, flagNames.Namespace, "", "If present, the namespace scope for this CLI request.")
|
||||
BindContextFlags(&overrides.Context, flags, flagNames.ContextOverrideFlags)
|
||||
flags.StringVar(&overrides.CurrentContext, flagNames.CurrentContext, "", "The name of the kubeconfig context to use")
|
||||
flags.StringVar(&overrides.ClusterName, flagNames.ClusterName, "", "The name of the kubeconfig cluster to use")
|
||||
flags.StringVar(&overrides.AuthInfoName, flagNames.AuthInfoName, "", "The name of the kubeconfig user to use")
|
||||
}
|
||||
|
||||
// BindFlags is a convenience method to bind the specified flags to their associated variables
|
||||
func BindContextFlags(contextInfo *clientcmdapi.Context, flags *pflag.FlagSet, flagNames ContextOverrideFlags) {
|
||||
flags.StringVar(&contextInfo.Cluster, flagNames.ClusterName, "", "The name of the kubeconfig cluster to use")
|
||||
flags.StringVar(&contextInfo.AuthInfo, flagNames.AuthInfoName, "", "The name of the kubeconfig user to use")
|
||||
flags.StringVar(&contextInfo.Namespace, flagNames.Namespace, "", "If present, the namespace scope for this CLI request.")
|
||||
flags.StringVar(&contextInfo.NamespacePath, flagNames.NamespacePath, "", "Path to the namespace info file that holds the namespace context to use for CLI requests.")
|
||||
}
|
||||
|
Reference in New Issue
Block a user