Add dns node lookup support in partitions
This commit is contained in:
parent
dcf96d9563
commit
cfc90ea2d5
35
agent/dns.go
35
agent/dns.go
|
@ -107,6 +107,14 @@ type serviceLookup struct {
|
||||||
acl.EnterpriseMeta
|
acl.EnterpriseMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type nodeLookup struct {
|
||||||
|
Datacenter string
|
||||||
|
Node string
|
||||||
|
Tag string
|
||||||
|
MaxRecursionLevel int
|
||||||
|
acl.EnterpriseMeta
|
||||||
|
}
|
||||||
|
|
||||||
// DNSServer is used to wrap an Agent and expose various
|
// DNSServer is used to wrap an Agent and expose various
|
||||||
// service discovery endpoints using a DNS interface.
|
// service discovery endpoints using a DNS interface.
|
||||||
type DNSServer struct {
|
type DNSServer struct {
|
||||||
|
@ -846,13 +854,27 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi
|
||||||
return invalid()
|
return invalid()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !d.parseDatacenter(querySuffixes, &datacenter) {
|
if !d.parseDatacenterAndEnterpriseMeta(querySuffixes, cfg, &datacenter, &entMeta) {
|
||||||
|
return invalid()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Namespace should not be set for node queries
|
||||||
|
ns := entMeta.NamespaceOrEmpty()
|
||||||
|
if ns != "" && ns != acl.DefaultNamespaceName {
|
||||||
return invalid()
|
return invalid()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow a "." in the node name, just join all the parts
|
// Allow a "." in the node name, just join all the parts
|
||||||
node := strings.Join(queryParts, ".")
|
node := strings.Join(queryParts, ".")
|
||||||
return d.nodeLookup(cfg, datacenter, node, req, resp, maxRecursionLevel)
|
|
||||||
|
lookup := nodeLookup{
|
||||||
|
Datacenter: datacenter,
|
||||||
|
Node: node,
|
||||||
|
MaxRecursionLevel: maxRecursionLevel,
|
||||||
|
EnterpriseMeta: entMeta,
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.nodeLookup(cfg, lookup, req, resp)
|
||||||
|
|
||||||
case "query":
|
case "query":
|
||||||
// ensure we have a query name
|
// ensure we have a query name
|
||||||
|
@ -959,7 +981,7 @@ func rCodeFromError(err error) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodeLookup is used to handle a node query
|
// nodeLookup is used to handle a node query
|
||||||
func (d *DNSServer) nodeLookup(cfg *dnsConfig, datacenter, node string, req, resp *dns.Msg, maxRecursionLevel int) error {
|
func (d *DNSServer) nodeLookup(cfg *dnsConfig, lookup nodeLookup, req, resp *dns.Msg) error {
|
||||||
// Only handle ANY, A, AAAA, and TXT type requests
|
// Only handle ANY, A, AAAA, and TXT type requests
|
||||||
qType := req.Question[0].Qtype
|
qType := req.Question[0].Qtype
|
||||||
if qType != dns.TypeANY && qType != dns.TypeA && qType != dns.TypeAAAA && qType != dns.TypeTXT {
|
if qType != dns.TypeANY && qType != dns.TypeA && qType != dns.TypeAAAA && qType != dns.TypeTXT {
|
||||||
|
@ -968,12 +990,13 @@ func (d *DNSServer) nodeLookup(cfg *dnsConfig, datacenter, node string, req, res
|
||||||
|
|
||||||
// Make an RPC request
|
// Make an RPC request
|
||||||
args := &structs.NodeSpecificRequest{
|
args := &structs.NodeSpecificRequest{
|
||||||
Datacenter: datacenter,
|
Datacenter: lookup.Datacenter,
|
||||||
Node: node,
|
Node: lookup.Node,
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
Token: d.agent.tokens.UserToken(),
|
Token: d.agent.tokens.UserToken(),
|
||||||
AllowStale: cfg.AllowStale,
|
AllowStale: cfg.AllowStale,
|
||||||
},
|
},
|
||||||
|
EnterpriseMeta: lookup.EnterpriseMeta,
|
||||||
}
|
}
|
||||||
out, err := d.lookupNode(cfg, args)
|
out, err := d.lookupNode(cfg, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -996,7 +1019,7 @@ func (d *DNSServer) nodeLookup(cfg *dnsConfig, datacenter, node string, req, res
|
||||||
q := req.Question[0]
|
q := req.Question[0]
|
||||||
// Only compute A and CNAME record if query is not TXT type
|
// Only compute A and CNAME record if query is not TXT type
|
||||||
if qType != dns.TypeTXT {
|
if qType != dns.TypeTXT {
|
||||||
records := d.makeRecordFromNode(n, q.Qtype, q.Name, cfg.NodeTTL, maxRecursionLevel)
|
records := d.makeRecordFromNode(n, q.Qtype, q.Name, cfg.NodeTTL, lookup.MaxRecursionLevel)
|
||||||
resp.Answer = append(resp.Answer, records...)
|
resp.Answer = append(resp.Answer, records...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -467,9 +467,9 @@ using the [`advertise-wan`](/docs/agent/config/cli-flags#_advertise-wan) and
|
||||||
[`translate_wan_addrs`](/docs/agent/config/config-files#translate_wan_addrs) configuration
|
[`translate_wan_addrs`](/docs/agent/config/config-files#translate_wan_addrs) configuration
|
||||||
options.
|
options.
|
||||||
|
|
||||||
## Namespaced/Partitioned Services <EnterpriseAlert inline />
|
## Namespaced/Partitioned Services and Nodes <EnterpriseAlert inline />
|
||||||
|
|
||||||
Consul Enterprise supports resolving namespaced and partitioned services via DNS.
|
Consul Enterprise supports resolving namespaced and partitioned services and nodes via DNS.
|
||||||
To maintain backwards compatibility existing queries can be used and these will
|
To maintain backwards compatibility existing queries can be used and these will
|
||||||
resolve services within the `default` namespace and partition. However, for resolving
|
resolve services within the `default` namespace and partition. However, for resolving
|
||||||
services from other namespaces or partitions the following form can be used:
|
services from other namespaces or partitions the following form can be used:
|
||||||
|
@ -478,13 +478,20 @@ services from other namespaces or partitions the following form can be used:
|
||||||
[tag.]<service>.service.<namespace>.ns.<partition>.ap.<datacenter>.dc.<domain>
|
[tag.]<service>.service.<namespace>.ns.<partition>.ap.<datacenter>.dc.<domain>
|
||||||
```
|
```
|
||||||
|
|
||||||
This is the canonical name of a Consul Enterprise service. Currently all parts must be
|
This is the canonical name of a Consul Enterprise service. Currently at least 2 of
|
||||||
present - in a future version (once the
|
`[namespace, partition, datacenter]` must be present - in a future version (once the
|
||||||
[`prefer_namespace` configuration](/docs/agent/config/config-files#dns_prefer_namespace) has been
|
[`prefer_namespace` configuration](/docs/agent/config/config-files#dns_prefer_namespace) has been
|
||||||
deprecated), the namespace, partition and datacenter components will become optional
|
deprecated), the namespace, partition and datacenter components will all become optional
|
||||||
and may be individually omitted to default to the `default` namespace, local partition
|
and may be individually omitted to default to the `default` namespace, local partition
|
||||||
or local datacenter respectively.
|
or local datacenter respectively.
|
||||||
|
|
||||||
|
For node lookups, only the partition and datacenter need to be specified (nodes cannot be
|
||||||
|
namespaced):
|
||||||
|
|
||||||
|
```text
|
||||||
|
[tag.]<service>.service.<partition>.ap.<datacenter>.dc.<domain>
|
||||||
|
```
|
||||||
|
|
||||||
## DNS with ACLs
|
## DNS with ACLs
|
||||||
|
|
||||||
In order to use the DNS interface when
|
In order to use the DNS interface when
|
||||||
|
|
Loading…
Reference in New Issue