diff --git a/consul/internal_endpoint_test.go b/consul/internal_endpoint_test.go index e3c33fe925..45b57f21ca 100644 --- a/consul/internal_endpoint_test.go +++ b/consul/internal_endpoint_test.go @@ -1,6 +1,8 @@ package consul import ( + "encoding/base64" + "fmt" "github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/testutil" "os" @@ -150,3 +152,89 @@ func TestInternal_NodeDump(t *testing.T) { t.Fatalf("missing foo or bar") } } + +func TestInternal_KeyringOperation(t *testing.T) { + key1 := "H1dfkSZOVnP/JUnaBfTzXg==" + keyBytes1, err := base64.StdEncoding.DecodeString(key1) + if err != nil { + t.Fatalf("err: %s", err) + } + dir1, s1 := testServerWithConfig(t, func(c *Config) { + c.SerfLANConfig.MemberlistConfig.SecretKey = keyBytes1 + c.SerfWANConfig.MemberlistConfig.SecretKey = keyBytes1 + }) + defer os.RemoveAll(dir1) + defer s1.Shutdown() + client := rpcClient(t, s1) + defer client.Close() + + testutil.WaitForLeader(t, client.Call, "dc1") + + var out structs.KeyringResponses + req := structs.KeyringRequest{ + Operation: structs.KeyringList, + Datacenter: "dc1", + } + if err := client.Call("Internal.KeyringOperation", &req, &out); err != nil { + t.Fatalf("err: %v", err) + } + + // Two responses (local lan/wan pools) from single-node cluster + if len(out.Responses) != 2 { + t.Fatalf("bad: %#v", out) + } + if _, ok := out.Responses[0].Keys[key1]; !ok { + t.Fatalf("bad: %#v", out) + } + wanResp, lanResp := 0, 0 + for _, resp := range out.Responses { + if resp.WAN { + wanResp++ + } else { + lanResp++ + } + } + if lanResp != 1 || wanResp != 1 { + t.Fatalf("should have one lan and one wan response") + } + + // Start a second agent to test cross-dc queries + dir2, s2 := testServerWithConfig(t, func(c *Config) { + c.SerfLANConfig.MemberlistConfig.SecretKey = keyBytes1 + c.SerfWANConfig.MemberlistConfig.SecretKey = keyBytes1 + c.Datacenter = "dc2" + }) + defer os.RemoveAll(dir2) + defer s2.Shutdown() + + // Try to join + addr := fmt.Sprintf("127.0.0.1:%d", + s1.config.SerfWANConfig.MemberlistConfig.BindPort) + if _, err := s2.JoinWAN([]string{addr}); err != nil { + t.Fatalf("err: %v", err) + } + + var out2 structs.KeyringResponses + req2 := structs.KeyringRequest{ + Operation: structs.KeyringList, + } + if err := client.Call("Internal.KeyringOperation", &req2, &out2); err != nil { + t.Fatalf("err: %v", err) + } + + // 3 responses (one from each DC LAN, one from WAN) in two-node cluster + if len(out2.Responses) != 3 { + t.Fatalf("bad: %#v", out) + } + wanResp, lanResp = 0, 0 + for _, resp := range out2.Responses { + if resp.WAN { + wanResp++ + } else { + lanResp++ + } + } + if lanResp != 2 || wanResp != 1 { + t.Fatalf("should have two lan and one wan response") + } +}