Add dr-token Flag to Autopilot CLI (#21165)

* Add dr-token flag for raft autopilot

* Add changelog

* Cleanup bad patch apply

* Set dr token explicitly
This commit is contained in:
Luis (LT) Carbonell
2023-07-27 11:35:25 -04:00
committed by GitHub
parent f45e9b90d4
commit 727c73cbd1
6 changed files with 84 additions and 5 deletions

View File

@@ -276,11 +276,19 @@ func (c *Sys) RaftAutopilotState() (*AutopilotState, error) {
return c.RaftAutopilotStateWithContext(context.Background())
}
// RaftAutopilotStateWithToken wraps RaftAutopilotStateWithContext using the given token.
func (c *Sys) RaftAutopilotStateWithDRToken(drToken string) (*AutopilotState, error) {
return c.RaftAutopilotStateWithContext(context.WithValue(context.Background(), "dr-token", drToken))
}
// RaftAutopilotStateWithContext returns the state of the raft cluster as seen by autopilot.
func (c *Sys) RaftAutopilotStateWithContext(ctx context.Context) (*AutopilotState, error) {
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
defer cancelFunc()
if ctx.Value("dr-token") != nil {
c.c.SetToken(ctx.Value("dr-token").(string))
}
r := c.c.NewRequest(http.MethodGet, "/v1/sys/storage/raft/autopilot/state")
resp, err := c.c.rawRequestWithContext(ctx, r)
@@ -316,11 +324,20 @@ func (c *Sys) RaftAutopilotConfiguration() (*AutopilotConfig, error) {
return c.RaftAutopilotConfigurationWithContext(context.Background())
}
// RaftAutopilotConfigurationWithDRToken wraps RaftAutopilotConfigurationWithContext using the given token.
func (c *Sys) RaftAutopilotConfigurationWithDRToken(drToken string) (*AutopilotConfig, error) {
return c.RaftAutopilotConfigurationWithContext(context.WithValue(context.Background(), "dr-token", drToken))
}
// RaftAutopilotConfigurationWithContext fetches the autopilot config.
func (c *Sys) RaftAutopilotConfigurationWithContext(ctx context.Context) (*AutopilotConfig, error) {
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
defer cancelFunc()
if ctx.Value("dr-token") != nil {
c.c.SetToken(ctx.Value("dr-token").(string))
}
r := c.c.NewRequest(http.MethodGet, "/v1/sys/storage/raft/autopilot/configuration")
resp, err := c.c.rawRequestWithContext(ctx, r)

3
changelog/21165.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:bug
raft/autopilot: Add dr-token flag for raft autopilot cli commands
```

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"strings"
"github.com/hashicorp/vault/api"
"github.com/mitchellh/cli"
"github.com/posener/complete"
)
@@ -18,6 +19,7 @@ var (
type OperatorRaftAutopilotGetConfigCommand struct {
*BaseCommand
flagDRToken string
}
func (c *OperatorRaftAutopilotGetConfigCommand) Synopsis() string {
@@ -37,6 +39,17 @@ Usage: vault operator raft autopilot get-config
func (c *OperatorRaftAutopilotGetConfigCommand) Flags() *FlagSets {
set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
f := set.NewFlagSet("Command Options")
f.StringVar(&StringVar{
Name: "dr-token",
Target: &c.flagDRToken,
Default: "",
EnvVar: "",
Completion: complete.PredictAnything,
Usage: "DR operation token used to authorize this request (if a DR secondary node).",
})
return set
}
@@ -70,10 +83,12 @@ func (c *OperatorRaftAutopilotGetConfigCommand) Run(args []string) int {
return 2
}
config, err := client.Sys().RaftAutopilotConfiguration()
if err != nil {
c.UI.Error(err.Error())
return 2
var config *api.AutopilotConfig
switch {
case c.flagDRToken != "":
config, err = client.Sys().RaftAutopilotConfigurationWithDRToken(c.flagDRToken)
default:
config, err = client.Sys().RaftAutopilotConfiguration()
}
if config == nil {

View File

@@ -26,6 +26,7 @@ type OperatorRaftAutopilotSetConfigCommand struct {
flagMinQuorum uint
flagServerStabilizationTime time.Duration
flagDisableUpgradeMigration BoolPtr
flagDRToken string
}
func (c *OperatorRaftAutopilotSetConfigCommand) Synopsis() string {
@@ -50,36 +51,52 @@ func (c *OperatorRaftAutopilotSetConfigCommand) Flags() *FlagSets {
f.BoolPtrVar(&BoolPtrVar{
Name: "cleanup-dead-servers",
Target: &c.flagCleanupDeadServers,
Usage: "Controls whether to remove dead servers from the Raft peer list periodically or when a new server joins.",
})
f.DurationVar(&DurationVar{
Name: "last-contact-threshold",
Target: &c.flagLastContactThreshold,
Usage: "Limit on the amount of time a server can go without leader contact before being considered unhealthy.",
})
f.DurationVar(&DurationVar{
Name: "dead-server-last-contact-threshold",
Target: &c.flagDeadServerLastContactThreshold,
Usage: "Limit on the amount of time a server can go without leader contact before being considered failed. This takes effect only when cleanup_dead_servers is set.",
})
f.Uint64Var(&Uint64Var{
Name: "max-trailing-logs",
Target: &c.flagMaxTrailingLogs,
Usage: "Amount of entries in the Raft Log that a server can be behind before being considered unhealthy.",
})
f.UintVar(&UintVar{
Name: "min-quorum",
Target: &c.flagMinQuorum,
Usage: "Minimum number of servers allowed in a cluster before autopilot can prune dead servers. This should at least be 3.",
})
f.DurationVar(&DurationVar{
Name: "server-stabilization-time",
Target: &c.flagServerStabilizationTime,
Usage: "Minimum amount of time a server must be in a stable, healthy state before it can be added to the cluster.",
})
f.BoolPtrVar(&BoolPtrVar{
Name: "disable-upgrade-migration",
Target: &c.flagDisableUpgradeMigration,
Usage: "Whether or not to perform automated version upgrades.",
})
f.StringVar(&StringVar{
Name: "dr-token",
Target: &c.flagDRToken,
Default: "",
EnvVar: "",
Completion: complete.PredictAnything,
Usage: "DR operation token used to authorize this request (if a DR secondary node).",
})
return set
@@ -137,6 +154,9 @@ func (c *OperatorRaftAutopilotSetConfigCommand) Run(args []string) int {
if c.flagDisableUpgradeMigration.IsSet() {
data["disable_upgrade_migration"] = c.flagDisableUpgradeMigration.Get()
}
if c.flagDRToken != "" {
data["dr_operation_token"] = c.flagDRToken
}
secret, err := client.Logical().Write("sys/storage/raft/autopilot/configuration", data)
if err != nil {

View File

@@ -8,6 +8,7 @@ import (
"fmt"
"strings"
"github.com/hashicorp/vault/api"
"github.com/mitchellh/cli"
"github.com/posener/complete"
)
@@ -19,6 +20,7 @@ var (
type OperatorRaftAutopilotStateCommand struct {
*BaseCommand
flagDRToken string
}
func (c *OperatorRaftAutopilotStateCommand) Synopsis() string {
@@ -38,6 +40,17 @@ Usage: vault operator raft autopilot state
func (c *OperatorRaftAutopilotStateCommand) Flags() *FlagSets {
set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
f := set.NewFlagSet("Command Options")
f.StringVar(&StringVar{
Name: "dr-token",
Target: &c.flagDRToken,
Default: "",
EnvVar: "",
Completion: complete.PredictAnything,
Usage: "DR operation token used to authorize this request (if a DR secondary node).",
})
// The output of the state endpoint contains nested values and is not fit for
// the default "table" display format. Override the default display format to
// "pretty", both in the flag and in the UI.
@@ -83,7 +96,14 @@ func (c *OperatorRaftAutopilotStateCommand) Run(args []string) int {
return 2
}
state, err := client.Sys().RaftAutopilotState()
var state *api.AutopilotState
switch {
case c.flagDRToken != "":
state, err = client.Sys().RaftAutopilotStateWithDRToken(c.flagDRToken)
default:
state, err = client.Sys().RaftAutopilotState()
}
if err != nil {
c.UI.Error(fmt.Sprintf("Error checking autopilot state: %s", err))
return 2

View File

@@ -196,6 +196,10 @@ func (b *SystemBackend) raftStoragePaths() []*framework.Path {
Type: framework.TypeBool,
Description: "Whether or not to perform automated version upgrades.",
},
"dr_operation_token": {
Type: framework.TypeString,
Description: "DR operation token used to authorize this request (if a DR secondary node).",
},
},
Operations: map[logical.Operation]framework.OperationHandler{