Add a CLI command for retrieving the autopilot configuration. (#9142)

This commit is contained in:
Matt Keeler 2020-11-11 13:19:02 -05:00 committed by GitHub
parent 4b9034b976
commit 58f98db227
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1768 additions and 12 deletions

View File

@ -11,6 +11,8 @@ func autopilotToAPIServerEnterprise(_ *autopilot.ServerState, _ *api.AutopilotSe
// noop in oss
}
func autopilotToAPIStateEnterprise(_ *autopilot.State, _ *api.AutopilotState) {
// noop in oss
func autopilotToAPIStateEnterprise(state *autopilot.State, apiState *api.AutopilotState) {
// without the enterprise features there is no different between these two and we don't want to
// alarm anyone by leaving this as the zero value.
apiState.OptimisticFailureTolerance = state.FailureTolerance
}

View File

@ -656,9 +656,10 @@ func TestAutopilotStateToAPIConversion(t *testing.T) {
}
expected := api.AutopilotState{
Healthy: true,
FailureTolerance: 1,
Leader: string(leaderID),
Healthy: true,
FailureTolerance: 1,
OptimisticFailureTolerance: 1,
Leader: string(leaderID),
Voters: []string{
string(leaderID),
string(follower1ID),

View File

@ -114,7 +114,7 @@ type OperatorHealthReply struct {
type AutopilotState struct {
Healthy bool
FailureTolerance int
OptimisitcFailureTolerance int
OptimisticFailureTolerance int
Servers map[string]AutopilotServer
Leader string
@ -137,7 +137,7 @@ type AutopilotServer struct {
StableSince time.Time
RedundancyZone string `json:",omitempty"`
UpgradeVersion string `json:",omitempty"`
ReadReplica bool `json:",omitempty"`
ReadReplica bool
Status AutopilotServerStatus
Meta map[string]string
NodeType AutopilotServerType

View File

@ -85,6 +85,7 @@ import (
operauto "github.com/hashicorp/consul/command/operator/autopilot"
operautoget "github.com/hashicorp/consul/command/operator/autopilot/get"
operautoset "github.com/hashicorp/consul/command/operator/autopilot/set"
operautostate "github.com/hashicorp/consul/command/operator/autopilot/state"
operraft "github.com/hashicorp/consul/command/operator/raft"
operraftlist "github.com/hashicorp/consul/command/operator/raft/listpeers"
operraftremove "github.com/hashicorp/consul/command/operator/raft/removepeer"
@ -202,6 +203,7 @@ func init() {
Register("operator autopilot", func(cli.Ui) (cli.Command, error) { return operauto.New(), nil })
Register("operator autopilot get-config", func(ui cli.Ui) (cli.Command, error) { return operautoget.New(ui), nil })
Register("operator autopilot set-config", func(ui cli.Ui) (cli.Command, error) { return operautoset.New(ui), nil })
Register("operator autopilot state", func(ui cli.Ui) (cli.Command, error) { return operautostate.New(ui), nil })
Register("operator raft", func(cli.Ui) (cli.Command, error) { return operraft.New(), nil })
Register("operator raft list-peers", func(ui cli.Ui) (cli.Command, error) { return operraftlist.New(ui), nil })
Register("operator raft remove-peer", func(ui cli.Ui) (cli.Command, error) { return operraftremove.New(ui), nil })

View File

@ -0,0 +1,206 @@
package state
import (
"bytes"
"encoding/json"
"fmt"
"sort"
"github.com/hashicorp/consul/api"
)
const (
PrettyFormat string = "pretty"
JSONFormat string = "json"
)
// Formatter defines methods provided by an autopilot state output formatter
type Formatter interface {
FormatState(state *api.AutopilotState) (string, error)
}
// GetSupportedFormats returns supported formats
func GetSupportedFormats() []string {
return []string{PrettyFormat, JSONFormat}
}
// NewFormatter returns Formatter implementation
func NewFormatter(format string) (formatter Formatter, err error) {
switch format {
case PrettyFormat:
formatter = newPrettyFormatter()
case JSONFormat:
formatter = newJSONFormatter()
default:
err = fmt.Errorf("Unknown format: %s", format)
}
return formatter, err
}
func newPrettyFormatter() Formatter {
return &prettyFormatter{}
}
type prettyFormatter struct {
}
func outputStringSlice(buffer *bytes.Buffer, indent string, values []string) {
for _, val := range values {
buffer.WriteString(fmt.Sprintf("%s%s\n", indent, val))
}
}
type mapOutput struct {
key string
value string
}
func formatZone(zoneName string, zone *api.AutopilotZone) string {
var buffer bytes.Buffer
buffer.WriteString(fmt.Sprintf(" %s:\n", zoneName))
buffer.WriteString(fmt.Sprintf(" Failure Tolerance: %d\n", zone.FailureTolerance))
buffer.WriteString(" Voters:\n")
outputStringSlice(&buffer, " ", zone.Voters)
buffer.WriteString(" Servers:\n")
outputStringSlice(&buffer, " ", zone.Servers)
return buffer.String()
}
func formatServer(srv *api.AutopilotServer) string {
var buffer bytes.Buffer
buffer.WriteString(fmt.Sprintf(" %s\n", srv.ID))
buffer.WriteString(fmt.Sprintf(" Name: %s\n", srv.Name))
buffer.WriteString(fmt.Sprintf(" Address: %s\n", srv.Address))
buffer.WriteString(fmt.Sprintf(" Version: %s\n", srv.Version))
buffer.WriteString(fmt.Sprintf(" Status: %s\n", srv.Status))
buffer.WriteString(fmt.Sprintf(" Node Type: %s\n", srv.NodeType))
buffer.WriteString(fmt.Sprintf(" Node Status: %s\n", srv.NodeStatus))
buffer.WriteString(fmt.Sprintf(" Healthy: %t\n", srv.Healthy))
buffer.WriteString(fmt.Sprintf(" Last Contact: %s\n", srv.LastContact.String()))
buffer.WriteString(fmt.Sprintf(" Last Term: %d\n", srv.LastTerm))
buffer.WriteString(fmt.Sprintf(" Last Index: %d\n", srv.LastIndex))
if srv.RedundancyZone != "" {
buffer.WriteString(fmt.Sprintf(" Redundancy Zone: %s\n", srv.RedundancyZone))
}
if srv.UpgradeVersion != "" {
buffer.WriteString(fmt.Sprintf(" Upgrade Version: %s\n", srv.UpgradeVersion))
}
if srv.ReadReplica {
buffer.WriteString(fmt.Sprintf(" Read Replica: %t\n", srv.ReadReplica))
}
if len(srv.Meta) > 0 {
buffer.WriteString(fmt.Sprintf(" Meta\n"))
var outputs []mapOutput
for k, v := range srv.Meta {
outputs = append(outputs, mapOutput{key: k, value: fmt.Sprintf(" %q: %q\n", k, v)})
}
sort.Slice(outputs, func(i, j int) bool {
return outputs[i].key < outputs[j].key
})
for _, output := range outputs {
buffer.WriteString(output.value)
}
}
return buffer.String()
}
func (f *prettyFormatter) FormatState(state *api.AutopilotState) (string, error) {
var buffer bytes.Buffer
buffer.WriteString(fmt.Sprintf("Healthy: %t\n", state.Healthy))
buffer.WriteString(fmt.Sprintf("Failure Tolerance: %d\n", state.FailureTolerance))
buffer.WriteString(fmt.Sprintf("Optimistic Failure Tolerance: %d\n", state.OptimisticFailureTolerance))
buffer.WriteString(fmt.Sprintf("Leader: %s\n", state.Leader))
buffer.WriteString("Voters:\n")
outputStringSlice(&buffer, " ", state.Voters)
if len(state.ReadReplicas) > 0 {
buffer.WriteString("Read Replicas:\n")
outputStringSlice(&buffer, " ", state.ReadReplicas)
}
if len(state.RedundancyZones) > 0 {
var outputs []mapOutput
buffer.WriteString("Redundancy Zones:\n")
for zoneName, zone := range state.RedundancyZones {
outputs = append(outputs, mapOutput{key: zoneName, value: formatZone(zoneName, &zone)})
}
sort.Slice(outputs, func(i, j int) bool {
return outputs[i].key < outputs[j].key
})
for _, output := range outputs {
buffer.WriteString(output.value)
}
}
if state.Upgrade != nil {
u := state.Upgrade
buffer.WriteString("Upgrade:\n")
buffer.WriteString(fmt.Sprintf(" Status: %s\n", u.Status))
buffer.WriteString(fmt.Sprintf(" Target Version: %s\n", u.TargetVersion))
if len(u.TargetVersionVoters) > 0 {
buffer.WriteString(" Target Version Voters:\n")
outputStringSlice(&buffer, " ", u.TargetVersionVoters)
}
if len(u.TargetVersionNonVoters) > 0 {
buffer.WriteString(" Target Version Non-Voters:\n")
outputStringSlice(&buffer, " ", u.TargetVersionNonVoters)
}
if len(u.TargetVersionReadReplicas) > 0 {
buffer.WriteString(" Target Version ReadReplicas:\n")
outputStringSlice(&buffer, " ", u.TargetVersionReadReplicas)
}
if len(u.OtherVersionVoters) > 0 {
buffer.WriteString(" Other Version Voters:\n")
outputStringSlice(&buffer, " ", u.OtherVersionVoters)
}
if len(u.OtherVersionNonVoters) > 0 {
buffer.WriteString(" Other Version Non-Voters:\n")
outputStringSlice(&buffer, " ", u.OtherVersionNonVoters)
}
if len(u.OtherVersionReadReplicas) > 0 {
buffer.WriteString(" Other Version ReadReplicas:\n")
outputStringSlice(&buffer, " ", u.OtherVersionReadReplicas)
}
}
buffer.WriteString("Servers:\n")
var outputs []mapOutput
for id, srv := range state.Servers {
outputs = append(outputs, mapOutput{key: id, value: formatServer(&srv)})
}
sort.Slice(outputs, func(i, j int) bool {
return outputs[i].key < outputs[j].key
})
for _, output := range outputs {
buffer.WriteString(output.value)
}
return buffer.String(), nil
}
func newJSONFormatter() Formatter {
return &jsonFormatter{}
}
type jsonFormatter struct {
}
func (f *jsonFormatter) FormatState(state *api.AutopilotState) (string, error) {
b, err := json.MarshalIndent(state, "", " ")
if err != nil {
return "", fmt.Errorf("Failed to marshal token: %v", err)
}
return string(b), nil
}

View File

@ -0,0 +1,99 @@
package state
import (
"flag"
"fmt"
"strings"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/command/flags"
"github.com/mitchellh/cli"
)
func New(ui cli.Ui) *cmd {
c := &cmd{UI: ui}
c.init()
return c
}
type cmd struct {
UI cli.Ui
flags *flag.FlagSet
http *flags.HTTPFlags
help string
format string
}
func (c *cmd) init() {
c.flags = flag.NewFlagSet("", flag.ContinueOnError)
c.flags.StringVar(
&c.format,
"format",
PrettyFormat,
fmt.Sprintf("Output format {%s}", strings.Join(GetSupportedFormats(), "|")),
)
c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags())
flags.Merge(c.flags, c.http.ServerFlags())
c.help = flags.Usage(help, c.flags)
}
func (c *cmd) Run(args []string) int {
if err := c.flags.Parse(args); err != nil {
if err == flag.ErrHelp {
return 0
}
c.UI.Error(fmt.Sprintf("Failed to parse args: %v", err))
return 1
}
// Set up a client.
client, err := c.http.APIClient()
if err != nil {
c.UI.Error(fmt.Sprintf("Error initializing client: %s", err))
return 1
}
// Fetch the current configuration.
opts := &api.QueryOptions{
AllowStale: c.http.Stale(),
}
state, err := client.Operator().AutopilotState(opts)
if err != nil {
c.UI.Error(fmt.Sprintf("Error querying Autopilot state: %s", err))
return 1
}
formatter, err := NewFormatter(c.format)
if err != nil {
c.UI.Error(err.Error())
return 1
}
out, err := formatter.FormatState(state)
if err != nil {
c.UI.Error(err.Error())
return 1
}
if out != "" {
c.UI.Info(out)
}
return 0
}
func (c *cmd) Synopsis() string {
return synopsis
}
func (c *cmd) Help() string {
return c.help
}
const synopsis = "Display the current Autopilot configuration"
const help = `
Usage: consul operator autopilot get-config [options]
Displays the current Autopilot configuration.
`

View File

@ -0,0 +1,126 @@
package state
import (
"encoding/json"
"flag"
"io/ioutil"
"path/filepath"
"strings"
"testing"
"github.com/hashicorp/consul/agent"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/testrpc"
"github.com/mitchellh/cli"
"github.com/stretchr/testify/require"
)
// update allows golden files to be updated based on the current output.
var update = flag.Bool("update", false, "update golden files")
// golden reads and optionally writes the expected data to the golden file,
// returning the contents as a string.
func golden(t *testing.T, name, got string) string {
t.Helper()
golden := filepath.Join("testdata", name+".golden")
if *update && got != "" {
err := ioutil.WriteFile(golden, []byte(got), 0644)
require.NoError(t, err)
}
expected, err := ioutil.ReadFile(golden)
require.NoError(t, err)
return string(expected)
}
func TestStateCommand_noTabs(t *testing.T) {
t.Parallel()
if strings.ContainsRune(New(cli.NewMockUi()).Help(), '\t') {
t.Fatal("help has tabs")
}
}
func TestStateCommand_Pretty(t *testing.T) {
t.Parallel()
a := agent.NewTestAgent(t, `
node_id = "f0427127-7531-455a-b651-f1ea1d8451f0"
`)
defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1")
ui := cli.NewMockUi()
cmd := New(ui)
args := []string{
"-http-addr=" + a.HTTPAddr(),
}
code := cmd.Run(args)
require.Empty(t, ui.ErrorWriter.String())
require.Equal(t, code, 0)
output := ui.OutputWriter.String()
// Just a few quick checks to ensure we got output
// the output formatter will be tested in another test.
require.Regexp(t, `^Healthy:`, output)
require.Regexp(t, `(?m)^Leader:`, output)
}
func TestStateCommand_JSON(t *testing.T) {
t.Parallel()
a := agent.NewTestAgent(t, "")
defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1")
ui := cli.NewMockUi()
cmd := New(ui)
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-format=json",
}
code := cmd.Run(args)
require.Empty(t, ui.ErrorWriter.String())
require.Equal(t, code, 0)
output := ui.OutputWriter.String()
var state api.AutopilotState
require.NoError(t, json.Unmarshal([]byte(output), &state))
}
func TestStateCommand_Formatter(t *testing.T) {
cases := []string{
"oss",
"enterprise",
}
for _, name := range cases {
t.Run(name, func(t *testing.T) {
statePath := filepath.Join("testdata", name, "state.json")
input, err := ioutil.ReadFile(statePath)
require.NoError(t, err)
var state api.AutopilotState
require.NoError(t, json.Unmarshal(input, &state))
for _, format := range GetSupportedFormats() {
t.Run(format, func(t *testing.T) {
formatter, err := NewFormatter(format)
require.NoError(t, err)
actual, err := formatter.FormatState(&state)
require.NoError(t, err)
expected := golden(t, filepath.Join(name, format), actual)
require.Equal(t, expected, actual)
})
}
})
}
}

View File

@ -0,0 +1,401 @@
{
"Healthy": true,
"FailureTolerance": 1,
"OptimisticFailureTolerance": 0,
"Servers": {
"1b8044f6-1d25-4a83-9662-acdf404341d2": {
"ID": "1b8044f6-1d25-4a83-9662-acdf404341d2",
"Name": "node6.new",
"Address": "198.18.1.6:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone3",
"UpgradeVersion": "2.0.0",
"ReadReplica": false,
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "2.0.0",
"zone": "zone3"
},
"NodeType": "zone-standby"
},
"1baeb453-ad9e-489a-bbfe-53bee097aec8": {
"ID": "1baeb453-ad9e-489a-bbfe-53bee097aec8",
"Name": "node4",
"Address": "198.18.0.4:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone2",
"UpgradeVersion": "1.0.0",
"ReadReplica": false,
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "1.0.0",
"zone": "zone2"
},
"NodeType": "zone-standby"
},
"3044d109-f028-4489-b59c-f267afe408f2": {
"ID": "3044d109-f028-4489-b59c-f267afe408f2",
"Name": "node2.new",
"Address": "198.18.1.2:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone1",
"UpgradeVersion": "2.0.0",
"ReadReplica": false,
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "2.0.0",
"zone": "zone1"
},
"NodeType": "zone-standby"
},
"4691e516-6989-4a16-8f55-12ff2226a3c9": {
"ID": "4691e516-6989-4a16-8f55-12ff2226a3c9",
"Name": "node4.new",
"Address": "198.18.1.4:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone2",
"UpgradeVersion": "2.0.0",
"ReadReplica": false,
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "2.0.0",
"zone": "zone2"
},
"NodeType": "zone-standby"
},
"4c42fe86-321d-4e8f-be0d-c261e6cfc453": {
"ID": "4c42fe86-321d-4e8f-be0d-c261e6cfc453",
"Name": "node5",
"Address": "198.18.0.5:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone3",
"UpgradeVersion": "1.0.0",
"ReadReplica": false,
"Status": "voter",
"Meta": {
"foo": "bar",
"upgrade": "1.0.0",
"zone": "zone3"
},
"NodeType": "zone-voter"
},
"6ca5a41c-6162-41c1-b4eb-09082efe206f": {
"ID": "6ca5a41c-6162-41c1-b4eb-09082efe206f",
"Name": "node2",
"Address": "198.18.0.2:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone1",
"UpgradeVersion": "1.0.0",
"ReadReplica": false,
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "1.0.0",
"zone": "zone1"
},
"NodeType": "zone-standby"
},
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d": {
"ID": "6e8a37e5-a1c4-4212-a75e-91487d8cda6d",
"Name": "node3",
"Address": "198.18.0.3:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone2",
"UpgradeVersion": "1.0.0",
"ReadReplica": false,
"Status": "voter",
"Meta": {
"foo": "bar",
"upgrade": "1.0.0",
"zone": "zone2"
},
"NodeType": "zone-voter"
},
"746b8782-ce77-41fd-bce0-cce62cca62b4": {
"ID": "746b8782-ce77-41fd-bce0-cce62cca62b4",
"Name": "node6",
"Address": "198.18.0.6:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone3",
"UpgradeVersion": "1.0.0",
"ReadReplica": false,
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "1.0.0",
"zone": "zone3"
},
"NodeType": "zone-standby"
},
"79324811-9588-4311-b208-f272e38aaabf": {
"ID": "79324811-9588-4311-b208-f272e38aaabf",
"Name": "node1",
"Address": "198.18.0.1:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "0s",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone1",
"UpgradeVersion": "1.0.0",
"ReadReplica": false,
"Status": "leader",
"Meta": {
"foo": "bar",
"upgrade": "1.0.0",
"zone": "zone1"
},
"NodeType": "zone-voter"
},
"7b02a615-ccce-4251-bda8-b89e0bd4f7c7": {
"ID": "7b02a615-ccce-4251-bda8-b89e0bd4f7c7",
"Name": "read-replica",
"Address": "198.18.0.7:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "2ms",
"LastTerm": 3,
"LastIndex": 39,
"Healthy": true,
"StableSince": "2020-11-06T14:53:00Z",
"UpgradeVersion": "1.0.0",
"ReadReplica": true,
"Status": "non-voter",
"Meta": {
"baz": "foo",
"version": "1.0.0"
},
"NodeType": "read-replica"
},
"98dfd0fd-504e-4280-8e73-6983a6af1b8c": {
"ID": "98dfd0fd-504e-4280-8e73-6983a6af1b8c",
"Name": "node5.new",
"Address": "198.18.1.5:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone3",
"UpgradeVersion": "2.0.0",
"ReadReplica": false,
"Status": "non-voter",
"Meta": {
"foo": "bar",
"upgrade": "2.0.0",
"zone": "zone3"
},
"NodeType": "zone-standby"
},
"997b0851-37c5-4d65-a477-a8b3a56eea42": {
"ID": "997b0851-37c5-4d65-a477-a8b3a56eea42",
"Name": "node3.new",
"Address": "198.18.1.3:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone2",
"UpgradeVersion": "2.0.0",
"ReadReplica": false,
"Status": "non-voter",
"Meta": {
"foo": "bar",
"upgrade": "2.0.0",
"zone": "zone2"
},
"NodeType": "zone-standby"
},
"de95799e-15a4-4c86-b508-78840554b7cb": {
"ID": "de95799e-15a4-4c86-b508-78840554b7cb",
"Name": "node1.new",
"Address": "198.18.1.1:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "0s",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone1",
"UpgradeVersion": "2.0.0",
"ReadReplica": false,
"Status": "non-voter",
"Meta": {
"foo": "bar",
"upgrade": "2.0.0",
"zone": "zone1"
},
"NodeType": "zone-standby"
}
},
"Leader": "79324811-9588-4311-b208-f272e38aaabf",
"Voters": [
"79324811-9588-4311-b208-f272e38aaabf",
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d",
"4c42fe86-321d-4e8f-be0d-c261e6cfc453"
],
"ReadReplicas": [
"7b02a615-ccce-4251-bda8-b89e0bd4f7c7"
],
"RedundancyZones": {
"zone1": {
"Servers": [
"79324811-9588-4311-b208-f272e38aaabf",
"6ca5a41c-6162-41c1-b4eb-09082efe206f",
"de95799e-15a4-4c86-b508-78840554b7cb",
"3044d109-f028-4489-b59c-f267afe408f2"
],
"Voters": [
"79324811-9588-4311-b208-f272e38aaabf"
],
"FailureTolerance": 3
},
"zone2": {
"Servers": [
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d",
"1baeb453-ad9e-489a-bbfe-53bee097aec8",
"997b0851-37c5-4d65-a477-a8b3a56eea42",
"4691e516-6989-4a16-8f55-12ff2226a3c9"
],
"Voters": [
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d"
],
"FailureTolerance": 3
},
"zone3": {
"Servers": [
"4c42fe86-321d-4e8f-be0d-c261e6cfc453",
"746b8782-ce77-41fd-bce0-cce62cca62b4",
"98dfd0fd-504e-4280-8e73-6983a6af1b8c",
"1b8044f6-1d25-4a83-9662-acdf404341d2"
],
"Voters": [
"4c42fe86-321d-4e8f-be0d-c261e6cfc453"
],
"FailureTolerance": 3
}
},
"Upgrade": {
"Status": "promoting",
"TargetVersion": "2.0.0",
"TargetVersionNonVoters": [
"de95799e-15a4-4c86-b508-78840554b7cb",
"3044d109-f028-4489-b59c-f267afe408f2",
"997b0851-37c5-4d65-a477-a8b3a56eea42",
"4691e516-6989-4a16-8f55-12ff2226a3c9",
"98dfd0fd-504e-4280-8e73-6983a6af1b8c",
"1b8044f6-1d25-4a83-9662-acdf404341d2"
],
"OtherVersionVoters": [
"79324811-9588-4311-b208-f272e38aaabf",
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d",
"4c42fe86-321d-4e8f-be0d-c261e6cfc453"
],
"OtherVersionNonVoters": [
"6ca5a41c-6162-41c1-b4eb-09082efe206f",
"1baeb453-ad9e-489a-bbfe-53bee097aec8",
"746b8782-ce77-41fd-bce0-cce62cca62b4"
],
"OtherVersionReadReplicas": [
"7b02a615-ccce-4251-bda8-b89e0bd4f7c7"
],
"RedundancyZones": {
"zone1": {
"TargetVersionNonVoters": [
"de95799e-15a4-4c86-b508-78840554b7cb",
"3044d109-f028-4489-b59c-f267afe408f2"
],
"OtherVersionVoters": [
"79324811-9588-4311-b208-f272e38aaabf"
],
"OtherVersionNonVoters": [
"6ca5a41c-6162-41c1-b4eb-09082efe206f"
]
},
"zone2": {
"TargetVersionNonVoters": [
"997b0851-37c5-4d65-a477-a8b3a56eea42",
"4691e516-6989-4a16-8f55-12ff2226a3c9"
],
"OtherVersionVoters": [
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d"
],
"OtherVersionNonVoters": [
"1baeb453-ad9e-489a-bbfe-53bee097aec8"
]
},
"zone3": {
"TargetVersionNonVoters": [
"98dfd0fd-504e-4280-8e73-6983a6af1b8c",
"1b8044f6-1d25-4a83-9662-acdf404341d2"
],
"OtherVersionVoters": [
"4c42fe86-321d-4e8f-be0d-c261e6cfc453"
],
"OtherVersionNonVoters": [
"746b8782-ce77-41fd-bce0-cce62cca62b4"
]
}
}
}
}

