go.ligato.io/vpp-agent/v3@v3.5.0/cmd/agentctl/commands/kvdb.go (about) 1 // Copyright (c) 2019 Cisco and/or its affiliates. 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 commands 16 17 import ( 18 "errors" 19 "fmt" 20 21 "github.com/sirupsen/logrus" 22 "github.com/spf13/cobra" 23 24 agentcli "go.ligato.io/vpp-agent/v3/cmd/agentctl/cli" 25 ) 26 27 func NewKvdbCommand(cli agentcli.Cli) *cobra.Command { 28 cmd := &cobra.Command{ 29 Use: "kvdb", 30 Aliases: []string{"kv"}, 31 Short: "Manage agent data in KVDB", 32 Args: cobra.NoArgs, 33 } 34 cmd.AddCommand( 35 newKvdbListCommand(cli), 36 newKvdbGetCommand(cli), 37 newKvdbPutCommand(cli), 38 newKvdbDelCommand(cli), 39 ) 40 return cmd 41 } 42 43 func newKvdbListCommand(cli agentcli.Cli) *cobra.Command { 44 var keysOnly bool 45 46 cmd := &cobra.Command{ 47 Use: "list [flags] [PREFIX]", 48 Aliases: []string{"ls", "l"}, 49 Short: "List key-value entries", 50 Args: cobra.RangeArgs(0, 1), 51 RunE: func(cmd *cobra.Command, args []string) error { 52 var key string 53 if len(args) > 0 { 54 key = args[0] 55 } 56 return runKvdbList(cli, key, keysOnly) 57 }, 58 } 59 cmd.Flags().BoolVar(&keysOnly, "keys-only", false, "List only the keys") 60 return cmd 61 } 62 63 func runKvdbList(cli agentcli.Cli, key string, keysOnly bool) error { 64 logrus.Debugf("kvdb.List - KEY: %q", key) 65 66 kvdb, err := cli.Client().KVDBClient() 67 if err != nil { 68 return fmt.Errorf("connecting to KVDB failed: %v", err) 69 } 70 if keysOnly { 71 iter, err := kvdb.ListKeys(key) 72 if err != nil { 73 return errors.New("failed to list values from KVDB: " + err.Error()) 74 } 75 for { 76 key, _, stop := iter.GetNext() 77 if stop { 78 break 79 } 80 fmt.Printf("%s\n", key) 81 } 82 } else { 83 iter, err := kvdb.ListValues(key) 84 if err != nil { 85 return errors.New("failed to list values from KVDB: " + err.Error()) 86 } 87 for { 88 kv, stop := iter.GetNext() 89 if stop { 90 break 91 } 92 fmt.Printf("%s\n%s\n", kv.GetKey(), kv.GetValue()) 93 } 94 } 95 return nil 96 } 97 98 func newKvdbGetCommand(cli agentcli.Cli) *cobra.Command { 99 cmd := &cobra.Command{ 100 Use: "get KEY", 101 Aliases: []string{"g"}, 102 Short: "Get key-value entry", 103 Args: cobra.ExactArgs(1), 104 RunE: func(cmd *cobra.Command, args []string) error { 105 key := args[0] 106 return runKvdbGet(cli, key) 107 }, 108 } 109 return cmd 110 } 111 112 func runKvdbGet(cli agentcli.Cli, key string) error { 113 logrus.Debugf("kvdb.Get - KEY: %q", key) 114 115 kvdb, err := cli.Client().KVDBClient() 116 if err != nil { 117 return fmt.Errorf("connecting to KVDB failed: %v", err) 118 } 119 120 value, found, _, err := kvdb.GetValue(key) 121 if err != nil { 122 return errors.New("Failed to get value from Etcd: " + err.Error()) 123 } else if !found { 124 return errors.New("key not found") 125 } 126 127 fmt.Fprintf(cli.Out(), "%s\n", value) 128 return nil 129 } 130 131 func newKvdbPutCommand(cli agentcli.Cli) *cobra.Command { 132 cmd := &cobra.Command{ 133 Use: "put KEY VALUE", 134 Aliases: []string{"p"}, 135 Short: "Put key-value entry", 136 Long: ` 137 Put configuration file to Etcd. 138 139 Supported key formats: 140 /vnf-agent/vpp1/config/vpp/v2/interfaces/iface1 141 config/vpp/v2/interfaces/iface1 142 143 For short key, put command use default microservice label. 144 `, 145 Example: ` 146 # Set route configuration for 'vpp1' 147 {{.CommandPath}} /vnf-agent/vpp1/config/vpp/v2/route/vrf/1/dst/10.1.1.3/32/gw/192.168.1.13 '{ 148 "type": 1, 149 "vrf_id": 1, 150 "dst_network": "10.1.1.3/32", 151 "next_hop_addr": "192.168.1.13" 152 }' 153 `, 154 Args: cobra.RangeArgs(1, 2), 155 RunE: func(cmd *cobra.Command, args []string) error { 156 key := args[0] 157 val := args[1] 158 return runKvdbPut(cli, key, val) 159 }, 160 } 161 return cmd 162 } 163 164 func runKvdbPut(cli agentcli.Cli, key, value string) error { 165 logrus.Debugf("kvdb.Put - KEY: %q VAL: %q", key, value) 166 167 kvdb, err := cli.Client().KVDBClient() 168 if err != nil { 169 return fmt.Errorf("connecting to KVDB failed: %v", err) 170 } 171 172 data := []byte(value) 173 if err := kvdb.Put(key, data); err != nil { 174 return err 175 } 176 177 fmt.Fprintln(cli.Out(), "OK") 178 return nil 179 } 180 181 func newKvdbDelCommand(cli agentcli.Cli) *cobra.Command { 182 cmd := &cobra.Command{ 183 Use: "del KEY", 184 Aliases: []string{"d"}, 185 Short: "Delete key-value entry", 186 Args: cobra.ExactArgs(1), 187 RunE: func(cmd *cobra.Command, args []string) error { 188 key := args[0] 189 return runKvdbDel(cli, key) 190 }, 191 } 192 return cmd 193 } 194 195 func runKvdbDel(cli agentcli.Cli, key string) error { 196 logrus.Debugf("kvdb.Del - KEY: %q", key) 197 198 kvdb, err := cli.Client().KVDBClient() 199 if err != nil { 200 return fmt.Errorf("connecting to KVDB failed: %v", err) 201 } 202 203 if _, found, _, err := kvdb.GetValue(key); err != nil { 204 return err 205 } else if !found { 206 return fmt.Errorf("key does not exist") 207 } 208 209 // FIXME: existed can never be true, missing WithPrevKV() option 210 if _, err := kvdb.Delete(key); err != nil { 211 return err 212 } 213 214 fmt.Fprintln(cli.Out(), "OK") 215 return nil 216 }