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 := getConfigFromFileOrDie(file) currConfig.Preferences = newPrefs if err := clientcmd.WriteToFile(*currConfig, file); err != nil { return err } return nil } for _, file := range configAccess.GetLoadingPrecedence() { currConfig := getConfigFromFileOrDie(file) if !reflect.DeepEqual(currConfig.Preferences, newPrefs) { currConfig.Preferences = newPrefs if err := clientcmd.WriteToFile(*currConfig, file); err != nil { return err } return nil } } return errors.New("no config found to write preferences") }
// writeCurrentContext takes three possible paths. // If newCurrentContext is the same as the startingConfig's current context, then we exit. // If newCurrentContext has a value, then that value is written into the default destination file. // If newCurrentContext is empty, then we find the config file that is setting the CurrentContext and clear the value from that file 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 := getConfigFromFileOrDie(file) currConfig.CurrentContext = newCurrentContext if err := clientcmd.WriteToFile(*currConfig, file); err != nil { return err } return nil } if len(newCurrentContext) > 0 { destinationFile := configAccess.GetDefaultFilename() config := getConfigFromFileOrDie(destinationFile) config.CurrentContext = newCurrentContext if err := clientcmd.WriteToFile(*config, destinationFile); err != nil { return err } return nil } // we're supposed to be clearing the current context. We need to find the first spot in the chain that is setting it and clear it for _, file := range configAccess.GetLoadingPrecedence() { if _, err := os.Stat(file); err == nil { currConfig := getConfigFromFileOrDie(file) if len(currConfig.CurrentContext) > 0 { currConfig.CurrentContext = newCurrentContext if err := clientcmd.WriteToFile(*currConfig, file); err != nil { return err } return nil } } } return errors.New("no config found to write context") }
// ChangeUser changes the user used by the current CLI session. func (c *CLI) ChangeUser(name string) *CLI { adminClientConfig, err := testutil.GetClusterAdminClientConfig(c.adminConfigPath) if err != nil { FatalErr(err) } _, _, clientConfig, err := testutil.GetClientForUser(*adminClientConfig, name) if err != nil { FatalErr(err) } kubeConfig, err := config.CreateConfig(c.Namespace(), clientConfig) if err != nil { FatalErr(err) } c.configPath = filepath.Join(c.outputDir, name+".kubeconfig") err = clientcmd.WriteToFile(*kubeConfig, c.configPath) if err != nil { FatalErr(err) } c.username = name fmt.Printf("INFO: configPath is now %q\n", c.configPath) return c }
func writeClientConfigToKubeConfig(config kclient.Config, path string) error { kubeConfig := &clientcmdapi.Config{ Clusters: map[string]*clientcmdapi.Cluster{"myserver": {Server: config.Host, CertificateAuthority: config.CAFile, CertificateAuthorityData: config.CAData}}, AuthInfos: map[string]*clientcmdapi.AuthInfo{"myuser": {Token: config.BearerToken}}, Contexts: map[string]*clientcmdapi.Context{"mycontext": {Cluster: "myserver", AuthInfo: "myuser"}}, CurrentContext: "mycontext", } if err := os.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil { return err } if err := clientcmd.WriteToFile(*kubeConfig, path); err != nil { return err } return nil }
func testConfigCommand(args []string, startingConfig clientcmdapi.Config, t *testing.T) (string, clientcmdapi.Config) { fakeKubeFile, _ := ioutil.TempFile("", "") defer os.Remove(fakeKubeFile.Name()) err := clientcmd.WriteToFile(startingConfig, fakeKubeFile.Name()) if err != nil { t.Fatalf("unexpected error: %v", err) } argsToUse := make([]string, 0, 2+len(args)) argsToUse = append(argsToUse, "--kubeconfig="+fakeKubeFile.Name()) argsToUse = append(argsToUse, args...) buf := bytes.NewBuffer([]byte{}) cmd := NewCmdConfig(NewDefaultPathOptions(), buf) cmd.SetArgs(argsToUse) cmd.Execute() // outBytes, _ := ioutil.ReadFile(fakeKubeFile.Name()) config := getConfigFromFileOrDie(fakeKubeFile.Name()) return buf.String(), *config }
func (o CreateKubeConfigOptions) CreateKubeConfig() (*clientcmdapi.Config, error) { glog.V(4).Infof("creating a .kubeconfig with: %#v", o) // read all the referenced filenames caData, err := ioutil.ReadFile(o.APIServerCAFile) if err != nil { return nil, err } certData, err := ioutil.ReadFile(o.CertFile) if err != nil { return nil, err } keyData, err := ioutil.ReadFile(o.KeyFile) if err != nil { return nil, err } certConfig, err := crypto.GetTLSCertificateConfig(o.CertFile, o.KeyFile) if err != nil { return nil, err } // determine all the nicknames clusterNick, err := cliconfig.GetClusterNicknameFromURL(o.APIServerURL) if err != nil { return nil, err } userNick, err := cliconfig.GetUserNicknameFromCert(clusterNick, certConfig.Certs...) if err != nil { return nil, err } contextNick, err := cliconfig.GetContextNickname(o.ContextNamespace, clusterNick, userNick) if err != nil { return nil, err } credentials := make(map[string]*clientcmdapi.AuthInfo) credentials[userNick] = &clientcmdapi.AuthInfo{ ClientCertificateData: certData, ClientKeyData: keyData, } clusters := make(map[string]*clientcmdapi.Cluster) clusters[clusterNick] = &clientcmdapi.Cluster{ Server: o.APIServerURL, CertificateAuthorityData: caData, } contexts := make(map[string]*clientcmdapi.Context) contexts[contextNick] = &clientcmdapi.Context{Cluster: clusterNick, AuthInfo: userNick, Namespace: o.ContextNamespace} createPublic := (len(o.PublicAPIServerURL) > 0) && o.APIServerURL != o.PublicAPIServerURL if createPublic { publicClusterNick, err := cliconfig.GetClusterNicknameFromURL(o.PublicAPIServerURL) if err != nil { return nil, err } publicContextNick, err := cliconfig.GetContextNickname(o.ContextNamespace, publicClusterNick, userNick) if err != nil { return nil, err } clusters[publicClusterNick] = &clientcmdapi.Cluster{ Server: o.PublicAPIServerURL, CertificateAuthorityData: caData, } contexts[publicContextNick] = &clientcmdapi.Context{Cluster: publicClusterNick, AuthInfo: userNick, Namespace: o.ContextNamespace} } kubeConfig := &clientcmdapi.Config{ Clusters: clusters, AuthInfos: credentials, Contexts: contexts, CurrentContext: contextNick, } glog.V(3).Infof("Generating '%s' API client config as %s\n", userNick, o.KubeConfigFile) // Ensure the parent dir exists if err := os.MkdirAll(filepath.Dir(o.KubeConfigFile), os.FileMode(0755)); err != nil { return nil, err } if err := clientcmd.WriteToFile(*kubeConfig, o.KubeConfigFile); err != nil { return nil, err } return kubeConfig, nil }
// ModifyConfig takes a Config object, iterates through Clusters, AuthInfos, and Contexts, uses the LocationOfOrigin if specified or // uses the default destination file to write the results into. This results in multiple file reads, but it's very easy to follow. // Preferences and CurrentContext should always be set in the default destination file. Since we can't distinguish between empty and missing values // (no nil strings), we're forced have separate handling for them. In the kubeconfig cases, newConfig should have at most one difference, // that means that this code will only write into a single file. If you want to relativizePaths, you must provide a fully qualified path in any // modified element. func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config, relativizePaths bool) error { startingConfig, err := configAccess.GetStartingConfig() if err != nil { return err } // We need to find all differences, locate their original files, read a partial config to modify only that stanza and write out the file. // Special case the test for current context and preferences since those always write to the default file. if reflect.DeepEqual(*startingConfig, newConfig) { // nothing to do 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 } } // Search every cluster, authInfo, and context. First from new to old for differences, then from old to new for deletions 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 := getConfigFromFileOrDie(destinationFile) t := *cluster configToWrite.Clusters[key] = &t configToWrite.Clusters[key].LocationOfOrigin = destinationFile if relativizePaths { if err := clientcmd.RelativizeClusterLocalPaths(configToWrite.Clusters[key]); err != nil { return err } } if err := clientcmd.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 := getConfigFromFileOrDie(destinationFile) configToWrite.Contexts[key] = context if err := clientcmd.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 := getConfigFromFileOrDie(destinationFile) t := *authInfo configToWrite.AuthInfos[key] = &t configToWrite.AuthInfos[key].LocationOfOrigin = destinationFile if relativizePaths { if err := clientcmd.RelativizeAuthInfoLocalPaths(configToWrite.AuthInfos[key]); err != nil { return err } } if err := clientcmd.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 := getConfigFromFileOrDie(destinationFile) delete(configToWrite.Clusters, key) if err := clientcmd.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 := getConfigFromFileOrDie(destinationFile) delete(configToWrite.Contexts, key) if err := clientcmd.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 := getConfigFromFileOrDie(destinationFile) delete(configToWrite.AuthInfos, key) if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil { return err } } } return nil }