From b51d76f46922bc234419b51af5706971fb8beea6 Mon Sep 17 00:00:00 2001 From: Kyle Havlovitz Date: Thu, 16 Aug 2018 11:58:50 -0700 Subject: [PATCH 1/2] fsm: add missing CA config to snapshot/restore logic --- agent/consul/fsm/fsm.go | 4 +++- agent/consul/fsm/snapshot_oss.go | 32 +++++++++++++++++++++++++++ agent/consul/fsm/snapshot_oss_test.go | 17 ++++++++++++++ agent/structs/structs.go | 1 + 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/agent/consul/fsm/fsm.go b/agent/consul/fsm/fsm.go index 87824b872360..58c126b22f2d 100644 --- a/agent/consul/fsm/fsm.go +++ b/agent/consul/fsm/fsm.go @@ -14,7 +14,9 @@ import ( ) // msgpackHandle is a shared handle for encoding/decoding msgpack payloads -var msgpackHandle = &codec.MsgpackHandle{} +var msgpackHandle = &codec.MsgpackHandle{ + RawToString: true, +} // command is a command method on the FSM. type command func(buf []byte, index uint64) interface{} diff --git a/agent/consul/fsm/snapshot_oss.go b/agent/consul/fsm/snapshot_oss.go index f9eb18cc89e5..ce9b4c9af802 100644 --- a/agent/consul/fsm/snapshot_oss.go +++ b/agent/consul/fsm/snapshot_oss.go @@ -23,6 +23,7 @@ func init() { registerRestorer(structs.IntentionRequestType, restoreIntention) registerRestorer(structs.ConnectCARequestType, restoreConnectCA) registerRestorer(structs.ConnectCAProviderStateType, restoreConnectCAProviderState) + registerRestorer(structs.ConnectCAConfigType, restoreConnectCAConfig) } func persistOSS(s *snapshot, sink raft.SnapshotSink, encoder *codec.Encoder) error { @@ -56,6 +57,9 @@ func persistOSS(s *snapshot, sink raft.SnapshotSink, encoder *codec.Encoder) err if err := s.persistConnectCAProviderState(sink, encoder); err != nil { return err } + if err := s.persistConnectCAConfig(sink, encoder); err != nil { + return err + } return nil } @@ -285,6 +289,23 @@ func (s *snapshot) persistConnectCA(sink raft.SnapshotSink, return err } } + + return nil +} + +func (s *snapshot) persistConnectCAConfig(sink raft.SnapshotSink, + encoder *codec.Encoder) error { + config, err := s.state.CAConfig() + if err != nil { + return err + } + + if _, err := sink.Write([]byte{byte(structs.ConnectCAConfigType)}); err != nil { + return err + } + if err := encoder.Encode(config); err != nil { + return err + } return nil } @@ -463,3 +484,14 @@ func restoreConnectCAProviderState(header *snapshotHeader, restore *state.Restor } return nil } + +func restoreConnectCAConfig(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error { + var req structs.CAConfiguration + if err := decoder.Decode(&req); err != nil { + return err + } + if err := restore.CAConfig(&req); err != nil { + return err + } + return nil +} diff --git a/agent/consul/fsm/snapshot_oss_test.go b/agent/consul/fsm/snapshot_oss_test.go index 9a6f3a355562..0c8811a07b30 100644 --- a/agent/consul/fsm/snapshot_oss_test.go +++ b/agent/consul/fsm/snapshot_oss_test.go @@ -131,6 +131,18 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) { assert.Nil(err) assert.True(ok) + // CA Config + caConfig := &structs.CAConfiguration{ + ClusterID: "foo", + Provider: "consul", + Config: map[string]interface{}{ + "foo": "asdf", + "bar": 6.5, + }, + } + err = fsm.state.CASetConfig(17, caConfig) + assert.Nil(err) + // Snapshot snap, err := fsm.Snapshot() if err != nil { @@ -310,6 +322,11 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) { assert.Equal("foo", state.PrivateKey) assert.Equal("bar", state.RootCert) + // Verify CA configuration is restored. + _, caConf, err := fsm2.state.CAConfig() + assert.Nil(err) + assert.Equal(caConfig, caConf) + // Snapshot snap, err = fsm2.Snapshot() if err != nil { diff --git a/agent/structs/structs.go b/agent/structs/structs.go index f5308b351e91..e22e06e08506 100644 --- a/agent/structs/structs.go +++ b/agent/structs/structs.go @@ -46,6 +46,7 @@ const ( IntentionRequestType = 12 ConnectCARequestType = 13 ConnectCAProviderStateType = 14 + ConnectCAConfigType = 15 // FSM snapshots only. ) const ( From f186edc42c4e8ab5a86c5906b135d9b7db045a64 Mon Sep 17 00:00:00 2001 From: Kyle Havlovitz Date: Thu, 16 Aug 2018 12:58:54 -0700 Subject: [PATCH 2/2] fsm: add connect service config to snapshot/restore test --- agent/consul/fsm/snapshot_oss_test.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/agent/consul/fsm/snapshot_oss_test.go b/agent/consul/fsm/snapshot_oss_test.go index 0c8811a07b30..abd2fadf4434 100644 --- a/agent/consul/fsm/snapshot_oss_test.go +++ b/agent/consul/fsm/snapshot_oss_test.go @@ -29,7 +29,27 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) { // Add some state fsm.state.EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) fsm.state.EnsureNode(2, &structs.Node{Node: "baz", Address: "127.0.0.2", TaggedAddresses: map[string]string{"hello": "1.2.3.4"}}) - fsm.state.EnsureService(3, "foo", &structs.NodeService{ID: "web", Service: "web", Tags: nil, Address: "127.0.0.1", Port: 80}) + + // Add a service instance with Connect config. + connectConf := structs.ServiceConnect{ + Native: true, + Proxy: &structs.ServiceDefinitionConnectProxy{ + Command: []string{"foo", "bar"}, + ExecMode: "a", + Config: map[string]interface{}{ + "a": "qwer", + "b": 4.3, + }, + }, + } + fsm.state.EnsureService(3, "foo", &structs.NodeService{ + ID: "web", + Service: "web", + Tags: nil, + Address: "127.0.0.1", + Port: 80, + Connect: connectConf, + }) fsm.state.EnsureService(4, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.1", Port: 5000}) fsm.state.EnsureService(5, "baz", &structs.NodeService{ID: "web", Service: "web", Tags: nil, Address: "127.0.0.2", Port: 80}) fsm.state.EnsureService(6, "baz", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"secondary"}, Address: "127.0.0.2", Port: 5000}) @@ -201,6 +221,10 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) { if fooSrv.Services["db"].Port != 5000 { t.Fatalf("Bad: %v", fooSrv) } + connectSrv := fooSrv.Services["web"] + if !reflect.DeepEqual(connectSrv.Connect, connectConf) { + t.Fatalf("got: %v, want: %v", connectSrv.Connect, connectConf) + } _, checks, err := fsm2.state.NodeChecks(nil, "foo") if err != nil {