Esempio n. 1
0
// SetupContext creates a new cluster and context in ~/.kube using the provided API Server. If setCurrent is true, it is made the current context.
func SetupContext(clusterName, contextName, kubeAPIServer string, setCurrent bool) error {
	pathOpts := kubectlcfg.NewDefaultPathOptions()
	config, err := getConfig(pathOpts)
	if err != nil {
		return err
	}

	cluster, exists := config.Clusters[clusterName]
	if !exists {
		cluster = kubecfg.NewCluster()
	}

	// configure cluster
	cluster.Server = kubeAPIServer
	cluster.InsecureSkipTLSVerify = true
	config.Clusters[clusterName] = cluster

	context, exists := config.Contexts[contextName]
	if !exists {
		context = kubecfg.NewContext()
	}

	// configure context
	context.Cluster = clusterName
	config.Contexts[contextName] = context

	// set as current if requested
	if setCurrent {
		config.CurrentContext = contextName
	}

	return kubectlcfg.ModifyConfig(pathOpts, *config, true)
}
Esempio n. 2
0
// setupKubeconfig reads config from disk, adds the minikube settings, and writes it back.
// activeContext is true when minikube is the CurrentContext
// If no CurrentContext is set, the given name will be used.
func setupKubeconfig(server, certAuth string) error {
	configFile := constants.KubeconfigPath

	// read existing config or create new if does not exist
	config, err := kubeconfig.ReadConfigOrNew(configFile)
	if err != nil {
		return err
	}

	currentContextName := config.CurrentContext
	currentContext := config.Contexts[currentContextName]

	clusterName, err := ocfg.GetClusterNicknameFromURL(server)
	if err != nil {
		return err
	}
	cluster := cfg.NewCluster()
	cluster.Server = server
	cluster.CertificateAuthorityData = []byte(certAuth)
	config.Clusters[clusterName] = cluster

	// user
	userName := "******" + clusterName
	user := cfg.NewAuthInfo()
	if currentContext != nil && currentContext.AuthInfo == userName {
		currentUser := config.AuthInfos[userName]
		if currentUser != nil {
			user.Token = config.AuthInfos[userName].Token
		}
	}
	config.AuthInfos[userName] = user

	// context
	context := cfg.NewContext()
	context.Cluster = clusterName
	context.AuthInfo = userName
	context.Namespace = api.NamespaceDefault
	contextName := ocfg.GetContextNickname(api.NamespaceDefault, clusterName, userName)
	if currentContext != nil && currentContext.Cluster == clusterName && currentContext.AuthInfo == userName {
		contextName = currentContextName
		context.Namespace = currentContext.Namespace
	}
	config.Contexts[contextName] = context

	config.CurrentContext = contextName

	// write back to disk
	if err := kubeconfig.WriteConfig(config, configFile); err != nil {
		return err
	}

	fmt.Println("oc is now configured to use the cluster.")
	if len(user.Token) == 0 {
		fmt.Println("Run this command to use the cluster: ")
		fmt.Println("oc login --username=admin --password=admin")
	}

	return nil
}
Esempio n. 3
0
func TestSetCurrentContext(t *testing.T) {
	expectedConfig := newRedFederalCowHammerConfig()
	startingConfig := newRedFederalCowHammerConfig()

	newContextName := "the-new-context"

	startingConfig.Contexts[newContextName] = clientcmdapi.NewContext()
	expectedConfig.Contexts[newContextName] = clientcmdapi.NewContext()

	expectedConfig.CurrentContext = newContextName

	test := configCommandTest{
		args:           []string{"use-context", "the-new-context"},
		startingConfig: startingConfig,
		expectedConfig: expectedConfig,
	}

	test.run(t)
}
Esempio n. 4
0
func TestNewEmptyContext(t *testing.T) {
	expectedConfig := *clientcmdapi.NewConfig()
	expectedConfig.Contexts["new-context"] = clientcmdapi.NewContext()
	test := configCommandTest{
		args:           []string{"set-context", "new-context"},
		startingConfig: *clientcmdapi.NewConfig(),
		expectedConfig: expectedConfig,
	}

	test.run(t)
}
Esempio n. 5
0
func TestSetIntoNewConfig(t *testing.T) {
	expectedConfig := *clientcmdapi.NewConfig()
	context := clientcmdapi.NewContext()
	context.AuthInfo = "fake-user"
	expectedConfig.Contexts["new-context"] = context
	test := configCommandTest{
		args:           []string{"set", "contexts.new-context.user", "fake-user"},
		startingConfig: *clientcmdapi.NewConfig(),
		expectedConfig: expectedConfig,
	}

	test.run(t)
}
Esempio n. 6
0
// CreateConfig takes a clientCfg and builds a config (kubeconfig style) from it.
func CreateConfig(namespace string, clientCfg *client.Config) (*clientcmdapi.Config, error) {
	clusterNick, err := GetClusterNicknameFromConfig(clientCfg)
	if err != nil {
		return nil, err
	}

	userNick, err := GetUserNicknameFromConfig(clientCfg)
	if err != nil {
		return nil, err
	}

	contextNick, err := GetContextNicknameFromConfig(namespace, clientCfg)
	if err != nil {
		return nil, err
	}

	config := clientcmdapi.NewConfig()

	credentials := clientcmdapi.NewAuthInfo()
	credentials.Token = clientCfg.BearerToken
	credentials.ClientCertificate = clientCfg.TLSClientConfig.CertFile
	if len(credentials.ClientCertificate) == 0 {
		credentials.ClientCertificateData = clientCfg.TLSClientConfig.CertData
	}
	credentials.ClientKey = clientCfg.TLSClientConfig.KeyFile
	if len(credentials.ClientKey) == 0 {
		credentials.ClientKeyData = clientCfg.TLSClientConfig.KeyData
	}
	config.AuthInfos[userNick] = credentials

	cluster := clientcmdapi.NewCluster()
	cluster.Server = clientCfg.Host
	cluster.CertificateAuthority = clientCfg.CAFile
	if len(cluster.CertificateAuthority) == 0 {
		cluster.CertificateAuthorityData = clientCfg.CAData
	}
	cluster.InsecureSkipTLSVerify = clientCfg.Insecure
	if clientCfg.GroupVersion != nil {
		cluster.APIVersion = clientCfg.GroupVersion.String()
	}
	config.Clusters[clusterNick] = cluster

	context := clientcmdapi.NewContext()
	context.Cluster = clusterNick
	context.AuthInfo = userNick
	context.Namespace = namespace
	config.Contexts[contextNick] = context
	config.CurrentContext = contextNick

	return config, nil
}
Esempio n. 7
0
func TestKubectlValidation(t *testing.T) {
	testCases := []struct {
		data string
		err  bool
	}{
		{`{"apiVersion": "v1", "kind": "thisObjectShouldNotExistInAnyGroup"}`, true},
		{`{"apiVersion": "invalidVersion", "kind": "Pod"}`, true},
		{`{"apiVersion": "v1", "kind": "Pod"}`, false},

		// The following test the experimental api.
		// TODO: Replace with something more robust. These may move.
		{`{"apiVersion": "extensions/v1beta1", "kind": "Ingress"}`, false},
		{`{"apiVersion": "extensions/v1beta1", "kind": "Job"}`, false},
		{`{"apiVersion": "vNotAVersion", "kind": "Job"}`, true},
	}
	components := framework.NewMasterComponents(&framework.Config{})
	defer components.Stop(true, true)
	ctx := clientcmdapi.NewContext()
	cfg := clientcmdapi.NewConfig()
	// Enable swagger api on master.
	components.KubeMaster.InstallSwaggerAPI()
	cluster := clientcmdapi.NewCluster()

	cluster.Server = components.ApiServer.URL
	cluster.InsecureSkipTLSVerify = true
	cfg.Contexts = map[string]*clientcmdapi.Context{"test": ctx}
	cfg.CurrentContext = "test"
	overrides := clientcmd.ConfigOverrides{
		ClusterInfo: *cluster,
	}
	cmdConfig := clientcmd.NewNonInteractiveClientConfig(*cfg, "test", &overrides, nil)
	factory := util.NewFactory(cmdConfig)
	schema, err := factory.Validator(true, "")
	if err != nil {
		t.Errorf("failed to get validator: %v", err)
		return
	}
	for i, test := range testCases {
		err := schema.ValidateBytes([]byte(test.data))
		if err == nil {
			if test.err {
				t.Errorf("case %d: expected error", i)
			}
		} else {
			if !test.err {
				t.Errorf("case %d: unexpected error: %v", i, err)
			}
		}
	}
}
Esempio n. 8
0
func TestAdditionalContext(t *testing.T) {
	expectedConfig := newRedFederalCowHammerConfig()
	context := clientcmdapi.NewContext()
	context.Cluster = "some-cluster"
	context.AuthInfo = "some-user"
	context.Namespace = "different-namespace"
	expectedConfig.Contexts["different-context"] = context
	test := configCommandTest{
		args:           []string{"set-context", "different-context", "--" + clientcmd.FlagClusterName + "=some-cluster", "--" + clientcmd.FlagAuthInfoName + "=some-user", "--" + clientcmd.FlagNamespace + "=different-namespace"},
		startingConfig: newRedFederalCowHammerConfig(),
		expectedConfig: expectedConfig,
	}

	test.run(t)
}
Esempio n. 9
0
func MakeClientConfigWithToken(config *clientcmdapi.Config, clusterName string, userName string, token string) *clientcmdapi.Config {
	newConfig := config
	name := fmt.Sprintf("%s@%s", userName, clusterName)

	authInfo := clientcmdapi.NewAuthInfo()
	authInfo.Token = token

	context := clientcmdapi.NewContext()
	context.Cluster = clusterName
	context.AuthInfo = userName

	newConfig.AuthInfos[userName] = authInfo
	newConfig.Contexts[name] = context
	newConfig.CurrentContext = name

	return newConfig
}
Esempio n. 10
0
func MakeClientConfigWithCerts(config *clientcmdapi.Config, clusterName string, userName string, clientKey []byte, clientCert []byte) *clientcmdapi.Config {
	newConfig := config
	name := fmt.Sprintf("%s@%s", userName, clusterName)

	authInfo := clientcmdapi.NewAuthInfo()
	authInfo.ClientKeyData = clientKey
	authInfo.ClientCertificateData = clientCert

	context := clientcmdapi.NewContext()
	context.Cluster = clusterName
	context.AuthInfo = userName

	newConfig.AuthInfos[userName] = authInfo
	newConfig.Contexts[name] = context
	newConfig.CurrentContext = name

	return newConfig
}
Esempio n. 11
0
func updateKubeconfig(config util.AdminConfig, name, endpoint string, entKeyPairs *entityKeyPairs, dryRun bool) error {
	po := config.PathOptions()
	kubeconfig, err := po.GetStartingConfig()
	if err != nil {
		return err
	}

	// Populate API server endpoint info.
	cluster := clientcmdapi.NewCluster()
	// Prefix "https" as the URL scheme to endpoint.
	if !strings.HasPrefix(endpoint, "https://") {
		endpoint = fmt.Sprintf("https://%s", endpoint)
	}
	cluster.Server = endpoint
	cluster.CertificateAuthorityData = certutil.EncodeCertPEM(entKeyPairs.ca.Cert)

	// Populate credentials.
	authInfo := clientcmdapi.NewAuthInfo()
	authInfo.ClientCertificateData = certutil.EncodeCertPEM(entKeyPairs.admin.Cert)
	authInfo.ClientKeyData = certutil.EncodePrivateKeyPEM(entKeyPairs.admin.Key)
	authInfo.Username = AdminCN

	// Populate context.
	context := clientcmdapi.NewContext()
	context.Cluster = name
	context.AuthInfo = name

	// Update the config struct with API server endpoint info,
	// credentials and context.
	kubeconfig.Clusters[name] = cluster
	kubeconfig.AuthInfos[name] = authInfo
	kubeconfig.Contexts[name] = context

	if !dryRun {
		// Write the update kubeconfig.
		if err := clientcmd.ModifyConfig(po, *kubeconfig, true); err != nil {
			return err
		}
	}

	return nil
}
Esempio n. 12
0
// MergeConfig adds the additional Config stanzas to the startingConfig.  It blindly stomps clusters and users, but
// it searches for a matching context before writing a new one.
func MergeConfig(startingConfig, addition clientcmdapi.Config) (*clientcmdapi.Config, error) {
	ret := startingConfig

	for requestedKey, value := range addition.Clusters {
		ret.Clusters[requestedKey] = value
	}

	for requestedKey, value := range addition.AuthInfos {
		ret.AuthInfos[requestedKey] = value
	}

	requestedContextNamesToActualContextNames := map[string]string{}
	for requestedKey, newContext := range addition.Contexts {
		actualContext := clientcmdapi.NewContext()
		actualContext.AuthInfo = newContext.AuthInfo
		actualContext.Cluster = newContext.Cluster
		actualContext.Namespace = newContext.Namespace
		actualContext.Extensions = newContext.Extensions

		if existingName := FindExistingContextName(startingConfig, *actualContext); len(existingName) > 0 {
			// if this already exists, just move to the next, our job is done
			requestedContextNamesToActualContextNames[requestedKey] = existingName
			continue
		}

		requestedContextNamesToActualContextNames[requestedKey] = requestedKey
		ret.Contexts[requestedKey] = actualContext
	}

	if len(addition.CurrentContext) > 0 {
		if newCurrentContext, exists := requestedContextNamesToActualContextNames[addition.CurrentContext]; exists {
			ret.CurrentContext = newCurrentContext
		} else {
			ret.CurrentContext = addition.CurrentContext
		}
	}

	return &ret, nil
}
Esempio n. 13
0
// setupKubeconfig reads config from disk, adds the minikube settings, and writes it back.
// activeContext is true when minikube is the CurrentContext
// If no CurrentContext is set, the given name will be used.
func setupKubeconfig(name, server, certAuth, cliCert, cliKey string) error {
	configFile := constants.KubeconfigPath

	// read existing config or create new if does not exist
	config, err := kubeconfig.ReadConfigOrNew(configFile)
	if err != nil {
		return err
	}

	clusterName := name
	cluster := cfg.NewCluster()
	cluster.Server = server
	cluster.CertificateAuthority = certAuth
	config.Clusters[clusterName] = cluster

	// user
	userName := name
	user := cfg.NewAuthInfo()
	user.ClientCertificate = cliCert
	user.ClientKey = cliKey
	config.AuthInfos[userName] = user

	// context
	contextName := name
	context := cfg.NewContext()
	context.Cluster = clusterName
	context.AuthInfo = userName
	config.Contexts[contextName] = context

	// Always set current context to minikube.
	config.CurrentContext = contextName

	// write back to disk
	if err := kubeconfig.WriteConfig(config, configFile); err != nil {
		return err
	}
	return nil
}
Esempio n. 14
0
// minikubeConfig returns a config that reasonably approximates a localkube cluster
func minikubeConfig(config *api.Config) {
	// cluster
	clusterName := "minikube"
	cluster := api.NewCluster()
	cluster.Server = "https://192.168.99.100:" + strconv.Itoa(constants.APIServerPort)
	cluster.CertificateAuthority = "/home/tux/.minikube/apiserver.crt"
	config.Clusters[clusterName] = cluster

	// user
	userName := "******"
	user := api.NewAuthInfo()
	user.ClientCertificate = "/home/tux/.minikube/apiserver.crt"
	user.ClientKey = "/home/tux/.minikube/apiserver.key"
	config.AuthInfos[userName] = user

	// context
	contextName := "minikube"
	context := api.NewContext()
	context.Cluster = clusterName
	context.AuthInfo = userName
	config.Contexts[contextName] = context

	config.CurrentContext = contextName
}
func (o createContextOptions) run() error {
	err := o.validate()
	if err != nil {
		return err
	}

	config, err := o.configAccess.GetStartingConfig()
	if err != nil {
		return err
	}

	startingStanza, exists := config.Contexts[o.name]
	if !exists {
		startingStanza = clientcmdapi.NewContext()
	}
	context := o.modifyContext(*startingStanza)
	config.Contexts[o.name] = &context

	if err := clientcmd.ModifyConfig(o.configAccess, *config, true); err != nil {
		return err
	}

	return nil
}
Esempio n. 16
0
func init() {
	err := api.Scheme.AddConversionFuncs(
		func(in *Cluster, out *api.Cluster, s conversion.Scope) error {
			return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
		},
		func(in *api.Cluster, out *Cluster, s conversion.Scope) error {
			return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
		},
		func(in *Preferences, out *api.Preferences, s conversion.Scope) error {
			return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
		},
		func(in *api.Preferences, out *Preferences, s conversion.Scope) error {
			return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
		},
		func(in *AuthInfo, out *api.AuthInfo, s conversion.Scope) error {
			return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
		},
		func(in *api.AuthInfo, out *AuthInfo, s conversion.Scope) error {
			return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
		},
		func(in *Context, out *api.Context, s conversion.Scope) error {
			return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
		},
		func(in *api.Context, out *Context, s conversion.Scope) error {
			return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
		},

		func(in *Config, out *api.Config, s conversion.Scope) error {
			out.CurrentContext = in.CurrentContext
			if err := s.Convert(&in.Preferences, &out.Preferences, 0); err != nil {
				return err
			}

			out.Clusters = make(map[string]*api.Cluster)
			if err := s.Convert(&in.Clusters, &out.Clusters, 0); err != nil {
				return err
			}
			out.AuthInfos = make(map[string]*api.AuthInfo)
			if err := s.Convert(&in.AuthInfos, &out.AuthInfos, 0); err != nil {
				return err
			}
			out.Contexts = make(map[string]*api.Context)
			if err := s.Convert(&in.Contexts, &out.Contexts, 0); err != nil {
				return err
			}
			out.Extensions = make(map[string]runtime.Object)
			if err := s.Convert(&in.Extensions, &out.Extensions, 0); err != nil {
				return err
			}
			return nil
		},
		func(in *api.Config, out *Config, s conversion.Scope) error {
			out.CurrentContext = in.CurrentContext
			if err := s.Convert(&in.Preferences, &out.Preferences, 0); err != nil {
				return err
			}

			out.Clusters = make([]NamedCluster, 0, 0)
			if err := s.Convert(&in.Clusters, &out.Clusters, 0); err != nil {
				return err
			}
			out.AuthInfos = make([]NamedAuthInfo, 0, 0)
			if err := s.Convert(&in.AuthInfos, &out.AuthInfos, 0); err != nil {
				return err
			}
			out.Contexts = make([]NamedContext, 0, 0)
			if err := s.Convert(&in.Contexts, &out.Contexts, 0); err != nil {
				return err
			}
			out.Extensions = make([]NamedExtension, 0, 0)
			if err := s.Convert(&in.Extensions, &out.Extensions, 0); err != nil {
				return err
			}
			return nil
		},
		func(in *[]NamedCluster, out *map[string]*api.Cluster, s conversion.Scope) error {
			for _, curr := range *in {
				newCluster := api.NewCluster()
				if err := s.Convert(&curr.Cluster, newCluster, 0); err != nil {
					return err
				}
				(*out)[curr.Name] = newCluster
			}

			return nil
		},
		func(in *map[string]*api.Cluster, out *[]NamedCluster, s conversion.Scope) error {
			allKeys := make([]string, 0, len(*in))
			for key := range *in {
				allKeys = append(allKeys, key)
			}
			sort.Strings(allKeys)

			for _, key := range allKeys {
				newCluster := (*in)[key]
				oldCluster := &Cluster{}
				if err := s.Convert(newCluster, oldCluster, 0); err != nil {
					return err
				}

				namedCluster := NamedCluster{key, *oldCluster}
				*out = append(*out, namedCluster)
			}

			return nil
		},
		func(in *[]NamedAuthInfo, out *map[string]*api.AuthInfo, s conversion.Scope) error {
			for _, curr := range *in {
				newAuthInfo := api.NewAuthInfo()
				if err := s.Convert(&curr.AuthInfo, newAuthInfo, 0); err != nil {
					return err
				}
				(*out)[curr.Name] = newAuthInfo
			}

			return nil
		},
		func(in *map[string]*api.AuthInfo, out *[]NamedAuthInfo, s conversion.Scope) error {
			allKeys := make([]string, 0, len(*in))
			for key := range *in {
				allKeys = append(allKeys, key)
			}
			sort.Strings(allKeys)

			for _, key := range allKeys {
				newAuthInfo := (*in)[key]
				oldAuthInfo := &AuthInfo{}
				if err := s.Convert(newAuthInfo, oldAuthInfo, 0); err != nil {
					return err
				}

				namedAuthInfo := NamedAuthInfo{key, *oldAuthInfo}
				*out = append(*out, namedAuthInfo)
			}

			return nil
		},
		func(in *[]NamedContext, out *map[string]*api.Context, s conversion.Scope) error {
			for _, curr := range *in {
				newContext := api.NewContext()
				if err := s.Convert(&curr.Context, newContext, 0); err != nil {
					return err
				}
				(*out)[curr.Name] = newContext
			}

			return nil
		},
		func(in *map[string]*api.Context, out *[]NamedContext, s conversion.Scope) error {
			allKeys := make([]string, 0, len(*in))
			for key := range *in {
				allKeys = append(allKeys, key)
			}
			sort.Strings(allKeys)

			for _, key := range allKeys {
				newContext := (*in)[key]
				oldContext := &Context{}
				if err := s.Convert(newContext, oldContext, 0); err != nil {
					return err
				}

				namedContext := NamedContext{key, *oldContext}
				*out = append(*out, namedContext)
			}

			return nil
		},
		func(in *[]NamedExtension, out *map[string]runtime.Object, s conversion.Scope) error {
			for _, curr := range *in {
				var newExtension runtime.Object
				if err := s.Convert(&curr.Extension, &newExtension, 0); err != nil {
					return err
				}
				(*out)[curr.Name] = newExtension
			}

			return nil
		},
		func(in *map[string]runtime.Object, out *[]NamedExtension, s conversion.Scope) error {
			allKeys := make([]string, 0, len(*in))
			for key := range *in {
				allKeys = append(allKeys, key)
			}
			sort.Strings(allKeys)

			for _, key := range allKeys {
				newExtension := (*in)[key]
				oldExtension := &runtime.RawExtension{}
				if err := s.Convert(newExtension, oldExtension, 0); err != nil {
					return err
				}

				namedExtension := NamedExtension{key, *oldExtension}
				*out = append(*out, namedExtension)
			}

			return nil
		},
	)
	if err != nil {
		// If one of the conversion functions is malformed, detect it immediately.
		panic(err)
	}
}
Esempio n. 17
0
func modifyConfig(configAccess clientcmd.ConfigAccess, suppliedConfig *clientcmdapi.Config) error {
	config, err := configAccess.GetStartingConfig()
	if err != nil {
		return err
	}

	for name, authInfo := range suppliedConfig.AuthInfos {
		initial, ok := config.AuthInfos[name]
		if !ok {
			initial = clientcmdapi.NewAuthInfo()
		}
		modifiedAuthInfo := *initial

		var setToken, setBasic bool

		if len(authInfo.ClientCertificate) > 0 {
			modifiedAuthInfo.ClientCertificate = authInfo.ClientCertificate
		}
		if len(authInfo.ClientCertificateData) > 0 {
			modifiedAuthInfo.ClientCertificateData = authInfo.ClientCertificateData
		}

		if len(authInfo.ClientKey) > 0 {
			modifiedAuthInfo.ClientKey = authInfo.ClientKey
		}
		if len(authInfo.ClientKeyData) > 0 {
			modifiedAuthInfo.ClientKeyData = authInfo.ClientKeyData
		}

		if len(authInfo.Token) > 0 {
			modifiedAuthInfo.Token = authInfo.Token
			setToken = len(modifiedAuthInfo.Token) > 0
		}

		if len(authInfo.Username) > 0 {
			modifiedAuthInfo.Username = authInfo.Username
			setBasic = setBasic || len(modifiedAuthInfo.Username) > 0
		}
		if len(authInfo.Password) > 0 {
			modifiedAuthInfo.Password = authInfo.Password
			setBasic = setBasic || len(modifiedAuthInfo.Password) > 0
		}

		// If any auth info was set, make sure any other existing auth types are cleared
		if setToken || setBasic {
			if !setToken {
				modifiedAuthInfo.Token = ""
			}
			if !setBasic {
				modifiedAuthInfo.Username = ""
				modifiedAuthInfo.Password = ""
			}
		}
		config.AuthInfos[name] = &modifiedAuthInfo
	}

	for name, cluster := range suppliedConfig.Clusters {
		initial, ok := config.Clusters[name]
		if !ok {
			initial = clientcmdapi.NewCluster()
		}
		modifiedCluster := *initial

		if len(cluster.Server) > 0 {
			modifiedCluster.Server = cluster.Server
		}
		if cluster.InsecureSkipTLSVerify {
			modifiedCluster.InsecureSkipTLSVerify = cluster.InsecureSkipTLSVerify
			// Specifying insecure mode clears any certificate authority
			if modifiedCluster.InsecureSkipTLSVerify {
				modifiedCluster.CertificateAuthority = ""
				modifiedCluster.CertificateAuthorityData = nil
			}
		}
		if len(cluster.CertificateAuthorityData) > 0 {
			modifiedCluster.CertificateAuthorityData = cluster.CertificateAuthorityData
			modifiedCluster.InsecureSkipTLSVerify = false
		}
		if len(cluster.CertificateAuthority) > 0 {
			modifiedCluster.CertificateAuthority = cluster.CertificateAuthority
			modifiedCluster.InsecureSkipTLSVerify = false
		}
		config.Clusters[name] = &modifiedCluster
	}

	for name, context := range suppliedConfig.Contexts {
		initial, ok := config.Contexts[name]
		if !ok {
			initial = clientcmdapi.NewContext()
		}
		modifiedContext := *initial

		if len(context.Cluster) > 0 {
			modifiedContext.Cluster = context.Cluster
		}
		if len(context.AuthInfo) > 0 {
			modifiedContext.AuthInfo = context.AuthInfo
		}
		if len(context.Namespace) > 0 {
			modifiedContext.Namespace = context.Namespace
		}
		config.Contexts[name] = &modifiedContext
	}

	if err := clientcmd.ModifyConfig(configAccess, *config, true); err != nil {
		return err
	}

	return nil
}