Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NET 1594 - Snapshot Agent Filename Should Include Consul Version / Datacenter #18625

Merged
merged 15 commits into from Sep 1, 2023
4 changes: 4 additions & 0 deletions .changelog/18625.txt
@@ -0,0 +1,4 @@
```release-note:improvement
Adds flag -append-filename (which works on two values version and dc) to consul snapshot save command.
Adding the flag -append-filename version,dc will add consul version and consul datacenter in the file name given in the snapshot save command before the file extension.
```
55 changes: 51 additions & 4 deletions command/snapshot/save/snapshot_save.go
Expand Up @@ -6,7 +6,10 @@ package save
import (
"flag"
"fmt"
"golang.org/x/exp/slices"
"os"
"path/filepath"
"strings"

"github.com/mitchellh/cli"
"github.com/rboyer/safeio"
Expand All @@ -23,17 +26,26 @@ func New(ui cli.Ui) *cmd {
}

type cmd struct {
UI cli.Ui
flags *flag.FlagSet
http *flags.HTTPFlags
help string
UI cli.Ui
flags *flag.FlagSet
http *flags.HTTPFlags
help string
appendFileNameFlag flags.StringValue
}

func (c *cmd) getAppendFileNameFlag() *flag.FlagSet {
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.Var(&c.appendFileNameFlag, "append-filename", "Append filename flag takes two possible values. "+
absolutelightning marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description is a bit confusing to me. Can we rephrase this to something like?

Append filename flag supports the following comma-separated arguments. 1. version, 2. dc. 3. node 4. status. It appends these values to the filename provided in the command

"1. version, 2. dc. It appends consul version and datacenter to filename given in command")
absolutelightning marked this conversation as resolved.
Show resolved Hide resolved
return fs
}

func (c *cmd) init() {
c.flags = flag.NewFlagSet("", flag.ContinueOnError)
c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags())
flags.Merge(c.flags, c.http.ServerFlags())
flags.Merge(c.flags, c.getAppendFileNameFlag())
c.help = flags.Usage(help, c.flags)
}

Expand All @@ -58,6 +70,41 @@ func (c *cmd) Run(args []string) int {

// Create and test the HTTP client
client, err := c.http.APIClient()

appendFileNameFlags := strings.Split(c.appendFileNameFlag.String(), ",")

var agentSelfResponse map[string]map[string]interface{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line can be removed


if len(appendFileNameFlags) != 0 {
agentSelfResponse, err = client.Agent().Self()
if err != nil {
c.UI.Error(fmt.Sprintf("Error connecting to Consul agent and fetching datacenter/version: %s", err))
return 1
}

fileExt := filepath.Ext(file)
fileNameWithoutExt := strings.TrimSuffix(file, fileExt)

if slices.Contains(appendFileNameFlags, "version") {
if config, ok := agentSelfResponse["Config"]; ok {
if version, ok := config["Version"]; ok {
fileNameWithoutExt = fileNameWithoutExt + "-" + version.(string)
}
}
}

if slices.Contains(appendFileNameFlags, "dc") {
if config, ok := agentSelfResponse["Config"]; ok {
if datacenter, ok := config["Datacenter"]; ok {
fileNameWithoutExt = fileNameWithoutExt + "-" + datacenter.(string)
}
}
}

//adding extension back
file = fileNameWithoutExt + fileExt
}

if err != nil {
c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
return 1
Expand Down
42 changes: 42 additions & 0 deletions command/snapshot/save/snapshot_save_test.go
Expand Up @@ -72,6 +72,48 @@ func TestSnapshotSaveCommand_Validation(t *testing.T) {
}
}

func TestSnapshotSaveCommandWithAppendFileNameFlag(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}

t.Parallel()
a := agent.NewTestAgent(t, ``)
defer a.Shutdown()
client := a.Client()

ui := cli.NewMockUi()
c := New(ui)

dir := testutil.TempDir(t, "snapshot")
file := filepath.Join(dir, "backup.tgz")
args := []string{
"-append-filename=version,dc",
file,
}

newFilePath := filepath.Join(dir, "backup"+"-"+a.Config.Version+"-"+a.Config.Datacenter+".tgz")

code := c.Run(args)
if code != 0 {
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
}

fi, err := os.Stat(newFilePath)
require.NoError(t, err)
require.Equal(t, fi.Mode(), os.FileMode(0600))

f, err := os.Open(newFilePath)
if err != nil {
t.Fatalf("err: %v", err)
}
defer f.Close()

if err := client.Snapshot().Restore(nil, f); err != nil {
t.Fatalf("err: %v", err)
}
}

func TestSnapshotSaveCommand(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
Expand Down