func GetConfigFromFileOrDie(filename string) *clientcmdapi.Config {
	config, err := getConfigFromFile(filename)
	if err != nil {
		glog.FatalDepth(1, err)
	}
	return config
}
GetConfigFromFileOrDie tries to read a kubeconfig file and if it can't, it calls exit.  One exception, missing files result in empty configs, not an exit
package clientcmd
import (
	"errors"
	"os"
	"path"
	"path/filepath"
	"reflect"
	"sort"
	"github.com/golang/glog"
	restclient "k8s.io/client-go/rest"
	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)
type ConfigAccess interface {
	GetLoadingPrecedence() []string
	GetStartingConfig() (*clientcmdapi.Config, error)
	GetDefaultFilename() string
	IsExplicitFile() bool
	GetExplicitFile() string
}
type PathOptions struct {
	GlobalFile string
	EnvVar string
	ExplicitFileFlag string
	GlobalFileSubpath string
	LoadingRules *ClientConfigLoadingRules
}
func (o *PathOptions) GetEnvVarFiles() []string {
	if len(o.EnvVar) == 0 {
		return []string{}
	}
	envVarValue := os.Getenv(o.EnvVar)
	if len(envVarValue) == 0 {
		return []string{}
	}
	fileList := filepath.SplitList(envVarValue)
	return deduplicate(fileList)
}
func (o *PathOptions) GetLoadingPrecedence() []string {
	if envVarFiles := o.GetEnvVarFiles(); len(envVarFiles) > 0 {
		return envVarFiles
	}
	return []string{o.GlobalFile}
}
func (o *PathOptions) GetStartingConfig() (*clientcmdapi.Config, error) {
	loadingRules := *o.LoadingRules
	loadingRules.Precedence = o.GetLoadingPrecedence()
	clientConfig := NewNonInteractiveDeferredLoadingClientConfig(&loadingRules, &ConfigOverrides{})
	rawConfig, err := clientConfig.RawConfig()
	if os.IsNotExist(err) {
		return clientcmdapi.NewConfig(), nil
	}
	if err != nil {
		return nil, err
	}
	return &rawConfig, nil
}
func (o *PathOptions) GetDefaultFilename() string {
	if o.IsExplicitFile() {
		return o.GetExplicitFile()
	}
	if envVarFiles := o.GetEnvVarFiles(); len(envVarFiles) > 0 {
		if len(envVarFiles) == 1 {
			return envVarFiles[0]
		}
		for _, envVarFile := range envVarFiles {
			if _, err := os.Stat(envVarFile); err == nil {
				return envVarFile
			}
		}
		return envVarFiles[len(envVarFiles)-1]
	}
	return o.GlobalFile
}
func (o *PathOptions) IsExplicitFile() bool {
	if len(o.LoadingRules.ExplicitPath) > 0 {
		return true
	}
	return false
}
func (o *PathOptions) GetExplicitFile() string {
	return o.LoadingRules.ExplicitPath
}
func NewDefaultPathOptions() *PathOptions {
	ret := &PathOptions{
		GlobalFile:       RecommendedHomeFile,
		EnvVar:           RecommendedConfigPathEnvVar,
		ExplicitFileFlag: RecommendedConfigPathFlag,
		GlobalFileSubpath: path.Join(RecommendedHomeDir, RecommendedFileName),
		LoadingRules: NewDefaultClientConfigLoadingRules(),
	}
	ret.LoadingRules.DoNotResolvePaths = true
	return ret
}
func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config, relativizePaths bool) error {
	possibleSources := configAccess.GetLoadingPrecedence()
	sort.Strings(possibleSources)
	for _, filename := range possibleSources {
		if err := lockFile(filename); err != nil {
			return err
		}
		defer unlockFile(filename)
	}
	startingConfig, err := configAccess.GetStartingConfig()
	if err != nil {
		return err
	}
	if reflect.DeepEqual(*startingConfig, newConfig) {
		return nil
	}
	if startingConfig.CurrentContext != newConfig.CurrentContext {
		if err := writeCurrentContext(configAccess, newConfig.CurrentContext); err != nil {
			return err
		}
	}
	if !reflect.DeepEqual(startingConfig.Preferences, newConfig.Preferences) {
		if err := writePreferences(configAccess, newConfig.Preferences); err != nil {
			return err
		}
	}
	for key, cluster := range newConfig.Clusters {
		startingCluster, exists := startingConfig.Clusters[key]
		if !reflect.DeepEqual(cluster, startingCluster) || !exists {
			destinationFile := cluster.LocationOfOrigin
			if len(destinationFile) == 0 {
				destinationFile = configAccess.GetDefaultFilename()
			}
			configToWrite, err := getConfigFromFile(destinationFile)
			if err != nil {
				return err
			}
			t := *cluster
			configToWrite.Clusters[key] = &t
			configToWrite.Clusters[key].LocationOfOrigin = destinationFile
			if relativizePaths {
				if err := RelativizeClusterLocalPaths(configToWrite.Clusters[key]); err != nil {
					return err
				}
			}
			if err := WriteToFile(*configToWrite, destinationFile); err != nil {
				return err
			}
		}
	}
	for key, context := range newConfig.Contexts {
		startingContext, exists := startingConfig.Contexts[key]
		if !reflect.DeepEqual(context, startingContext) || !exists {
			destinationFile := context.LocationOfOrigin
			if len(destinationFile) == 0 {
				destinationFile = configAccess.GetDefaultFilename()
			}
			configToWrite, err := getConfigFromFile(destinationFile)
			if err != nil {
				return err
			}
			configToWrite.Contexts[key] = context
			if err := WriteToFile(*configToWrite, destinationFile); err != nil {
				return err
			}
		}
	}
	for key, authInfo := range newConfig.AuthInfos {
		startingAuthInfo, exists := startingConfig.AuthInfos[key]
		if !reflect.DeepEqual(authInfo, startingAuthInfo) || !exists {
			destinationFile := authInfo.LocationOfOrigin
			if len(destinationFile) == 0 {
				destinationFile = configAccess.GetDefaultFilename()
			}
			configToWrite, err := getConfigFromFile(destinationFile)
			if err != nil {
				return err
			}
			t := *authInfo
			configToWrite.AuthInfos[key] = &t
			configToWrite.AuthInfos[key].LocationOfOrigin = destinationFile
			if relativizePaths {
				if err := RelativizeAuthInfoLocalPaths(configToWrite.AuthInfos[key]); err != nil {
					return err
				}
			}
			if err := WriteToFile(*configToWrite, destinationFile); err != nil {
				return err
			}
		}
	}
	for key, cluster := range startingConfig.Clusters {
		if _, exists := newConfig.Clusters[key]; !exists {
			destinationFile := cluster.LocationOfOrigin
			if len(destinationFile) == 0 {
				destinationFile = configAccess.GetDefaultFilename()
			}
			configToWrite, err := getConfigFromFile(destinationFile)
			if err != nil {
				return err
			}
			delete(configToWrite.Clusters, key)
			if err := WriteToFile(*configToWrite, destinationFile); err != nil {
				return err
			}
		}
	}
	for key, context := range startingConfig.Contexts {
		if _, exists := newConfig.Contexts[key]; !exists {
			destinationFile := context.LocationOfOrigin
			if len(destinationFile) == 0 {
				destinationFile = configAccess.GetDefaultFilename()
			}
			configToWrite, err := getConfigFromFile(destinationFile)
			if err != nil {
				return err
			}
			delete(configToWrite.Contexts, key)
			if err := WriteToFile(*configToWrite, destinationFile); err != nil {
				return err
			}
		}
	}
	for key, authInfo := range startingConfig.AuthInfos {
		if _, exists := newConfig.AuthInfos[key]; !exists {
			destinationFile := authInfo.LocationOfOrigin
			if len(destinationFile) == 0 {
				destinationFile = configAccess.GetDefaultFilename()
			}
			configToWrite, err := getConfigFromFile(destinationFile)
			if err != nil {
				return err
			}
			delete(configToWrite.AuthInfos, key)
			if err := WriteToFile(*configToWrite, destinationFile); err != nil {
				return err
			}
		}
	}
	return nil
}
func PersisterForUser(configAccess ConfigAccess, user string) restclient.AuthProviderConfigPersister {
	return &persister{configAccess, user}
}
type persister struct {
	configAccess ConfigAccess
	user         string
}
func (p *persister) Persist(config map[string]string) error {
	newConfig, err := p.configAccess.GetStartingConfig()
	if err != nil {
		return err
	}
	authInfo, ok := newConfig.AuthInfos[p.user]
	if ok && authInfo.AuthProvider != nil {
		authInfo.AuthProvider.Config = config
		ModifyConfig(p.configAccess, *newConfig, false)
	}
	return nil
}
func writeCurrentContext(configAccess ConfigAccess, newCurrentContext string) error {
	if startingConfig, err := configAccess.GetStartingConfig(); err != nil {
		return err
	} else if startingConfig.CurrentContext == newCurrentContext {
		return nil
	}
	if configAccess.IsExplicitFile() {
		file := configAccess.GetExplicitFile()
		currConfig, err := getConfigFromFile(file)
		if err != nil {
			return err
		}
		currConfig.CurrentContext = newCurrentContext
		if err := WriteToFile(*currConfig, file); err != nil {
			return err
		}
		return nil
	}
	if len(newCurrentContext) > 0 {
		destinationFile := configAccess.GetDefaultFilename()
		config, err := getConfigFromFile(destinationFile)
		if err != nil {
			return err
		}
		config.CurrentContext = newCurrentContext
		if err := WriteToFile(*config, destinationFile); err != nil {
			return err
		}
		return nil
	}
	for _, file := range configAccess.GetLoadingPrecedence() {
		if _, err := os.Stat(file); err == nil {
			currConfig, err := getConfigFromFile(file)
			if err != nil {
				return err
			}
			if len(currConfig.CurrentContext) > 0 {
				currConfig.CurrentContext = newCurrentContext
				if err := WriteToFile(*currConfig, file); err != nil {
					return err
				}
				return nil
			}
		}
	}
	return errors.New("no config found to write context")
}
func writePreferences(configAccess ConfigAccess, newPrefs clientcmdapi.Preferences) error {
	if startingConfig, err := configAccess.GetStartingConfig(); err != nil {
		return err
	} else if reflect.DeepEqual(startingConfig.Preferences, newPrefs) {
		return nil
	}
	if configAccess.IsExplicitFile() {
		file := configAccess.GetExplicitFile()
		currConfig, err := getConfigFromFile(file)
		if err != nil {
			return err
		}
		currConfig.Preferences = newPrefs
		if err := WriteToFile(*currConfig, file); err != nil {
			return err
		}
		return nil
	}
	for _, file := range configAccess.GetLoadingPrecedence() {
		currConfig, err := getConfigFromFile(file)
		if err != nil {
			return err
		}
		if !reflect.DeepEqual(currConfig.Preferences, newPrefs) {
			currConfig.Preferences = newPrefs
			if err := WriteToFile(*currConfig, file); err != nil {
				return err
			}
			return nil
		}
	}
	return errors.New("no config found to write preferences")
}
func getConfigFromFile(filename string) (*clientcmdapi.Config, error) {
	config, err := LoadFromFile(filename)
	if err != nil && !os.IsNotExist(err) {
		return nil, err
	}
	if config == nil {
		config = clientcmdapi.NewConfig()
	}
	return config, nil
}