diff --git a/consul/state_store.go b/consul/state_store.go index 3f1f9a1494..2d9a4f5b80 100644 --- a/consul/state_store.go +++ b/consul/state_store.go @@ -192,6 +192,12 @@ func (s *StateStore) initialize() error { Unique: true, Fields: []string{"Key"}, }, + "id_prefix": &MDBIndex{ + Virtual: true, + RealIndex: "id", + Fields: []string{"Key"}, + IdxFunc: DefaultIndexPrefixFunc, + }, }, Decoder: func(buf []byte) interface{} { out := new(structs.DirEntry) @@ -749,8 +755,13 @@ func (s *StateStore) KVSGet(key string) (uint64, *structs.DirEntry, error) { } // KVSList is used to list all KV entries with a prefix -func (s *StateStore) KVSList() (uint64, structs.DirEntries, error) { - return 0, nil, nil +func (s *StateStore) KVSList(prefix string) (uint64, structs.DirEntries, error) { + idx, res, err := s.kvsTable.Get("id_prefix", prefix) + ents := make(structs.DirEntries, len(res)) + for idx, r := range res { + ents[idx] = r.(*structs.DirEntry) + } + return idx, ents, err } // KVSDelete is used to delete a KVS entry @@ -778,6 +789,7 @@ func (s *StateStore) KVSDelete(index uint64, key string) error { // KVSDeleteTree is used to delete all keys with a given prefix func (s *StateStore) KVSDeleteTree() error { + // TODO: return nil } diff --git a/consul/state_store_test.go b/consul/state_store_test.go index c9a26e6763..36d19629fd 100644 --- a/consul/state_store_test.go +++ b/consul/state_store_test.go @@ -1107,3 +1107,59 @@ func TestKVSCheckAndSet(t *testing.T) { t.Fatalf("expected commit") } } + +func TestKVS_List(t *testing.T) { + store, err := testStateStore() + if err != nil { + t.Fatalf("err: %v", err) + } + defer store.Close() + + // Should not exist + idx, ents, err := store.KVSList("/web") + if err != nil { + t.Fatalf("err: %v", err) + } + if idx != 0 { + t.Fatalf("bad: %v", idx) + } + if len(ents) != 0 { + t.Fatalf("bad: %v", ents) + } + + // Create the entries + d := &structs.DirEntry{Key: "/web/a", Flags: 42, Value: []byte("test")} + if err := store.KVSSet(1000, d); err != nil { + t.Fatalf("err: %v", err) + } + d = &structs.DirEntry{Key: "/web/b", Flags: 42, Value: []byte("test")} + if err := store.KVSSet(1001, d); err != nil { + t.Fatalf("err: %v", err) + } + d = &structs.DirEntry{Key: "/web/sub/c", Flags: 42, Value: []byte("test")} + if err := store.KVSSet(1002, d); err != nil { + t.Fatalf("err: %v", err) + } + + // Should list + idx, ents, err = store.KVSList("/web") + if err != nil { + t.Fatalf("err: %v", err) + } + if idx != 1002 { + t.Fatalf("bad: %v", idx) + } + if len(ents) != 3 { + t.Fatalf("bad: %v", ents) + } + + if ents[0].Key != "/web/a" { + t.Fatalf("bad: %v", ents[0]) + } + if ents[1].Key != "/web/b" { + t.Fatalf("bad: %v", ents[1]) + } + if ents[2].Key != "/web/sub/c" { + t.Fatalf("bad: %v", ents[2]) + } +}