github.com/argoproj/argo-cd/v3@v3.2.1/cmd/argocd/commands/context.go (about) 1 package commands 2 3 import ( 4 stderrors "errors" 5 "fmt" 6 "os" 7 "path" 8 "strings" 9 "text/tabwriter" 10 11 log "github.com/sirupsen/logrus" 12 "github.com/spf13/cobra" 13 14 argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient" 15 "github.com/argoproj/argo-cd/v3/util/errors" 16 "github.com/argoproj/argo-cd/v3/util/localconfig" 17 ) 18 19 // NewContextCommand returns a new instance of an `argocd ctx` command 20 func NewContextCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { 21 var deletion bool 22 command := &cobra.Command{ 23 Use: "context [CONTEXT]", 24 Aliases: []string{"ctx"}, 25 Short: "Switch between contexts", 26 Example: `# List Argo CD Contexts 27 argocd context 28 29 # Switch Argo CD context 30 argocd context cd.argoproj.io 31 32 # Delete Argo CD context 33 argocd context cd.argoproj.io --delete`, 34 Run: func(c *cobra.Command, args []string) { 35 localCfg, err := localconfig.ReadLocalConfig(clientOpts.ConfigPath) 36 errors.CheckError(err) 37 38 if deletion { 39 if len(args) == 0 { 40 c.HelpFunc()(c, args) 41 os.Exit(1) 42 } 43 err := deleteContext(args[0], clientOpts.ConfigPath) 44 errors.CheckError(err) 45 return 46 } 47 48 if len(args) == 0 { 49 printArgoCDContexts(clientOpts.ConfigPath) 50 return 51 } 52 53 ctxName := args[0] 54 55 argoCDDir, err := localconfig.DefaultConfigDir() 56 errors.CheckError(err) 57 prevCtxFile := path.Join(argoCDDir, ".prev-ctx") 58 59 if ctxName == "-" { 60 prevCtxBytes, err := os.ReadFile(prevCtxFile) 61 errors.CheckError(err) 62 ctxName = string(prevCtxBytes) 63 } 64 if localCfg.CurrentContext == ctxName { 65 fmt.Printf("Already at context '%s'\n", localCfg.CurrentContext) 66 return 67 } 68 if _, err = localCfg.ResolveContext(ctxName); err != nil { 69 log.Fatal(err) 70 } 71 prevCtx := localCfg.CurrentContext 72 localCfg.CurrentContext = ctxName 73 74 err = localconfig.WriteLocalConfig(*localCfg, clientOpts.ConfigPath) 75 errors.CheckError(err) 76 err = os.WriteFile(prevCtxFile, []byte(prevCtx), 0o644) 77 errors.CheckError(err) 78 fmt.Printf("Switched to context '%s'\n", localCfg.CurrentContext) 79 }, 80 } 81 command.Flags().BoolVar(&deletion, "delete", false, "Delete the context instead of switching to it") 82 return command 83 } 84 85 func deleteContext(context, configPath string) error { 86 localCfg, err := localconfig.ReadLocalConfig(configPath) 87 errors.CheckError(err) 88 if localCfg == nil { 89 return stderrors.New("nothing to logout from") 90 } 91 92 serverName, ok := localCfg.RemoveContext(context) 93 if !ok { 94 return fmt.Errorf("context %s does not exist", context) 95 } 96 _ = localCfg.RemoveUser(context) 97 _ = localCfg.RemoveServer(serverName) 98 99 if localCfg.IsEmpty() { 100 err = localconfig.DeleteLocalConfig(configPath) 101 errors.CheckError(err) 102 } else { 103 if localCfg.CurrentContext == context { 104 localCfg.CurrentContext = "" 105 } 106 err = localconfig.ValidateLocalConfig(*localCfg) 107 if err != nil { 108 return stderrors.New("error in logging out") 109 } 110 err = localconfig.WriteLocalConfig(*localCfg, configPath) 111 errors.CheckError(err) 112 } 113 fmt.Printf("Context '%s' deleted\n", context) 114 return nil 115 } 116 117 func printArgoCDContexts(configPath string) { 118 localCfg, err := localconfig.ReadLocalConfig(configPath) 119 errors.CheckError(err) 120 if localCfg == nil { 121 log.Fatalf("No contexts defined in %s", configPath) 122 } 123 w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) 124 defer func() { _ = w.Flush() }() 125 columnNames := []string{"CURRENT", "NAME", "SERVER"} 126 _, err = fmt.Fprintf(w, "%s\n", strings.Join(columnNames, "\t")) 127 errors.CheckError(err) 128 129 for _, contextRef := range localCfg.Contexts { 130 context, err := localCfg.ResolveContext(contextRef.Name) 131 if err != nil { 132 log.Warnf("Context '%s' had error: %v", contextRef.Name, err) 133 } 134 prefix := " " 135 if localCfg.CurrentContext == context.Name { 136 prefix = "*" 137 } 138 _, err = fmt.Fprintf(w, "%s\t%s\t%s\n", prefix, context.Name, context.Server.Server) 139 errors.CheckError(err) 140 } 141 }