View File

@ -0,0 +1,279 @@
Healthy: true
Failure Tolerance: 1
Optimistic Failure Tolerance: 0
Leader: 79324811-9588-4311-b208-f272e38aaabf
Voters:
79324811-9588-4311-b208-f272e38aaabf
6e8a37e5-a1c4-4212-a75e-91487d8cda6d
4c42fe86-321d-4e8f-be0d-c261e6cfc453
Read Replicas:
7b02a615-ccce-4251-bda8-b89e0bd4f7c7
Redundancy Zones:
zone1:
Failure Tolerance: 3
Voters:
79324811-9588-4311-b208-f272e38aaabf
Servers:
79324811-9588-4311-b208-f272e38aaabf
6ca5a41c-6162-41c1-b4eb-09082efe206f
de95799e-15a4-4c86-b508-78840554b7cb
3044d109-f028-4489-b59c-f267afe408f2
zone2:
Failure Tolerance: 3
Voters:
6e8a37e5-a1c4-4212-a75e-91487d8cda6d
Servers:
6e8a37e5-a1c4-4212-a75e-91487d8cda6d
1baeb453-ad9e-489a-bbfe-53bee097aec8
997b0851-37c5-4d65-a477-a8b3a56eea42
4691e516-6989-4a16-8f55-12ff2226a3c9
zone3:
Failure Tolerance: 3
Voters:
4c42fe86-321d-4e8f-be0d-c261e6cfc453
Servers:
4c42fe86-321d-4e8f-be0d-c261e6cfc453
746b8782-ce77-41fd-bce0-cce62cca62b4
98dfd0fd-504e-4280-8e73-6983a6af1b8c
1b8044f6-1d25-4a83-9662-acdf404341d2
Upgrade:
Status: promoting
Target Version: 2.0.0
Target Version Non-Voters:
de95799e-15a4-4c86-b508-78840554b7cb
3044d109-f028-4489-b59c-f267afe408f2
997b0851-37c5-4d65-a477-a8b3a56eea42
4691e516-6989-4a16-8f55-12ff2226a3c9
98dfd0fd-504e-4280-8e73-6983a6af1b8c
1b8044f6-1d25-4a83-9662-acdf404341d2
Other Version Voters:
79324811-9588-4311-b208-f272e38aaabf
6e8a37e5-a1c4-4212-a75e-91487d8cda6d
4c42fe86-321d-4e8f-be0d-c261e6cfc453
Other Version Non-Voters:
6ca5a41c-6162-41c1-b4eb-09082efe206f
1baeb453-ad9e-489a-bbfe-53bee097aec8
746b8782-ce77-41fd-bce0-cce62cca62b4
Other Version ReadReplicas:
7b02a615-ccce-4251-bda8-b89e0bd4f7c7
Servers:
1b8044f6-1d25-4a83-9662-acdf404341d2
Name: node6.new
Address: 198.18.1.6:8300
Version: 1.9.0
Status: non-voter
Node Type: zone-standby
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 41
Redundancy Zone: zone3
Upgrade Version: 2.0.0
Meta
"bar": "baz"
"upgrade": "2.0.0"
"zone": "zone3"
1baeb453-ad9e-489a-bbfe-53bee097aec8
Name: node4
Address: 198.18.0.4:8300
Version: 1.9.0
Status: non-voter
Node Type: zone-standby
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 41
Redundancy Zone: zone2
Upgrade Version: 1.0.0
Meta
"bar": "baz"
"upgrade": "1.0.0"
"zone": "zone2"
3044d109-f028-4489-b59c-f267afe408f2
Name: node2.new
Address: 198.18.1.2:8300
Version: 1.9.0
Status: non-voter
Node Type: zone-standby
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 41
Redundancy Zone: zone1
Upgrade Version: 2.0.0
Meta
"bar": "baz"
"upgrade": "2.0.0"
"zone": "zone1"
4691e516-6989-4a16-8f55-12ff2226a3c9
Name: node4.new
Address: 198.18.1.4:8300
Version: 1.9.0
Status: non-voter
Node Type: zone-standby
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 41
Redundancy Zone: zone2
Upgrade Version: 2.0.0
Meta
"bar": "baz"
"upgrade": "2.0.0"
"zone": "zone2"
4c42fe86-321d-4e8f-be0d-c261e6cfc453
Name: node5
Address: 198.18.0.5:8300
Version: 1.9.0
Status: voter
Node Type: zone-voter
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 42
Redundancy Zone: zone3
Upgrade Version: 1.0.0
Meta
"foo": "bar"
"upgrade": "1.0.0"
"zone": "zone3"
6ca5a41c-6162-41c1-b4eb-09082efe206f
Name: node2
Address: 198.18.0.2:8300
Version: 1.9.0
Status: non-voter
Node Type: zone-standby
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 41
Redundancy Zone: zone1
Upgrade Version: 1.0.0
Meta
"bar": "baz"
"upgrade": "1.0.0"
"zone": "zone1"
6e8a37e5-a1c4-4212-a75e-91487d8cda6d
Name: node3
Address: 198.18.0.3:8300
Version: 1.9.0
Status: voter
Node Type: zone-voter
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 42
Redundancy Zone: zone2
Upgrade Version: 1.0.0
Meta
"foo": "bar"
"upgrade": "1.0.0"
"zone": "zone2"
746b8782-ce77-41fd-bce0-cce62cca62b4
Name: node6
Address: 198.18.0.6:8300
Version: 1.9.0
Status: non-voter
Node Type: zone-standby
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 41
Redundancy Zone: zone3
Upgrade Version: 1.0.0
Meta
"bar": "baz"
"upgrade": "1.0.0"
"zone": "zone3"
79324811-9588-4311-b208-f272e38aaabf
Name: node1
Address: 198.18.0.1:8300
Version: 1.9.0
Status: leader
Node Type: zone-voter
Node Status: alive
Healthy: true
Last Contact: 0s
Last Term: 3
Last Index: 42
Redundancy Zone: zone1
Upgrade Version: 1.0.0
Meta
"foo": "bar"
"upgrade": "1.0.0"
"zone": "zone1"
7b02a615-ccce-4251-bda8-b89e0bd4f7c7
Name: read-replica
Address: 198.18.0.7:8300
Version: 1.9.0
Status: non-voter
Node Type: read-replica
Node Status: alive
Healthy: true
Last Contact: 2ms
Last Term: 3
Last Index: 39
Upgrade Version: 1.0.0
Read Replica: true
Meta
"baz": "foo"
"version": "1.0.0"
98dfd0fd-504e-4280-8e73-6983a6af1b8c
Name: node5.new
Address: 198.18.1.5:8300
Version: 1.9.0
Status: non-voter
Node Type: zone-standby
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 42
Redundancy Zone: zone3
Upgrade Version: 2.0.0
Meta
"foo": "bar"
"upgrade": "2.0.0"
"zone": "zone3"
997b0851-37c5-4d65-a477-a8b3a56eea42
Name: node3.new
Address: 198.18.1.3:8300
Version: 1.9.0
Status: non-voter
Node Type: zone-standby
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 42
Redundancy Zone: zone2
Upgrade Version: 2.0.0
Meta
"foo": "bar"
"upgrade": "2.0.0"
"zone": "zone2"
de95799e-15a4-4c86-b508-78840554b7cb
Name: node1.new
Address: 198.18.1.1:8300
Version: 1.9.0
Status: non-voter
Node Type: zone-standby
Node Status: alive
Healthy: true
Last Contact: 0s
Last Term: 3
Last Index: 42
Redundancy Zone: zone1
Upgrade Version: 2.0.0
Meta
"foo": "bar"
"upgrade": "2.0.0"
"zone": "zone1"

