From d91d4c53e6f5ad76878b7f79d4731e69d9f107b0 Mon Sep 17 00:00:00 2001 From: fabriziopandini Date: Sat, 27 Jul 2019 15:21:24 +0200 Subject: [PATCH 1/3] autogenerated --- cmd/kubeadm/app/discovery/BUILD | 1 + cmd/kubeadm/app/discovery/file/BUILD | 5 +---- cmd/kubeadm/app/util/kubeconfig/BUILD | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cmd/kubeadm/app/discovery/BUILD b/cmd/kubeadm/app/discovery/BUILD index 86cbd313a5..e4e075a54e 100644 --- a/cmd/kubeadm/app/discovery/BUILD +++ b/cmd/kubeadm/app/discovery/BUILD @@ -19,6 +19,7 @@ go_library( "//cmd/kubeadm/app/util/kubeconfig:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", + "//vendor/k8s.io/klog:go_default_library", ], ) diff --git a/cmd/kubeadm/app/discovery/file/BUILD b/cmd/kubeadm/app/discovery/file/BUILD index 6a287f1b68..f901a6480b 100644 --- a/cmd/kubeadm/app/discovery/file/BUILD +++ b/cmd/kubeadm/app/discovery/file/BUILD @@ -1,9 +1,6 @@ package(default_visibility = ["//visibility:public"]) -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) +load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", diff --git a/cmd/kubeadm/app/util/kubeconfig/BUILD b/cmd/kubeadm/app/util/kubeconfig/BUILD index 934cea1339..ff126b502a 100644 --- a/cmd/kubeadm/app/util/kubeconfig/BUILD +++ b/cmd/kubeadm/app/util/kubeconfig/BUILD @@ -10,6 +10,7 @@ go_test( name = "go_default_test", srcs = ["kubeconfig_test.go"], embed = [":go_default_library"], + deps = ["//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library"], ) go_library( From a1ee8d63beed44202f40d64fd852a7b838580f39 Mon Sep 17 00:00:00 2001 From: fabriziopandini Date: Sat, 27 Jul 2019 19:19:29 +0200 Subject: [PATCH 2/3] fix-file-discovery --- cmd/kubeadm/app/discovery/discovery.go | 31 ++-- cmd/kubeadm/app/discovery/file/file.go | 79 ++++------ cmd/kubeadm/app/util/kubeconfig/kubeconfig.go | 74 +++++++++ .../app/util/kubeconfig/kubeconfig_test.go | 142 ++++++++++++++++++ 4 files changed, 271 insertions(+), 55 deletions(-) diff --git a/cmd/kubeadm/app/discovery/discovery.go b/cmd/kubeadm/app/discovery/discovery.go index 52ffea832c..4e86c0d834 100644 --- a/cmd/kubeadm/app/discovery/discovery.go +++ b/cmd/kubeadm/app/discovery/discovery.go @@ -22,6 +22,7 @@ import ( "github.com/pkg/errors" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + "k8s.io/klog" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2" "k8s.io/kubernetes/cmd/kubeadm/app/discovery/file" @@ -43,17 +44,29 @@ func For(cfg *kubeadmapi.JoinConfiguration) (*clientcmdapi.Config, error) { return nil, errors.Wrap(err, "couldn't validate the identity of the API Server") } - if len(cfg.Discovery.TLSBootstrapToken) == 0 { + // If the users has provided a TLSBootstrapToken use it for the join process. + // This is usually the case of Token discovery, but it can also be used with a discovery file + // without embedded authentication credentials. + if len(cfg.Discovery.TLSBootstrapToken) != 0 { + klog.V(1).Info("[discovery] Using provided TLSBootstrapToken as authentication credentials for the join process") + + clusterinfo := kubeconfigutil.GetClusterFromKubeConfig(config) + return kubeconfigutil.CreateWithToken( + clusterinfo.Server, + kubeadmapiv1beta2.DefaultClusterName, + TokenUser, + clusterinfo.CertificateAuthorityData, + cfg.Discovery.TLSBootstrapToken, + ), nil + } + + // if the config returned from discovery has authentication credentials, proceed with the TLS boostrap process + if kubeconfigutil.HasAuthenticationCredentials(config) { return config, nil } - clusterinfo := kubeconfigutil.GetClusterFromKubeConfig(config) - return kubeconfigutil.CreateWithToken( - clusterinfo.Server, - kubeadmapiv1beta2.DefaultClusterName, - TokenUser, - clusterinfo.CertificateAuthorityData, - cfg.Discovery.TLSBootstrapToken, - ), nil + + // if there are no authentication credentials (nor in the config returned from discovery, nor in the TLSBootstrapToken), fail + return nil, errors.New("couldn't find authentication credentials for the TLS boostrap process. Please use Token discovery, a discovery file with embedded authentication credentials or a discovery file without authentication credentials and the TLSBootstrapToken flag") } // DiscoverValidatedKubeConfig returns a validated Config object that specifies where the cluster is and the CA cert to trust diff --git a/cmd/kubeadm/app/discovery/file/file.go b/cmd/kubeadm/app/discovery/file/file.go index 4942613c44..1d6d78a2f8 100644 --- a/cmd/kubeadm/app/discovery/file/file.go +++ b/cmd/kubeadm/app/discovery/file/file.go @@ -17,8 +17,6 @@ limitations under the License. package file import ( - "io/ioutil" - "github.com/pkg/errors" "k8s.io/api/core/v1" @@ -53,58 +51,44 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien return nil, err } - // This is the cluster object we've got from the cluster-info kubeconfig file - defaultCluster := kubeconfigutil.GetClusterFromKubeConfig(config) + var kubeconfig *clientcmdapi.Config - // Create a new kubeconfig object from the given, just copy over the server and the CA cert - // We do this in order to not pick up other possible misconfigurations in the clusterinfo file - kubeconfig := kubeconfigutil.CreateBasic( - defaultCluster.Server, - clustername, - "", // no user provided - defaultCluster.CertificateAuthorityData, - ) - // load pre-existing client certificates - if config.Contexts[config.CurrentContext] != nil && len(config.AuthInfos) > 0 { - user := config.Contexts[config.CurrentContext].AuthInfo - authInfo, ok := config.AuthInfos[user] - if !ok || authInfo == nil { - return nil, errors.Errorf("empty settings for user %q", user) - } - if len(authInfo.ClientCertificateData) == 0 && len(authInfo.ClientCertificate) != 0 { - clientCert, err := ioutil.ReadFile(authInfo.ClientCertificate) - if err != nil { - return nil, err - } - authInfo.ClientCertificateData = clientCert - } - if len(authInfo.ClientKeyData) == 0 && len(authInfo.ClientKey) != 0 { - clientKey, err := ioutil.ReadFile(authInfo.ClientKey) - if err != nil { - return nil, err - } - authInfo.ClientKeyData = clientKey - } + // If the discovery file config contains a authentication credentials + if kubeconfigutil.HasAuthenticationCredentials(config) { + klog.V(1).Info("[discovery] Using authentication credentials from the discovery file for validating TLS connection") - if len(authInfo.ClientCertificateData) == 0 || len(authInfo.ClientKeyData) == 0 { - return nil, errors.New("couldn't read authentication info from the given kubeconfig file") + // Use the discovery file config for starting the join process + kubeconfig = config + + // We should ensure that all the authentication info are embedded in config file, so everything will work also when + // the kubeconfig file will be stored in /etc/kubernetes/boostrap-kubelet.conf + if err := kubeconfigutil.EnsureAuthenticationInfoAreEmbedded(kubeconfig); err != nil { + return nil, errors.Wrap(err, "error while reading client cert file or client key file") } - kubeconfig = kubeconfigutil.CreateWithCerts( - defaultCluster.Server, + } else { + // If the discovery file config does not contains authentication credentials + klog.V(1).Info("[discovery] Discovery file does not contains authentication credentials, using unauthenticated request for validating TLS connection") + + // Create a new kubeconfig object from the discovery file config, with only the server and the CA cert. + // NB. We do this in order to not pick up other possible misconfigurations in the clusterinfo file + var fileCluster = kubeconfigutil.GetClusterFromKubeConfig(config) + kubeconfig = kubeconfigutil.CreateBasic( + fileCluster.Server, clustername, "", // no user provided - defaultCluster.CertificateAuthorityData, - authInfo.ClientKeyData, - authInfo.ClientCertificateData, + fileCluster.CertificateAuthorityData, ) } + // Try to read the cluster-info config map; this step was required by the original design in order + // to validate the TLS connection to the server early in the process client, err := kubeconfigutil.ToClientSet(kubeconfig) if err != nil { return nil, err } - klog.V(1).Infof("[discovery] Created cluster-info discovery client, requesting info from %q\n", defaultCluster.Server) + var currentCluster = kubeconfigutil.GetClusterFromKubeConfig(kubeconfig) + klog.V(1).Infof("[discovery] Created cluster-info discovery client, requesting info from %q\n", currentCluster.Server) var clusterinfoCM *v1.ConfigMap wait.PollInfinite(constants.DiscoveryRetryInterval, func() (bool, error) { @@ -113,11 +97,11 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien if err != nil { if apierrors.IsForbidden(err) { // If the request is unauthorized, the cluster admin has not granted access to the cluster info configmap for unauthenticated users - // In that case, trust the cluster admin and do not refresh the cluster-info credentials + // In that case, trust the cluster admin and do not refresh the cluster-info data klog.Warningf("[discovery] Could not access the %s ConfigMap for refreshing the cluster-info information, but the TLS cert is valid so proceeding...\n", bootstrapapi.ConfigMapClusterInfo) return true, nil } - klog.V(1).Infof("[discovery] Failed to validate the API Server's identity, will try again: [%v]\n", err) + klog.V(1).Infof("[discovery] Error reading the %s ConfigMap, will try again: [%v]\n", bootstrapapi.ConfigMapClusterInfo, err) return false, nil } return true, nil @@ -135,9 +119,12 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien return kubeconfig, nil } - klog.V(1).Infoln("[discovery] Synced cluster-info information from the API Server so we have got the latest information") - // In an HA world in the future, this will make more sense, because now we've got new information, possibly about new API Servers to talk to - return refreshedBaseKubeConfig, nil + var refreshedCluster = kubeconfigutil.GetClusterFromKubeConfig(refreshedBaseKubeConfig) + currentCluster.Server = refreshedCluster.Server + currentCluster.CertificateAuthorityData = refreshedCluster.CertificateAuthorityData + + klog.V(1).Infof("[discovery] Synced server and CA from the %s ConfigMap so we have got the latest information", bootstrapapi.ConfigMapClusterInfo) + return kubeconfig, nil } // tryParseClusterInfoFromConfigMap tries to parse a kubeconfig file from a ConfigMap key diff --git a/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go b/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go index 867f4e67fb..a7b5bcd0f8 100644 --- a/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go +++ b/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go @@ -18,6 +18,7 @@ package kubeconfig import ( "fmt" + "io/ioutil" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" @@ -112,3 +113,76 @@ func GetClusterFromKubeConfig(config *clientcmdapi.Config) *clientcmdapi.Cluster } return nil } + +// HasAuthenticationCredentials returns true if the current user has valid authentication credentials for +// token authentication, basic authentication or X509 authentication +func HasAuthenticationCredentials(config *clientcmdapi.Config) bool { + authInfo := getCurrentAuthInfo(config) + if authInfo == nil { + return false + } + + // token authentication + if len(authInfo.Token) != 0 { + return true + } + + // basic authentication + if len(authInfo.Username) != 0 && len(authInfo.Password) != 0 { + return true + } + + // X509 authentication + if (len(authInfo.ClientCertificate) != 0 || len(authInfo.ClientCertificateData) != 0) && + (len(authInfo.ClientKey) != 0 || len(authInfo.ClientKeyData) != 0) { + return true + } + + return false +} + +// EnsureAuthenticationInfoAreEmbedded check if some authentication info are provided as external key/certificate +// files, and eventually embeds such files into the kubeconfig file +func EnsureAuthenticationInfoAreEmbedded(config *clientcmdapi.Config) error { + authInfo := getCurrentAuthInfo(config) + if authInfo == nil { + return errors.New("invalid kubeconfig file. AuthInfo is not defined for the current user") + } + + if len(authInfo.ClientCertificateData) == 0 && len(authInfo.ClientCertificate) != 0 { + clientCert, err := ioutil.ReadFile(authInfo.ClientCertificate) + if err != nil { + return err + } + authInfo.ClientCertificateData = clientCert + authInfo.ClientCertificate = "" + } + if len(authInfo.ClientKeyData) == 0 && len(authInfo.ClientKey) != 0 { + clientKey, err := ioutil.ReadFile(authInfo.ClientKey) + if err != nil { + return err + } + authInfo.ClientKeyData = clientKey + authInfo.ClientKey = "" + } + + return nil +} + +// getCurrentAuthInfo returns current authInfo, if defined +func getCurrentAuthInfo(config *clientcmdapi.Config) *clientcmdapi.AuthInfo { + if config == nil || config.CurrentContext == "" { + return nil + } + + if len(config.Contexts) == 0 || config.Contexts[config.CurrentContext] == nil { + return nil + } + user := config.Contexts[config.CurrentContext].AuthInfo + + if user == "" || len(config.AuthInfos) == 0 || config.AuthInfos[user] == nil { + return nil + } + + return config.AuthInfos[user] +} diff --git a/cmd/kubeadm/app/util/kubeconfig/kubeconfig_test.go b/cmd/kubeadm/app/util/kubeconfig/kubeconfig_test.go index 569419864e..628ace1eff 100644 --- a/cmd/kubeadm/app/util/kubeconfig/kubeconfig_test.go +++ b/cmd/kubeadm/app/util/kubeconfig/kubeconfig_test.go @@ -22,6 +22,8 @@ import ( "io/ioutil" "os" "testing" + + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) const ( @@ -186,3 +188,143 @@ func TestWriteKubeconfigToDisk(t *testing.T) { }) } } + +func TestGetCurrentAuthInfo(t *testing.T) { + var testCases = []struct { + name string + config *clientcmdapi.Config + expected bool + }{ + { + name: "nil context", + config: nil, + expected: false, + }, + { + name: "no CurrentContext value", + config: &clientcmdapi.Config{}, + expected: false, + }, + { + name: "no CurrentContext object 1", + config: &clientcmdapi.Config{CurrentContext: "kubernetes"}, + expected: false, + }, + { + name: "no CurrentContext object ", + config: &clientcmdapi.Config{ + CurrentContext: "kubernetes", + Contexts: map[string]*clientcmdapi.Context{"NOTkubernetes": {}}, + }, + expected: false, + }, + { + name: "no AuthInfo value", + config: &clientcmdapi.Config{ + CurrentContext: "kubernetes", + Contexts: map[string]*clientcmdapi.Context{"kubernetes": {}}, + }, + expected: false, + }, + { + name: "no AuthInfo object 1", + config: &clientcmdapi.Config{ + CurrentContext: "kubernetes", + Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}}, + }, + expected: false, + }, + { + name: "no AuthInfo object 2", + config: &clientcmdapi.Config{ + CurrentContext: "kubernetes", + Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}}, + AuthInfos: map[string]*clientcmdapi.AuthInfo{"NOTkubernetes": {}}, + }, + expected: false, + }, + { + name: "authInfo", + config: &clientcmdapi.Config{ + CurrentContext: "kubernetes", + Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}}, + AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {}}, + }, + expected: true, + }, + } + for _, rt := range testCases { + t.Run(rt.name, func(t *testing.T) { + r := getCurrentAuthInfo(rt.config) + if rt.expected != (r != nil) { + t.Errorf( + "failed TestHasCredentials:\n\texpected: %v\n\t actual: %v", + rt.expected, + r, + ) + } + }) + } +} + +func TestHasCredentials(t *testing.T) { + var testCases = []struct { + name string + config *clientcmdapi.Config + expected bool + }{ + { + name: "no authInfo", + config: nil, + expected: false, + }, + { + name: "no credentials", + config: &clientcmdapi.Config{ + CurrentContext: "kubernetes", + Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}}, + AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {}}, + }, + expected: false, + }, + { + name: "token authentication credentials", + config: &clientcmdapi.Config{ + CurrentContext: "kubernetes", + Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}}, + AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {Token: "123"}}, + }, + expected: true, + }, + { + name: "basic authentication credentials", + config: &clientcmdapi.Config{ + CurrentContext: "kubernetes", + Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}}, + AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {Username: "A", Password: "B"}}, + }, + expected: true, + }, + { + name: "X509 authentication credentials", + config: &clientcmdapi.Config{ + CurrentContext: "kubernetes", + Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}}, + AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {ClientKey: "A", ClientCertificate: "B"}}, + }, + expected: true, + }, + } + for _, rt := range testCases { + t.Run(rt.name, func(t *testing.T) { + r := HasAuthenticationCredentials(rt.config) + if rt.expected != r { + t.Errorf( + "failed TestHasCredentials:\n\texpected: %v\n\t actual: %v", + rt.expected, + r, + ) + } + }) + } +} From 8e95f9fafd657c87f724fbc04549f1a345e99950 Mon Sep 17 00:00:00 2001 From: fabriziopandini Date: Mon, 29 Jul 2019 10:48:23 +0200 Subject: [PATCH 3/3] feedback 1 --- cmd/kubeadm/app/discovery/discovery.go | 2 +- cmd/kubeadm/app/discovery/file/file.go | 12 ++++++------ cmd/kubeadm/app/util/kubeconfig/kubeconfig.go | 7 ++----- cmd/kubeadm/app/util/kubeconfig/kubeconfig_test.go | 10 +++++----- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/cmd/kubeadm/app/discovery/discovery.go b/cmd/kubeadm/app/discovery/discovery.go index 4e86c0d834..691f171bce 100644 --- a/cmd/kubeadm/app/discovery/discovery.go +++ b/cmd/kubeadm/app/discovery/discovery.go @@ -66,7 +66,7 @@ func For(cfg *kubeadmapi.JoinConfiguration) (*clientcmdapi.Config, error) { } // if there are no authentication credentials (nor in the config returned from discovery, nor in the TLSBootstrapToken), fail - return nil, errors.New("couldn't find authentication credentials for the TLS boostrap process. Please use Token discovery, a discovery file with embedded authentication credentials or a discovery file without authentication credentials and the TLSBootstrapToken flag") + return nil, errors.New("couldn't find authentication credentials for the TLS boostrap process. Please use Token discovery, a discovery file with embedded authentication credentials or a discovery file without authentication credentials but with the TLSBootstrapToken flag") } // DiscoverValidatedKubeConfig returns a validated Config object that specifies where the cluster is and the CA cert to trust diff --git a/cmd/kubeadm/app/discovery/file/file.go b/cmd/kubeadm/app/discovery/file/file.go index 1d6d78a2f8..a1c84a97b2 100644 --- a/cmd/kubeadm/app/discovery/file/file.go +++ b/cmd/kubeadm/app/discovery/file/file.go @@ -53,14 +53,14 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien var kubeconfig *clientcmdapi.Config - // If the discovery file config contains a authentication credentials + // If the discovery file config contains authentication credentials if kubeconfigutil.HasAuthenticationCredentials(config) { klog.V(1).Info("[discovery] Using authentication credentials from the discovery file for validating TLS connection") // Use the discovery file config for starting the join process kubeconfig = config - // We should ensure that all the authentication info are embedded in config file, so everything will work also when + // We should ensure that all the authentication info is embedded in config file, so everything will work also when // the kubeconfig file will be stored in /etc/kubernetes/boostrap-kubelet.conf if err := kubeconfigutil.EnsureAuthenticationInfoAreEmbedded(kubeconfig); err != nil { return nil, errors.Wrap(err, "error while reading client cert file or client key file") @@ -87,7 +87,7 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien return nil, err } - var currentCluster = kubeconfigutil.GetClusterFromKubeConfig(kubeconfig) + currentCluster := kubeconfigutil.GetClusterFromKubeConfig(kubeconfig) klog.V(1).Infof("[discovery] Created cluster-info discovery client, requesting info from %q\n", currentCluster.Server) var clusterinfoCM *v1.ConfigMap @@ -101,7 +101,7 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien klog.Warningf("[discovery] Could not access the %s ConfigMap for refreshing the cluster-info information, but the TLS cert is valid so proceeding...\n", bootstrapapi.ConfigMapClusterInfo) return true, nil } - klog.V(1).Infof("[discovery] Error reading the %s ConfigMap, will try again: [%v]\n", bootstrapapi.ConfigMapClusterInfo, err) + klog.V(1).Infof("[discovery] Error reading the %s ConfigMap, will try again: %v\n", bootstrapapi.ConfigMapClusterInfo, err) return false, nil } return true, nil @@ -119,11 +119,11 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien return kubeconfig, nil } - var refreshedCluster = kubeconfigutil.GetClusterFromKubeConfig(refreshedBaseKubeConfig) + refreshedCluster := kubeconfigutil.GetClusterFromKubeConfig(refreshedBaseKubeConfig) currentCluster.Server = refreshedCluster.Server currentCluster.CertificateAuthorityData = refreshedCluster.CertificateAuthorityData - klog.V(1).Infof("[discovery] Synced server and CA from the %s ConfigMap so we have got the latest information", bootstrapapi.ConfigMapClusterInfo) + klog.V(1).Infof("[discovery] Synced Server and CertificateAuthorityData from the %s ConfigMap", bootstrapapi.ConfigMapClusterInfo) return kubeconfig, nil } diff --git a/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go b/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go index a7b5bcd0f8..e8111834b5 100644 --- a/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go +++ b/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go @@ -171,11 +171,8 @@ func EnsureAuthenticationInfoAreEmbedded(config *clientcmdapi.Config) error { // getCurrentAuthInfo returns current authInfo, if defined func getCurrentAuthInfo(config *clientcmdapi.Config) *clientcmdapi.AuthInfo { - if config == nil || config.CurrentContext == "" { - return nil - } - - if len(config.Contexts) == 0 || config.Contexts[config.CurrentContext] == nil { + if config == nil || config.CurrentContext == "" || + len(config.Contexts) == 0 || config.Contexts[config.CurrentContext] == nil { return nil } user := config.Contexts[config.CurrentContext].AuthInfo diff --git a/cmd/kubeadm/app/util/kubeconfig/kubeconfig_test.go b/cmd/kubeadm/app/util/kubeconfig/kubeconfig_test.go index 628ace1eff..44cbbaa679 100644 --- a/cmd/kubeadm/app/util/kubeconfig/kubeconfig_test.go +++ b/cmd/kubeadm/app/util/kubeconfig/kubeconfig_test.go @@ -206,12 +206,12 @@ func TestGetCurrentAuthInfo(t *testing.T) { expected: false, }, { - name: "no CurrentContext object 1", + name: "no CurrentContext object", config: &clientcmdapi.Config{CurrentContext: "kubernetes"}, expected: false, }, { - name: "no CurrentContext object ", + name: "CurrentContext object with bad contents", config: &clientcmdapi.Config{ CurrentContext: "kubernetes", Contexts: map[string]*clientcmdapi.Context{"NOTkubernetes": {}}, @@ -227,7 +227,7 @@ func TestGetCurrentAuthInfo(t *testing.T) { expected: false, }, { - name: "no AuthInfo object 1", + name: "no AuthInfo object", config: &clientcmdapi.Config{ CurrentContext: "kubernetes", Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}}, @@ -235,7 +235,7 @@ func TestGetCurrentAuthInfo(t *testing.T) { expected: false, }, { - name: "no AuthInfo object 2", + name: "AuthInfo object with bad contents", config: &clientcmdapi.Config{ CurrentContext: "kubernetes", Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}}, @@ -244,7 +244,7 @@ func TestGetCurrentAuthInfo(t *testing.T) { expected: false, }, { - name: "authInfo", + name: "valid AuthInfo", config: &clientcmdapi.Config{ CurrentContext: "kubernetes", Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}},