Skip to content

Commit

Permalink
Bachport patch for hashicorpGH-1954
Browse files Browse the repository at this point in the history
Prevent blank CA config from being committed to the snapshot.

hashicorp#4954
  • Loading branch information
Andrew Glen-Young committed Dec 10, 2018
1 parent f2b13f3 commit b834b2d
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 3 deletions.
11 changes: 8 additions & 3 deletions agent/consul/fsm/snapshot_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,18 +258,19 @@ func (s *snapshot) persistPreparedQueries(sink raft.SnapshotSink,

func (s *snapshot) persistAutopilot(sink raft.SnapshotSink,
encoder *codec.Encoder) error {
autopilot, err := s.state.Autopilot()
config, err := s.state.Autopilot()
if err != nil {
return err
}
if autopilot == nil {
// Make sure we don't write a nil config out to a snapshot.
if config == nil {
return nil
}

if _, err := sink.Write([]byte{byte(structs.AutopilotRequestType)}); err != nil {
return err
}
if err := encoder.Encode(autopilot); err != nil {
if err := encoder.Encode(config); err != nil {
return err
}
return nil
Expand Down Expand Up @@ -300,6 +301,10 @@ func (s *snapshot) persistConnectCAConfig(sink raft.SnapshotSink,
if err != nil {
return err
}
// Make sure we don't write a nil config out to a snapshot.
if config == nil {
return nil
}

if _, err := sink.Write([]byte{byte(structs.ConnectCAConfigType)}); err != nil {
return err
Expand Down
42 changes: 42 additions & 0 deletions agent/consul/fsm/snapshot_oss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,3 +418,45 @@ func TestFSM_BadRestore_OSS(t *testing.T) {
default:
}
}

func TestFSM_BadSnapshot_NilCAConfig(t *testing.T) {
t.Parallel()
// Create an FSM with no config entry.
fsm, err := New(nil, os.Stderr)
if err != nil {
t.Fatalf("err: %v", err)
}
// Snapshot
snap, err := fsm.Snapshot()
if err != nil {
t.Fatalf("err: %v", err)
}
defer snap.Release()
// Persist
buf := bytes.NewBuffer(nil)
sink := &MockSink{buf, false}
if err := snap.Persist(sink); err != nil {
t.Fatalf("err: %v", err)
}
// Try to restore on a new FSM
fsm2, err := New(nil, os.Stderr)
if err != nil {
t.Fatalf("err: %v", err)
}
// Do a restore
if err := fsm2.Restore(sink); err != nil {
t.Fatalf("err: %v", err)
}
// Make sure there's no entry in the CA config table.
state := fsm2.State()
idx, config, err := state.CAConfig()
if err != nil {
t.Fatalf("err: %v", err)
}
if idx != uint64(0) {
t.Fatalf("index should be zero: %v", idx)
}
if config != nil {
t.Fatalf("config should be nil")
}
}
6 changes: 6 additions & 0 deletions agent/consul/state/connect_ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ func (s *Snapshot) CAConfig() (*structs.CAConfiguration, error) {

// CAConfig is used when restoring from a snapshot.
func (s *Restore) CAConfig(config *structs.CAConfiguration) error {
// Don't restore a blank CA config
// https://github.com/hashicorp/consul/issues/4954
if config.Provider == "" {
return nil
}

if err := s.tx.Insert(caConfigTableName, config); err != nil {
return fmt.Errorf("failed restoring CA config: %s", err)
}
Expand Down
33 changes: 33 additions & 0 deletions agent/consul/state/connect_ca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,39 @@ func TestStore_CAConfig_Snapshot_Restore(t *testing.T) {
verify.Values(t, "", before, res)
}

// Make sure we handle the case of a leftover blank CA config that
// got stuck in a snapshot, as in https://github.com/hashicorp/consul/issues/4954
func TestStore_CAConfig_Snapshot_Restore_BlankConfig(t *testing.T) {
s := testStateStore(t)
before := &structs.CAConfiguration{}
if err := s.CASetConfig(99, before); err != nil {
t.Fatal(err)
}
snap := s.Snapshot()
defer snap.Close()
snapped, err := snap.CAConfig()
if err != nil {
t.Fatalf("err: %s", err)
}
verify.Values(t, "", before, snapped)
s2 := testStateStore(t)
restore := s2.Restore()
if err := restore.CAConfig(snapped); err != nil {
t.Fatalf("err: %s", err)
}
restore.Commit()
idx, result, err := s2.CAConfig()
if err != nil {
t.Fatalf("err: %s", err)
}
if idx != 0 {
t.Fatalf("bad index: %d", idx)
}
if result != nil {
t.Fatalf("should be nil: %v", result)
}
}

func TestStore_CARootSetList(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
Expand Down

0 comments on commit b834b2d

Please sign in to comment.