Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow other data types to export and import #16

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func Import(path, file, ver string) error {

// Write each keypair to vault
for _, item := range wrap.Data {
data := make(map[string]string)
data := make(map[string]interface{})
for _, kv := range item.Pairs {
data[kv.Key] = kv.Value
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ type Item struct {
Pairs []Pair `json:"pairs"`
}
type Pair struct {
Key string `json:"key"`
Value string `json:"value"`
Key string `json:"key"`
Value interface{} `json:"value"`
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,5 @@ require (
gopkg.in/yaml.v2 v2.2.1 // indirect
gotest.tools v2.1.0+incompatible // indirect
)

go 1.13
18 changes: 14 additions & 4 deletions it/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ func TestMigrator__integration(t *testing.T) {
data := []struct {
path string
key string
value string
value interface{}
}{
{"secret/foo", "foo", "YmFyCg=="}, // bar
{"secret/bar/baz", "username", "YWRhbQo="}, // adam
{"secret/baz", "integer", 100},
}
os.Setenv("VAULT_ADDR", "http://127.0.0.1:8200")
os.Setenv("VAULT_TOKEN", token)
Expand All @@ -86,9 +87,18 @@ func TestMigrator__integration(t *testing.T) {

// write values
for i := range data {
client.Write(data[i].path, map[string]string{
data[i].key: data[i].value,
}, "1")
m := make(map[string]interface{})

switch d := data[i].value.(type) {
case int:
m[data[i].key] = d
case string:
m[data[i].key] = d
default:
t.Fatal("Error: unsupported data type")
}
client.Write(data[i].path, m, "1")

kv := client.Read(data[i].path)
if kv[data[i].key] != data[i].value {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is reflect.DeepEqual easier to use here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I think the same, json unmarshal code or reflection should be here, just wanted to finish this one really quick, but stuck on integration test

t.Fatalf("path=%q, kv[%s]=%q, value=%q, err=%v", data[i].path, data[i].key, kv[data[i].key], data[i].value, err)
Expand Down
52 changes: 45 additions & 7 deletions vault/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package vault

import (
"encoding/base64"
"encoding/json"
"fmt"
"os"

Expand Down Expand Up @@ -78,13 +79,38 @@ func (v *Vault) Read(path string) map[string]interface{} {
}
for k, v := range s.Data {
switch t := v.(type) {
case json.Number:
if n, err := t.Int64(); err == nil {
out[k] = n
} else if f, err := t.Float64(); err == nil {
out[k] = f
} else {
out[k] = v
}
case string:
out[k] = base64.StdEncoding.EncodeToString([]byte(t))
case map[string]interface{}:
if k == "data" {
for x, y := range t {
if z, ok := y.(string); ok {
out[x] = base64.StdEncoding.EncodeToString([]byte(z))
switch t := y.(type) {
case json.Number:
if n, err := t.Int64(); err == nil {
out[k] = n
} else if f, err := t.Float64(); err == nil {
out[k] = f
} else {
out[k] = y
}
case string:
out[x] = base64.StdEncoding.EncodeToString([]byte(t))
case map[string]interface{}:
js, err := json.Marshal(&t)
if err != nil {
fmt.Println(err)
}
out[x] = base64.StdEncoding.EncodeToString(js)
default:
fmt.Printf("error reading value at %s, key=%s, type=%T\n", path, k, v)
}
}
}
Expand All @@ -97,16 +123,28 @@ func (v *Vault) Read(path string) map[string]interface{} {
}

// Write takes in a vault path and base64 encoded data to be written at that path.
func (v *Vault) Write(path string, data map[string]string, ver string) error {
func (v *Vault) Write(path string, data map[string]interface{}, ver string) error {
body := make(map[string]interface{})

// Decode the base64 values
for k, v := range data {
b, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return err
stringv, ok := v.(string)
if ok {
b, err := base64.StdEncoding.DecodeString(stringv)
if err != nil {
return err
}
isValid := json.Valid(b)
if isValid {
var mapValue map[string]interface{}
json.Unmarshal(b, &mapValue)
body[k] = mapValue
} else {
body[k] = string(b)
}
} else {
body[k] = v
}
body[k] = string(b)
}

var err error
Expand Down