Merge pull request #113998 from SataQiu/fix-kubeadm-20221117

kubeadm: respect user provided kubeconfig during discovery process
This commit is contained in:
Kubernetes Prow Robot 2022-12-10 03:17:39 -08:00 committed by GitHub
commit 2e6d3393f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 29 deletions

View File

@ -589,7 +589,7 @@ func fetchInitConfigurationFromJoinConfiguration(cfg *kubeadmapi.JoinConfigurati
}
// Create the final KubeConfig file with the cluster name discovered after fetching the cluster configuration
clusterinfo := kubeconfigutil.GetClusterFromKubeConfig(tlsBootstrapCfg)
_, clusterinfo := kubeconfigutil.GetClusterFromKubeConfig(tlsBootstrapCfg)
tlsBootstrapCfg.Clusters = map[string]*clientcmdapi.Cluster{
initConfiguration.ClusterName: clusterinfo,
}

View File

@ -59,7 +59,7 @@ func getJoinCommand(kubeConfigFile, token, key string, controlPlane, skipTokenPr
}
// load the default cluster config
clusterConfig := kubeconfigutil.GetClusterFromKubeConfig(config)
_, clusterConfig := kubeconfigutil.GetClusterFromKubeConfig(config)
if clusterConfig == nil {
return "", errors.New("failed to get default cluster config")
}

View File

@ -51,7 +51,7 @@ func For(cfg *kubeadmapi.JoinConfiguration) (*clientcmdapi.Config, error) {
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)
_, clusterinfo := kubeconfigutil.GetClusterFromKubeConfig(config)
return kubeconfigutil.CreateWithToken(
clusterinfo.Server,
kubeadmapiv1.DefaultClusterName,
@ -76,9 +76,9 @@ func DiscoverValidatedKubeConfig(cfg *kubeadmapi.JoinConfiguration) (*clientcmda
case cfg.Discovery.File != nil:
kubeConfigPath := cfg.Discovery.File.KubeConfigPath
if isHTTPSURL(kubeConfigPath) {
return https.RetrieveValidatedConfigInfo(kubeConfigPath, kubeadmapiv1.DefaultClusterName, cfg.Discovery.Timeout.Duration)
return https.RetrieveValidatedConfigInfo(kubeConfigPath, cfg.Discovery.Timeout.Duration)
}
return file.RetrieveValidatedConfigInfo(kubeConfigPath, kubeadmapiv1.DefaultClusterName, cfg.Discovery.Timeout.Duration)
return file.RetrieveValidatedConfigInfo(kubeConfigPath, cfg.Discovery.Timeout.Duration)
case cfg.Discovery.BootstrapToken != nil:
return token.RetrieveValidatedConfigInfo(&cfg.Discovery)
default:

View File

@ -38,22 +38,22 @@ import (
// RetrieveValidatedConfigInfo connects to the API Server and makes sure it can talk
// securely to the API Server using the provided CA cert and
// optionally refreshes the cluster-info information from the cluster-info ConfigMap
func RetrieveValidatedConfigInfo(filepath, clustername string, discoveryTimeout time.Duration) (*clientcmdapi.Config, error) {
func RetrieveValidatedConfigInfo(filepath string, discoveryTimeout time.Duration) (*clientcmdapi.Config, error) {
config, err := clientcmd.LoadFromFile(filepath)
if err != nil {
return nil, err
}
return ValidateConfigInfo(config, clustername, discoveryTimeout)
return ValidateConfigInfo(config, discoveryTimeout)
}
// ValidateConfigInfo connects to the API Server and makes sure it can talk
// securely to the API Server using the provided CA cert/client certificates and
// optionally refreshes the cluster-info information from the cluster-info ConfigMap
func ValidateConfigInfo(config *clientcmdapi.Config, clustername string, discoveryTimeout time.Duration) (*clientcmdapi.Config, error) {
func ValidateConfigInfo(config *clientcmdapi.Config, discoveryTimeout time.Duration) (*clientcmdapi.Config, error) {
if len(config.Clusters) < 1 {
return nil, errors.New("the provided kubeconfig file must have at least one Cluster defined")
}
currentCluster := kubeconfigutil.GetClusterFromKubeConfig(config)
currentClusterName, currentCluster := kubeconfigutil.GetClusterFromKubeConfig(config)
if currentCluster == nil {
return nil, errors.New("the provided kubeconfig file must have a unnamed Cluster or a CurrentContext that specifies a non-nil Cluster")
}
@ -78,15 +78,6 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string, discove
} 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
config = kubeconfigutil.CreateBasic(
currentCluster.Server,
clustername,
"", // no user provided
currentCluster.CertificateAuthorityData,
)
}
// Try to read the cluster-info config map; this step was required by the original design in order
@ -131,11 +122,16 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string, discove
return config, nil
}
refreshedCluster := kubeconfigutil.GetClusterFromKubeConfig(refreshedBaseKubeConfig)
currentCluster.Server = refreshedCluster.Server
currentCluster.CertificateAuthorityData = refreshedCluster.CertificateAuthorityData
_, refreshedCluster := kubeconfigutil.GetClusterFromKubeConfig(refreshedBaseKubeConfig)
if currentCluster.Server != refreshedCluster.Server {
klog.Warningf("[discovery] the API Server endpoint %q in use is different from the endpoint %q which defined in the %s ConfigMap", currentCluster.Server, refreshedCluster.Server, bootstrapapi.ConfigMapClusterInfo)
}
if len(currentCluster.CertificateAuthorityData) == 0 && len(refreshedCluster.CertificateAuthorityData) > 0 {
config.Clusters[currentClusterName].CertificateAuthorityData = refreshedCluster.CertificateAuthorityData
klog.V(1).Infof("[discovery] Synced CertificateAuthorityData from the %s ConfigMap", bootstrapapi.ConfigMapClusterInfo)
}
klog.V(1).Infof("[discovery] Synced Server and CertificateAuthorityData from the %s ConfigMap", bootstrapapi.ConfigMapClusterInfo)
return config, nil
}

View File

@ -31,7 +31,7 @@ import (
// RetrieveValidatedConfigInfo connects to the API Server and makes sure it can talk
// securely to the API Server using the provided CA cert and
// optionally refreshes the cluster-info information from the cluster-info ConfigMap
func RetrieveValidatedConfigInfo(httpsURL, clustername string, discoveryTimeout time.Duration) (*clientcmdapi.Config, error) {
func RetrieveValidatedConfigInfo(httpsURL string, discoveryTimeout time.Duration) (*clientcmdapi.Config, error) {
client := &http.Client{Transport: netutil.SetOldTransportDefaults(&http.Transport{})}
response, err := client.Get(httpsURL)
if err != nil {
@ -48,5 +48,5 @@ func RetrieveValidatedConfigInfo(httpsURL, clustername string, discoveryTimeout
if err != nil {
return nil, err
}
return file.ValidateConfigInfo(config, clustername, discoveryTimeout)
return file.ValidateConfigInfo(config, discoveryTimeout)
}

View File

@ -104,15 +104,17 @@ func WriteToDisk(filename string, kubeconfig *clientcmdapi.Config) error {
}
// GetClusterFromKubeConfig returns the default Cluster of the specified KubeConfig
func GetClusterFromKubeConfig(config *clientcmdapi.Config) *clientcmdapi.Cluster {
func GetClusterFromKubeConfig(config *clientcmdapi.Config) (string, *clientcmdapi.Cluster) {
// If there is an unnamed cluster object, use it
if config.Clusters[""] != nil {
return config.Clusters[""]
return "", config.Clusters[""]
}
if config.Contexts[config.CurrentContext] != nil {
return config.Clusters[config.Contexts[config.CurrentContext].Cluster]
currentContext := config.Contexts[config.CurrentContext]
if currentContext != nil {
return currentContext.Cluster, config.Clusters[currentContext.Cluster]
}
return nil
return "", nil
}
// HasAuthenticationCredentials returns true if the current user has valid authentication credentials for