From 792a2299362ebadc9ca68c72347884330db23b2a Mon Sep 17 00:00:00 2001 From: Di Xu Date: Mon, 4 Dec 2017 14:39:05 +0800 Subject: [PATCH] forbid unnamed context --- pkg/kubectl/cmd/config/use_context.go | 2 +- .../pkg/util/webhook/webhook_test.go | 13 ++++++--- .../client-go/tools/clientcmd/validation.go | 4 +++ .../tools/clientcmd/validation_test.go | 29 +++++++++++++++++++ 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/pkg/kubectl/cmd/config/use_context.go b/pkg/kubectl/cmd/config/use_context.go index 38f77eea2c3..c90165aff44 100644 --- a/pkg/kubectl/cmd/config/use_context.go +++ b/pkg/kubectl/cmd/config/use_context.go @@ -88,7 +88,7 @@ func (o *useContextOptions) complete(cmd *cobra.Command) error { func (o useContextOptions) validate(config *clientcmdapi.Config) error { if len(o.contextName) == 0 { - return errors.New("you must specify a current-context") + return errors.New("empty context names are not allowed") } for name := range config.Contexts { diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook_test.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook_test.go index f47e088beeb..3bda51bb894 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook_test.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook_test.go @@ -114,15 +114,15 @@ func TestKubeConfigFile(t *testing.T) { errRegex: errNoConfiguration, }, { - test: "missing context (specified context is missing)", - cluster: &namedCluster, - currentContext: "missing-context", - errRegex: errNoConfiguration, + test: "missing context (specified context is missing)", + cluster: &namedCluster, + errRegex: errNoConfiguration, }, { test: "context without cluster", context: &v1.NamedContext{ Context: v1.Context{}, + Name: "testing-context", }, currentContext: "testing-context", errRegex: errNoConfiguration, @@ -134,6 +134,7 @@ func TestKubeConfigFile(t *testing.T) { Context: v1.Context{ Cluster: namedCluster.Name, }, + Name: "testing-context", }, currentContext: "testing-context", errRegex: "", // Not an error at parse time, only when using the webhook @@ -145,6 +146,7 @@ func TestKubeConfigFile(t *testing.T) { Context: v1.Context{ Cluster: "missing-cluster", }, + Name: "fake", }, errRegex: errNoConfiguration, }, @@ -156,6 +158,7 @@ func TestKubeConfigFile(t *testing.T) { Cluster: namedCluster.Name, AuthInfo: "missing-user", }, + Name: "testing-context", }, currentContext: "testing-context", errRegex: "", // Not an error at parse time, only when using the webhook @@ -267,6 +270,8 @@ func TestKubeConfigFile(t *testing.T) { kubeConfig.AuthInfos = []v1.NamedAuthInfo{*tt.user} } + kubeConfig.CurrentContext = tt.currentContext + kubeConfigFile, err := newKubeConfigFile(kubeConfig) if err == nil { diff --git a/staging/src/k8s.io/client-go/tools/clientcmd/validation.go b/staging/src/k8s.io/client-go/tools/clientcmd/validation.go index 2bae0c395d2..4c7b15b78c2 100644 --- a/staging/src/k8s.io/client-go/tools/clientcmd/validation.go +++ b/staging/src/k8s.io/client-go/tools/clientcmd/validation.go @@ -253,6 +253,10 @@ func validateAuthInfo(authInfoName string, authInfo clientcmdapi.AuthInfo) []err func validateContext(contextName string, context clientcmdapi.Context, config clientcmdapi.Config) []error { validationErrors := make([]error, 0) + if len(contextName) == 0 { + validationErrors = append(validationErrors, fmt.Errorf("empty context name for %#v is not allowed", context)) + } + if len(context.AuthInfo) == 0 { validationErrors = append(validationErrors, fmt.Errorf("user was not specified for context %q", contextName)) } else if _, exists := config.AuthInfos[context.AuthInfo]; !exists { diff --git a/staging/src/k8s.io/client-go/tools/clientcmd/validation_test.go b/staging/src/k8s.io/client-go/tools/clientcmd/validation_test.go index 6441f148376..fcf86ab0a7f 100644 --- a/staging/src/k8s.io/client-go/tools/clientcmd/validation_test.go +++ b/staging/src/k8s.io/client-go/tools/clientcmd/validation_test.go @@ -62,6 +62,7 @@ func TestConfirmUsableBadInfoButOkConfig(t *testing.T) { okTest.testConfirmUsable("clean", t) badValidation.testConfig(t) } + func TestConfirmUsableBadInfoConfig(t *testing.T) { config := clientcmdapi.NewConfig() config.Clusters["missing ca"] = &clientcmdapi.Cluster{ @@ -83,6 +84,7 @@ func TestConfirmUsableBadInfoConfig(t *testing.T) { test.testConfirmUsable("first", t) } + func TestConfirmUsableEmptyConfig(t *testing.T) { config := clientcmdapi.NewConfig() test := configValidationTest{ @@ -92,6 +94,7 @@ func TestConfirmUsableEmptyConfig(t *testing.T) { test.testConfirmUsable("", t) } + func TestConfirmUsableMissingConfig(t *testing.T) { config := clientcmdapi.NewConfig() test := configValidationTest{ @@ -101,6 +104,7 @@ func TestConfirmUsableMissingConfig(t *testing.T) { test.testConfirmUsable("not-here", t) } + func TestValidateEmptyConfig(t *testing.T) { config := clientcmdapi.NewConfig() test := configValidationTest{ @@ -110,6 +114,7 @@ func TestValidateEmptyConfig(t *testing.T) { test.testConfig(t) } + func TestValidateMissingCurrentContextConfig(t *testing.T) { config := clientcmdapi.NewConfig() config.CurrentContext = "anything" @@ -120,6 +125,7 @@ func TestValidateMissingCurrentContextConfig(t *testing.T) { test.testConfig(t) } + func TestIsContextNotFound(t *testing.T) { config := clientcmdapi.NewConfig() config.CurrentContext = "anything" @@ -172,6 +178,7 @@ func TestValidateMissingReferencesConfig(t *testing.T) { test.testContext("anything", t) test.testConfig(t) } + func TestValidateEmptyContext(t *testing.T) { config := clientcmdapi.NewConfig() config.CurrentContext = "anything" @@ -185,6 +192,19 @@ func TestValidateEmptyContext(t *testing.T) { test.testConfig(t) } +func TestValidateEmptyContextName(t *testing.T) { + config := clientcmdapi.NewConfig() + config.CurrentContext = "anything" + config.Contexts[""] = &clientcmdapi.Context{Cluster: "missing", AuthInfo: "missing"} + test := configValidationTest{ + config: config, + expectedErrorSubstring: []string{"empty context name", "is not allowed"}, + } + + test.testContext("", t) + test.testConfig(t) +} + func TestValidateEmptyClusterInfo(t *testing.T) { config := clientcmdapi.NewConfig() config.Clusters["empty"] = clientcmdapi.NewCluster() @@ -223,6 +243,7 @@ func TestValidateMissingCAFileClusterInfo(t *testing.T) { test.testCluster("missing ca", t) test.testConfig(t) } + func TestValidateCleanClusterInfo(t *testing.T) { config := clientcmdapi.NewConfig() config.Clusters["clean"] = &clientcmdapi.Cluster{ @@ -235,6 +256,7 @@ func TestValidateCleanClusterInfo(t *testing.T) { test.testCluster("clean", t) test.testConfig(t) } + func TestValidateCleanWithCAClusterInfo(t *testing.T) { tempFile, _ := ioutil.TempFile("", "") defer os.Remove(tempFile.Name()) @@ -262,6 +284,7 @@ func TestValidateEmptyAuthInfo(t *testing.T) { test.testAuthInfo("error", t) test.testConfig(t) } + func TestValidateCertFilesNotFoundAuthInfo(t *testing.T) { config := clientcmdapi.NewConfig() config.AuthInfos["error"] = &clientcmdapi.AuthInfo{ @@ -276,6 +299,7 @@ func TestValidateCertFilesNotFoundAuthInfo(t *testing.T) { test.testAuthInfo("error", t) test.testConfig(t) } + func TestValidateCertDataOverridesFiles(t *testing.T) { tempFile, _ := ioutil.TempFile("", "") defer os.Remove(tempFile.Name()) @@ -295,6 +319,7 @@ func TestValidateCertDataOverridesFiles(t *testing.T) { test.testAuthInfo("clean", t) test.testConfig(t) } + func TestValidateCleanCertFilesAuthInfo(t *testing.T) { tempFile, _ := ioutil.TempFile("", "") defer os.Remove(tempFile.Name()) @@ -311,6 +336,7 @@ func TestValidateCleanCertFilesAuthInfo(t *testing.T) { test.testAuthInfo("clean", t) test.testConfig(t) } + func TestValidateCleanTokenAuthInfo(t *testing.T) { config := clientcmdapi.NewConfig() config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ @@ -363,6 +389,7 @@ func (c configValidationTest) testContext(contextName string, t *testing.T) { } } } + func (c configValidationTest) testConfirmUsable(contextName string, t *testing.T) { err := ConfirmUsable(*c.config, contextName) @@ -382,6 +409,7 @@ func (c configValidationTest) testConfirmUsable(contextName string, t *testing.T } } } + func (c configValidationTest) testConfig(t *testing.T) { err := Validate(*c.config) @@ -404,6 +432,7 @@ func (c configValidationTest) testConfig(t *testing.T) { } } } + func (c configValidationTest) testCluster(clusterName string, t *testing.T) { errs := validateClusterInfo(clusterName, *c.config.Clusters[clusterName])