consul: Adding ListKeys endpoint

This commit is contained in:
Armon Dadgar 2014-04-28 16:33:54 -07:00 committed by Jack Pearkes
parent a631821f6c
commit a649ea1cbc
3 changed files with 100 additions and 0 deletions

View File

@ -115,3 +115,27 @@ func (k *KVS) List(args *structs.KeyRequest, reply *structs.IndexedDirEntries) e
return nil
})
}
// ListKeys is used to list all keys with a given prefix to a seperator
func (k *KVS) ListKeys(args *structs.KeyListRequest, reply *structs.IndexedKeyList) error {
// Ensure we have a seperator
if args.Seperator == "" {
return fmt.Errorf("Missing seperator")
}
// Forward if necessary
if done, err := k.srv.forward("KVS.ListKeys", args, args, reply); done {
return err
}
// Get the local state
state := k.srv.fsm.State()
return k.srv.blockingRPC(&args.QueryOptions,
&reply.QueryMeta,
state.QueryTables("KVSListKeys"),
func() error {
var err error
reply.Index, reply.Keys, err = state.KVSListKeys(args.Prefix, args.Seperator)
return err
})
}

View File

@ -171,3 +171,62 @@ func TestKVSEndpoint_List(t *testing.T) {
}
}
}
func TestKVSEndpoint_ListKeys(t *testing.T) {
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
client := rpcClient(t, s1)
defer client.Close()
// Wait for leader
time.Sleep(100 * time.Millisecond)
keys := []string{
"/test/key1",
"/test/key2",
"/test/sub/key3",
}
for _, key := range keys {
arg := structs.KVSRequest{
Datacenter: "dc1",
Op: structs.KVSSet,
DirEnt: structs.DirEntry{
Key: key,
Flags: 1,
},
}
var out bool
if err := client.Call("KVS.Apply", &arg, &out); err != nil {
t.Fatalf("err: %v", err)
}
}
getR := structs.KeyListRequest{
Datacenter: "dc1",
Prefix: "/test/",
Seperator: "/",
}
var dirent structs.IndexedKeyList
if err := client.Call("KVS.ListKeys", &getR, &dirent); err != nil {
t.Fatalf("err: %v", err)
}
if dirent.Index == 0 {
t.Fatalf("Bad: %v", dirent)
}
if len(dirent.Keys) != 3 {
t.Fatalf("Bad: %v", dirent.Keys)
}
if dirent.Keys[0] != "/test/key1" {
t.Fatalf("Bad: %v", dirent.Keys)
}
if dirent.Keys[1] != "/test/key2" {
t.Fatalf("Bad: %v", dirent.Keys)
}
if dirent.Keys[2] != "/test/sub/" {
t.Fatalf("Bad: %v", dirent.Keys)
}
}

View File

@ -313,11 +313,28 @@ func (r *KeyRequest) RequestDatacenter() string {
return r.Datacenter
}
// KeyListRequest is used to list keys
type KeyListRequest struct {
Datacenter string
Prefix string
Seperator string
QueryOptions
}
func (r *KeyListRequest) RequestDatacenter() string {
return r.Datacenter
}
type IndexedDirEntries struct {
Entries DirEntries
QueryMeta
}
type IndexedKeyList struct {
Keys []string
QueryMeta
}
// Decode is used to decode a MsgPack encoded object
func Decode(buf []byte, out interface{}) error {
var handle codec.MsgpackHandle