...

Source file src/k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go

Documentation: k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package kubeconfig
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  
    23  	"github.com/pkg/errors"
    24  
    25  	clientset "k8s.io/client-go/kubernetes"
    26  	"k8s.io/client-go/tools/clientcmd"
    27  	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
    28  )
    29  
    30  // CreateBasic creates a basic, general KubeConfig object that then can be extended
    31  func CreateBasic(serverURL, clusterName, userName string, caCert []byte) *clientcmdapi.Config {
    32  	// Use the cluster and the username as the context name
    33  	contextName := fmt.Sprintf("%s@%s", userName, clusterName)
    34  
    35  	return &clientcmdapi.Config{
    36  		Clusters: map[string]*clientcmdapi.Cluster{
    37  			clusterName: {
    38  				Server:                   serverURL,
    39  				CertificateAuthorityData: caCert,
    40  			},
    41  		},
    42  		Contexts: map[string]*clientcmdapi.Context{
    43  			contextName: {
    44  				Cluster:  clusterName,
    45  				AuthInfo: userName,
    46  			},
    47  		},
    48  		AuthInfos:      map[string]*clientcmdapi.AuthInfo{},
    49  		CurrentContext: contextName,
    50  	}
    51  }
    52  
    53  // CreateWithCerts creates a KubeConfig object with access to the API server with client certificates
    54  func CreateWithCerts(serverURL, clusterName, userName string, caCert []byte, clientKey []byte, clientCert []byte) *clientcmdapi.Config {
    55  	config := CreateBasic(serverURL, clusterName, userName, caCert)
    56  	config.AuthInfos[userName] = &clientcmdapi.AuthInfo{
    57  		ClientKeyData:         clientKey,
    58  		ClientCertificateData: clientCert,
    59  	}
    60  	return config
    61  }
    62  
    63  // CreateWithToken creates a KubeConfig object with access to the API server with a token
    64  func CreateWithToken(serverURL, clusterName, userName string, caCert []byte, token string) *clientcmdapi.Config {
    65  	config := CreateBasic(serverURL, clusterName, userName, caCert)
    66  	config.AuthInfos[userName] = &clientcmdapi.AuthInfo{
    67  		Token: token,
    68  	}
    69  	return config
    70  }
    71  
    72  // ClientSetFromFile returns a ready-to-use client from a kubeconfig file
    73  func ClientSetFromFile(path string) (clientset.Interface, error) {
    74  	config, err := clientcmd.LoadFromFile(path)
    75  	if err != nil {
    76  		return nil, errors.Wrap(err, "failed to load admin kubeconfig")
    77  	}
    78  	return ToClientSet(config)
    79  }
    80  
    81  // ToClientSet converts a KubeConfig object to a client
    82  func ToClientSet(config *clientcmdapi.Config) (clientset.Interface, error) {
    83  	overrides := clientcmd.ConfigOverrides{Timeout: "10s"}
    84  	clientConfig, err := clientcmd.NewDefaultClientConfig(*config, &overrides).ClientConfig()
    85  	if err != nil {
    86  		return nil, errors.Wrap(err, "failed to create API client configuration from kubeconfig")
    87  	}
    88  
    89  	client, err := clientset.NewForConfig(clientConfig)
    90  	if err != nil {
    91  		return nil, errors.Wrap(err, "failed to create API client")
    92  	}
    93  	return client, nil
    94  }
    95  
    96  // WriteToDisk writes a KubeConfig object down to disk with mode 0600
    97  func WriteToDisk(filename string, kubeconfig *clientcmdapi.Config) error {
    98  	err := clientcmd.WriteToFile(*kubeconfig, filename)
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	return nil
   104  }
   105  
   106  // GetClusterFromKubeConfig returns the default Cluster of the specified KubeConfig
   107  func GetClusterFromKubeConfig(config *clientcmdapi.Config) (string, *clientcmdapi.Cluster) {
   108  	// If there is an unnamed cluster object, use it
   109  	if config.Clusters[""] != nil {
   110  		return "", config.Clusters[""]
   111  	}
   112  
   113  	currentContext := config.Contexts[config.CurrentContext]
   114  	if currentContext != nil {
   115  		return currentContext.Cluster, config.Clusters[currentContext.Cluster]
   116  	}
   117  	return "", nil
   118  }
   119  
   120  // HasAuthenticationCredentials returns true if the current user has valid authentication credentials for
   121  // token authentication, basic authentication or X509 authentication
   122  func HasAuthenticationCredentials(config *clientcmdapi.Config) bool {
   123  	authInfo := getCurrentAuthInfo(config)
   124  	if authInfo == nil {
   125  		return false
   126  	}
   127  
   128  	// token authentication
   129  	if len(authInfo.Token) != 0 || len(authInfo.TokenFile) != 0 {
   130  		return true
   131  	}
   132  
   133  	// basic authentication
   134  	if len(authInfo.Username) != 0 && len(authInfo.Password) != 0 {
   135  		return true
   136  	}
   137  
   138  	// X509 authentication
   139  	if (len(authInfo.ClientCertificate) != 0 || len(authInfo.ClientCertificateData) != 0) &&
   140  		(len(authInfo.ClientKey) != 0 || len(authInfo.ClientKeyData) != 0) {
   141  		return true
   142  	}
   143  
   144  	// exec authentication
   145  	if authInfo.Exec != nil && len(authInfo.Exec.Command) != 0 {
   146  		return true
   147  	}
   148  
   149  	// authprovider authentication
   150  	if authInfo.AuthProvider != nil && len(authInfo.AuthProvider.Name) != 0 {
   151  		return true
   152  	}
   153  
   154  	return false
   155  }
   156  
   157  // EnsureAuthenticationInfoAreEmbedded check if some authentication info are provided as external key/certificate
   158  // files, and eventually embeds such files into the kubeconfig file
   159  func EnsureAuthenticationInfoAreEmbedded(config *clientcmdapi.Config) error {
   160  	authInfo := getCurrentAuthInfo(config)
   161  	if authInfo == nil {
   162  		return errors.New("invalid kubeconfig file. AuthInfo is not defined for the current user")
   163  	}
   164  
   165  	if len(authInfo.ClientCertificateData) == 0 && len(authInfo.ClientCertificate) != 0 {
   166  		clientCert, err := os.ReadFile(authInfo.ClientCertificate)
   167  		if err != nil {
   168  			return errors.Wrap(err, "error while reading client cert file defined in kubeconfig")
   169  		}
   170  		authInfo.ClientCertificateData = clientCert
   171  		authInfo.ClientCertificate = ""
   172  	}
   173  	if len(authInfo.ClientKeyData) == 0 && len(authInfo.ClientKey) != 0 {
   174  		clientKey, err := os.ReadFile(authInfo.ClientKey)
   175  		if err != nil {
   176  			return errors.Wrap(err, "error while reading client key file defined in kubeconfig")
   177  		}
   178  		authInfo.ClientKeyData = clientKey
   179  		authInfo.ClientKey = ""
   180  	}
   181  	if len(authInfo.Token) == 0 && len(authInfo.TokenFile) != 0 {
   182  		tokenBytes, err := os.ReadFile(authInfo.TokenFile)
   183  		if err != nil {
   184  			return errors.Wrap(err, "error while reading token file defined in kubeconfig")
   185  		}
   186  		authInfo.Token = string(tokenBytes)
   187  		authInfo.TokenFile = ""
   188  	}
   189  
   190  	return nil
   191  }
   192  
   193  // EnsureCertificateAuthorityIsEmbedded check if the certificate authority is provided as an external
   194  // file and eventually embeds it into the kubeconfig
   195  func EnsureCertificateAuthorityIsEmbedded(cluster *clientcmdapi.Cluster) error {
   196  	if cluster == nil {
   197  		return errors.New("received nil value for Cluster")
   198  	}
   199  
   200  	if len(cluster.CertificateAuthorityData) == 0 && len(cluster.CertificateAuthority) != 0 {
   201  		ca, err := os.ReadFile(cluster.CertificateAuthority)
   202  		if err != nil {
   203  			return errors.Wrap(err, "error while reading certificate authority file defined in kubeconfig")
   204  		}
   205  		cluster.CertificateAuthorityData = ca
   206  		cluster.CertificateAuthority = ""
   207  	}
   208  
   209  	return nil
   210  }
   211  
   212  // getCurrentAuthInfo returns current authInfo, if defined
   213  func getCurrentAuthInfo(config *clientcmdapi.Config) *clientcmdapi.AuthInfo {
   214  	if config == nil || config.CurrentContext == "" ||
   215  		len(config.Contexts) == 0 || config.Contexts[config.CurrentContext] == nil {
   216  		return nil
   217  	}
   218  	user := config.Contexts[config.CurrentContext].AuthInfo
   219  
   220  	if user == "" || len(config.AuthInfos) == 0 || config.AuthInfos[user] == nil {
   221  		return nil
   222  	}
   223  
   224  	return config.AuthInfos[user]
   225  }
   226  

View as plain text