From 47eefa1faf8b00c7c1888469edb5f2f3baf6e400 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Thu, 17 Sep 2020 09:26:40 +1000 Subject: [PATCH] exec: spawn new shell on no arguments When no arguments are provided, spawn a fresh shell with the current environment and the credentials populated. --- cmd/exec.go | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/cmd/exec.go b/cmd/exec.go index 2dd8c98..d2c19b5 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "strings" + "syscall" "os/exec" @@ -50,31 +51,40 @@ var execCmd = &cobra.Command{ } if profileSection.Key("email").String() == "" { - log.Fatal(fmt.Sprintf("no profile matching %q found in the configuration file at %s", profileName, defaultFullConfigPath)) + log.Fatalf("no profile matching %q found in the configuration file at %s", profileName, defaultFullConfigPath) } - - command := strings.Split(args[1], " ") - executable := command[0] - argv0, err := exec.LookPath(executable) - if err != nil { - log.Fatalf("couldn't find the executable '%s': %w", executable, err) + // Don't allow nesting of cf-vault sessions, it gets messy. + if os.Getenv("CLOUDFLARE_VAULT_SESSION") != "" { + log.Fatal("cf-vault sessions shouldn't be nested, unset CLOUDFLARE_VAULT_SESSION to continue or open a new shell session") } ring, _ := keyring.Open(keyringDefaults) keychain, _ := ring.Get(fmt.Sprintf("%s-%s", profileName, profileSection.Key("auth_type").String())) - runningCommand := exec.Command(executable, args...) - runningCommand.Env = append(os.Environ(), + cloudflareCreds := []string{ + fmt.Sprintf("CLOUDFLARE_VAULT_SESSION=%s", profileName), fmt.Sprintf("CLOUDFLARE_EMAIL=%s", profileSection.Key("email").String()), fmt.Sprintf("CLOUDFLARE_%s=%s", strings.ToUpper(profileSection.Key("auth_type").String()), string(keychain.Data)), - ) - stdoutStderr, err := runningCommand.CombinedOutput() + } + // Should a command not be provided, drop into a fresh shell with the + // credentials populated alongside the existing env. + if len(args) == 0 { + log.Debug("launching new shell with credentials populated") + envVars := append(syscall.Environ(), cloudflareCreds...) + syscall.Exec(os.Getenv("SHELL"), []string{os.Getenv("SHELL")}, envVars) + } + + executable := args[0] + pathtoExec, err := exec.LookPath(executable) if err != nil { - log.Fatal(err) + log.Fatalf("couldn't find the executable '%s': %w", pathtoExec, err) } - fmt.Printf("%s\n", stdoutStderr) + log.Debugf("found executable %s", pathtoExec) + log.Debugf("executing command: %s", strings.Join(args, " ")) + + syscall.Exec(pathtoExec, args, cloudflareCreds) }, }