Support RFC 2782 for prepared query DNS lookups (#14465)
Format: _<query id or name>._tcp.query[.<datacenter>].<domain>
This commit is contained in:
parent
fb46ae870c
commit
b97acfb107
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
dns: support RFC 2782 SRV lookups for prepared queries using format `_<query id or name>._tcp.query[.<datacenter>].<domain>`.
|
||||
```
|
22
agent/dns.go
22
agent/dns.go
|
@ -908,10 +908,11 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi
|
|||
return d.nodeLookup(cfg, lookup, req, resp)
|
||||
|
||||
case "query":
|
||||
n := len(queryParts)
|
||||
datacenter := d.agent.config.Datacenter
|
||||
|
||||
// ensure we have a query name
|
||||
if len(queryParts) < 1 {
|
||||
if n < 1 {
|
||||
return invalid()
|
||||
}
|
||||
|
||||
|
@ -919,8 +920,23 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi
|
|||
return invalid()
|
||||
}
|
||||
|
||||
// Allow a "." in the query name, just join all the parts.
|
||||
query := strings.Join(queryParts, ".")
|
||||
query := ""
|
||||
|
||||
// If the first and last DNS query parts begin with _, this is an RFC 2782 style SRV lookup.
|
||||
// This allows for prepared query names to include "." (for backwards compatibility).
|
||||
// Otherwise, this is a standard prepared query lookup.
|
||||
if n >= 2 && strings.HasPrefix(queryParts[0], "_") && strings.HasPrefix(queryParts[n-1], "_") {
|
||||
// The last DNS query part is the protocol field (ignored).
|
||||
// All prior parts are the prepared query name or ID.
|
||||
query = strings.Join(queryParts[:n-1], ".")
|
||||
|
||||
// Strip leading underscore
|
||||
query = query[1:]
|
||||
} else {
|
||||
// Allow a "." in the query name, just join all the parts.
|
||||
query = strings.Join(queryParts, ".")
|
||||
}
|
||||
|
||||
err := d.preparedQueryLookup(cfg, datacenter, query, remoteAddr, req, resp, maxRecursionLevel)
|
||||
return ecsNotGlobalError{error: err}
|
||||
|
||||
|
|
|
@ -2743,13 +2743,16 @@ func TestDNS_ServiceLookup_ServiceAddress_SRV(t *testing.T) {
|
|||
}
|
||||
|
||||
// Register an equivalent prepared query.
|
||||
// Specify prepared query name containing "." to test
|
||||
// since that is technically supported (though atypical).
|
||||
var id string
|
||||
preparedQueryName := "query.name.with.dots"
|
||||
{
|
||||
args := &structs.PreparedQueryRequest{
|
||||
Datacenter: "dc1",
|
||||
Op: structs.PreparedQueryCreate,
|
||||
Query: &structs.PreparedQuery{
|
||||
Name: "test",
|
||||
Name: preparedQueryName,
|
||||
Service: structs.ServiceQuery{
|
||||
Service: "db",
|
||||
},
|
||||
|
@ -2764,6 +2767,9 @@ func TestDNS_ServiceLookup_ServiceAddress_SRV(t *testing.T) {
|
|||
questions := []string{
|
||||
"db.service.consul.",
|
||||
id + ".query.consul.",
|
||||
preparedQueryName + ".query.consul.",
|
||||
fmt.Sprintf("_%s._tcp.query.consul.", id),
|
||||
fmt.Sprintf("_%s._tcp.query.consul.", preparedQueryName),
|
||||
}
|
||||
for _, question := range questions {
|
||||
m := new(dns.Msg)
|
||||
|
|
|
@ -396,16 +396,24 @@ you can use the following query formats specify namespace but not partition:
|
|||
|
||||
### Prepared Query Lookups
|
||||
|
||||
The format of a prepared query lookup is:
|
||||
The following formats are valid for prepared query lookups:
|
||||
|
||||
```text
|
||||
<query or name>.query[.<datacenter>].<domain>
|
||||
```
|
||||
- Standard lookup
|
||||
|
||||
```text
|
||||
<query name or id>.query[.<datacenter>].<domain>
|
||||
```
|
||||
|
||||
- [RFC 2782](https://tools.ietf.org/html/rfc2782) SRV lookup
|
||||
|
||||
```text
|
||||
_<query name or id>._tcp.query[.<datacenter>].<domain>
|
||||
```
|
||||
|
||||
The `datacenter` is optional, and if not provided, the datacenter of this Consul
|
||||
agent is assumed.
|
||||
|
||||
The `query or name` is the ID or given name of an existing
|
||||
The `query name or id` is the given name or ID of an existing
|
||||
[Prepared Query](/api-docs/query). These behave like standard service
|
||||
queries but provide a much richer set of features, such as filtering by multiple
|
||||
tags and automatically failing over to look for services in remote datacenters if
|
||||
|
|
Loading…
Reference in New Issue