github.com/outbrain/consul@v1.4.5/command/kv/exp/kv_export.go (about)

     1  package exp
     2  
     3  import (
     4  	"encoding/json"
     5  	"flag"
     6  	"fmt"
     7  
     8  	"github.com/hashicorp/consul/api"
     9  	"github.com/hashicorp/consul/command/flags"
    10  	"github.com/hashicorp/consul/command/kv/impexp"
    11  	"github.com/mitchellh/cli"
    12  )
    13  
    14  func New(ui cli.Ui) *cmd {
    15  	c := &cmd{UI: ui}
    16  	c.init()
    17  	return c
    18  }
    19  
    20  type cmd struct {
    21  	UI    cli.Ui
    22  	flags *flag.FlagSet
    23  	http  *flags.HTTPFlags
    24  	help  string
    25  }
    26  
    27  func (c *cmd) init() {
    28  	c.flags = flag.NewFlagSet("", flag.ContinueOnError)
    29  	c.http = &flags.HTTPFlags{}
    30  	flags.Merge(c.flags, c.http.ClientFlags())
    31  	flags.Merge(c.flags, c.http.ServerFlags())
    32  	c.help = flags.Usage(help, c.flags)
    33  }
    34  
    35  func (c *cmd) Run(args []string) int {
    36  	if err := c.flags.Parse(args); err != nil {
    37  		return 1
    38  	}
    39  
    40  	key := ""
    41  	// Check for arg validation
    42  	args = c.flags.Args()
    43  	switch len(args) {
    44  	case 0:
    45  		key = ""
    46  	case 1:
    47  		key = args[0]
    48  	default:
    49  		c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args)))
    50  		return 1
    51  	}
    52  
    53  	// This is just a "nice" thing to do. Since pairs cannot start with a /, but
    54  	// users will likely put "/" or "/foo", lets go ahead and strip that for them
    55  	// here.
    56  	if len(key) > 0 && key[0] == '/' {
    57  		key = key[1:]
    58  	}
    59  
    60  	// Create and test the HTTP client
    61  	client, err := c.http.APIClient()
    62  	if err != nil {
    63  		c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
    64  		return 1
    65  	}
    66  
    67  	pairs, _, err := client.KV().List(key, &api.QueryOptions{
    68  		AllowStale: c.http.Stale(),
    69  	})
    70  	if err != nil {
    71  		c.UI.Error(fmt.Sprintf("Error querying Consul agent: %s", err))
    72  		return 1
    73  	}
    74  
    75  	exported := make([]*impexp.Entry, len(pairs))
    76  	for i, pair := range pairs {
    77  		exported[i] = impexp.ToEntry(pair)
    78  	}
    79  
    80  	marshaled, err := json.MarshalIndent(exported, "", "\t")
    81  	if err != nil {
    82  		c.UI.Error(fmt.Sprintf("Error exporting KV data: %s", err))
    83  		return 1
    84  	}
    85  
    86  	c.UI.Info(string(marshaled))
    87  
    88  	return 0
    89  }
    90  
    91  func (c *cmd) Synopsis() string {
    92  	return synopsis
    93  }
    94  
    95  func (c *cmd) Help() string {
    96  	return c.help
    97  }
    98  
    99  const synopsis = "Exports a tree from the KV store as JSON"
   100  const help = `
   101  Usage: consul kv export [KEY_OR_PREFIX]
   102  
   103    Retrieves key-value pairs for the given prefix from Consul's key-value store,
   104    and writes a JSON representation to stdout. This can be used with the command
   105    "consul kv import" to move entire trees between Consul clusters.
   106  
   107        $ consul kv export vault
   108  
   109    For a full list of options and examples, please see the Consul documentation.
   110  `