diff --git a/agent/dns_ce_test.go b/agent/dns_ce_test.go index c01f62d938..180a48fe91 100644 --- a/agent/dns_ce_test.go +++ b/agent/dns_ce_test.go @@ -17,117 +17,122 @@ import ( "github.com/hashicorp/consul/testrpc" ) +// TODO(v2-dns): NET-7910 - Fix ENT and CE variants of DNS v1 compatibility tests func TestDNS_CE_PeeredServices(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") } - a := StartTestAgent(t, TestAgent{HCL: ``, Overrides: `peering = { test_allow_peer_registrations = true }`}) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") + for name, experimentsHCL := range getVersionHCL(false) { + t.Run(name, func(t *testing.T) { + a := StartTestAgent(t, TestAgent{HCL: ``, Overrides: `peering = { test_allow_peer_registrations = true } ` + experimentsHCL}) + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") - makeReq := func() *structs.RegisterRequest { - return &structs.RegisterRequest{ - PeerName: "peer1", - Datacenter: "dc1", - Node: "peernode1", - Address: "198.18.1.1", - Service: &structs.NodeService{ - PeerName: "peer1", - Kind: structs.ServiceKindConnectProxy, - Service: "web-proxy", - Address: "199.0.0.1", - Port: 12345, - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "peer-web", - }, - EnterpriseMeta: *acl.DefaultEnterpriseMeta(), - }, - EnterpriseMeta: *acl.DefaultEnterpriseMeta(), - } + makeReq := func() *structs.RegisterRequest { + return &structs.RegisterRequest{ + PeerName: "peer1", + Datacenter: "dc1", + Node: "peernode1", + Address: "198.18.1.1", + Service: &structs.NodeService{ + PeerName: "peer1", + Kind: structs.ServiceKindConnectProxy, + Service: "web-proxy", + Address: "199.0.0.1", + Port: 12345, + Proxy: structs.ConnectProxyConfig{ + DestinationServiceName: "peer-web", + }, + EnterpriseMeta: *acl.DefaultEnterpriseMeta(), + }, + EnterpriseMeta: *acl.DefaultEnterpriseMeta(), + } + } + + dnsQuery := func(t *testing.T, question string, typ uint16) *dns.Msg { + m := new(dns.Msg) + m.SetQuestion(question, typ) + + c := new(dns.Client) + reply, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, reply.Answer, 1, "zero valid records found for %q", question) + return reply + } + + assertARec := func(t *testing.T, rec dns.RR, expectName, expectIP string) { + aRec, ok := rec.(*dns.A) + require.True(t, ok, "Extra is not an A record: %T", rec) + require.Equal(t, expectName, aRec.Hdr.Name) + require.Equal(t, expectIP, aRec.A.String()) + } + + assertSRVRec := func(t *testing.T, rec dns.RR, expectName string, expectPort uint16) { + srvRec, ok := rec.(*dns.SRV) + require.True(t, ok, "Answer is not a SRV record: %T", rec) + require.Equal(t, expectName, srvRec.Target) + require.Equal(t, expectPort, srvRec.Port) + } + + t.Run("srv-with-addr-reply", func(t *testing.T) { + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", makeReq(), &struct{}{})) + q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 1) + + addr := "c7000001.addr.consul." + assertSRVRec(t, q.Answer[0], addr, 12345) + assertARec(t, q.Extra[0], addr, "199.0.0.1") + + // Query the addr to make sure it's also valid. + q = dnsQuery(t, addr, dns.TypeA) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 0) + assertARec(t, q.Answer[0], addr, "199.0.0.1") + }) + + t.Run("srv-with-node-reply", func(t *testing.T) { + req := makeReq() + // Clear service address to trigger node response + req.Service.Address = "" + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", req, &struct{}{})) + q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 1) + + nodeName := "peernode1.node.peer1.peer.consul." + assertSRVRec(t, q.Answer[0], nodeName, 12345) + assertARec(t, q.Extra[0], nodeName, "198.18.1.1") + + // Query the node to make sure it's also valid. + q = dnsQuery(t, nodeName, dns.TypeA) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 0) + assertARec(t, q.Answer[0], nodeName, "198.18.1.1") + }) + + t.Run("srv-with-fqdn-reply", func(t *testing.T) { + req := makeReq() + // Set non-ip address to trigger external response + req.Address = "localhost" + req.Service.Address = "" + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", req, &struct{}{})) + q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 0) + assertSRVRec(t, q.Answer[0], "localhost.", 12345) + }) + + t.Run("a-reply", func(t *testing.T) { + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", makeReq(), &struct{}{})) + q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeA) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 0) + assertARec(t, q.Answer[0], "web-proxy.service.peer1.peer.consul.", "199.0.0.1") + }) + }) } - - dnsQuery := func(t *testing.T, question string, typ uint16) *dns.Msg { - m := new(dns.Msg) - m.SetQuestion(question, typ) - - c := new(dns.Client) - reply, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, reply.Answer, 1, "zero valid records found for %q", question) - return reply - } - - assertARec := func(t *testing.T, rec dns.RR, expectName, expectIP string) { - aRec, ok := rec.(*dns.A) - require.True(t, ok, "Extra is not an A record: %T", rec) - require.Equal(t, expectName, aRec.Hdr.Name) - require.Equal(t, expectIP, aRec.A.String()) - } - - assertSRVRec := func(t *testing.T, rec dns.RR, expectName string, expectPort uint16) { - srvRec, ok := rec.(*dns.SRV) - require.True(t, ok, "Answer is not a SRV record: %T", rec) - require.Equal(t, expectName, srvRec.Target) - require.Equal(t, expectPort, srvRec.Port) - } - - t.Run("srv-with-addr-reply", func(t *testing.T) { - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", makeReq(), &struct{}{})) - q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 1) - - addr := "c7000001.addr.consul." - assertSRVRec(t, q.Answer[0], addr, 12345) - assertARec(t, q.Extra[0], addr, "199.0.0.1") - - // Query the addr to make sure it's also valid. - q = dnsQuery(t, addr, dns.TypeA) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 0) - assertARec(t, q.Answer[0], addr, "199.0.0.1") - }) - - t.Run("srv-with-node-reply", func(t *testing.T) { - req := makeReq() - // Clear service address to trigger node response - req.Service.Address = "" - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", req, &struct{}{})) - q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 1) - - nodeName := "peernode1.node.peer1.peer.consul." - assertSRVRec(t, q.Answer[0], nodeName, 12345) - assertARec(t, q.Extra[0], nodeName, "198.18.1.1") - - // Query the node to make sure it's also valid. - q = dnsQuery(t, nodeName, dns.TypeA) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 0) - assertARec(t, q.Answer[0], nodeName, "198.18.1.1") - }) - - t.Run("srv-with-fqdn-reply", func(t *testing.T) { - req := makeReq() - // Set non-ip address to trigger external response - req.Address = "localhost" - req.Service.Address = "" - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", req, &struct{}{})) - q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 0) - assertSRVRec(t, q.Answer[0], "localhost.", 12345) - }) - - t.Run("a-reply", func(t *testing.T) { - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", makeReq(), &struct{}{})) - q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeA) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 0) - assertARec(t, q.Answer[0], "web-proxy.service.peer1.peer.consul.", "199.0.0.1") - }) } func getTestCasesParseLocality() []testCaseParseLocality {