etcdctl: add support for filtering by {min,max} x {create,mod} x {revision}

Signed-off-by: Cristian Ferretti <jcferretti2020@gmail.com>
This commit is contained in:
Cristian Ferretti 2024-07-02 12:48:00 -04:00
parent a897676d54
commit 07b35dd7e3
3 changed files with 88 additions and 14 deletions

View File

@ -125,6 +125,14 @@ RPC: Range
- keys-only -- Get only the keys
- max-create-revision -- restrict results to kvs with create revision lower or equal than the supplied revision
- min-create-revision -- restrict results to kvs with create revision greater or equal than the supplied revision
- max-mod-revision -- restrict results to kvs with modified revision lower or equal than the supplied revision
- min-mod-revision -- restrict results to kvs with modified revision greater or equal than the supplied revision
#### Output
Prints the data in format below,
```

View File

@ -35,6 +35,10 @@ var (
getKeysOnly bool
getCountOnly bool
printValueOnly bool
getMinCreateRev int64
getMaxCreateRev int64
getMinModRev int64
getMaxModRev int64
)
// NewGetCommand returns the cobra command for "get".
@ -55,6 +59,10 @@ func NewGetCommand() *cobra.Command {
cmd.Flags().BoolVar(&getKeysOnly, "keys-only", false, "Get only the keys")
cmd.Flags().BoolVar(&getCountOnly, "count-only", false, "Get only the count")
cmd.Flags().BoolVar(&printValueOnly, "print-value-only", false, `Only write values when using the "simple" output format`)
cmd.Flags().Int64Var(&getMinCreateRev, "min-create-rev", 0, "Minimum create revision")
cmd.Flags().Int64Var(&getMaxCreateRev, "max-create-rev", 0, "Maximum create revision")
cmd.Flags().Int64Var(&getMinModRev, "min-mod-rev", 0, "Minimum modification revision")
cmd.Flags().Int64Var(&getMaxModRev, "max-mod-rev", 0, "Maximum modification revision")
cmd.RegisterFlagCompletionFunc("consistency", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return []string{"l", "s"}, cobra.ShellCompDirectiveDefault
@ -184,5 +192,29 @@ func getGetOp(args []string) (string, []clientv3.OpOption) {
opts = append(opts, clientv3.WithCountOnly())
}
if getMinCreateRev > 0 {
opts = append(opts, clientv3.WithMinCreateRev(getMinCreateRev))
}
if getMaxCreateRev > 0 {
if getMinCreateRev > getMaxCreateRev {
cobrautl.ExitWithError(cobrautl.ExitBadFeature,
fmt.Errorf("getMinCreateRev(=%v) > getMaxCreateRev(=%v)", getMinCreateRev, getMaxCreateRev))
}
opts = append(opts, clientv3.WithMaxCreateRev(getMaxCreateRev))
}
if getMinModRev > 0 {
opts = append(opts, clientv3.WithMinModRev(getMinModRev))
}
if getMaxModRev > 0 {
if getMinModRev > getMaxModRev {
cobrautl.ExitWithError(cobrautl.ExitBadFeature,
fmt.Errorf("getMinModRev(=%v) > getMaxModRev(=%v)", getMinModRev, getMaxModRev))
}
opts = append(opts, clientv3.WithMaxModRev(getMaxModRev))
}
return key, opts
}

View File

@ -39,6 +39,7 @@ func TestCtlV3GetTimeout(t *testing.T) { testCtl(t, getTest, withDefaultDialTime
func TestCtlV3GetFormat(t *testing.T) { testCtl(t, getFormatTest) }
func TestCtlV3GetRev(t *testing.T) { testCtl(t, getRevTest) }
func TestCtlV3GetMinMaxCreateModRev(t *testing.T) { testCtl(t, getMinMaxCreateModRevTest) }
func TestCtlV3GetKeysOnly(t *testing.T) { testCtl(t, getKeysOnlyTest) }
func TestCtlV3GetCountOnly(t *testing.T) { testCtl(t, getCountOnlyTest) }
@ -216,6 +217,39 @@ func getRevTest(cx ctlCtx) {
}
}
func getMinMaxCreateModRevTest(cx ctlCtx) {
var (
kvs = []kv{ // revision: store | key create | key modify
{"key1", "val1"}, // 2 2 2
{"key2", "val2"}, // 3 3 3
{"key1", "val3"}, // 4 2 4
{"key4", "val4"}, // 5 5 5
}
)
for i := range kvs {
if err := ctlV3Put(cx, kvs[i].key, kvs[i].val, ""); err != nil {
cx.t.Fatalf("getRevTest #%d: ctlV3Put error (%v)", i, err)
}
}
tests := []struct {
args []string
wkv []kv
}{
{[]string{"key", "--prefix", "--max-create-rev", "3"}, []kv{kvs[1], kvs[2]}},
{[]string{"key", "--prefix", "--min-create-rev", "3"}, []kv{kvs[1], kvs[3]}},
{[]string{"key", "--prefix", "--max-mod-rev", "3"}, []kv{kvs[1]}},
{[]string{"key", "--prefix", "--min-mod-rev", "4"}, kvs[2:]},
}
for i, tt := range tests {
if err := ctlV3Get(cx, tt.args, tt.wkv...); err != nil {
cx.t.Errorf("getMinModRevTest #%d: ctlV3Get error (%v)", i, err)
}
}
}
func getKeysOnlyTest(cx ctlCtx) {
if err := ctlV3Put(cx, "key", "val", ""); err != nil {
cx.t.Fatal(err)