agent: First pass supporting DNS TTLs

This commit is contained in:
Armon Dadgar 2014-06-08 16:01:06 -07:00
parent 3b3d235880
commit 66a5387742

View File

@ -334,14 +334,15 @@ RPC:
} }
// Add the node record // Add the node record
records := d.formatNodeRecord(&out.NodeServices.Node, req.Question[0].Name, qType) records := d.formatNodeRecord(&out.NodeServices.Node, req.Question[0].Name,
qType, d.config.NodeTTL)
if records != nil { if records != nil {
resp.Answer = append(resp.Answer, records...) resp.Answer = append(resp.Answer, records...)
} }
} }
// formatNodeRecord takes a Node and returns an A, AAAA, or CNAME record // formatNodeRecord takes a Node and returns an A, AAAA, or CNAME record
func (d *DNSServer) formatNodeRecord(node *structs.Node, qName string, qType uint16) (records []dns.RR) { func (d *DNSServer) formatNodeRecord(node *structs.Node, qName string, qType uint16, ttl time.Duration) (records []dns.RR) {
// Parse the IP // Parse the IP
ip := net.ParseIP(node.Address) ip := net.ParseIP(node.Address)
var ipv4 net.IP var ipv4 net.IP
@ -355,7 +356,7 @@ func (d *DNSServer) formatNodeRecord(node *structs.Node, qName string, qType uin
Name: qName, Name: qName,
Rrtype: dns.TypeA, Rrtype: dns.TypeA,
Class: dns.ClassINET, Class: dns.ClassINET,
Ttl: 0, Ttl: uint32(ttl / time.Second),
}, },
A: ip, A: ip,
}} }}
@ -366,7 +367,7 @@ func (d *DNSServer) formatNodeRecord(node *structs.Node, qName string, qType uin
Name: qName, Name: qName,
Rrtype: dns.TypeAAAA, Rrtype: dns.TypeAAAA,
Class: dns.ClassINET, Class: dns.ClassINET,
Ttl: 0, Ttl: uint32(ttl / time.Second),
}, },
AAAA: ip, AAAA: ip,
}} }}
@ -379,7 +380,7 @@ func (d *DNSServer) formatNodeRecord(node *structs.Node, qName string, qType uin
Name: qName, Name: qName,
Rrtype: dns.TypeCNAME, Rrtype: dns.TypeCNAME,
Class: dns.ClassINET, Class: dns.ClassINET,
Ttl: 0, Ttl: uint32(ttl / time.Second),
}, },
Target: dns.Fqdn(node.Address), Target: dns.Fqdn(node.Address),
} }
@ -436,6 +437,16 @@ RPC:
return return
} }
// Determine the TTL
var ttl time.Duration
if d.config.ServiceTTL != nil {
var ok bool
ttl, ok = d.config.ServiceTTL[service]
if !ok {
ttl = d.config.ServiceTTL["*"]
}
}
// Filter out any service nodes due to health checks // Filter out any service nodes due to health checks
out.Nodes = d.filterServiceNodes(out.Nodes) out.Nodes = d.filterServiceNodes(out.Nodes)
@ -449,10 +460,10 @@ RPC:
// Add various responses depending on the request // Add various responses depending on the request
qType := req.Question[0].Qtype qType := req.Question[0].Qtype
d.serviceNodeRecords(out.Nodes, req, resp) d.serviceNodeRecords(out.Nodes, req, resp, ttl)
if qType == dns.TypeSRV { if qType == dns.TypeSRV {
d.serviceSRVRecords(datacenter, out.Nodes, req, resp) d.serviceSRVRecords(datacenter, out.Nodes, req, resp, ttl)
} }
} }
@ -484,7 +495,7 @@ func shuffleServiceNodes(nodes structs.CheckServiceNodes) {
} }
// serviceNodeRecords is used to add the node records for a service lookup // serviceNodeRecords is used to add the node records for a service lookup
func (d *DNSServer) serviceNodeRecords(nodes structs.CheckServiceNodes, req, resp *dns.Msg) { func (d *DNSServer) serviceNodeRecords(nodes structs.CheckServiceNodes, req, resp *dns.Msg, ttl time.Duration) {
qName := req.Question[0].Name qName := req.Question[0].Name
qType := req.Question[0].Qtype qType := req.Question[0].Qtype
handled := make(map[string]struct{}) handled := make(map[string]struct{})
@ -498,7 +509,7 @@ func (d *DNSServer) serviceNodeRecords(nodes structs.CheckServiceNodes, req, res
handled[addr] = struct{}{} handled[addr] = struct{}{}
// Add the node record // Add the node record
records := d.formatNodeRecord(&node.Node, qName, qType) records := d.formatNodeRecord(&node.Node, qName, qType, ttl)
if records != nil { if records != nil {
resp.Answer = append(resp.Answer, records...) resp.Answer = append(resp.Answer, records...)
} }
@ -506,7 +517,7 @@ func (d *DNSServer) serviceNodeRecords(nodes structs.CheckServiceNodes, req, res
} }
// serviceARecords is used to add the SRV records for a service lookup // serviceARecords is used to add the SRV records for a service lookup
func (d *DNSServer) serviceSRVRecords(dc string, nodes structs.CheckServiceNodes, req, resp *dns.Msg) { func (d *DNSServer) serviceSRVRecords(dc string, nodes structs.CheckServiceNodes, req, resp *dns.Msg, ttl time.Duration) {
handled := make(map[string]struct{}) handled := make(map[string]struct{})
for _, node := range nodes { for _, node := range nodes {
// Avoid duplicate entries, possible if a node has // Avoid duplicate entries, possible if a node has
@ -523,7 +534,7 @@ func (d *DNSServer) serviceSRVRecords(dc string, nodes structs.CheckServiceNodes
Name: req.Question[0].Name, Name: req.Question[0].Name,
Rrtype: dns.TypeSRV, Rrtype: dns.TypeSRV,
Class: dns.ClassINET, Class: dns.ClassINET,
Ttl: 0, Ttl: uint32(ttl / time.Second),
}, },
Priority: 1, Priority: 1,
Weight: 1, Weight: 1,
@ -533,7 +544,7 @@ func (d *DNSServer) serviceSRVRecords(dc string, nodes structs.CheckServiceNodes
resp.Answer = append(resp.Answer, srvRec) resp.Answer = append(resp.Answer, srvRec)
// Add the extra record // Add the extra record
records := d.formatNodeRecord(&node.Node, srvRec.Target, dns.TypeANY) records := d.formatNodeRecord(&node.Node, srvRec.Target, dns.TypeANY, ttl)
if records != nil { if records != nil {
resp.Extra = append(resp.Extra, records...) resp.Extra = append(resp.Extra, records...)
} }