Skip to content

Commit

Permalink
Fixed search and tree to be able to distinguish between KV version 1 …
Browse files Browse the repository at this point in the history
…and version 2
  • Loading branch information
ilijamt committed Mar 13, 2020
1 parent 9106e39 commit 6eab2c6
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 6 deletions.
73 changes: 72 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Requires that you have **VAULT_ADDR** set in your environment. For the token you

Take care when using the **tree** and **search** functionality as if there are a lot of paths the process can take quite a while.

**IMPORTANT**: If you want to search on a KV v2 backend make sure you prefix your path with **secret/metadata**, where **secret** is the name of the backend you want to search in.
**IMPORTANT**: If you want to delete from a KV v2 backend make sure you prefix your path with **secret/metadata**, where **secret** is the name of the backend you want to delete in.

## Badges

Expand Down Expand Up @@ -60,3 +60,74 @@ brew install vht
snap install vht
```

## Example

Create a docker instance
```shell script
docker run -d --rm --cap-add=IPC_LOCK -p 1234:1234 --name vault -e 'VAULT_DEV_ROOT_TOKEN_ID=myroot' -e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:1234' vault
```

Now let's pre fill it with some data
```shell script

export VAULT_ADDR='http://127.0.0.1:1234'
export VAULT_TOKEN=myroot
vault secrets enable -version=2 -path kv2 kv
vault secrets enable -version=1 -path kv1 kv
export KV_DATE=$(date +%s)

vht search -r kv1
vht search -r kv2

vault kv put kv1/abba timestamp=$KV_DATE value=abba
vault kv put kv1/abba/caab/qaz timestamp=$KV_DATE value=qaz
vault kv put kv1/qaz/abba/caab timestamp=$KV_DATE value=caab
vault kv put kv1/abba/overwrite timestamp=$KV_DATE value=overwrite
vault kv put kv1/abba/overwrite timestamp=$KV_DATE value=overriden

vault kv put kv2/abba timestamp=$KV_DATE value=abba
vault kv put kv2/abba/caab/qaz timestamp=$KV_DATE value=qaz
vault kv put kv2/qaz/abba/caab timestamp=$KV_DATE value=caab
vault kv put kv2/abba/overwrite timestamp=$KV_DATE value=overwrite
vault kv put kv2/abba/overwrite timestamp=$KV_DATE value=overriden
```

Let's see it in action

```
$ vht search -r kv1 -k "q.z"
kv1/abba/caab/qaz
-----------------
timestamp = 1584114901
value = qaz
kv1/qaz/abba/caab
-----------------
timestamp = 1584114901
value = caab
$ vht search -r kv2 -k "q.z" -f "c*b"
kv2/qaz/abba/caab
-----------------
timestamp = 1584114901
value = caab
$ vht search -r kv2 -k "q.z"
kv2/abba/caab/qaz
-----------------
timestamp = 1584114901
value = qaz
kv2/qaz/abba/caab
-----------------
timestamp = 1584114901
value = caab
$ vht search -r kv1 -k "q.z" -f "c*b"
kv1/qaz/abba/caab
-----------------
timestamp = 1584114901
value = caab
```

34 changes: 30 additions & 4 deletions cmd/vht/cmd/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ var searchCmd = &cobra.Command{
return err
}

mountPoint := strings.Split(rootPath, "/")[0] + "/"
isv2, err := vault.IsV2(mountPoint, client)
if err != nil {
return err
}

dataFilter, _ := cmd.Flags().GetString("data-filter")
rDataFilter, err := regexp.Compile(dataFilter)
if err != nil {
Expand All @@ -42,6 +48,10 @@ var searchCmd = &cobra.Command{
return err
}

// we need to assemble the path if we are searching in a v2 kv store
if isv2 {
rootPath = strings.ReplaceAll(mountPoint+"/metadata/"+strings.Join(strings.Split(rootPath, "/")[1:], "/"), "//", "/")
}
if paths, err = getTree(serial, rootPath, client, concurrent); err != nil {
return err
}
Expand All @@ -51,29 +61,45 @@ var searchCmd = &cobra.Command{
}

type FilteredData struct {
Path string
Data map[string]interface{}
Path string
Data map[string]interface{}
Metadata map[string]interface{}
}

var data []FilteredData
var muLock = &sync.Mutex{}
var task = func(path string) func() {
return func() {
secret, err := client.Logical().Read(path)
var pathv = path
if isv2 {
path = strings.ReplaceAll(path, "/metadata/", "/")
parts := strings.Split(path, "/")
pathv = parts[0] + "/data/" + strings.Join(parts[1:], "/")
}
secret, err := client.Logical().Read(pathv)
if err != nil {
fmt.Println(err)
return
}

j, err := jsonutil.EncodeJSON(secret.Data)
if err != nil {
fmt.Println(err)
return
}

if rDataFilter.MatchString(string(j)) {
muLock.Lock()
data = append(data, FilteredData{Path: path, Data: secret.Data})
var payload = secret.Data
var metadata map[string]interface{}
if isv2 {
payload = secret.Data["data"].(map[string]interface{})
metadata = secret.Data["metadata"].(map[string]interface{})
}
data = append(data, FilteredData{Path: path, Data: payload, Metadata: metadata})
muLock.Unlock()
}

}
}

Expand Down
11 changes: 10 additions & 1 deletion cmd/vht/cmd/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/ilijamt/vht/internal/vault"
"github.com/spf13/cobra"
"regexp"
"strings"
)

var treeCmd = &cobra.Command{
Expand All @@ -28,14 +29,22 @@ var treeCmd = &cobra.Command{
if err != nil {
return err
}
mountPoint := strings.Split(rootPath, "/")[0] + "/"
isv2, err := vault.IsV2(mountPoint, client)
if err != nil {
return err
}
if isv2 {
rootPath = strings.ReplaceAll(mountPoint+"/metadata/"+strings.Join(strings.Split(rootPath, "/")[1:], "/"), "//", "/")
}
if paths, err = getTree(serial, rootPath, client, concurrent); err != nil {
return err
}
if len(paths) == 0 {
return nil
}
for _, path := range vault.FilterDataPaths(paths, rFilter) {
fmt.Println(path)
fmt.Println(strings.ReplaceAll(path, "/metadata/", "/"))
}
return err
},
Expand Down

0 comments on commit 6eab2c6

Please sign in to comment.