Commit 818d2b10 authored by Miek Gieben's avatar Miek Gieben Committed by GitHub

cidr everywhere: check all middleware (#915)

* cidr everywhere: check all middleware

Add tests for cidr in only that middleware that already tests for this.
Check the other ones manually (and put reverse in the tests cases
anyway).

Make etcd setup_test run without +build etcd tag - it is not needed
for this test - move rest of the code to lookup_test.go.

Cleanup proxy test a bit and remove TempDir as there is test.TempFile
that does the same thing.

Fixes #909

* coredns package

* Fix test compile
parent 0c02708d
...@@ -22,6 +22,12 @@ func TestAutoParse(t *testing.T) { ...@@ -22,6 +22,12 @@ func TestAutoParse(t *testing.T) {
}`, }`,
false, "/tmp", "${1}", `db\.(.*)`, []string{"127.0.0.1:53"}, false, "/tmp", "${1}", `db\.(.*)`, []string{"127.0.0.1:53"},
}, },
{
`auto 10.0.0.0/24 {
directory /tmp
}`,
false, "/tmp", "${1}", `db\.(.*)`, nil,
},
{ {
`auto { `auto {
directory /tmp directory /tmp
......
...@@ -21,21 +21,18 @@ func TestSetupAutoPath(t *testing.T) { ...@@ -21,21 +21,18 @@ func TestSetupAutoPath(t *testing.T) {
tests := []struct { tests := []struct {
input string input string
shouldErr bool shouldErr bool
expectedZone string
expectedMw string // expected middleware. expectedMw string // expected middleware.
expectedSearch []string // expected search path expectedSearch []string // expected search path
expectedErrContent string // substring from the expected error. Empty for positive cases. expectedErrContent string // substring from the expected error. Empty for positive cases.
}{ }{
// positive // positive
{ {`autopath @kubernetes`, false, "", "kubernetes", nil, ""},
`autopath @kubernetes`, false, "kubernetes", nil, "", {`autopath example.org @kubernetes`, false, "example.org.", "kubernetes", nil, ""},
}, {`autopath 10.0.0.0/8 @kubernetes`, false, "10.in-addr.arpa.", "kubernetes", nil, ""},
{ {`autopath ` + resolv, false, "", "", []string{"bar.com.", "baz.com.", ""}, ""},
`autopath ` + resolv, false, "", []string{"bar.com.", "baz.com.", ""}, "",
},
// negative // negative
{ {`autopath kubernetes`, true, "", "", nil, "open kubernetes: no such file or directory"},
`autopath kubernetes`, true, "", nil, "open kubernetes: no such file or directory",
},
} }
for i, test := range tests { for i, test := range tests {
...@@ -64,6 +61,11 @@ func TestSetupAutoPath(t *testing.T) { ...@@ -64,6 +61,11 @@ func TestSetupAutoPath(t *testing.T) {
t.Errorf("Test %d, wrong searchpath for input %s. Expected: '%v', actual: '%v'", i, test.input, test.expectedSearch, ap.search) t.Errorf("Test %d, wrong searchpath for input %s. Expected: '%v', actual: '%v'", i, test.input, test.expectedSearch, ap.search)
} }
} }
if !test.shouldErr && test.expectedZone != "" {
if test.expectedZone != ap.Zones[0] {
t.Errorf("Test %d, expected zone %q for input %s, got: %q", i, test.expectedZone, test.input, ap.Zones[0])
}
}
} }
} }
......
...@@ -20,12 +20,15 @@ func TestSetupDnssec(t *testing.T) { ...@@ -20,12 +20,15 @@ func TestSetupDnssec(t *testing.T) {
`dnssec`, false, nil, nil, defaultCap, "", `dnssec`, false, nil, nil, defaultCap, "",
}, },
{ {
`dnssec miek.nl`, false, []string{"miek.nl."}, nil, defaultCap, "", `dnssec example.org`, false, []string{"example.org."}, nil, defaultCap, "",
}, },
{ {
`dnssec miek.nl { `dnssec 10.0.0.0/8`, false, []string{"10.in-addr.arpa."}, nil, defaultCap, "",
},
{
`dnssec example.org {
cache_capacity 100 cache_capacity 100
}`, false, []string{"miek.nl."}, nil, 100, "", }`, false, []string{"example.org."}, nil, 100, "",
}, },
} }
......
...@@ -3,12 +3,27 @@ ...@@ -3,12 +3,27 @@
package etcd package etcd
import ( import (
"context"
"encoding/json"
"sort"
"testing"
"time"
"github.com/coredns/coredns/middleware/etcd/msg" "github.com/coredns/coredns/middleware/etcd/msg"
"github.com/coredns/coredns/middleware/pkg/dnsrecorder"
"github.com/coredns/coredns/middleware/pkg/singleflight"
"github.com/coredns/coredns/middleware/pkg/tls"
"github.com/coredns/coredns/middleware/proxy"
"github.com/coredns/coredns/middleware/test" "github.com/coredns/coredns/middleware/test"
etcdc "github.com/coreos/etcd/client"
"github.com/miekg/dns" "github.com/miekg/dns"
) )
func init() {
ctxt, _ = context.WithTimeout(context.Background(), etcdTimeout)
}
// Note the key is encoded as DNS name, while in "reality" it is a etcd path. // Note the key is encoded as DNS name, while in "reality" it is a etcd path.
var services = []*msg.Service{ var services = []*msg.Service{
{Host: "dev.server1", Port: 8080, Key: "a.server1.dev.region1.skydns.test."}, {Host: "dev.server1", Port: 8080, Key: "a.server1.dev.region1.skydns.test."},
...@@ -206,3 +221,70 @@ var dnsTestCases = []test.Case{ ...@@ -206,3 +221,70 @@ var dnsTestCases = []test.Case{
Answer: []dns.RR{test.PTR("1.0.0.10.in-addr.arpa. 300 PTR reverse.example.com.")}, Answer: []dns.RR{test.PTR("1.0.0.10.in-addr.arpa. 300 PTR reverse.example.com.")},
}, },
} }
func newEtcdMiddleware() *Etcd {
ctxt, _ = context.WithTimeout(context.Background(), etcdTimeout)
endpoints := []string{"http://localhost:2379"}
tlsc, _ := tls.NewTLSConfigFromArgs()
client, _ := newEtcdClient(endpoints, tlsc)
return &Etcd{
Proxy: proxy.NewLookup([]string{"8.8.8.8:53"}),
PathPrefix: "skydns",
Ctx: context.Background(),
Inflight: &singleflight.Group{},
Zones: []string{"skydns.test.", "skydns_extra.test.", "in-addr.arpa."},
Client: client,
}
}
func set(t *testing.T, e *Etcd, k string, ttl time.Duration, m *msg.Service) {
b, err := json.Marshal(m)
if err != nil {
t.Fatal(err)
}
path, _ := msg.PathWithWildcard(k, e.PathPrefix)
e.Client.Set(ctxt, path, string(b), &etcdc.SetOptions{TTL: ttl})
}
func delete(t *testing.T, e *Etcd, k string) {
path, _ := msg.PathWithWildcard(k, e.PathPrefix)
e.Client.Delete(ctxt, path, &etcdc.DeleteOptions{Recursive: false})
}
func TestLookup(t *testing.T) {
etc := newEtcdMiddleware()
for _, serv := range services {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
}
for _, tc := range dnsTestCases {
m := tc.Msg()
rec := dnsrecorder.New(&test.ResponseWriter{})
etc.ServeDNS(ctxt, rec, m)
resp := rec.Msg
sort.Sort(test.RRSet(resp.Answer))
sort.Sort(test.RRSet(resp.Ns))
sort.Sort(test.RRSet(resp.Extra))
if !test.Header(t, tc, resp) {
t.Logf("%v\n", resp)
continue
}
if !test.Section(t, tc, test.Answer, resp.Answer) {
t.Logf("%v\n", resp)
}
if !test.Section(t, tc, test.Ns, resp.Ns) {
t.Logf("%v\n", resp)
}
if !test.Section(t, tc, test.Extra, resp.Extra) {
t.Logf("%v\n", resp)
}
}
}
var ctxt context.Context
// +build etcd
package etcd package etcd
import ( import (
"encoding/json"
"sort"
"strings" "strings"
"testing" "testing"
"time"
"github.com/coredns/coredns/middleware/etcd/msg"
"github.com/coredns/coredns/middleware/pkg/dnsrecorder"
"github.com/coredns/coredns/middleware/pkg/singleflight"
"github.com/coredns/coredns/middleware/pkg/tls"
"github.com/coredns/coredns/middleware/proxy"
"github.com/coredns/coredns/middleware/test"
etcdc "github.com/coreos/etcd/client"
"github.com/mholt/caddy" "github.com/mholt/caddy"
"golang.org/x/net/context"
) )
func init() {
ctxt, _ = context.WithTimeout(context.Background(), etcdTimeout)
}
func newEtcdMiddleware() *Etcd {
ctxt, _ = context.WithTimeout(context.Background(), etcdTimeout)
endpoints := []string{"http://localhost:2379"}
tlsc, _ := tls.NewTLSConfigFromArgs()
client, _ := newEtcdClient(endpoints, tlsc)
return &Etcd{
Proxy: proxy.NewLookup([]string{"8.8.8.8:53"}),
PathPrefix: "skydns",
Ctx: context.Background(),
Inflight: &singleflight.Group{},
Zones: []string{"skydns.test.", "skydns_extra.test.", "in-addr.arpa."},
Client: client,
}
}
func set(t *testing.T, e *Etcd, k string, ttl time.Duration, m *msg.Service) {
b, err := json.Marshal(m)
if err != nil {
t.Fatal(err)
}
path, _ := msg.PathWithWildcard(k, e.PathPrefix)
e.Client.Set(ctxt, path, string(b), &etcdc.SetOptions{TTL: ttl})
}
func delete(t *testing.T, e *Etcd, k string) {
path, _ := msg.PathWithWildcard(k, e.PathPrefix)
e.Client.Delete(ctxt, path, &etcdc.DeleteOptions{Recursive: false})
}
func TestLookup(t *testing.T) {
etc := newEtcdMiddleware()
for _, serv := range services {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
}
for _, tc := range dnsTestCases {
m := tc.Msg()
rec := dnsrecorder.New(&test.ResponseWriter{})
etc.ServeDNS(ctxt, rec, m)
resp := rec.Msg
sort.Sort(test.RRSet(resp.Answer))
sort.Sort(test.RRSet(resp.Ns))
sort.Sort(test.RRSet(resp.Extra))
if !test.Header(t, tc, resp) {
t.Logf("%v\n", resp)
continue
}
if !test.Section(t, tc, test.Answer, resp.Answer) {
t.Logf("%v\n", resp)
}
if !test.Section(t, tc, test.Ns, resp.Ns) {
t.Logf("%v\n", resp)
}
if !test.Section(t, tc, test.Extra, resp.Extra) {
t.Logf("%v\n", resp)
}
}
}
func TestSetupEtcd(t *testing.T) { func TestSetupEtcd(t *testing.T) {
tests := []struct { tests := []struct {
input string input string
...@@ -145,5 +62,3 @@ func TestSetupEtcd(t *testing.T) { ...@@ -145,5 +62,3 @@ func TestSetupEtcd(t *testing.T) {
} }
} }
} }
var ctxt context.Context
...@@ -48,6 +48,11 @@ func TestFileParse(t *testing.T) { ...@@ -48,6 +48,11 @@ func TestFileParse(t *testing.T) {
false, false,
Zones{Names: []string{"dnssex.nl."}}, Zones{Names: []string{"dnssex.nl."}},
}, },
{
`file ` + zoneFileName2 + ` 10.0.0.0/8`,
false,
Zones{Names: []string{"10.in-addr.arpa."}},
},
} }
for i, test := range tests { for i, test := range tests {
......
...@@ -50,10 +50,10 @@ func TestHostsParse(t *testing.T) { ...@@ -50,10 +50,10 @@ func TestHostsParse(t *testing.T) {
false, "/etc/hosts", []string{"miek.nl."}, true, false, "/etc/hosts", []string{"miek.nl."}, true,
}, },
{ {
`hosts /etc/hosts miek.nl. pun.gent. { `hosts /etc/hosts miek.nl 10.0.0.9/8 {
fallthrough fallthrough
}`, }`,
false, "/etc/hosts", []string{"miek.nl.", "pun.gent."}, true, false, "/etc/hosts", []string{"miek.nl.", "10.in-addr.arpa."}, true,
}, },
} }
......
...@@ -4,7 +4,6 @@ import ( ...@@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"net" "net"
"strconv" "strconv"
"strings"
"sync/atomic" "sync/atomic"
"time" "time"
...@@ -44,6 +43,8 @@ func NewStaticUpstreams(c *caddyfile.Dispenser) ([]Upstream, error) { ...@@ -44,6 +43,8 @@ func NewStaticUpstreams(c *caddyfile.Dispenser) ([]Upstream, error) {
if !c.Args(&upstream.from) { if !c.Args(&upstream.from) {
return upstreams, c.ArgErr() return upstreams, c.ArgErr()
} }
upstream.from = middleware.Host(upstream.from).Normalize()
to := c.RemainingArgs() to := c.RemainingArgs()
if len(to) == 0 { if len(to) == 0 {
return upstreams, c.ArgErr() return upstreams, c.ArgErr()
...@@ -168,7 +169,7 @@ func parseBlock(c *caddyfile.Dispenser, u *staticUpstream) error { ...@@ -168,7 +169,7 @@ func parseBlock(c *caddyfile.Dispenser, u *staticUpstream) error {
return c.ArgErr() return c.ArgErr()
} }
for i := 0; i < len(ignoredDomains); i++ { for i := 0; i < len(ignoredDomains); i++ {
ignoredDomains[i] = strings.ToLower(dns.Fqdn(ignoredDomains[i])) ignoredDomains[i] = middleware.Host(ignoredDomains[i]).Normalize()
} }
u.IgnoredSubDomains = ignoredDomains u.IgnoredSubDomains = ignoredDomains
case "spray": case "spray":
......
package proxy package proxy
import ( import (
"io/ioutil"
"os"
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
...@@ -35,19 +33,6 @@ func TestAllowedDomain(t *testing.T) { ...@@ -35,19 +33,6 @@ func TestAllowedDomain(t *testing.T) {
} }
} }
func writeTmpFile(t *testing.T, data string) (string, string) {
tempDir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("tempDir: %v", err)
}
path := filepath.Join(tempDir, "resolv.conf")
if err := ioutil.WriteFile(path, []byte(data), 0644); err != nil {
t.Fatalf("writeFile: %v", err)
}
return tempDir, path
}
func TestProxyParse(t *testing.T) { func TestProxyParse(t *testing.T) {
rmFunc, cert, key, ca := getPEMFiles(t) rmFunc, cert, key, ca := getPEMFiles(t)
defer rmFunc() defer rmFunc()
...@@ -65,6 +50,10 @@ func TestProxyParse(t *testing.T) { ...@@ -65,6 +50,10 @@ func TestProxyParse(t *testing.T) {
`proxy . 8.8.8.8:53`, `proxy . 8.8.8.8:53`,
false, false,
}, },
{
`proxy 10.0.0.0/24 8.8.8.8:53`,
false,
},
{ {
` `
proxy . 8.8.8.8:53 { proxy . 8.8.8.8:53 {
...@@ -103,7 +92,7 @@ proxy . 8.8.8.8:53 { ...@@ -103,7 +92,7 @@ proxy . 8.8.8.8:53 {
{ {
` `
proxy . 8.8.8.8:53 { proxy . 8.8.8.8:53 {
except miek.nl example.org except miek.nl example.org 10.0.0.0/24
}`, }`,
false, false,
}, },
...@@ -283,13 +272,18 @@ junky resolve.conf ...@@ -283,13 +272,18 @@ junky resolve.conf
[]string{"1.1.1.1:5000", "2.2.2.2:1234"}, []string{"1.1.1.1:5000", "2.2.2.2:1234"},
}, },
} }
for i, test := range tests { for i, tc := range tests {
tempDir, path := writeTmpFile(t, test.filedata)
defer os.RemoveAll(tempDir) path, rm, err := test.TempFile(".", tc.filedata)
config := strings.Replace(test.inputUpstreams, "FILE", path, -1) if err != nil {
t.Fatalf("Test %d could not creat temp file %v", i, err)
}
defer rm()
config := strings.Replace(tc.inputUpstreams, "FILE", path, -1)
c := caddy.NewTestController("dns", config) c := caddy.NewTestController("dns", config)
upstreams, err := NewStaticUpstreams(&c.Dispenser) upstreams, err := NewStaticUpstreams(&c.Dispenser)
if (err != nil) != test.shouldErr { if (err != nil) != tc.shouldErr {
t.Errorf("Test %d expected no error, got %v", i+1, err) t.Errorf("Test %d expected no error, got %v", i+1, err)
} }
var hosts []string var hosts []string
...@@ -298,18 +292,18 @@ junky resolve.conf ...@@ -298,18 +292,18 @@ junky resolve.conf
hosts = append(hosts, h.Name) hosts = append(hosts, h.Name)
} }
} }
if !test.shouldErr { if !tc.shouldErr {
if len(hosts) != len(test.expected) { if len(hosts) != len(tc.expected) {
t.Errorf("Test %d expected %d hosts got %d", i+1, len(test.expected), len(upstreams)) t.Errorf("Test %d expected %d hosts got %d", i+1, len(tc.expected), len(upstreams))
} else { } else {
ok := true ok := true
for i, v := range test.expected { for i, v := range tc.expected {
if v != hosts[i] { if v != hosts[i] {
ok = false ok = false
} }
} }
if !ok { if !ok {
t.Errorf("Test %d expected %v got %v", i+1, test.expected, upstreams) t.Errorf("Test %d expected %v got %v", i+1, tc.expected, upstreams)
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment