plugin/template: add upstream option (#1529)
* add upstream * docs * tests
This commit is contained in:
parent
ba573c0f40
commit
2cad04ec10
4 changed files with 33 additions and 1 deletions
|
@ -18,6 +18,7 @@ template CLASS TYPE [ZONE...] {
|
||||||
[authority RR]
|
[authority RR]
|
||||||
[...]
|
[...]
|
||||||
[rcode CODE]
|
[rcode CODE]
|
||||||
|
[upstream [ADDRESS...]]
|
||||||
[fallthrough [ZONE...]]
|
[fallthrough [ZONE...]]
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
@ -29,6 +30,9 @@ template CLASS TYPE [ZONE...] {
|
||||||
* `answer|additional|authority` **RR** A [RFC 1035](https://tools.ietf.org/html/rfc1035#section-5) style resource record fragment
|
* `answer|additional|authority` **RR** A [RFC 1035](https://tools.ietf.org/html/rfc1035#section-5) style resource record fragment
|
||||||
built by a [Go template](https://golang.org/pkg/text/template/) that contains the reply.
|
built by a [Go template](https://golang.org/pkg/text/template/) that contains the reply.
|
||||||
* `rcode` **CODE** A response code (`NXDOMAIN, SERVFAIL, ...`). The default is `SUCCESS`.
|
* `rcode` **CODE** A response code (`NXDOMAIN, SERVFAIL, ...`). The default is `SUCCESS`.
|
||||||
|
* `upstream` [**ADDRESS**...] defines the upstream resolvers used for resolving CNAME.
|
||||||
|
If no **ADDRESS** is given, CoreDNS will resolve CNAMEs against itself. **ADDRESS**
|
||||||
|
can be an IP, an IP:port, or a path to a file structured like resolv.conf.
|
||||||
* `fallthrough` Continue with the next plugin if the zone matched but no regex matched.
|
* `fallthrough` Continue with the next plugin if the zone matched but no regex matched.
|
||||||
If specific zones are listed (for example `in-addr.arpa` and `ip6.arpa`), then only queries for
|
If specific zones are listed (for example `in-addr.arpa` and `ip6.arpa`), then only queries for
|
||||||
those zones will be subject to fallthrough.
|
those zones will be subject to fallthrough.
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/coredns/coredns/core/dnsserver"
|
"github.com/coredns/coredns/core/dnsserver"
|
||||||
"github.com/coredns/coredns/plugin"
|
"github.com/coredns/coredns/plugin"
|
||||||
|
"github.com/coredns/coredns/plugin/pkg/upstream"
|
||||||
|
|
||||||
"github.com/mholt/caddy"
|
"github.com/mholt/caddy"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
|
@ -142,6 +143,13 @@ func templateParse(c *caddy.Controller) (handler Handler, err error) {
|
||||||
case "fallthrough":
|
case "fallthrough":
|
||||||
t.fall.SetZonesFromArgs(c.RemainingArgs())
|
t.fall.SetZonesFromArgs(c.RemainingArgs())
|
||||||
|
|
||||||
|
case "upstream":
|
||||||
|
args := c.RemainingArgs()
|
||||||
|
u, err := upstream.NewUpstream(args)
|
||||||
|
if err != nil {
|
||||||
|
return handler, err
|
||||||
|
}
|
||||||
|
t.upstream = u
|
||||||
default:
|
default:
|
||||||
return handler, c.ArgErr()
|
return handler, c.ArgErr()
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,20 @@ func TestSetupParse(t *testing.T) {
|
||||||
}`,
|
}`,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
`template ANY ANY up.stream.local {
|
||||||
|
answer "up.stream.local 5 IN CNAME up.river.local"
|
||||||
|
upstream
|
||||||
|
}`,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`template ANY ANY up.stream.local {
|
||||||
|
answer "up.stream.local 5 IN CNAME up.river.local"
|
||||||
|
upstream invalid-upstream-argument
|
||||||
|
}`,
|
||||||
|
true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
c := caddy.NewTestController("dns", test.inputFileRules)
|
c := caddy.NewTestController("dns", test.inputFileRules)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/coredns/coredns/plugin"
|
"github.com/coredns/coredns/plugin"
|
||||||
"github.com/coredns/coredns/plugin/pkg/fall"
|
"github.com/coredns/coredns/plugin/pkg/fall"
|
||||||
|
"github.com/coredns/coredns/plugin/pkg/upstream"
|
||||||
"github.com/coredns/coredns/request"
|
"github.com/coredns/coredns/request"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
|
@ -32,6 +33,7 @@ type template struct {
|
||||||
qclass uint16
|
qclass uint16
|
||||||
qtype uint16
|
qtype uint16
|
||||||
fall fall.F
|
fall fall.F
|
||||||
|
upstream upstream.Upstream
|
||||||
}
|
}
|
||||||
|
|
||||||
type templateData struct {
|
type templateData struct {
|
||||||
|
@ -48,7 +50,7 @@ type templateData struct {
|
||||||
|
|
||||||
// ServeDNS implements the plugin.Handler interface.
|
// ServeDNS implements the plugin.Handler interface.
|
||||||
func (h Handler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
func (h Handler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
||||||
state := request.Request{W: w, Req: r}
|
state := request.Request{W: w, Req: r, Context: ctx}
|
||||||
|
|
||||||
zone := plugin.Zones(h.Zones).Matches(state.Name())
|
zone := plugin.Zones(h.Zones).Matches(state.Name())
|
||||||
if zone == "" {
|
if zone == "" {
|
||||||
|
@ -81,6 +83,10 @@ func (h Handler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
|
||||||
return dns.RcodeServerFailure, err
|
return dns.RcodeServerFailure, err
|
||||||
}
|
}
|
||||||
msg.Answer = append(msg.Answer, rr)
|
msg.Answer = append(msg.Answer, rr)
|
||||||
|
if rr.Header().Rrtype == dns.TypeCNAME {
|
||||||
|
up, _ := template.upstream.Lookup(state, rr.(*dns.CNAME).Target, dns.TypeA)
|
||||||
|
msg.Answer = append(msg.Answer, up.Answer...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, additional := range template.additional {
|
for _, additional := range template.additional {
|
||||||
rr, err := executeRRTemplate("additional", additional, data)
|
rr, err := executeRRTemplate("additional", additional, data)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue