From da4434e306fe1f7510709357e49a51b5316252f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Hedenstr=C3=B6m?= <erik@hedenstroem.com> Date: Thu, 12 Mar 2020 13:58:52 +0100 Subject: [PATCH] Implemented powershell compatible output. Added commands for password and upload. --- cmd/password.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ cmd/read.go | 27 +++++++++++++++++---- cmd/upload.go | 32 +++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 cmd/password.go create mode 100644 cmd/upload.go diff --git a/cmd/password.go b/cmd/password.go new file mode 100644 index 0000000..33e15c8 --- /dev/null +++ b/cmd/password.go @@ -0,0 +1,62 @@ +package cmd + +import ( + "crypto/rand" + "encoding/base64" + "errors" + "fmt" + + "github.com/spf13/cobra" + "gitlab.brickchain.com/tools/vaultenv/vault" +) + +var passwordCmd = &cobra.Command{ + Use: "password [flags] path", + Short: "password Retrieve a password stored in vault.", + Long: `password Retrieve a password stored in vault. Creates a new password if none exists`, + RunE: func(cmd *cobra.Command, args []string) error { + + if len(args) < 1 { + return errors.New("Expected at least 1 argument") + } + + data, err := vault.GetSecret(args[0]) + if err != nil { + if vault_err, ok := err.(*vault.Error); ok { + if vault_err.Status != 404 { + return err + } + + data, err = createPwd(args[0]) + if err != nil { + return err + } + } else { + return err + } + } + + fmt.Println(data["PASSWORD"].(string)) + + return nil + + }, +} + +func createPwd(path string) (map[string]interface{}, error) { + + // generate random string of 32 bytes + b := make([]byte, 32) + if _, err := rand.Read(b); err != nil { + return nil, err + } + + data := make(map[string]interface{}) + data["PASSWORD"] = base64.URLEncoding.EncodeToString(b) + + return data, vault.PostSecret(path, data) +} + +func init() { + RootCmd.AddCommand(passwordCmd) +} diff --git a/cmd/read.go b/cmd/read.go index a652661..654b377 100644 --- a/cmd/read.go +++ b/cmd/read.go @@ -16,22 +16,39 @@ import ( var shellFormat bool +// eval $(vaultenv read -s ...) +// vaultenv.exe read -s powershell ... | Invoke-Expression +// vaultenv.exe read -s cmd ..., then copy and paste into shell var readCmd = &cobra.Command{ Use: "read [flags] path", Short: "read Short", Long: `read Long`, RunE: func(cmd *cobra.Command, args []string) (err error) { - if len(args) != 1 { + if len(args) < 1 { return errors.New("Expected 1 argument") } - data, err := vault.GetSecret(args[0]) + data, err := vault.GetSecret(args[len(args)-1]) if data != nil { if shellFormat { + shell := "default" + if len(args) > 1 { + shell = args[0] + } for k, v := range data { qv := strconv.QuoteToASCII(v.(string)) - qv = strings.Replace(qv, "'", "\\x27", -1) - qv = qv[1 : len(qv)-1] - fmt.Printf("%s=$'%s'; export %s;\n", k, qv, k) + switch shell { + case "ps": + fmt.Printf("$Env:%s = %s\n", k, qv) + case "powershell": + fmt.Printf("$Env:%s = %s\n", k, qv) + case "cmd": + qv = qv[1 : len(qv)-1] + fmt.Printf("set %s=%s\n", k, qv) + default: + qv = strings.Replace(qv, "'", "\\x27", -1) + qv = qv[1 : len(qv)-1] + fmt.Printf("%s=$'%s'; export %s;\n", k, qv, k) + } } } else { b, _ := json.MarshalIndent(data, "", "\t") diff --git a/cmd/upload.go b/cmd/upload.go new file mode 100644 index 0000000..92dc406 --- /dev/null +++ b/cmd/upload.go @@ -0,0 +1,32 @@ +package cmd + +import ( + "encoding/base64" + "errors" + "io/ioutil" + + "github.com/spf13/cobra" + "gitlab.hedenstroem.com/go/vaultenv/vault" +) + +var uploadCmd = &cobra.Command{ + Use: "upload [flags] path file", + Short: "upload Short", + Long: `upload Long`, + RunE: func(cmd *cobra.Command, args []string) (err error) { + if len(args) != 2 { + return errors.New("Expected 2 arguments; path and file.") + } + b, err := ioutil.ReadFile(args[1]) + if b != nil { + data := make(map[string]interface{}) + data["file"] = base64.StdEncoding.EncodeToString(b) + err = vault.PostSecret(args[0], data) + } + return + }, +} + +func init() { + RootCmd.AddCommand(uploadCmd) +} -- GitLab