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  }