View File

@ -0,0 +1,389 @@
{
"Healthy": true,
"FailureTolerance": 1,
"OptimisitcFailureTolerance": 10,
"Servers": {
"1b8044f6-1d25-4a83-9662-acdf404341d2": {
"ID": "1b8044f6-1d25-4a83-9662-acdf404341d2",
"Name": "node6.new",
"Address": "198.18.1.6:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone3",
"UpgradeVersion": "2.0.0",
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "2.0.0",
"zone": "zone3"
},
"NodeType": "zone-standby"
},
"1baeb453-ad9e-489a-bbfe-53bee097aec8": {
"ID": "1baeb453-ad9e-489a-bbfe-53bee097aec8",
"Name": "node4",
"Address": "198.18.0.4:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone2",
"UpgradeVersion": "1.0.0",
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "1.0.0",
"zone": "zone2"
},
"NodeType": "zone-standby"
},
"3044d109-f028-4489-b59c-f267afe408f2": {
"ID": "3044d109-f028-4489-b59c-f267afe408f2",
"Name": "node2.new",
"Address": "198.18.1.2:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone1",
"UpgradeVersion": "2.0.0",
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "2.0.0",
"zone": "zone1"
},
"NodeType": "zone-standby"
},
"4691e516-6989-4a16-8f55-12ff2226a3c9": {
"ID": "4691e516-6989-4a16-8f55-12ff2226a3c9",
"Name": "node4.new",
"Address": "198.18.1.4:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone2",
"UpgradeVersion": "2.0.0",
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "2.0.0",
"zone": "zone2"
},
"NodeType": "zone-standby"
},
"4c42fe86-321d-4e8f-be0d-c261e6cfc453": {
"ID": "4c42fe86-321d-4e8f-be0d-c261e6cfc453",
"Name": "node5",
"Address": "198.18.0.5:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone3",
"UpgradeVersion": "1.0.0",
"Status": "voter",
"Meta": {
"foo": "bar",
"upgrade": "1.0.0",
"zone": "zone3"
},
"NodeType": "zone-voter"
},
"6ca5a41c-6162-41c1-b4eb-09082efe206f": {
"ID": "6ca5a41c-6162-41c1-b4eb-09082efe206f",
"Name": "node2",
"Address": "198.18.0.2:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone1",
"UpgradeVersion": "1.0.0",
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "1.0.0",
"zone": "zone1"
},
"NodeType": "zone-standby"
},
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d": {
"ID": "6e8a37e5-a1c4-4212-a75e-91487d8cda6d",
"Name": "node3",
"Address": "198.18.0.3:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone2",
"UpgradeVersion": "1.0.0",
"Status": "voter",
"Meta": {
"foo": "bar",
"upgrade": "1.0.0",
"zone": "zone2"
},
"NodeType": "zone-voter"
},
"746b8782-ce77-41fd-bce0-cce62cca62b4": {
"ID": "746b8782-ce77-41fd-bce0-cce62cca62b4",
"Name": "node6",
"Address": "198.18.0.6:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"RedundancyZone": "zone3",
"UpgradeVersion": "1.0.0",
"Status": "non-voter",
"Meta": {
"bar": "baz",
"upgrade": "1.0.0",
"zone": "zone3"
},
"NodeType": "zone-standby"
},
"79324811-9588-4311-b208-f272e38aaabf": {
"ID": "79324811-9588-4311-b208-f272e38aaabf",
"Name": "node1",
"Address": "198.18.0.1:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "0s",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone1",
"UpgradeVersion": "1.0.0",
"Status": "leader",
"Meta": {
"foo": "bar",
"upgrade": "1.0.0",
"zone": "zone1"
},
"NodeType": "zone-voter"
},
"7b02a615-ccce-4251-bda8-b89e0bd4f7c7": {
"ID": "7b02a615-ccce-4251-bda8-b89e0bd4f7c7",
"Name": "read-replica",
"Address": "198.18.0.7:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "2ms",
"LastTerm": 3,
"LastIndex": 39,
"Healthy": true,
"StableSince": "2020-11-06T14:53:00Z",
"UpgradeVersion": "1.0.0",
"ReadReplica": true,
"Status": "non-voter",
"Meta": {
"baz": "foo",
"version": "1.0.0"
},
"NodeType": "read-replica"
},
"98dfd0fd-504e-4280-8e73-6983a6af1b8c": {
"ID": "98dfd0fd-504e-4280-8e73-6983a6af1b8c",
"Name": "node5.new",
"Address": "198.18.1.5:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone3",
"UpgradeVersion": "2.0.0",
"Status": "non-voter",
"Meta": {
"foo": "bar",
"upgrade": "2.0.0",
"zone": "zone3"
},
"NodeType": "zone-standby"
},
"997b0851-37c5-4d65-a477-a8b3a56eea42": {
"ID": "997b0851-37c5-4d65-a477-a8b3a56eea42",
"Name": "node3.new",
"Address": "198.18.1.3:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone2",
"UpgradeVersion": "2.0.0",
"Status": "non-voter",
"Meta": {
"foo": "bar",
"upgrade": "2.0.0",
"zone": "zone2"
},
"NodeType": "zone-standby"
},
"de95799e-15a4-4c86-b508-78840554b7cb": {
"ID": "de95799e-15a4-4c86-b508-78840554b7cb",
"Name": "node1.new",
"Address": "198.18.1.1:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "0s",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"RedundancyZone": "zone1",
"UpgradeVersion": "2.0.0",
"Status": "non-voter",
"Meta": {
"foo": "bar",
"upgrade": "2.0.0",
"zone": "zone1"
},
"NodeType": "zone-standby"
}
},
"Leader": "79324811-9588-4311-b208-f272e38aaabf",
"Voters": [
"79324811-9588-4311-b208-f272e38aaabf",
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d",
"4c42fe86-321d-4e8f-be0d-c261e6cfc453"
],
"ReadReplicas": [
"7b02a615-ccce-4251-bda8-b89e0bd4f7c7"
],
"RedundancyZones": {
"zone1": {
"Servers": [
"79324811-9588-4311-b208-f272e38aaabf",
"6ca5a41c-6162-41c1-b4eb-09082efe206f",
"de95799e-15a4-4c86-b508-78840554b7cb",
"3044d109-f028-4489-b59c-f267afe408f2"
],
"Voters": [
"79324811-9588-4311-b208-f272e38aaabf"
],
"FailureTolerance": 3
},
"zone2": {
"Servers": [
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d",
"1baeb453-ad9e-489a-bbfe-53bee097aec8",
"997b0851-37c5-4d65-a477-a8b3a56eea42",
"4691e516-6989-4a16-8f55-12ff2226a3c9"
],
"Voters": [
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d"
],
"FailureTolerance": 3
},
"zone3": {
"Servers": [
"4c42fe86-321d-4e8f-be0d-c261e6cfc453",
"746b8782-ce77-41fd-bce0-cce62cca62b4",
"98dfd0fd-504e-4280-8e73-6983a6af1b8c",
"1b8044f6-1d25-4a83-9662-acdf404341d2"
],
"Voters": [
"4c42fe86-321d-4e8f-be0d-c261e6cfc453"
],
"FailureTolerance": 3
}
},
"Upgrade": {
"Status": "promoting",
"TargetVersion": "2.0.0",
"TargetVersionNonVoters": [
"de95799e-15a4-4c86-b508-78840554b7cb",
"3044d109-f028-4489-b59c-f267afe408f2",
"997b0851-37c5-4d65-a477-a8b3a56eea42",
"4691e516-6989-4a16-8f55-12ff2226a3c9",
"98dfd0fd-504e-4280-8e73-6983a6af1b8c",
"1b8044f6-1d25-4a83-9662-acdf404341d2"
],
"OtherVersionVoters": [
"79324811-9588-4311-b208-f272e38aaabf",
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d",
"4c42fe86-321d-4e8f-be0d-c261e6cfc453"
],
"OtherVersionNonVoters": [
"6ca5a41c-6162-41c1-b4eb-09082efe206f",
"1baeb453-ad9e-489a-bbfe-53bee097aec8",
"746b8782-ce77-41fd-bce0-cce62cca62b4"
],
"OtherVersionReadReplicas": [
"7b02a615-ccce-4251-bda8-b89e0bd4f7c7"
],
"RedundancyZones": {
"zone1": {
"TargetVersionNonVoters": [
"de95799e-15a4-4c86-b508-78840554b7cb",
"3044d109-f028-4489-b59c-f267afe408f2"
],
"OtherVersionVoters": [
"79324811-9588-4311-b208-f272e38aaabf"
],
"OtherVersionNonVoters": [
"6ca5a41c-6162-41c1-b4eb-09082efe206f"
]
},
"zone2": {
"TargetVersionNonVoters": [
"997b0851-37c5-4d65-a477-a8b3a56eea42",
"4691e516-6989-4a16-8f55-12ff2226a3c9"
],
"OtherVersionVoters": [
"6e8a37e5-a1c4-4212-a75e-91487d8cda6d"
],
"OtherVersionNonVoters": [
"1baeb453-ad9e-489a-bbfe-53bee097aec8"
]
},
"zone3": {
"TargetVersionNonVoters": [
"98dfd0fd-504e-4280-8e73-6983a6af1b8c",
"1b8044f6-1d25-4a83-9662-acdf404341d2"
],
"OtherVersionVoters": [
"4c42fe86-321d-4e8f-be0d-c261e6cfc453"
],
"OtherVersionNonVoters": [
"746b8782-ce77-41fd-bce0-cce62cca62b4"
]
}
}
}
}

View File

@ -0,0 +1,67 @@
{
"Healthy": true,
"FailureTolerance": 1,
"OptimisticFailureTolerance": 0,
"Servers": {
"79324811-9588-4311-b208-f272e38aaabf": {
"ID": "79324811-9588-4311-b208-f272e38aaabf",
"Name": "node1",
"Address": "198.18.0.1:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "0s",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"ReadReplica": false,
"Status": "leader",
"Meta": {
"foo": "bar"
},
"NodeType": "voter"
},
"ae84aefb-a303-4734-8739-5c102d4ee2d9": {
"ID": "ae84aefb-a303-4734-8739-5c102d4ee2d9",
"Name": "node3",
"Address": "198.18.0.3:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "2ms",
"LastTerm": 3,
"LastIndex": 39,
"Healthy": true,
"StableSince": "2020-11-06T14:53:00Z",
"ReadReplica": false,
"Status": "voter",
"Meta": {
"baz": "foo"
},
"NodeType": "voter"
},
"ef8aee9a-f9d6-4ec4-b383-aac956bdb80f": {
"ID": "ef8aee9a-f9d6-4ec4-b383-aac956bdb80f",
"Name": "node2",
"Address": "198.18.0.2:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"ReadReplica": false,
"Status": "voter",
"Meta": {
"bar": "baz"
},
"NodeType": "voter"
}
},
"Leader": "79324811-9588-4311-b208-f272e38aaabf",
"Voters": [
"79324811-9588-4311-b208-f272e38aaabf",
"ef8aee9a-f9d6-4ec4-b383-aac956bdb80f",
"ae84aefb-a303-4734-8739-5c102d4ee2d9"
]
}

View File

@ -0,0 +1,48 @@
Healthy: true
Failure Tolerance: 1
Optimistic Failure Tolerance: 0
Leader: 79324811-9588-4311-b208-f272e38aaabf
Voters:
79324811-9588-4311-b208-f272e38aaabf
ef8aee9a-f9d6-4ec4-b383-aac956bdb80f
ae84aefb-a303-4734-8739-5c102d4ee2d9
Servers:
79324811-9588-4311-b208-f272e38aaabf
Name: node1
Address: 198.18.0.1:8300
Version: 1.9.0
Status: leader
Node Type: voter
Node Status: alive
Healthy: true
Last Contact: 0s
Last Term: 3
Last Index: 42
Meta
"foo": "bar"
ae84aefb-a303-4734-8739-5c102d4ee2d9
Name: node3
Address: 198.18.0.3:8300
Version: 1.9.0
Status: voter
Node Type: voter
Node Status: alive
Healthy: true
Last Contact: 2ms
Last Term: 3
Last Index: 39
Meta
"baz": "foo"
ef8aee9a-f9d6-4ec4-b383-aac956bdb80f
Name: node2
Address: 198.18.0.2:8300
Version: 1.9.0
Status: voter
Node Type: voter
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 41
Meta
"bar": "baz"

View File

