From 0b348d7441fcb48f1e94d36b223674ad8251f9c6 Mon Sep 17 00:00:00 2001 From: "Zida (Edward)" Date: Wed, 17 Jul 2019 17:21:27 +0800 Subject: [PATCH] Support multi config files (#222) * Handle error for multi config files over `--kubeconfig` flag * Add test cases for multi configs * Refactor type cases --- pkg/kn/commands/namespaced.go | 7 ++- pkg/kn/commands/types.go | 42 +++++++++++--- pkg/kn/commands/types_test.go | 106 ++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 pkg/kn/commands/types_test.go diff --git a/pkg/kn/commands/namespaced.go b/pkg/kn/commands/namespaced.go index e37fa3ebf..414976b17 100644 --- a/pkg/kn/commands/namespaced.go +++ b/pkg/kn/commands/namespaced.go @@ -63,12 +63,17 @@ func (params *KnParams) GetNamespace(cmd *cobra.Command) (string, error) { return namespace, nil } +// CurrentNamespace returns the current namespace which is either provided as option or picked up from kubeconfig func (params *KnParams) CurrentNamespace() (string, error) { + var err error if params.fixedCurrentNamespace != "" { return params.fixedCurrentNamespace, nil } if params.ClientConfig == nil { - params.ClientConfig = params.GetClientConfig() + params.ClientConfig, err = params.GetClientConfig() + if err != nil { + return "", err + } } name, _, err := params.ClientConfig.Namespace() return name, err diff --git a/pkg/kn/commands/types.go b/pkg/kn/commands/types.go index 80ff7afe3..bd06d1f84 100644 --- a/pkg/kn/commands/types.go +++ b/pkg/kn/commands/types.go @@ -15,7 +15,11 @@ package commands import ( + "errors" + "fmt" "io" + "os" + "path/filepath" serving_kn_v1alpha1 "github.com/knative/client/pkg/serving/v1alpha1" @@ -51,11 +55,17 @@ func (params *KnParams) newClient(namespace string) (serving_kn_v1alpha1.KnClien return serving_kn_v1alpha1.NewKnServingClient(client, namespace), nil } +// GetConfig returns Serving Client func (params *KnParams) GetConfig() (serving_v1alpha1_client.ServingV1alpha1Interface, error) { - if params.ClientConfig == nil { - params.ClientConfig = params.GetClientConfig() - } var err error + + if params.ClientConfig == nil { + params.ClientConfig, err = params.GetClientConfig() + if err != nil { + return nil, err + } + } + config, err := params.ClientConfig.ClientConfig() if err != nil { return nil, err @@ -63,10 +73,28 @@ func (params *KnParams) GetConfig() (serving_v1alpha1_client.ServingV1alpha1Inte return serving_v1alpha1_client.NewForConfig(config) } -func (params *KnParams) GetClientConfig() clientcmd.ClientConfig { +// GetClientConfig gets ClientConfig from KubeCfgPath +func (params *KnParams) GetClientConfig() (clientcmd.ClientConfig, error) { loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - if len(params.KubeCfgPath) > 0 { - loadingRules.ExplicitPath = params.KubeCfgPath + if len(params.KubeCfgPath) == 0 { + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}), nil + } + + _, err := os.Stat(params.KubeCfgPath) + if err == nil { + loadingRules.ExplicitPath = params.KubeCfgPath + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}), nil + } + + if !os.IsNotExist(err) { + return nil, err + } + + paths := filepath.SplitList(params.KubeCfgPath) + if len(paths) > 1 { + return nil, errors.New(fmt.Sprintf("Can not find config file. '%s' looks like a path. "+ + "Please use the env var KUBECONFIG if you want to check for multiple configuration files", params.KubeCfgPath)) + } else { + return nil, errors.New(fmt.Sprintf("Config file '%s' can not be found", params.KubeCfgPath)) } - return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) } diff --git a/pkg/kn/commands/types_test.go b/pkg/kn/commands/types_test.go new file mode 100644 index 000000000..2ea70296e --- /dev/null +++ b/pkg/kn/commands/types_test.go @@ -0,0 +1,106 @@ +// Copyright © 2019 The Knative Authors +// +// 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 commands + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/knative/client/pkg/util" + "gotest.tools/assert" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" +) + +type getConfigTestCase struct { + clientConfig clientcmd.ClientConfig + expectedErrString string +} + +func TestGetConfig(t *testing.T) { + for i, tc := range []getConfigTestCase{ + { + clientcmd.NewDefaultClientConfig(clientcmdapi.Config{}, &clientcmd.ConfigOverrides{}), + "no configuration has been provided", + }, + } { + p := &KnParams{ + ClientConfig: tc.clientConfig} + + _, err := p.GetConfig() + + switch len(tc.expectedErrString) { + case 0: + if err != nil { + t.Errorf("%d: unexpected error: %s", i, err.Error()) + } + default: + if err == nil { + t.Errorf("%d: wrong error detected: %s (expected) != %s (actual)", i, tc.expectedErrString, err) + } + if !strings.Contains(err.Error(), tc.expectedErrString) { + t.Errorf("%d: wrong error detected: %s (expected) != %s (actual)", i, tc.expectedErrString, err.Error()) + } + } + } +} + +type typeTestCase struct { + kubeCfgPath string + explicitPath string + expectedError string +} + +func TestGetClientConfig(t *testing.T) { + multiConfigs := fmt.Sprintf("%s%s%s", "/testing/assets/kube-config-01.yml", string(os.PathListSeparator), "/testing/assets/kube-config-02.yml") + + multiConfigs = multiConfigs + for _, tc := range []typeTestCase{ + { + "", + clientcmd.NewDefaultClientConfigLoadingRules().ExplicitPath, + "", + }, + { + "/testing/assets/kube-config-01.yml", + "", + fmt.Sprintf("Config file '%s' can not be found", "/testing/assets/kube-config-01.yml"), + }, + { + multiConfigs, + "", + fmt.Sprintf("Can not find config file. '%s' looks like a path. Please use the env var KUBECONFIG if you want to check for multiple configuration files", multiConfigs), + }, + } { + p := &KnParams{ + KubeCfgPath: tc.kubeCfgPath, + } + + clientConfig, err := p.GetClientConfig() + if tc.expectedError != "" { + assert.Assert(t, util.ContainsAll(err.Error(), tc.expectedError)) + } else { + assert.Assert(t, err == nil, err) + } + + if clientConfig != nil { + configAccess := clientConfig.ConfigAccess() + + assert.Assert(t, configAccess.GetExplicitFile() == tc.explicitPath) + } + } +}