Removed nodename and status from consul snapshot save -append-filename command and using leader version in version (#18680)

* init

* fix tests

* fix tests lint

* fix api call inside dc

* updated doc

* address comments
pull/18692/head
Ashesh Vidyut 1 year ago committed by GitHub
parent ac27585dd4
commit 60b0485497
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -36,7 +36,7 @@ type cmd struct {
func (c *cmd) getAppendFileNameFlag() *flag.FlagSet { func (c *cmd) getAppendFileNameFlag() *flag.FlagSet {
fs := flag.NewFlagSet("", flag.ContinueOnError) fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.Var(&c.appendFileNameFlag, "append-filename", "Append filename flag supports the following "+ 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 return fs
} }
@ -74,50 +74,35 @@ func (c *cmd) Run(args []string) int {
appendFileNameFlags := strings.Split(c.appendFileNameFlag.String(), ",") appendFileNameFlags := strings.Split(c.appendFileNameFlag.String(), ",")
if len(appendFileNameFlags) != 0 && len(c.appendFileNameFlag.String()) > 0 { 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) fileExt := filepath.Ext(file)
fileNameWithoutExt := strings.TrimSuffix(file, fileExt) fileNameWithoutExt := strings.TrimSuffix(file, fileExt)
if slices.Contains(appendFileNameFlags, "version") { if slices.Contains(appendFileNameFlags, "version") {
if config, ok := agentSelfResponse["Config"]; ok { operatorHealthResponse, err := client.Operator().AutopilotServerHealth(nil)
if version, ok := config["Version"]; ok { if err != nil {
fileNameWithoutExt = fileNameWithoutExt + "-" + version.(string) 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 slices.Contains(appendFileNameFlags, "dc") {
if config, ok := agentSelfResponse["Config"]; ok { agentSelfResponse, err := client.Agent().Self()
if datacenter, ok := config["Datacenter"]; ok { if err != nil {
fileNameWithoutExt = fileNameWithoutExt + "-" + datacenter.(string) 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 config, ok := agentSelfResponse["Config"]; ok {
if nodeName, ok := config["NodeName"]; ok { if datacenter, ok := config["Datacenter"]; ok {
fileNameWithoutExt = fileNameWithoutExt + "-" + nodeName.(string) fileNameWithoutExt = fileNameWithoutExt + "-" + datacenter.(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"
}
}
} }
} }
} }

@ -88,19 +88,11 @@ func TestSnapshotSaveCommandWithAppendFileNameFlag(t *testing.T) {
dir := testutil.TempDir(t, "snapshot") dir := testutil.TempDir(t, "snapshot")
file := filepath.Join(dir, "backup.tgz") file := filepath.Join(dir, "backup.tgz")
args := []string{ args := []string{
"-append-filename=version,dc,node,status", "-append-filename=version,dc",
"-http-addr=" + a.HTTPAddr(), "-http-addr=" + a.HTTPAddr(),
file, 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) // We need to use the self endpoint here for ENT, which returns the product suffix (+ent)
self, err := client.Agent().Self() self, err := client.Agent().Self()
require.NoError(t, err) require.NoError(t, err)
@ -108,14 +100,22 @@ func TestSnapshotSaveCommandWithAppendFileNameFlag(t *testing.T) {
cfg, ok := self["Config"] cfg, ok := self["Config"]
require.True(t, ok) require.True(t, ok)
versionAny, ok := cfg["Version"] dc, ok := cfg["Datacenter"]
require.True(t, ok) require.True(t, ok)
version, ok := versionAny.(string) datacenter := dc.(string)
require.True(t, ok)
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+ newFilePath := filepath.Join(dir, "backup"+"-"+version+"-"+datacenter+".tgz")
"-"+a.Config.NodeName+"-"+status+".tgz")
code := c.Run(args) code := c.Run(args)
if code != 0 { if code != 0 {

@ -77,20 +77,20 @@ $ consul snapshot save -stale backup.snap
# ... # ...
``` ```
To create snapshot file with consul version, datacenter, node name and leader/follower info, This is useful for situations where a cluster is in a degraded state and no
run 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 ```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 example - backup-1.17.0-dc1-local-machine-leader.tgz
Note Version is always the leader's consul version
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.
Please see the [HTTP API](/consul/api-docs/snapshot) documentation for Please see the [HTTP API](/consul/api-docs/snapshot) documentation for
more details about snapshot internals. more details about snapshot internals.

Loading…
Cancel
Save