logical/framework: PathMap can get missing things
This commit is contained in:
parent
4138e43f00
commit
83de0fd03d
|
@ -0,0 +1,105 @@
|
|||
package framework
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
)
|
||||
|
||||
// PathMap can be used to generate a path that stores mappings in the
|
||||
// storage. It is a structure that also exports functions for querying the
|
||||
// mappings.
|
||||
//
|
||||
// The primary use case for this is for credential providers to do their
|
||||
// mapping to policies.
|
||||
type PathMap struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// Get reads a value out of the mapping
|
||||
func (p *PathMap) Get(s logical.Storage, k string) (string, error) {
|
||||
entry, err := s.Get(fmt.Sprintf("map/%s/%s", p.Name, k))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if entry == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return string(entry.Value), nil
|
||||
}
|
||||
|
||||
// Put writes a value into the mapping
|
||||
func (p *PathMap) Put(s logical.Storage, k string, v string) error {
|
||||
return s.Put(&logical.StorageEntry{
|
||||
Key: fmt.Sprintf("map/%s/%s", p.Name, k),
|
||||
Value: []byte(v),
|
||||
})
|
||||
}
|
||||
|
||||
// Paths are the paths to append to the Backend paths.
|
||||
func (p *PathMap) Paths() []*Path {
|
||||
return []*Path{
|
||||
&Path{
|
||||
Pattern: fmt.Sprintf("map/%s$", p.Name),
|
||||
|
||||
Callbacks: map[logical.Operation]OperationFunc{
|
||||
logical.ListOperation: p.pathList,
|
||||
logical.ReadOperation: p.pathList,
|
||||
},
|
||||
},
|
||||
|
||||
&Path{
|
||||
Pattern: fmt.Sprintf("map/%s/(?P<key>\\w+)", p.Name),
|
||||
|
||||
Fields: map[string]*FieldSchema{
|
||||
"key": &FieldSchema{
|
||||
Type: TypeString,
|
||||
Description: "Key for the mapping",
|
||||
},
|
||||
|
||||
"value": &FieldSchema{
|
||||
Type: TypeString,
|
||||
Description: "Value for the mapping",
|
||||
},
|
||||
},
|
||||
|
||||
Callbacks: map[logical.Operation]OperationFunc{
|
||||
logical.WriteOperation: p.pathSingleWrite,
|
||||
logical.ReadOperation: p.pathSingleRead,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PathMap) pathList(
|
||||
req *logical.Request, d *FieldData) (*logical.Response, error) {
|
||||
keys, err := req.Storage.List(req.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return logical.ListResponse(keys), nil
|
||||
}
|
||||
|
||||
func (p *PathMap) pathSingleRead(
|
||||
req *logical.Request, d *FieldData) (*logical.Response, error) {
|
||||
v, err := p.Get(req.Storage, d.Get("key").(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &logical.Response{
|
||||
Data: map[string]interface{}{
|
||||
"value": v,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *PathMap) pathSingleWrite(
|
||||
req *logical.Request, d *FieldData) (*logical.Response, error) {
|
||||
err := p.Put(
|
||||
req.Storage,
|
||||
d.Get("key").(string), d.Get("value").(string))
|
||||
return nil, err
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package framework
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
)
|
||||
|
||||
func TestPathMap(t *testing.T) {
|
||||
p := &PathMap{Name: "foo"}
|
||||
storage := new(logical.InmemStorage)
|
||||
var b logical.Backend = &Backend{Paths: p.Paths()}
|
||||
|
||||
// Write via HTTP
|
||||
_, err := b.HandleRequest(&logical.Request{
|
||||
Operation: logical.WriteOperation,
|
||||
Path: "map/foo/a",
|
||||
Data: map[string]interface{}{
|
||||
"value": "bar",
|
||||
},
|
||||
Storage: storage,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %#v", err)
|
||||
}
|
||||
|
||||
// Read via HTTP
|
||||
resp, err := b.HandleRequest(&logical.Request{
|
||||
Operation: logical.ReadOperation,
|
||||
Path: "map/foo/a",
|
||||
Storage: storage,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %#v", err)
|
||||
}
|
||||
if resp.Data["value"] != "bar" {
|
||||
t.Fatalf("bad: %#v", resp)
|
||||
}
|
||||
|
||||
// Read via API
|
||||
v, err := p.Get(storage, "a")
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %#v", err)
|
||||
}
|
||||
if v != "bar" {
|
||||
t.Fatalf("bad: %#v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPathMap_getInvalid(t *testing.T) {
|
||||
p := &PathMap{Name: "foo"}
|
||||
storage := new(logical.InmemStorage)
|
||||
|
||||
v, err := p.Get(storage, "nope")
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %#v", err)
|
||||
}
|
||||
if v != "" {
|
||||
t.Fatalf("bad: %#v", v)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue