From 0d9ea8a4b7b0e51917a4041788ca82e023cb4f7f Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Fri, 11 Jun 2021 10:25:02 -0700 Subject: [PATCH] physical/raft: Add a function that gets the offline, stale configuration (#11821) * Add a function that gets the offline, stale configuration * Fix comment --- physical/raft/raft.go | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/physical/raft/raft.go b/physical/raft/raft.go index bf05c3b6a..f7065ef78 100644 --- a/physical/raft/raft.go +++ b/physical/raft/raft.go @@ -21,7 +21,7 @@ import ( "github.com/hashicorp/go-uuid" "github.com/hashicorp/raft" autopilot "github.com/hashicorp/raft-autopilot" - "github.com/hashicorp/raft-boltdb/v2" + raftboltdb "github.com/hashicorp/raft-boltdb/v2" snapshot "github.com/hashicorp/raft-snapshot" "github.com/hashicorp/vault/helper/metricsutil" "github.com/hashicorp/vault/sdk/helper/consts" @@ -982,6 +982,39 @@ func (b *RaftBackend) RemovePeer(ctx context.Context, peerID string) error { return b.autopilot.RemoveServer(raft.ServerID(peerID)) } +// GetConfigurationOffline is used to read the stale, last known raft +// configuration to this node. It accesses the last state written into the +// FSM. When a server is online use GetConfiguration instead. +func (b *RaftBackend) GetConfigurationOffline() (*RaftConfigurationResponse, error) { + b.l.RLock() + defer b.l.RUnlock() + + if b.raft != nil { + return nil, errors.New("raft storage is initialized, used GetConfiguration instead") + } + + if b.fsm == nil { + return nil, nil + } + + state, configuration := b.fsm.LatestState() + config := &RaftConfigurationResponse{ + Index: state.Index, + } + for _, server := range configuration.Servers { + entry := &RaftServer{ + NodeID: server.Id, + Address: server.Address, + // Since we are offline no node is the leader. + Leader: false, + Voter: raft.ServerSuffrage(server.Suffrage) == raft.Voter, + } + config.Servers = append(config.Servers, entry) + } + + return config, nil +} + func (b *RaftBackend) GetConfiguration(ctx context.Context) (*RaftConfigurationResponse, error) { b.l.RLock() defer b.l.RUnlock()