agent: working DNS for Connect queries, I think, but have to
implement Health endpoints to be sure
This commit is contained in:
parent
fa4f0d353b
commit
a5fe6204d5
23
agent/dns.go
23
agent/dns.go
|
@ -337,7 +337,7 @@ func (d *DNSServer) addSOA(msg *dns.Msg) {
|
||||||
// nameservers returns the names and ip addresses of up to three random servers
|
// nameservers returns the names and ip addresses of up to three random servers
|
||||||
// in the current cluster which serve as authoritative name servers for zone.
|
// in the current cluster which serve as authoritative name servers for zone.
|
||||||
func (d *DNSServer) nameservers(edns bool) (ns []dns.RR, extra []dns.RR) {
|
func (d *DNSServer) nameservers(edns bool) (ns []dns.RR, extra []dns.RR) {
|
||||||
out, err := d.lookupServiceNodes(d.agent.config.Datacenter, structs.ConsulServiceName, "")
|
out, err := d.lookupServiceNodes(d.agent.config.Datacenter, structs.ConsulServiceName, "", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.logger.Printf("[WARN] dns: Unable to get list of servers: %s", err)
|
d.logger.Printf("[WARN] dns: Unable to get list of servers: %s", err)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -415,7 +415,7 @@ PARSE:
|
||||||
n = n + 1
|
n = n + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
switch labels[n-1] {
|
switch kind := labels[n-1]; kind {
|
||||||
case "service":
|
case "service":
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
goto INVALID
|
goto INVALID
|
||||||
|
@ -433,7 +433,7 @@ PARSE:
|
||||||
}
|
}
|
||||||
|
|
||||||
// _name._tag.service.consul
|
// _name._tag.service.consul
|
||||||
d.serviceLookup(network, datacenter, labels[n-3][1:], tag, req, resp)
|
d.serviceLookup(network, datacenter, labels[n-3][1:], tag, false, req, resp)
|
||||||
|
|
||||||
// Consul 0.3 and prior format for SRV queries
|
// Consul 0.3 and prior format for SRV queries
|
||||||
} else {
|
} else {
|
||||||
|
@ -445,9 +445,17 @@ PARSE:
|
||||||
}
|
}
|
||||||
|
|
||||||
// tag[.tag].name.service.consul
|
// tag[.tag].name.service.consul
|
||||||
d.serviceLookup(network, datacenter, labels[n-2], tag, req, resp)
|
d.serviceLookup(network, datacenter, labels[n-2], tag, false, req, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "connect":
|
||||||
|
if n == 1 {
|
||||||
|
goto INVALID
|
||||||
|
}
|
||||||
|
|
||||||
|
// name.connect.consul
|
||||||
|
d.serviceLookup(network, datacenter, labels[n-2], "", true, req, resp)
|
||||||
|
|
||||||
case "node":
|
case "node":
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
goto INVALID
|
goto INVALID
|
||||||
|
@ -898,8 +906,9 @@ func (d *DNSServer) trimDNSResponse(network string, req, resp *dns.Msg) (trimmed
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookupServiceNodes returns nodes with a given service.
|
// lookupServiceNodes returns nodes with a given service.
|
||||||
func (d *DNSServer) lookupServiceNodes(datacenter, service, tag string) (structs.IndexedCheckServiceNodes, error) {
|
func (d *DNSServer) lookupServiceNodes(datacenter, service, tag string, connect bool) (structs.IndexedCheckServiceNodes, error) {
|
||||||
args := structs.ServiceSpecificRequest{
|
args := structs.ServiceSpecificRequest{
|
||||||
|
Connect: connect,
|
||||||
Datacenter: datacenter,
|
Datacenter: datacenter,
|
||||||
ServiceName: service,
|
ServiceName: service,
|
||||||
ServiceTag: tag,
|
ServiceTag: tag,
|
||||||
|
@ -935,8 +944,8 @@ func (d *DNSServer) lookupServiceNodes(datacenter, service, tag string) (structs
|
||||||
}
|
}
|
||||||
|
|
||||||
// serviceLookup is used to handle a service query
|
// serviceLookup is used to handle a service query
|
||||||
func (d *DNSServer) serviceLookup(network, datacenter, service, tag string, req, resp *dns.Msg) {
|
func (d *DNSServer) serviceLookup(network, datacenter, service, tag string, connect bool, req, resp *dns.Msg) {
|
||||||
out, err := d.lookupServiceNodes(datacenter, service, tag)
|
out, err := d.lookupServiceNodes(datacenter, service, tag, connect)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.logger.Printf("[ERR] dns: rpc error: %v", err)
|
d.logger.Printf("[ERR] dns: rpc error: %v", err)
|
||||||
resp.SetRcode(req, dns.RcodeServerFailure)
|
resp.SetRcode(req, dns.RcodeServerFailure)
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/hashicorp/serf/coordinate"
|
"github.com/hashicorp/serf/coordinate"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/pascaldekloe/goe/verify"
|
"github.com/pascaldekloe/goe/verify"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1041,6 +1042,48 @@ func TestDNS_ServiceLookupWithInternalServiceAddress(t *testing.T) {
|
||||||
verify.Values(t, "extra", in.Extra, wantExtra)
|
verify.Values(t, "extra", in.Extra, wantExtra)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDNS_ConnectServiceLookup(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert := assert.New(t)
|
||||||
|
a := NewTestAgent(t.Name(), "")
|
||||||
|
defer a.Shutdown()
|
||||||
|
|
||||||
|
// Register a node with an external service.
|
||||||
|
{
|
||||||
|
args := structs.TestRegisterRequestProxy(t)
|
||||||
|
args.Service.ProxyDestination = "db"
|
||||||
|
args.Service.Port = 12345
|
||||||
|
var out struct{}
|
||||||
|
assert.Nil(a.RPC("Catalog.Register", args, &out))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up the service
|
||||||
|
questions := []string{
|
||||||
|
"db.connect.consul.",
|
||||||
|
}
|
||||||
|
for _, question := range questions {
|
||||||
|
m := new(dns.Msg)
|
||||||
|
m.SetQuestion(question, dns.TypeSRV)
|
||||||
|
|
||||||
|
c := new(dns.Client)
|
||||||
|
in, _, err := c.Exchange(m, a.DNSAddr())
|
||||||
|
assert.Nil(err)
|
||||||
|
assert.Len(in.Answer, 1)
|
||||||
|
|
||||||
|
srvRec, ok := in.Answer[0].(*dns.SRV)
|
||||||
|
assert.True(ok)
|
||||||
|
assert.Equal(12345, srvRec.Port)
|
||||||
|
assert.Equal("foo.node.dc1.consul.", srvRec.Target)
|
||||||
|
assert.Equal(0, srvRec.Hdr.Ttl)
|
||||||
|
|
||||||
|
cnameRec, ok := in.Extra[0].(*dns.CNAME)
|
||||||
|
assert.True(ok)
|
||||||
|
assert.Equal("foo.node.dc1.consul.", cnameRec.Hdr.Name)
|
||||||
|
assert.Equal(0, srvRec.Hdr.Ttl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDNS_ExternalServiceLookup(t *testing.T) {
|
func TestDNS_ExternalServiceLookup(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
a := NewTestAgent(t.Name(), "")
|
a := NewTestAgent(t.Name(), "")
|
||||||
|
|
Loading…
Reference in New Issue