go.etcd.io/etcd@v3.3.27+incompatible/etcdctl/ctlv3/command/get_command.go (about) 1 // Copyright 2015 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package command 16 17 import ( 18 "fmt" 19 "strings" 20 21 "github.com/coreos/etcd/clientv3" 22 "github.com/spf13/cobra" 23 ) 24 25 var ( 26 getConsistency string 27 getLimit int64 28 getSortOrder string 29 getSortTarget string 30 getPrefix bool 31 getFromKey bool 32 getRev int64 33 getKeysOnly bool 34 printValueOnly bool 35 ) 36 37 // NewGetCommand returns the cobra command for "get". 38 func NewGetCommand() *cobra.Command { 39 cmd := &cobra.Command{ 40 Use: "get [options] <key> [range_end]", 41 Short: "Gets the key or a range of keys", 42 Run: getCommandFunc, 43 } 44 45 cmd.Flags().StringVar(&getConsistency, "consistency", "l", "Linearizable(l) or Serializable(s)") 46 cmd.Flags().StringVar(&getSortOrder, "order", "", "Order of results; ASCEND or DESCEND (ASCEND by default)") 47 cmd.Flags().StringVar(&getSortTarget, "sort-by", "", "Sort target; CREATE, KEY, MODIFY, VALUE, or VERSION") 48 cmd.Flags().Int64Var(&getLimit, "limit", 0, "Maximum number of results") 49 cmd.Flags().BoolVar(&getPrefix, "prefix", false, "Get keys with matching prefix") 50 cmd.Flags().BoolVar(&getFromKey, "from-key", false, "Get keys that are greater than or equal to the given key using byte compare") 51 cmd.Flags().Int64Var(&getRev, "rev", 0, "Specify the kv revision") 52 cmd.Flags().BoolVar(&getKeysOnly, "keys-only", false, "Get only the keys") 53 cmd.Flags().BoolVar(&printValueOnly, "print-value-only", false, `Only write values when using the "simple" output format`) 54 return cmd 55 } 56 57 // getCommandFunc executes the "get" command. 58 func getCommandFunc(cmd *cobra.Command, args []string) { 59 key, opts := getGetOp(cmd, args) 60 ctx, cancel := commandCtx(cmd) 61 resp, err := mustClientFromCmd(cmd).Get(ctx, key, opts...) 62 cancel() 63 if err != nil { 64 ExitWithError(ExitError, err) 65 } 66 67 if printValueOnly { 68 dp, simple := (display).(*simplePrinter) 69 if !simple { 70 ExitWithError(ExitBadArgs, fmt.Errorf("print-value-only is only for `--write-out=simple`.")) 71 } 72 dp.valueOnly = true 73 } 74 display.Get(*resp) 75 } 76 77 func getGetOp(cmd *cobra.Command, args []string) (string, []clientv3.OpOption) { 78 if len(args) == 0 { 79 ExitWithError(ExitBadArgs, fmt.Errorf("range command needs arguments.")) 80 } 81 82 if getPrefix && getFromKey { 83 ExitWithError(ExitBadArgs, fmt.Errorf("`--prefix` and `--from-key` cannot be set at the same time, choose one.")) 84 } 85 86 opts := []clientv3.OpOption{} 87 switch getConsistency { 88 case "s": 89 opts = append(opts, clientv3.WithSerializable()) 90 case "l": 91 default: 92 ExitWithError(ExitBadFeature, fmt.Errorf("unknown consistency flag %q", getConsistency)) 93 } 94 95 key := args[0] 96 if len(args) > 1 { 97 if getPrefix || getFromKey { 98 ExitWithError(ExitBadArgs, fmt.Errorf("too many arguments, only accept one argument when `--prefix` or `--from-key` is set.")) 99 } 100 opts = append(opts, clientv3.WithRange(args[1])) 101 } 102 103 opts = append(opts, clientv3.WithLimit(getLimit)) 104 if getRev > 0 { 105 opts = append(opts, clientv3.WithRev(getRev)) 106 } 107 108 sortByOrder := clientv3.SortNone 109 sortOrder := strings.ToUpper(getSortOrder) 110 switch { 111 case sortOrder == "ASCEND": 112 sortByOrder = clientv3.SortAscend 113 case sortOrder == "DESCEND": 114 sortByOrder = clientv3.SortDescend 115 case sortOrder == "": 116 // nothing 117 default: 118 ExitWithError(ExitBadFeature, fmt.Errorf("bad sort order %v", getSortOrder)) 119 } 120 121 sortByTarget := clientv3.SortByKey 122 sortTarget := strings.ToUpper(getSortTarget) 123 switch { 124 case sortTarget == "CREATE": 125 sortByTarget = clientv3.SortByCreateRevision 126 case sortTarget == "KEY": 127 sortByTarget = clientv3.SortByKey 128 case sortTarget == "MODIFY": 129 sortByTarget = clientv3.SortByModRevision 130 case sortTarget == "VALUE": 131 sortByTarget = clientv3.SortByValue 132 case sortTarget == "VERSION": 133 sortByTarget = clientv3.SortByVersion 134 case sortTarget == "": 135 // nothing 136 default: 137 ExitWithError(ExitBadFeature, fmt.Errorf("bad sort target %v", getSortTarget)) 138 } 139 140 opts = append(opts, clientv3.WithSort(sortByTarget, sortByOrder)) 141 142 if getPrefix { 143 if len(key) == 0 { 144 key = "\x00" 145 opts = append(opts, clientv3.WithFromKey()) 146 } else { 147 opts = append(opts, clientv3.WithPrefix()) 148 } 149 } 150 151 if getFromKey { 152 if len(key) == 0 { 153 key = "\x00" 154 } 155 opts = append(opts, clientv3.WithFromKey()) 156 } 157 158 if getKeysOnly { 159 opts = append(opts, clientv3.WithKeysOnly()) 160 } 161 162 return key, opts 163 }