agent: Support stale queries with retries
This commit is contained in:
parent
cb9540ea04
commit
dea2eba631
|
@ -227,8 +227,8 @@ func (c *Command) setupAgent(config *Config, logOutput io.Writer, logWriter *log
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := NewDNSServer(agent, logOutput, config.Domain,
|
server, err := NewDNSServer(agent, &config.DNSConfig, logOutput,
|
||||||
dnsAddr.String(), config.DNSRecursor)
|
config.Domain, dnsAddr.String(), config.DNSRecursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
agent.Shutdown()
|
agent.Shutdown()
|
||||||
c.Ui.Error(fmt.Sprintf("Error starting dns server: %s", err))
|
c.Ui.Error(fmt.Sprintf("Error starting dns server: %s", err))
|
||||||
|
|
|
@ -23,6 +23,7 @@ const (
|
||||||
// service discovery endpoints using a DNS interface.
|
// service discovery endpoints using a DNS interface.
|
||||||
type DNSServer struct {
|
type DNSServer struct {
|
||||||
agent *Agent
|
agent *Agent
|
||||||
|
config *DNSConfig
|
||||||
dnsHandler *dns.ServeMux
|
dnsHandler *dns.ServeMux
|
||||||
dnsServer *dns.Server
|
dnsServer *dns.Server
|
||||||
dnsServerTCP *dns.Server
|
dnsServerTCP *dns.Server
|
||||||
|
@ -32,7 +33,7 @@ type DNSServer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSServer starts a new DNS server to provide an agent interface
|
// NewDNSServer starts a new DNS server to provide an agent interface
|
||||||
func NewDNSServer(agent *Agent, logOutput io.Writer, domain, bind, recursor string) (*DNSServer, error) {
|
func NewDNSServer(agent *Agent, config *DNSConfig, logOutput io.Writer, domain, bind, recursor string) (*DNSServer, error) {
|
||||||
// Make sure domain is FQDN
|
// Make sure domain is FQDN
|
||||||
domain = dns.Fqdn(domain)
|
domain = dns.Fqdn(domain)
|
||||||
|
|
||||||
|
@ -55,6 +56,7 @@ func NewDNSServer(agent *Agent, logOutput io.Writer, domain, bind, recursor stri
|
||||||
// Create the server
|
// Create the server
|
||||||
srv := &DNSServer{
|
srv := &DNSServer{
|
||||||
agent: agent,
|
agent: agent,
|
||||||
|
config: config,
|
||||||
dnsHandler: mux,
|
dnsHandler: mux,
|
||||||
dnsServer: server,
|
dnsServer: server,
|
||||||
dnsServerTCP: serverTCP,
|
dnsServerTCP: serverTCP,
|
||||||
|
@ -308,14 +310,23 @@ func (d *DNSServer) nodeLookup(network, datacenter, node string, req, resp *dns.
|
||||||
args := structs.NodeSpecificRequest{
|
args := structs.NodeSpecificRequest{
|
||||||
Datacenter: datacenter,
|
Datacenter: datacenter,
|
||||||
Node: node,
|
Node: node,
|
||||||
|
QueryOptions: structs.QueryOptions{AllowStale: d.config.AllowStale},
|
||||||
}
|
}
|
||||||
var out structs.IndexedNodeServices
|
var out structs.IndexedNodeServices
|
||||||
|
RPC:
|
||||||
if err := d.agent.RPC("Catalog.NodeServices", &args, &out); err != nil {
|
if err := d.agent.RPC("Catalog.NodeServices", &args, &out); 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)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that request is not too stale, redo the request
|
||||||
|
if args.AllowStale && out.LastContact > d.config.MaxStale {
|
||||||
|
args.AllowStale = false
|
||||||
|
d.logger.Printf("[WARN] dns: Query results too stale, re-requesting")
|
||||||
|
goto RPC
|
||||||
|
}
|
||||||
|
|
||||||
// If we have no address, return not found!
|
// If we have no address, return not found!
|
||||||
if out.NodeServices == nil {
|
if out.NodeServices == nil {
|
||||||
resp.SetRcode(req, dns.RcodeNameError)
|
resp.SetRcode(req, dns.RcodeNameError)
|
||||||
|
@ -402,14 +413,23 @@ func (d *DNSServer) serviceLookup(network, datacenter, service, tag string, req,
|
||||||
ServiceName: service,
|
ServiceName: service,
|
||||||
ServiceTag: tag,
|
ServiceTag: tag,
|
||||||
TagFilter: tag != "",
|
TagFilter: tag != "",
|
||||||
|
QueryOptions: structs.QueryOptions{AllowStale: d.config.AllowStale},
|
||||||
}
|
}
|
||||||
var out structs.IndexedCheckServiceNodes
|
var out structs.IndexedCheckServiceNodes
|
||||||
|
RPC:
|
||||||
if err := d.agent.RPC("Health.ServiceNodes", &args, &out); err != nil {
|
if err := d.agent.RPC("Health.ServiceNodes", &args, &out); 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)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that request is not too stale, redo the request
|
||||||
|
if args.AllowStale && out.LastContact > d.config.MaxStale {
|
||||||
|
args.AllowStale = false
|
||||||
|
d.logger.Printf("[WARN] dns: Query results too stale, re-requesting")
|
||||||
|
goto RPC
|
||||||
|
}
|
||||||
|
|
||||||
// If we have no nodes, return not found!
|
// If we have no nodes, return not found!
|
||||||
if len(out.Nodes) == 0 {
|
if len(out.Nodes) == 0 {
|
||||||
resp.SetRcode(req, dns.RcodeNameError)
|
resp.SetRcode(req, dns.RcodeNameError)
|
||||||
|
|
|
@ -14,8 +14,9 @@ func makeDNSServer(t *testing.T) (string, *DNSServer) {
|
||||||
conf := nextConfig()
|
conf := nextConfig()
|
||||||
addr, _ := conf.ClientListener(conf.Ports.DNS)
|
addr, _ := conf.ClientListener(conf.Ports.DNS)
|
||||||
dir, agent := makeAgent(t, conf)
|
dir, agent := makeAgent(t, conf)
|
||||||
server, err := NewDNSServer(agent, agent.logOutput, conf.Domain,
|
config := &DNSConfig{}
|
||||||
addr.String(), "8.8.8.8:53")
|
server, err := NewDNSServer(agent, config, agent.logOutput,
|
||||||
|
conf.Domain, addr.String(), "8.8.8.8:53")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %v", err)
|
t.Fatalf("err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue