55 "fmt"
66 "os"
77 "strings"
8+ "syscall"
89
910 "os/exec"
1011
@@ -19,6 +20,22 @@ var execCmd = &cobra.Command{
1920 Use : "exec [profile]" ,
2021 Short : "Execute a command with Cloudflare credentials populated" ,
2122 Long : "" ,
23+ Example : `
24+ Execute a single command with credentials populated
25+
26+ $ cf-vault exec example-profile -- env | grep -i cloudflare
27+ CLOUDFLARE_VAULT_SESSION=example-profile
28+ 29+ CLOUDFLARE_API_KEY=s3cr3t
30+
31+ Spawn a new shell with credentials populated
32+
33+ $ cf-vault exec example-profile --
34+ $ env | grep -i cloudflare
35+ CLOUDFLARE_VAULT_SESSION=example-profile
36+ 37+ CLOUDFLARE_API_KEY=s3cr3t
38+ ` ,
2239 Args : func (cmd * cobra.Command , args []string ) error {
2340 if len (args ) < 1 {
2441 return errors .New ("requires a profile argument" )
@@ -32,6 +49,11 @@ var execCmd = &cobra.Command{
3249 },
3350 Run : func (cmd * cobra.Command , args []string ) {
3451 profileName := args [0 ]
52+ // Remove the extra executable name at the beginning of the slice.
53+ copy (args [0 :], args [0 + 1 :])
54+ args [len (args )- 1 ] = ""
55+ args = args [:len (args )- 1 ]
56+
3557 log .Debug ("using profile: " , profileName )
3658
3759 home , err := homedir .Dir ()
@@ -45,42 +67,40 @@ var execCmd = &cobra.Command{
4567 }
4668
4769 if profileSection .Key ("email" ).String () == "" {
48- log .Fatal ( fmt . Sprintf ( "no profile matching %q found in the configuration file at %s" , profileName , defaultFullConfigPath ) )
70+ log .Fatalf ( "no profile matching %q found in the configuration file at %s" , profileName , defaultFullConfigPath )
4971 }
5072
51- ring , _ := keyring .Open (keyring.Config {
52- FileDir : "~/.cf-vault/keys/" ,
53- ServiceName : projectName ,
54- KeychainName : projectName ,
55- })
56-
57- keychain , _ := ring .Get (fmt .Sprintf ("%s-%s" , profileName , profileSection .Key ("auth_type" ).String ()))
58-
59- command := strings .Split (args [1 ], " " )
60- executable := command [0 ]
61- argv0 , err := exec .LookPath (executable )
62- if err != nil {
63- log .Fatalf ("couldn't find the executable '%s': %w" , executable , err )
73+ // Don't allow nesting of cf-vault sessions, it gets messy.
74+ if os .Getenv ("CLOUDFLARE_VAULT_SESSION" ) != "" {
75+ log .Fatal ("cf-vault sessions shouldn't be nested, unset CLOUDFLARE_VAULT_SESSION to continue or open a new shell session" )
6476 }
6577
66- log .Printf ("found executable %s" , argv0 )
67-
68- // Remove the extra executable name at the beginning of the slice.
69- copy (args [0 :], args [0 + 1 :])
70- args [len (args )- 1 ] = ""
71- args = args [:len (args )- 1 ]
78+ ring , _ := keyring .Open (keyringDefaults )
79+ keychain , _ := ring .Get (fmt .Sprintf ("%s-%s" , profileName , profileSection .Key ("auth_type" ).String ()))
7280
73- runningCommand := exec . Command ( executable , args ... )
74- runningCommand . Env = append ( os . Environ ( ),
81+ cloudflareCreds := [] string {
82+ fmt . Sprintf ( "CLOUDFLARE_VAULT_SESSION=%s" , profileName ),
7583 fmt .Sprintf ("CLOUDFLARE_EMAIL=%s" , profileSection .Key ("email" ).String ()),
7684 fmt .Sprintf ("CLOUDFLARE_%s=%s" , strings .ToUpper (profileSection .Key ("auth_type" ).String ()), string (keychain .Data )),
77- )
78- stdoutStderr , err := runningCommand .CombinedOutput ()
85+ }
7986
87+ // Should a command not be provided, drop into a fresh shell with the
88+ // credentials populated alongside the existing env.
89+ if len (args ) == 0 {
90+ log .Debug ("launching new shell with credentials populated" )
91+ envVars := append (syscall .Environ (), cloudflareCreds ... )
92+ syscall .Exec (os .Getenv ("SHELL" ), []string {os .Getenv ("SHELL" )}, envVars )
93+ }
94+
95+ executable := args [0 ]
96+ pathtoExec , err := exec .LookPath (executable )
8097 if err != nil {
81- log .Fatal ( err )
98+ log .Fatalf ( "couldn't find the executable '%s': %w" , pathtoExec , err )
8299 }
83100
84- fmt .Printf ("%s\n " , stdoutStderr )
101+ log .Debugf ("found executable %s" , pathtoExec )
102+ log .Debugf ("executing command: %s" , strings .Join (args , " " ))
103+
104+ syscall .Exec (pathtoExec , args , cloudflareCreds )
85105 },
86106}
0 commit comments