diff --git a/.changelog/13421.txt b/.changelog/13421.txt
new file mode 100644
index 0000000000..324e82d895
--- /dev/null
+++ b/.changelog/13421.txt
@@ -0,0 +1,3 @@
+```release-note:improvement
+dns: Added support for specifying admin partition in node lookups.
+```
diff --git a/agent/dns.go b/agent/dns.go
index a973056a1a..9d0d3b9a5b 100644
--- a/agent/dns.go
+++ b/agent/dns.go
@@ -107,6 +107,14 @@ type serviceLookup struct {
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
// service discovery endpoints using a DNS interface.
type DNSServer struct {
@@ -846,13 +854,27 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi
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()
}
// Allow a "." in the node name, just join all the parts
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":
// ensure we have a query name
@@ -959,7 +981,7 @@ func rCodeFromError(err error) int {
}
// 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
qType := req.Question[0].Qtype
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
args := &structs.NodeSpecificRequest{
- Datacenter: datacenter,
- Node: node,
+ Datacenter: lookup.Datacenter,
+ Node: lookup.Node,
QueryOptions: structs.QueryOptions{
Token: d.agent.tokens.UserToken(),
AllowStale: cfg.AllowStale,
},
+ EnterpriseMeta: lookup.EnterpriseMeta,
}
out, err := d.lookupNode(cfg, args)
if err != nil {
@@ -996,7 +1019,7 @@ func (d *DNSServer) nodeLookup(cfg *dnsConfig, datacenter, node string, req, res
q := req.Question[0]
// Only compute A and CNAME record if query is not TXT type
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...)
}
diff --git a/website/content/docs/discovery/dns.mdx b/website/content/docs/discovery/dns.mdx
index 3b11a8df12..8a542b4ef2 100644
--- a/website/content/docs/discovery/dns.mdx
+++ b/website/content/docs/discovery/dns.mdx
@@ -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
options.
-## Namespaced/Partitioned Services
+## Namespaced/Partitioned Services and Nodes
-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
resolve services within the `default` namespace and partition. However, for resolving
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..ns..ap..dc.
```
-This is the canonical name of a Consul Enterprise service. Currently all parts must be
-present - in a future version (once the
+This is the canonical name of a Consul Enterprise service. Currently at least 2 of
+`[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
-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
or local datacenter respectively.
+For node lookups, only the partition and datacenter need to be specified (nodes cannot be
+namespaced):
+
+```text
+[tag.].service..ap..dc.
+```
+
## DNS with ACLs
In order to use the DNS interface when