@ -0,0 +1,64 @@
{
"Healthy": true,
"FailureTolerance": 1,
"OptimisitcFailureTolerance": 0,
"Servers": {
"79324811-9588-4311-b208-f272e38aaabf": {
"ID": "79324811-9588-4311-b208-f272e38aaabf",
"Name": "node1",
"Address": "198.18.0.1:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "0s",
"LastTerm": 3,
"LastIndex": 42,
"Healthy": true,
"StableSince": "2020-11-06T14:51:00Z",
"Status": "leader",
"Meta": {
"foo": "bar"
},
"NodeType": "voter"
},
"ae84aefb-a303-4734-8739-5c102d4ee2d9": {
"ID": "ae84aefb-a303-4734-8739-5c102d4ee2d9",
"Name": "node3",
"Address": "198.18.0.3:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "2ms",
"LastTerm": 3,
"LastIndex": 39,
"Healthy": true,
"StableSince": "2020-11-06T14:53:00Z",
"Status": "voter",
"Meta": {
"baz": "foo"
},
"NodeType": "voter"
},
"ef8aee9a-f9d6-4ec4-b383-aac956bdb80f": {
"ID": "ef8aee9a-f9d6-4ec4-b383-aac956bdb80f",
"Name": "node2",
"Address": "198.18.0.2:8300",
"NodeStatus": "alive",
"Version": "1.9.0",
"LastContact": "1ms",
"LastTerm": 3,
"LastIndex": 41,
"Healthy": true,
"StableSince": "2020-11-06T14:52:00Z",
"Status": "voter",
"Meta": {
"bar": "baz"
},
"NodeType": "voter"
}
},
"Leader": "79324811-9588-4311-b208-f272e38aaabf",
"Voters": [
"79324811-9588-4311-b208-f272e38aaabf",
"ef8aee9a-f9d6-4ec4-b383-aac956bdb80f",
"ae84aefb-a303-4734-8739-5c102d4ee2d9"
]
}

View File

@ -29,7 +29,7 @@ Subcommands:
## get-config
This command displays the current Raft peer configuration.
This command displays the current autopilot configuration.
Usage: `consul operator autopilot get-config [options]`
@ -39,9 +39,10 @@ Usage: `consul operator autopilot get-config [options]`
@include 'http_api_options_server.mdx'
The output looks like this:
### Command Output
```
```sh
$ consul operator autopilot get-config
CleanupDeadServers = true
LastContactThreshold = 200ms
MaxTrailingLogs = 250
@ -90,10 +91,81 @@ Usage: `consul operator autopilot set-config [options]`
- `-upgrade-version-tag` <EnterpriseAlert inline /> - Controls the [`-node-meta`](/docs/agent/options#_node_meta)
tag to use for version info when performing upgrade migrations. If left blank, the Consul version will be used.
The output looks like this:
### Command Output
```
```sh
$ consul operator autopilot set-config -min-quorum=3
Configuration updated!
```
The return code will indicate success or failure.
## state
This command displays the current autopilot state.
Usage: `consul operator autopilot state [options]`
#### API Options
@include 'http_api_options_client.mdx'
@include 'http_api_options_server.mdx'
#### Command Options
- `-format` - Specifies the output format. Must be one of `[pretty|json]` and it defaults to `pretty`.
#### Command Output
```sh
$ consul operator autopilot state
Healthy: true
Failure Tolerance: 1
Optimistic Failure Tolerance: 0
Leader: 79324811-9588-4311-b208-f272e38aaabf
Voters:
79324811-9588-4311-b208-f272e38aaabf
ef8aee9a-f9d6-4ec4-b383-aac956bdb80f
ae84aefb-a303-4734-8739-5c102d4ee2d9
Servers:
79324811-9588-4311-b208-f272e38aaabf
Name: node1
Address: 198.18.0.1:8300
Version: 1.9.0
Status: leader
Node Type: voter
Node Status: alive
Healthy: true
Last Contact: 0s
Last Term: 3
Last Index: 42
Meta
"foo": "bar"
ae84aefb-a303-4734-8739-5c102d4ee2d9
Name: node3
Address: 198.18.0.3:8300
Version: 1.9.0
Status: voter
Node Type: voter
Node Status: alive
Healthy: true
Last Contact: 2ms
Last Term: 3
Last Index: 39
Meta
"baz": "foo"
ef8aee9a-f9d6-4ec4-b383-aac956bdb80f
Name: node2
Address: 198.18.0.2:8300
Version: 1.9.0
Status: voter
Node Type: voter
Node Status: alive
Healthy: true
Last Contact: 1ms
Last Term: 3
Last Index: 41
Meta
"bar": "baz"
```