github.hscsec.cn/hashicorp/consul@v1.4.5/command/kv/del/kv_delete.go (about) 1 package del 2 3 import ( 4 "flag" 5 "fmt" 6 7 "github.com/hashicorp/consul/api" 8 "github.com/hashicorp/consul/command/flags" 9 "github.com/mitchellh/cli" 10 ) 11 12 func New(ui cli.Ui) *cmd { 13 c := &cmd{UI: ui} 14 c.init() 15 return c 16 } 17 18 type cmd struct { 19 UI cli.Ui 20 flags *flag.FlagSet 21 http *flags.HTTPFlags 22 help string 23 cas bool 24 modifyIndex uint64 25 recurse bool 26 } 27 28 func (c *cmd) init() { 29 c.flags = flag.NewFlagSet("", flag.ContinueOnError) 30 c.flags.BoolVar(&c.cas, "cas", false, 31 "Perform a Check-And-Set operation. Specifying this value also requires "+ 32 "the -modify-index flag to be set. The default value is false.") 33 c.flags.Uint64Var(&c.modifyIndex, "modify-index", 0, 34 "Unsigned integer representing the ModifyIndex of the key. This is "+ 35 "used in combination with the -cas flag.") 36 c.flags.BoolVar(&c.recurse, "recurse", false, 37 "Recursively delete all keys with the path. The default value is false.") 38 39 c.http = &flags.HTTPFlags{} 40 flags.Merge(c.flags, c.http.ClientFlags()) 41 flags.Merge(c.flags, c.http.ServerFlags()) 42 c.help = flags.Usage(help, c.flags) 43 } 44 45 func (c *cmd) Run(args []string) int { 46 if err := c.flags.Parse(args); err != nil { 47 return 1 48 } 49 50 key := "" 51 52 // Check for arg validation 53 args = c.flags.Args() 54 switch len(args) { 55 case 0: 56 key = "" 57 case 1: 58 key = args[0] 59 default: 60 c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args))) 61 return 1 62 } 63 64 // This is just a "nice" thing to do. Since pairs cannot start with a /, but 65 // users will likely put "/" or "/foo", lets go ahead and strip that for them 66 // here. 67 if len(key) > 0 && key[0] == '/' { 68 key = key[1:] 69 } 70 71 // If the key is empty and we are not doing a recursive delete, this is an 72 // error. 73 if key == "" && !c.recurse { 74 c.UI.Error("Error! Missing KEY argument") 75 return 1 76 } 77 78 // ModifyIndex is required for CAS 79 if c.cas && c.modifyIndex == 0 { 80 c.UI.Error("Must specify -modify-index with -cas!") 81 return 1 82 } 83 84 // Specifying a ModifyIndex for a non-CAS operation is not possible. 85 if c.modifyIndex != 0 && !c.cas { 86 c.UI.Error("Cannot specify -modify-index without -cas!") 87 return 1 88 } 89 90 // It is not valid to use a CAS and recurse in the same call 91 if c.recurse && c.cas { 92 c.UI.Error("Cannot specify both -cas and -recurse!") 93 return 1 94 } 95 96 // Create and test the HTTP client 97 client, err := c.http.APIClient() 98 if err != nil { 99 c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) 100 return 1 101 } 102 103 switch { 104 case c.recurse: 105 if _, err := client.KV().DeleteTree(key, nil); err != nil { 106 c.UI.Error(fmt.Sprintf("Error! Did not delete prefix %s: %s", key, err)) 107 return 1 108 } 109 110 c.UI.Info(fmt.Sprintf("Success! Deleted keys with prefix: %s", key)) 111 return 0 112 case c.cas: 113 pair := &api.KVPair{ 114 Key: key, 115 ModifyIndex: c.modifyIndex, 116 } 117 118 success, _, err := client.KV().DeleteCAS(pair, nil) 119 if err != nil { 120 c.UI.Error(fmt.Sprintf("Error! Did not delete key %s: %s", key, err)) 121 return 1 122 } 123 if !success { 124 c.UI.Error(fmt.Sprintf("Error! Did not delete key %s: CAS failed", key)) 125 return 1 126 } 127 128 c.UI.Info(fmt.Sprintf("Success! Deleted key: %s", key)) 129 return 0 130 default: 131 if _, err := client.KV().Delete(key, nil); err != nil { 132 c.UI.Error(fmt.Sprintf("Error deleting key %s: %s", key, err)) 133 return 1 134 } 135 136 c.UI.Info(fmt.Sprintf("Success! Deleted key: %s", key)) 137 return 0 138 } 139 } 140 141 func (c *cmd) Synopsis() string { 142 return synopsis 143 } 144 145 func (c *cmd) Help() string { 146 return c.help 147 } 148 149 const synopsis = "Removes data from the KV store" 150 const help = ` 151 Usage: consul kv delete [options] KEY_OR_PREFIX 152 153 Removes the value from Consul's key-value store at the given path. If no 154 key exists at the path, no action is taken. 155 156 To delete the value for the key named "foo" in the key-value store: 157 158 $ consul kv delete foo 159 160 To delete all keys which start with "foo", specify the -recurse option: 161 162 $ consul kv delete -recurse foo 163 164 This will delete the keys named "foo", "food", and "foo/bar/zip" if they 165 existed. 166 `