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

Backport of Removed nodename and status from consul snapshot save -append-filename command and using leader version in version into release/1.15.x #18685

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 18 additions & 33 deletions command/snapshot/save/snapshot_save.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type cmd struct {
func (c *cmd) getAppendFileNameFlag() *flag.FlagSet {
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.Var(&c.appendFileNameFlag, "append-filename", "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")
"comma-separated arguments. 1. version, 2. dc. It appends these values to the filename provided in the command")
return fs
}

Expand Down Expand Up @@ -71,50 +71,35 @@ func (c *cmd) Run(args []string) int {
appendFileNameFlags := strings.Split(c.appendFileNameFlag.String(), ",")

if len(appendFileNameFlags) != 0 && len(c.appendFileNameFlag.String()) > 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)
operatorHealthResponse, err := client.Operator().AutopilotServerHealth(nil)
if err != nil {
c.UI.Error(fmt.Sprintf("Error fetching version of Consul agent Leader: %s", err))
return 1
}
var version string
for _, server := range operatorHealthResponse.Servers {
if server.Leader {
version = server.Version
break
}
}
fileNameWithoutExt = fileNameWithoutExt + "-" + version
}

if slices.Contains(appendFileNameFlags, "dc") {
if config, ok := agentSelfResponse["Config"]; ok {
if datacenter, ok := config["Datacenter"]; ok {
fileNameWithoutExt = fileNameWithoutExt + "-" + datacenter.(string)
}
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
}
}

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

if slices.Contains(appendFileNameFlags, "status") {
if status, ok := agentSelfResponse["Stats"]; ok {
if config, ok := status["consul"]; ok {
configMap := config.(map[string]interface{})
if leader, ok := configMap["leader"]; ok {
if leader == "true" {
fileNameWithoutExt = fileNameWithoutExt + "-" + "leader"
} else {
fileNameWithoutExt = fileNameWithoutExt + "-" + "follower"
}
}
if datacenter, ok := config["Datacenter"]; ok {
fileNameWithoutExt = fileNameWithoutExt + "-" + datacenter.(string)
}
}
}
Expand Down
28 changes: 14 additions & 14 deletions command/snapshot/save/snapshot_save_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,34 +85,34 @@ func TestSnapshotSaveCommandWithAppendFileNameFlag(t *testing.T) {
dir := testutil.TempDir(t, "snapshot")
file := filepath.Join(dir, "backup.tgz")
args := []string{
"-append-filename=version,dc,node,status",
"-append-filename=version,dc",
"-http-addr=" + a.HTTPAddr(),
file,
}

stats := a.Stats()

status := "follower"

if stats["consul"]["leader"] == "true" {
status = "leader"
}

// We need to use the self endpoint here for ENT, which returns the product suffix (+ent)
self, err := client.Agent().Self()
require.NoError(t, err)

cfg, ok := self["Config"]
require.True(t, ok)

versionAny, ok := cfg["Version"]
dc, ok := cfg["Datacenter"]
require.True(t, ok)

version, ok := versionAny.(string)
require.True(t, ok)
datacenter := dc.(string)

operatorHealth, error := client.Operator().AutopilotServerHealth(nil)
require.NoError(t, error)

var version string
for _, server := range operatorHealth.Servers {
if server.Leader {
version = server.Version
}
}

newFilePath := filepath.Join(dir, "backup"+"-"+version+"-"+a.Config.Datacenter+
"-"+a.Config.NodeName+"-"+status+".tgz")
newFilePath := filepath.Join(dir, "backup"+"-"+version+"-"+datacenter+".tgz")

code := c.Run(args)
if code != 0 {
Expand Down
16 changes: 8 additions & 8 deletions website/content/commands/snapshot/save.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,20 @@ $ consul snapshot save -stale backup.snap
# ...
```

To create snapshot file with consul version, datacenter, node name and leader/follower info,
run
This is useful for situations where a cluster is in a degraded state and no
leader is available. To target a specific server for a snapshot, you can run
the `consul snapshot save` command on that specific server.

To create snapshot file with consul version and datacenter run

```shell-session
$ consul snapshot save -append-filename node,status,version,dc backup.snap
$ consul snapshot save -append-filename version,dc backup.snap
#...
```

File name created will be like backup-%CONSUL_VERSION%-%DC_NAME%-%NODE_NAME%-%STATUS.snap
File name created will be like backup-%CONSUL_VERSION%-%DC_NAME%.snap
example - backup-1.17.0-dc1-local-machine-leader.tgz

This is useful for situations where a cluster is in a degraded state and no
leader is available. To target a specific server for a snapshot, you can run
the `consul snapshot save` command on that specific server.
Note Version is always the leader's consul version

Please see the [HTTP API](/consul/api-docs/snapshot) documentation for
more details about snapshot internals.