mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 09:49:50 +00:00
only load kubeconfig files one time
This commit is contained in:
parent
ef505d8fa3
commit
8c326993d5
@ -67,25 +67,25 @@ type DirectClientConfig struct {
|
|||||||
|
|
||||||
// NewDefaultClientConfig creates a DirectClientConfig using the config.CurrentContext as the context name
|
// NewDefaultClientConfig creates a DirectClientConfig using the config.CurrentContext as the context name
|
||||||
func NewDefaultClientConfig(config clientcmdapi.Config, overrides *ConfigOverrides) ClientConfig {
|
func NewDefaultClientConfig(config clientcmdapi.Config, overrides *ConfigOverrides) ClientConfig {
|
||||||
return DirectClientConfig{config, config.CurrentContext, overrides, nil}
|
return &DirectClientConfig{config, config.CurrentContext, overrides, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNonInteractiveClientConfig creates a DirectClientConfig using the passed context name and does not have a fallback reader for auth information
|
// NewNonInteractiveClientConfig creates a DirectClientConfig using the passed context name and does not have a fallback reader for auth information
|
||||||
func NewNonInteractiveClientConfig(config clientcmdapi.Config, contextName string, overrides *ConfigOverrides) ClientConfig {
|
func NewNonInteractiveClientConfig(config clientcmdapi.Config, contextName string, overrides *ConfigOverrides) ClientConfig {
|
||||||
return DirectClientConfig{config, contextName, overrides, nil}
|
return &DirectClientConfig{config, contextName, overrides, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInteractiveClientConfig creates a DirectClientConfig using the passed context name and a reader in case auth information is not provided via files or flags
|
// NewInteractiveClientConfig creates a DirectClientConfig using the passed context name and a reader in case auth information is not provided via files or flags
|
||||||
func NewInteractiveClientConfig(config clientcmdapi.Config, contextName string, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
|
func NewInteractiveClientConfig(config clientcmdapi.Config, contextName string, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
|
||||||
return DirectClientConfig{config, contextName, overrides, fallbackReader}
|
return &DirectClientConfig{config, contextName, overrides, fallbackReader}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config DirectClientConfig) RawConfig() (clientcmdapi.Config, error) {
|
func (config *DirectClientConfig) RawConfig() (clientcmdapi.Config, error) {
|
||||||
return config.config, nil
|
return config.config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientConfig implements ClientConfig
|
// ClientConfig implements ClientConfig
|
||||||
func (config DirectClientConfig) ClientConfig() (*client.Config, error) {
|
func (config *DirectClientConfig) ClientConfig() (*client.Config, error) {
|
||||||
if err := config.ConfirmUsable(); err != nil {
|
if err := config.ConfirmUsable(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -217,7 +217,7 @@ func canIdentifyUser(config client.Config) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Namespace implements KubeConfig
|
// Namespace implements KubeConfig
|
||||||
func (config DirectClientConfig) Namespace() (string, bool, error) {
|
func (config *DirectClientConfig) Namespace() (string, bool, error) {
|
||||||
if err := config.ConfirmUsable(); err != nil {
|
if err := config.ConfirmUsable(); err != nil {
|
||||||
return "", false, err
|
return "", false, err
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ func (config DirectClientConfig) Namespace() (string, bool, error) {
|
|||||||
|
|
||||||
// ConfirmUsable looks a particular context and determines if that particular part of the config is useable. There might still be errors in the config,
|
// ConfirmUsable looks a particular context and determines if that particular part of the config is useable. There might still be errors in the config,
|
||||||
// but no errors in the sections requested or referenced. It does not return early so that it can find as many errors as possible.
|
// but no errors in the sections requested or referenced. It does not return early so that it can find as many errors as possible.
|
||||||
func (config DirectClientConfig) ConfirmUsable() error {
|
func (config *DirectClientConfig) ConfirmUsable() error {
|
||||||
validationErrors := make([]error, 0)
|
validationErrors := make([]error, 0)
|
||||||
validationErrors = append(validationErrors, validateAuthInfo(config.getAuthInfoName(), config.getAuthInfo())...)
|
validationErrors = append(validationErrors, validateAuthInfo(config.getAuthInfoName(), config.getAuthInfo())...)
|
||||||
validationErrors = append(validationErrors, validateClusterInfo(config.getClusterName(), config.getCluster())...)
|
validationErrors = append(validationErrors, validateClusterInfo(config.getClusterName(), config.getCluster())...)
|
||||||
@ -249,7 +249,7 @@ func (config DirectClientConfig) ConfirmUsable() error {
|
|||||||
return newErrConfigurationInvalid(validationErrors)
|
return newErrConfigurationInvalid(validationErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config DirectClientConfig) getContextName() string {
|
func (config *DirectClientConfig) getContextName() string {
|
||||||
if len(config.overrides.CurrentContext) != 0 {
|
if len(config.overrides.CurrentContext) != 0 {
|
||||||
return config.overrides.CurrentContext
|
return config.overrides.CurrentContext
|
||||||
}
|
}
|
||||||
@ -260,21 +260,21 @@ func (config DirectClientConfig) getContextName() string {
|
|||||||
return config.config.CurrentContext
|
return config.config.CurrentContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config DirectClientConfig) getAuthInfoName() string {
|
func (config *DirectClientConfig) getAuthInfoName() string {
|
||||||
if len(config.overrides.Context.AuthInfo) != 0 {
|
if len(config.overrides.Context.AuthInfo) != 0 {
|
||||||
return config.overrides.Context.AuthInfo
|
return config.overrides.Context.AuthInfo
|
||||||
}
|
}
|
||||||
return config.getContext().AuthInfo
|
return config.getContext().AuthInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config DirectClientConfig) getClusterName() string {
|
func (config *DirectClientConfig) getClusterName() string {
|
||||||
if len(config.overrides.Context.Cluster) != 0 {
|
if len(config.overrides.Context.Cluster) != 0 {
|
||||||
return config.overrides.Context.Cluster
|
return config.overrides.Context.Cluster
|
||||||
}
|
}
|
||||||
return config.getContext().Cluster
|
return config.getContext().Cluster
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config DirectClientConfig) getContext() clientcmdapi.Context {
|
func (config *DirectClientConfig) getContext() clientcmdapi.Context {
|
||||||
contexts := config.config.Contexts
|
contexts := config.config.Contexts
|
||||||
contextName := config.getContextName()
|
contextName := config.getContextName()
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ func (config DirectClientConfig) getContext() clientcmdapi.Context {
|
|||||||
return mergedContext
|
return mergedContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config DirectClientConfig) getAuthInfo() clientcmdapi.AuthInfo {
|
func (config *DirectClientConfig) getAuthInfo() clientcmdapi.AuthInfo {
|
||||||
authInfos := config.config.AuthInfos
|
authInfos := config.config.AuthInfos
|
||||||
authInfoName := config.getAuthInfoName()
|
authInfoName := config.getAuthInfoName()
|
||||||
|
|
||||||
@ -300,7 +300,7 @@ func (config DirectClientConfig) getAuthInfo() clientcmdapi.AuthInfo {
|
|||||||
return mergedAuthInfo
|
return mergedAuthInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config DirectClientConfig) getCluster() clientcmdapi.Cluster {
|
func (config *DirectClientConfig) getCluster() clientcmdapi.Cluster {
|
||||||
clusterInfos := config.config.Clusters
|
clusterInfos := config.config.Clusters
|
||||||
clusterInfoName := config.getClusterName()
|
clusterInfoName := config.getClusterName()
|
||||||
|
|
||||||
|
@ -117,23 +117,41 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
kubeConfigFiles = append(kubeConfigFiles, rules.Precedence...)
|
kubeConfigFiles = append(kubeConfigFiles, rules.Precedence...)
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeconfigs := []*clientcmdapi.Config{}
|
||||||
|
// read and cache the config files so that we only look at them once
|
||||||
|
for _, filename := range kubeConfigFiles {
|
||||||
|
if len(filename) == 0 {
|
||||||
|
// no work to do
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := LoadFromFile(filename)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
// skip missing files
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
errlist = append(errlist, fmt.Errorf("Error loading config file \"%s\": %v", filename, err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeconfigs = append(kubeconfigs, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// first merge all of our maps
|
// first merge all of our maps
|
||||||
mapConfig := clientcmdapi.NewConfig()
|
mapConfig := clientcmdapi.NewConfig()
|
||||||
for _, file := range kubeConfigFiles {
|
for _, kubeconfig := range kubeconfigs {
|
||||||
if err := mergeConfigWithFile(mapConfig, file); err != nil {
|
mergo.Merge(mapConfig, kubeconfig)
|
||||||
errlist = append(errlist, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// merge all of the struct values in the reverse order so that priority is given correctly
|
// merge all of the struct values in the reverse order so that priority is given correctly
|
||||||
// errors are not added to the list the second time
|
// errors are not added to the list the second time
|
||||||
nonMapConfig := clientcmdapi.NewConfig()
|
nonMapConfig := clientcmdapi.NewConfig()
|
||||||
for i := len(kubeConfigFiles) - 1; i >= 0; i-- {
|
for i := len(kubeconfigs) - 1; i >= 0; i-- {
|
||||||
file := kubeConfigFiles[i]
|
kubeconfig := kubeconfigs[i]
|
||||||
mergeConfigWithFile(nonMapConfig, file)
|
mergo.Merge(nonMapConfig, kubeconfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// since values are overwritten, but maps values are not, we can merge the non-map config on top of the map config and
|
// since values are overwritten, but maps values are not, we can merge the non-map config on top of the map config and
|
||||||
@ -198,25 +216,6 @@ func (rules *ClientConfigLoadingRules) Migrate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeConfigWithFile(startingConfig *clientcmdapi.Config, filename string) error {
|
|
||||||
if len(filename) == 0 {
|
|
||||||
// no work to do
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
config, err := LoadFromFile(filename)
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error loading config file \"%s\": %v", filename, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
mergo.Merge(startingConfig, config)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadFromFile takes a filename and deserializes the contents into Config object
|
// LoadFromFile takes a filename and deserializes the contents into Config object
|
||||||
func LoadFromFile(filename string) (*clientcmdapi.Config, error) {
|
func LoadFromFile(filename string) (*clientcmdapi.Config, error) {
|
||||||
kubeconfigBytes, err := ioutil.ReadFile(filename)
|
kubeconfigBytes, err := ioutil.ReadFile(filename)
|
||||||
|
@ -19,6 +19,7 @@ package clientcmd
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
@ -35,19 +36,27 @@ type DeferredLoadingClientConfig struct {
|
|||||||
loadingRules *ClientConfigLoadingRules
|
loadingRules *ClientConfigLoadingRules
|
||||||
overrides *ConfigOverrides
|
overrides *ConfigOverrides
|
||||||
fallbackReader io.Reader
|
fallbackReader io.Reader
|
||||||
|
|
||||||
|
clientConfig ClientConfig
|
||||||
|
loadingLock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNonInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name
|
// NewNonInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name
|
||||||
func NewNonInteractiveDeferredLoadingClientConfig(loadingRules *ClientConfigLoadingRules, overrides *ConfigOverrides) ClientConfig {
|
func NewNonInteractiveDeferredLoadingClientConfig(loadingRules *ClientConfigLoadingRules, overrides *ConfigOverrides) ClientConfig {
|
||||||
return DeferredLoadingClientConfig{loadingRules, overrides, nil}
|
return &DeferredLoadingClientConfig{loadingRules: loadingRules, overrides: overrides}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name and the fallback auth reader
|
// NewInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name and the fallback auth reader
|
||||||
func NewInteractiveDeferredLoadingClientConfig(loadingRules *ClientConfigLoadingRules, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
|
func NewInteractiveDeferredLoadingClientConfig(loadingRules *ClientConfigLoadingRules, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
|
||||||
return DeferredLoadingClientConfig{loadingRules, overrides, fallbackReader}
|
return &DeferredLoadingClientConfig{loadingRules: loadingRules, overrides: overrides, fallbackReader: fallbackReader}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config DeferredLoadingClientConfig) createClientConfig() (ClientConfig, error) {
|
func (config *DeferredLoadingClientConfig) createClientConfig() (ClientConfig, error) {
|
||||||
|
if config.clientConfig == nil {
|
||||||
|
config.loadingLock.Lock()
|
||||||
|
defer config.loadingLock.Unlock()
|
||||||
|
|
||||||
|
if config.clientConfig == nil {
|
||||||
mergedConfig, err := config.loadingRules.Load()
|
mergedConfig, err := config.loadingRules.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -60,10 +69,14 @@ func (config DeferredLoadingClientConfig) createClientConfig() (ClientConfig, er
|
|||||||
mergedClientConfig = NewNonInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides)
|
mergedClientConfig = NewNonInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides)
|
||||||
}
|
}
|
||||||
|
|
||||||
return mergedClientConfig, nil
|
config.clientConfig = mergedClientConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.clientConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config DeferredLoadingClientConfig) RawConfig() (clientcmdapi.Config, error) {
|
func (config *DeferredLoadingClientConfig) RawConfig() (clientcmdapi.Config, error) {
|
||||||
mergedConfig, err := config.createClientConfig()
|
mergedConfig, err := config.createClientConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clientcmdapi.Config{}, err
|
return clientcmdapi.Config{}, err
|
||||||
@ -73,7 +86,7 @@ func (config DeferredLoadingClientConfig) RawConfig() (clientcmdapi.Config, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ClientConfig implements ClientConfig
|
// ClientConfig implements ClientConfig
|
||||||
func (config DeferredLoadingClientConfig) ClientConfig() (*client.Config, error) {
|
func (config *DeferredLoadingClientConfig) ClientConfig() (*client.Config, error) {
|
||||||
mergedClientConfig, err := config.createClientConfig()
|
mergedClientConfig, err := config.createClientConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -94,7 +107,7 @@ func (config DeferredLoadingClientConfig) ClientConfig() (*client.Config, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Namespace implements KubeConfig
|
// Namespace implements KubeConfig
|
||||||
func (config DeferredLoadingClientConfig) Namespace() (string, bool, error) {
|
func (config *DeferredLoadingClientConfig) Namespace() (string, bool, error) {
|
||||||
mergedKubeConfig, err := config.createClientConfig()
|
mergedKubeConfig, err := config.createClientConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", false, err
|
return "", false, err
|
||||||
|
Loading…
Reference in New Issue
Block a user