diff --git a/cmd/write.go b/cmd/write.go index 99b2782366360e6cd9c407b04728bf7d23f85625..d06d43a9c4d5b9f36cb66bc99dfb56ad224a0b9e 100644 --- a/cmd/write.go +++ b/cmd/write.go @@ -14,24 +14,35 @@ var writeCmd = &cobra.Command{ Short: "write Short", Long: `write Long`, RunE: func(cmd *cobra.Command, args []string) (err error) { + if len(args) < 2 { return errors.New("Expected at least 2 arguments") } + data, err := vault.GetSecret(args[0]) - if data != nil { - if len(args) == 2 { - var b []byte - b, err = ioutil.ReadAll(os.Stdin) - if err != nil { - return - } - data[args[1]] = string(b) - } else { - data[args[1]] = args[2] + + if vault_err, ok := err.(*vault.Error); ok { + if vault_err.Status != 404 { + return } - err = vault.PostSecret(args[0], data) + data = make(map[string]interface{}) } + + if len(args) == 2 { + var b []byte + b, err = ioutil.ReadAll(os.Stdin) + if err != nil { + return + } + data[args[1]] = string(b) + } else { + data[args[1]] = args[2] + } + + err = vault.PostSecret(args[0], data) + return + }, } diff --git a/vault/http.go b/vault/http.go index 6dee93e46afd31de8ab58964abeaf6de9e930311..ab1deba5aa94adb907ff10a4793d2265fd1c722a 100644 --- a/vault/http.go +++ b/vault/http.go @@ -3,13 +3,24 @@ package vault import ( "bytes" "encoding/json" - "errors" "fmt" "net/http" + "io/ioutil" + "strconv" + "github.com/spf13/viper" ) +type Error struct { + Status int + Message string +} + +func (e *Error) Error() string { + return strconv.Itoa(e.Status) + " : " + e.Message +} + func GetSecret(path string) (data map[string]interface{}, err error) { client := &http.Client{} @@ -34,12 +45,18 @@ func GetSecret(path string) (data map[string]interface{}, err error) { case http.StatusNoContent: data = make(map[string]interface{}) case http.StatusNotFound: - err = errors.New(path + " was not found") + err = &Error{ + Status: res.StatusCode, + Message: "path " + path + " was not found", + } default: var parsed map[string]interface{} defer res.Body.Close() json.NewDecoder(res.Body).Decode(&parsed) - err = errors.New(fmt.Sprint(parsed["errors"])) + err = &Error{ + Status: res.StatusCode, + Message: fmt.Sprint(parsed["errors"]), + } } return @@ -68,10 +85,21 @@ func PostSecret(path string, data map[string]interface{}) (err error) { req.Header.Set("X-Vault-Token", viper.GetString("TOKEN")) req.Header.Set("Content-Type", "application/json") - res, err := client.Do(req) + if err != nil { + return + } + if res.StatusCode != http.StatusNoContent { - err = errors.New(res.Status) + defer res.Body.Close() + body, io_err := ioutil.ReadAll(res.Body) + if io_err != nil { + return + } + err = &Error{ + Status: res.StatusCode, + Message: string(body), + } } return