mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 17:07:16 +00:00
Signed-off-by: Anbraten <6918444+anbraten@users.noreply.github.com> Co-authored-by: Dan Garfield <dan@codefresh.io>
145 lines
3.9 KiB
Go
145 lines
3.9 KiB
Go
package commands
|
|
|
|
import (
|
|
stderrors "errors"
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
"text/tabwriter"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/spf13/cobra"
|
|
|
|
argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
|
|
"github.com/argoproj/argo-cd/v3/util/errors"
|
|
"github.com/argoproj/argo-cd/v3/util/localconfig"
|
|
)
|
|
|
|
// NewContextCommand returns a new instance of an `argocd ctx` command
|
|
func NewContextCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
|
var deletion bool
|
|
command := &cobra.Command{
|
|
Use: "context [CONTEXT]",
|
|
Aliases: []string{"ctx"},
|
|
Short: "Switch between contexts",
|
|
Example: `# List Argo CD Contexts
|
|
argocd context
|
|
|
|
# Switch Argo CD context
|
|
argocd context cd.argoproj.io
|
|
|
|
# Delete Argo CD context
|
|
argocd context cd.argoproj.io --delete`,
|
|
Run: func(c *cobra.Command, args []string) {
|
|
localCfg, err := localconfig.ReadLocalConfig(clientOpts.ConfigPath)
|
|
errors.CheckError(err)
|
|
if localCfg == nil {
|
|
fmt.Println("No local configuration found")
|
|
os.Exit(1)
|
|
}
|
|
|
|
if deletion {
|
|
if len(args) == 0 {
|
|
c.HelpFunc()(c, args)
|
|
os.Exit(1)
|
|
}
|
|
err := deleteContext(args[0], clientOpts.ConfigPath)
|
|
errors.CheckError(err)
|
|
return
|
|
}
|
|
|
|
if len(args) == 0 {
|
|
printArgoCDContexts(clientOpts.ConfigPath)
|
|
return
|
|
}
|
|
|
|
ctxName := args[0]
|
|
|
|
argoCDDir, err := localconfig.DefaultConfigDir()
|
|
errors.CheckError(err)
|
|
prevCtxFile := path.Join(argoCDDir, ".prev-ctx")
|
|
|
|
if ctxName == "-" {
|
|
prevCtxBytes, err := os.ReadFile(prevCtxFile)
|
|
errors.CheckError(err)
|
|
ctxName = string(prevCtxBytes)
|
|
}
|
|
if localCfg.CurrentContext == ctxName {
|
|
fmt.Printf("Already at context '%s'\n", localCfg.CurrentContext)
|
|
return
|
|
}
|
|
if _, err = localCfg.ResolveContext(ctxName); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
prevCtx := localCfg.CurrentContext
|
|
localCfg.CurrentContext = ctxName
|
|
|
|
err = localconfig.WriteLocalConfig(*localCfg, clientOpts.ConfigPath)
|
|
errors.CheckError(err)
|
|
err = os.WriteFile(prevCtxFile, []byte(prevCtx), 0o644)
|
|
errors.CheckError(err)
|
|
fmt.Printf("Switched to context '%s'\n", localCfg.CurrentContext)
|
|
},
|
|
}
|
|
command.Flags().BoolVar(&deletion, "delete", false, "Delete the context instead of switching to it")
|
|
return command
|
|
}
|
|
|
|
func deleteContext(context, configPath string) error {
|
|
localCfg, err := localconfig.ReadLocalConfig(configPath)
|
|
errors.CheckError(err)
|
|
if localCfg == nil {
|
|
return stderrors.New("nothing to logout from")
|
|
}
|
|
|
|
serverName, ok := localCfg.RemoveContext(context)
|
|
if !ok {
|
|
return fmt.Errorf("context %s does not exist", context)
|
|
}
|
|
_ = localCfg.RemoveUser(context)
|
|
_ = localCfg.RemoveServer(serverName)
|
|
|
|
if localCfg.IsEmpty() {
|
|
err = localconfig.DeleteLocalConfig(configPath)
|
|
errors.CheckError(err)
|
|
} else {
|
|
if localCfg.CurrentContext == context {
|
|
localCfg.CurrentContext = ""
|
|
}
|
|
err = localconfig.ValidateLocalConfig(*localCfg)
|
|
if err != nil {
|
|
return stderrors.New("error in logging out")
|
|
}
|
|
err = localconfig.WriteLocalConfig(*localCfg, configPath)
|
|
errors.CheckError(err)
|
|
}
|
|
fmt.Printf("Context '%s' deleted\n", context)
|
|
return nil
|
|
}
|
|
|
|
func printArgoCDContexts(configPath string) {
|
|
localCfg, err := localconfig.ReadLocalConfig(configPath)
|
|
errors.CheckError(err)
|
|
if localCfg == nil {
|
|
log.Fatalf("No contexts defined in %s", configPath)
|
|
}
|
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
|
defer func() { _ = w.Flush() }()
|
|
columnNames := []string{"CURRENT", "NAME", "SERVER"}
|
|
_, err = fmt.Fprintf(w, "%s\n", strings.Join(columnNames, "\t"))
|
|
errors.CheckError(err)
|
|
|
|
for _, contextRef := range localCfg.Contexts {
|
|
context, err := localCfg.ResolveContext(contextRef.Name)
|
|
if err != nil {
|
|
log.Warnf("Context '%s' had error: %v", contextRef.Name, err)
|
|
}
|
|
prefix := " "
|
|
if localCfg.CurrentContext == context.Name {
|
|
prefix = "*"
|
|
}
|
|
_, err = fmt.Fprintf(w, "%s\t%s\t%s\n", prefix, context.Name, context.Server.Server)
|
|
errors.CheckError(err)
|
|
}
|
|
}
|