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") }
func testConfigCommand(args []string, startingConfig clientcmdapi.Config) (string, clientcmdapi.Config) { fakeQingFile, _ := ioutil.TempFile("", "") defer os.Remove(fakeQingFile.Name()) clientcmd.WriteToFile(startingConfig, fakeQingFile.Name()) argsToUse := make([]string, 0, 2+len(args)) argsToUse = append(argsToUse, "--qingconfig="+fakeQingFile.Name()) argsToUse = append(argsToUse, args...) buf := bytes.NewBuffer([]byte{}) cmd := NewCmdConfig(NewDefaultPathOptions(), buf) cmd.SetArgs(argsToUse) cmd.Execute() // outBytes, _ := ioutil.ReadFile(fakeQingFile.Name()) config := getConfigFromFileOrDie(fakeQingFile.Name()) return buf.String(), *config }
// 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 qingconfig cases, newConfig should have at most one difference, // that means that this code will only write into a single file. func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config) 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) configToWrite.Clusters[key] = cluster 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) configToWrite.AuthInfos[key] = authInfo 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 }