// List is used to list all keys with a given prefix func (k *KVS) List(args *structs.KeyRequest, reply *structs.IndexedDirEntries) error { if done, err := k.srv.forward("KVS.List", args, args, reply); done { return err } acl, err := k.srv.resolveToken(args.Token) if err != nil { return err } // Get the local state state := k.srv.fsm.State() opts := blockingRPCOptions{ queryOpts: &args.QueryOptions, queryMeta: &reply.QueryMeta, kvWatch: true, kvPrefix: args.Key, run: func() error { tombIndex, index, ent, err := state.KVSList(args.Key) if err != nil { return err } if acl != nil { ent = FilterDirEnt(acl, ent) } if len(ent) == 0 { // Must provide non-zero index to prevent blocking // Index 1 is impossible anyways (due to Raft internals) if index == 0 { reply.Index = 1 } else { reply.Index = index } reply.Entries = nil } else { // Determine the maximum affected index var maxIndex uint64 for _, e := range ent { if e.ModifyIndex > maxIndex { maxIndex = e.ModifyIndex } } if tombIndex > maxIndex { maxIndex = tombIndex } reply.Index = maxIndex reply.Entries = ent } return nil }, } return k.srv.blockingRPCOpt(&opts) }
// Get is used to lookup a single key func (k *KVS) Get(args *structs.KeyRequest, reply *structs.IndexedDirEntries) error { if done, err := k.srv.forward("KVS.Get", args, args, reply); done { return err } acl, err := k.srv.resolveToken(args.Token) if err != nil { return err } // Get the local state state := k.srv.fsm.State() opts := blockingRPCOptions{ queryOpts: &args.QueryOptions, queryMeta: &reply.QueryMeta, kvWatch: true, kvPrefix: args.Key, run: func() error { index, ent, err := state.KVSGet(args.Key) if err != nil { return err } if acl != nil && !acl.KeyRead(args.Key) { ent = nil } if ent == nil { // Must provide non-zero index to prevent blocking // Index 1 is impossible anyways (due to Raft internals) if index == 0 { reply.Index = 1 } else { reply.Index = index } reply.Entries = nil } else { reply.Index = ent.ModifyIndex reply.Entries = structs.DirEntries{ent} } return nil }, } return k.srv.blockingRPCOpt(&opts) }