diff --git a/middleware/erratic/setup.go b/middleware/erratic/setup.go index cdfc3407d..98db02247 100644 --- a/middleware/erratic/setup.go +++ b/middleware/erratic/setup.go @@ -104,6 +104,8 @@ func parseErratic(c *caddy.Controller) (*Erratic, error) { return nil, fmt.Errorf("illegal amount value given %q", args[0]) } e.truncate = uint64(amount) + default: + return nil, c.Errf("unknown property '%s'", c.Val()) } } } diff --git a/middleware/etcd/README.md b/middleware/etcd/README.md index b2f4a05d0..9542dea6b 100644 --- a/middleware/etcd/README.md +++ b/middleware/etcd/README.md @@ -23,6 +23,7 @@ If you want to `round robin` A and AAAA responses look at the `loadbalance` midd ~~~ etcd [ZONES...] { stubzones + fallthrough path PATH endpoint ENDPOINT... upstream ADDRESS... @@ -33,6 +34,7 @@ etcd [ZONES...] { * `stubzones` enables the stub zones feature. The stubzone is *only* done in the etcd tree located under the *first* zone specified. +* `fallthrough` If zone matches but no record can be generated, pass request to the next middleware. * **PATH** the path inside etcd. Defaults to "/skydns". * **ENDPOINT** the etcd endpoints. Defaults to "http://localhost:2397". * `upstream` upstream resolvers to be used resolve external names found in etcd (think CNAMEs) diff --git a/middleware/etcd/etcd.go b/middleware/etcd/etcd.go index b438b794d..55ad03ba3 100644 --- a/middleware/etcd/etcd.go +++ b/middleware/etcd/etcd.go @@ -21,15 +21,16 @@ import ( // Etcd is a middleware talks to an etcd cluster. type Etcd struct { - Next middleware.Handler - Zones []string - PathPrefix string - Proxy proxy.Proxy // Proxy for looking up names during the resolution process - Client etcdc.KeysAPI - Ctx context.Context - Inflight *singleflight.Group - Stubmap *map[string]proxy.Proxy // list of proxies for stub resolving. - Debugging bool // Do we allow debug queries. + Next middleware.Handler + Fallthrough bool + Zones []string + PathPrefix string + Proxy proxy.Proxy // Proxy for looking up names during the resolution process + Client etcdc.KeysAPI + Ctx context.Context + Inflight *singleflight.Group + Stubmap *map[string]proxy.Proxy // list of proxies for stub resolving. + Debugging bool // Do we allow debug queries. endpoints []string // Stored here as well, to aid in testing. } diff --git a/middleware/etcd/handler.go b/middleware/etcd/handler.go index cf11f3f86..a5e5f1b80 100644 --- a/middleware/etcd/handler.go +++ b/middleware/etcd/handler.go @@ -46,7 +46,10 @@ func (e *Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) ( if opt.Debug != "" { r.Question[0].Name = opt.Debug } - return middleware.NextOrFailure(e.Name(), e.Next, ctx, w, r) + if e.Fallthrough { + return middleware.NextOrFailure(e.Name(), e.Next, ctx, w, r) + } + return dns.RcodeServerFailure, nil } var ( diff --git a/middleware/etcd/multi_test.go b/middleware/etcd/multi_test.go index 26ce9b3ce..bd2432a1a 100644 --- a/middleware/etcd/multi_test.go +++ b/middleware/etcd/multi_test.go @@ -16,6 +16,7 @@ import ( func TestMultiLookup(t *testing.T) { etc := newEtcdMiddleware() etc.Zones = []string{"skydns.test.", "miek.nl."} + etc.Fallthrough = true etc.Next = test.ErrorHandler() for _, serv := range servicesMulti { diff --git a/middleware/etcd/setup.go b/middleware/etcd/setup.go index 331227c34..ee5a93fff 100644 --- a/middleware/etcd/setup.go +++ b/middleware/etcd/setup.go @@ -74,6 +74,8 @@ func etcdParse(c *caddy.Controller) (*Etcd, bool, error) { switch c.Val() { case "stubzones": stubzones = true + case "fallthrough": + etc.Fallthrough = true case "debug": etc.Debugging = true case "path": diff --git a/middleware/file/setup.go b/middleware/file/setup.go index 62b561a35..2ac7610c5 100644 --- a/middleware/file/setup.go +++ b/middleware/file/setup.go @@ -115,6 +115,8 @@ func fileParse(c *caddy.Controller) (Zones, error) { return Zones{}, err } prxy = proxy.NewLookup(ups) + default: + return Zones{}, c.Errf("unknown property '%s'", c.Val()) } for _, origin := range origins { diff --git a/middleware/hosts/setup.go b/middleware/hosts/setup.go index d024d449e..38458541c 100644 --- a/middleware/hosts/setup.go +++ b/middleware/hosts/setup.go @@ -79,6 +79,8 @@ func hostsParse(c *caddy.Controller) (Hosts, error) { continue } return h, c.ArgErr() + default: + return h, c.Errf("unknown property '%s'", c.Val()) } } } diff --git a/middleware/kubernetes/README.md b/middleware/kubernetes/README.md index f11d7147c..7970fc45b 100644 --- a/middleware/kubernetes/README.md +++ b/middleware/kubernetes/README.md @@ -21,15 +21,14 @@ all the zones the middleware should be authoritative for. ``` kubernetes [ZONES...] { - resyncperiod DURATION - endpoint URL - tls CERT KEY CACERT - namespaces NAMESPACE [NAMESPACE...] - labels EXPRESSION - pods POD-MODE - upstream ADDRESS [ADDRESS...] - federation NAME DOMAIN - fallthrough + resyncperiod DURATION + endpoint URL + tls CERT KEY CACERT + namespaces NAMESPACE [NAMESPACE...] + labels EXPRESSION + pods POD-MODE + upstream ADDRESS [ADDRESS...] + fallthrough } ``` * `resyncperiod` specifies the Kubernetes data API **DURATION** period. @@ -63,8 +62,6 @@ kubernetes [ZONES...] { * `upstream` **ADDRESS [ADDRESS...]** defines the upstream resolvers used for resolving services that point to external hosts (External Services). **ADDRESS** can be an ip, an ip:port, or a path to a file structured like resolv.conf. -* `federation` **NAME DOMAIN** defines federation membership. One line for each federation - membership. Each line consists of the name of the federation, and the domain. * `fallthrough` If a query for a record in the cluster zone results in NXDOMAIN, normally that is what the response will be. However, if you specify this option, the query will instead be passed on down the middleware chain, which can include another middleware to handle the query. @@ -85,40 +82,47 @@ here: Or you can selectively expose some namespaces: - kubernetes cluster.local { - namespaces test staging - } - -If you want to use federation, just use the `federation` option. Here we handle all service requests -in the `prod` and `stage` federations. We resolve upstream records using the servers configured in -`/etc/resolv.conf`. - - . { - kubernetes cluster.local { - federation prod prod.feddomain.com - federation stage stage.feddomain.com - upstream /etc/resolv.conf - } + kubernetes cluster.local { + namespaces test staging } And finally we can connect to Kubernetes from outside the cluster: - kubernetes cluster.local { - endpoint https://k8s-endpoint:8443 - tls cert key cacert - } + kubernetes cluster.local { + endpoint https://k8s-endpoint:8443 + tls cert key cacert + } -## Enabling server-side domain search path completion with *autopath* +## AutoPath -The *kubernetes* middleware can be used in conjunction with the *autopath* middleware. Using this feature enables server-side domain search path completion in kubernetes clusters. Note: `pods` must be set to `verified` for this to function properly. +The *kubernetes* middleware can be used in conjunction with the *autopath* middleware. Using this +feature enables server-side domain search path completion in kubernetes clusters. Note: `pods` must +be set to `verified` for this to function properly. - autopath @kubernetes - kubernetes cluster.local { - pods verified - } + cluster.local { + autopath @kubernetes + kubernetes { + pods verified + } + } + +## Federation + +The *kubernetes* middleware can be used in conjunction with the *federation* middleware. Using this +feature enables serving federated domains from the kubernetes clusters. + + cluster.local { + federation { + fallthrough + prod prod.example.org + staging staging.example.org + + } + kubernetes + } -## Wildcard +## Wildcards Some query labels accept a wildcard value to match any value. If a label is a valid wildcard (\*, or the word "any"), then that label will match all values. The labels that accept wildcards are: diff --git a/middleware/kubernetes/federation.go b/middleware/kubernetes/federation.go deleted file mode 100644 index 4c8d20cfe..000000000 --- a/middleware/kubernetes/federation.go +++ /dev/null @@ -1,96 +0,0 @@ -package kubernetes - -import ( - "net" - "strings" - - "github.com/coredns/coredns/middleware/etcd/msg" -) - -// Federation holds TODO(...). -type Federation struct { - name string - zone string -} - -const ( - // TODO: Do not hardcode these labels. Pull them out of the API instead. - // - // We can get them via .... - // import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - // metav1.LabelZoneFailureDomain - // metav1.LabelZoneRegion - // - // But importing above breaks coredns with flag collision of 'log_dir' - - labelAvailabilityZone = "failure-domain.beta.kubernetes.io/zone" - labelRegion = "failure-domain.beta.kubernetes.io/region" -) - -// stripFederation removes the federation segment from the segment list, if it -// matches a configured federation name. -func (k *Kubernetes) stripFederation(segs []string) (string, []string) { - - if len(segs) < 3 { - return "", segs - } - for _, f := range k.Federations { - if f.name == segs[len(segs)-2] { - fed := segs[len(segs)-2] - segs[len(segs)-2] = segs[len(segs)-1] - segs = segs[:len(segs)-1] - return fed, segs - } - } - return "", segs -} - -// federationCNAMERecord returns a service record for the requested federated service -// with the target host in the federated CNAME format which the external DNS provider -// should be able to resolve -func (k *Kubernetes) federationCNAMERecord(r recordRequest) msg.Service { - - myNodeName := k.localNodeName() - node, err := k.APIConn.GetNodeByName(myNodeName) - if err != nil { - return msg.Service{} - } - - for _, f := range k.Federations { - if f.name != r.federation { - continue - } - if r.endpoint == "" { - return msg.Service{ - Key: strings.Join([]string{msg.Path(r.zone, "coredns"), r.podOrSvc, r.federation, r.namespace, r.service}, "/"), - Host: strings.Join([]string{r.service, r.namespace, r.federation, r.podOrSvc, node.Labels[labelAvailabilityZone], node.Labels[labelRegion], f.zone}, "."), - } - } - return msg.Service{ - Key: strings.Join([]string{msg.Path(r.zone, "coredns"), r.podOrSvc, r.federation, r.namespace, r.service, r.endpoint}, "/"), - Host: strings.Join([]string{r.endpoint, r.service, r.namespace, r.federation, r.podOrSvc, node.Labels[labelAvailabilityZone], node.Labels[labelRegion], f.zone}, "."), - } - } - - return msg.Service{} -} - -func (k *Kubernetes) localNodeName() string { - localIP := k.interfaceAddrsFunc() - if localIP == nil { - return "" - } - - // Find endpoint matching localIP - endpointsList := k.APIConn.EndpointsList() - for _, ep := range endpointsList.Items { - for _, eps := range ep.Subsets { - for _, addr := range eps.Addresses { - if localIP.Equal(net.ParseIP(addr.IP)) { - return *addr.NodeName - } - } - } - } - return "" -} diff --git a/middleware/kubernetes/federation_test.go b/middleware/kubernetes/federation_test.go deleted file mode 100644 index 410d2a54e..000000000 --- a/middleware/kubernetes/federation_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package kubernetes - -import ( - "net" - "strings" - "testing" - - "github.com/coredns/coredns/middleware/etcd/msg" - "github.com/coredns/coredns/request" - "github.com/miekg/dns" - "k8s.io/client-go/1.5/pkg/api" -) - -func testStripFederation(t *testing.T, k Kubernetes, input []string, expectedFed string, expectedSegs string) { - fed, segs := k.stripFederation(input) - - if expectedSegs != strings.Join(segs, ".") { - t.Errorf("For '%v', expected segs result '%v'. Instead got result '%v'.", strings.Join(input, "."), expectedSegs, strings.Join(segs, ".")) - } - if expectedFed != fed { - t.Errorf("For '%v', expected fed result '%v'. Instead got result '%v'.", strings.Join(input, "."), expectedFed, fed) - } -} - -func TestStripFederation(t *testing.T) { - k := Kubernetes{Zones: []string{"inter.webs.test"}} - k.Federations = []Federation{{name: "fed", zone: "era.tion.com"}} - - testStripFederation(t, k, []string{"service", "ns", "fed", Svc}, "fed", "service.ns.svc") - testStripFederation(t, k, []string{"service", "ns", "foo", Svc}, "", "service.ns.foo.svc") - testStripFederation(t, k, []string{"foo", "bar"}, "", "foo.bar") - -} - -type apiConnFedTest struct{} - -func (apiConnFedTest) Run() { return } -func (apiConnFedTest) Stop() error { return nil } -func (apiConnFedTest) ServiceList() []*api.Service { return []*api.Service{} } -func (apiConnFedTest) PodIndex(string) []interface{} { return nil } - -func (apiConnFedTest) EndpointsList() api.EndpointsList { - n := "test.node.foo.bar" - return api.EndpointsList{ - Items: []api.Endpoints{ - { - Subsets: []api.EndpointSubset{ - { - Addresses: []api.EndpointAddress{ - { - IP: "10.9.8.7", - NodeName: &n, - }, - }, - }, - }, - }, - }, - } -} - -func (apiConnFedTest) GetNodeByName(name string) (api.Node, error) { - if name != "test.node.foo.bar" { - return api.Node{}, nil - } - return api.Node{ - ObjectMeta: api.ObjectMeta{ - Name: "test.node.foo.bar", - Labels: map[string]string{ - labelRegion: "fd-r", - labelAvailabilityZone: "fd-az", - }, - }, - }, nil -} - -func testFederationCNAMERecord(t *testing.T, k Kubernetes, input recordRequest, expected msg.Service) { - svc := k.federationCNAMERecord(input) - - if expected.Host != svc.Host { - t.Errorf("For '%v', expected Host result '%v'. Instead got result '%v'.", input, expected.Host, svc.Host) - } - if expected.Key != svc.Key { - t.Errorf("For '%v', expected Key result '%v'. Instead got result '%v'.", input, expected.Key, svc.Key) - } -} - -func TestFederationCNAMERecord(t *testing.T) { - k := Kubernetes{Zones: []string{"inter.webs."}} - k.Federations = []Federation{{name: "fed", zone: "era.tion.com"}} - k.APIConn = apiConnFedTest{} - k.interfaceAddrsFunc = func() net.IP { return net.ParseIP("10.9.8.7") } - - m := new(dns.Msg) - state := request.Request{Zone: "inter.webs.", Req: m} - - m.SetQuestion("s1.ns.fed.svc.inter.webs.", dns.TypeA) - r, _ := k.parseRequest(state) - testFederationCNAMERecord(t, k, r, msg.Service{Key: "/coredns/webs/inter/svc/fed/ns/s1", Host: "s1.ns.fed.svc.fd-az.fd-r.era.tion.com"}) - - m.SetQuestion("ep1.s1.ns.fed.svc.inter.webs.", dns.TypeA) - r, _ = k.parseRequest(state) - testFederationCNAMERecord(t, k, r, msg.Service{Key: "/coredns/webs/inter/svc/fed/ns/s1/ep1", Host: "ep1.s1.ns.fed.svc.fd-az.fd-r.era.tion.com"}) - - m.SetQuestion("ep1.s1.ns.foo.svc.inter.webs.", dns.TypeA) - r, _ = k.parseRequest(state) - testFederationCNAMERecord(t, k, r, msg.Service{Key: "", Host: ""}) -} diff --git a/middleware/kubernetes/handler.go b/middleware/kubernetes/handler.go index 9e63ef387..1e41e9ebf 100644 --- a/middleware/kubernetes/handler.go +++ b/middleware/kubernetes/handler.go @@ -25,18 +25,10 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M // otherwise delegate to the next in the pipeline. zone := middleware.Zones(k.Zones).Matches(state.Name()) if zone == "" { - if state.QType() != dns.TypePTR { + if k.Fallthrough { return middleware.NextOrFailure(k.Name(), k.Next, ctx, w, r) } - // If this is a PTR request, and the request is in a defined - // pod/service cidr range, process the request in this middleware, - // otherwise pass to next middleware. - if !k.isRequestInReverseRange(state.Name()) { - return middleware.NextOrFailure(k.Name(), k.Next, ctx, w, r) - } - - // Set the zone to this specific request, as we want to handle this reverse request. - zone = state.Name() + return dns.RcodeServerFailure, nil } state.Zone = zone diff --git a/middleware/kubernetes/handler_test.go b/middleware/kubernetes/handler_test.go index f27caaa99..a68401250 100644 --- a/middleware/kubernetes/handler_test.go +++ b/middleware/kubernetes/handler_test.go @@ -59,28 +59,6 @@ var dnsTestCases = map[string](*test.Case){ test.CNAME("external.testns.svc.cluster.local. 0 IN CNAME ext.interwebs.test."), }, }, - "A Service (Local Federated)": { - Qname: "svc1.testns.fed.svc.cluster.local.", Qtype: dns.TypeA, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.A("svc1.testns.fed.svc.cluster.local. 0 IN A 10.0.0.1"), - }, - }, - "PTR Service": { - Qname: "1.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("1.0.0.10.in-addr.arpa. 0 IN PTR svc1.testns.svc.cluster.local."), - }, - }, - // TODO A Service (Remote Federated) - "CNAME Service (Remote Federated)": { - Qname: "svc0.testns.fed.svc.cluster.local.", Qtype: dns.TypeCNAME, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.CNAME("svc0.testns.fed.svc.cluster.local. 0 IN CNAME svc0.testns.fed.svc.fd-az.fd-r.federal.test."), - }, - }, "AAAA Service (existing service)": { Qname: "svc1.testns.svc.cluster.local.", Qtype: dns.TypeAAAA, Rcode: dns.RcodeSuccess, @@ -174,7 +152,6 @@ func TestServeDNS(t *testing.T) { _, cidr, _ := net.ParseCIDR("10.0.0.0/8") k.ReverseCidrs = []net.IPNet{*cidr} - k.Federations = []Federation{{name: "fed", zone: "federal.test."}} k.APIConn = &APIConnServeTest{} k.interfaceAddrsFunc = localPodIP k.Next = test.NextHandler(dns.RcodeSuccess, nil) @@ -405,10 +382,6 @@ func (APIConnServeTest) GetNodeByName(name string) (api.Node, error) { return api.Node{ ObjectMeta: api.ObjectMeta{ Name: "test.node.foo.bar", - Labels: map[string]string{ - labelRegion: "fd-r", - labelAvailabilityZone: "fd-az", - }, }, }, nil } diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go index c2e7d8faa..fef8ee0b7 100644 --- a/middleware/kubernetes/kubernetes.go +++ b/middleware/kubernetes/kubernetes.go @@ -41,7 +41,6 @@ type Kubernetes struct { APIConn dnsController ResyncPeriod time.Duration Namespaces []string - Federations []Federation LabelSelector *unversionedapi.LabelSelector Selector *labels.Selector PodMode string @@ -309,13 +308,6 @@ func (k *Kubernetes) Entries(r recordRequest) ([]msg.Service, error) { return nil, err } if len(services) == 0 && len(pods) == 0 { - // Did not find item in k8s, try federated - if r.federation != "" { - fedCNAME := k.federationCNAMERecord(r) - if fedCNAME.Key != "" { - return []msg.Service{fedCNAME}, nil - } - } return nil, errNoItems } @@ -344,15 +336,9 @@ func (k *Kubernetes) getRecordsForK8sItems(services []kService, pods []kPod, r r if svc.addr == api.ClusterIPNone || len(svc.endpoints) > 0 { // This is a headless service or endpoints are present, create records for each endpoint for _, ep := range svc.endpoints { - s := msg.Service{ - Host: ep.addr.IP, - Port: int(ep.port.Port), - } - if r.federation != "" { - s.Key = strings.Join([]string{zonePath, Svc, r.federation, svc.namespace, svc.name, endpointHostname(ep.addr)}, "/") - } else { - s.Key = strings.Join([]string{zonePath, Svc, svc.namespace, svc.name, endpointHostname(ep.addr)}, "/") - } + s := msg.Service{Host: ep.addr.IP, Port: int(ep.port.Port)} + s.Key = strings.Join([]string{zonePath, Svc, svc.namespace, svc.name, endpointHostname(ep.addr)}, "/") + records = append(records, s) } continue @@ -360,37 +346,22 @@ func (k *Kubernetes) getRecordsForK8sItems(services []kService, pods []kPod, r r // Create records for each exposed port... for _, p := range svc.ports { - s := msg.Service{ - Host: svc.addr, - Port: int(p.Port)} - - if r.federation != "" { - s.Key = strings.Join([]string{zonePath, Svc, r.federation, svc.namespace, svc.name}, "/") - } else { - s.Key = strings.Join([]string{zonePath, Svc, svc.namespace, svc.name}, "/") - } + s := msg.Service{Host: svc.addr, Port: int(p.Port)} + s.Key = strings.Join([]string{zonePath, Svc, svc.namespace, svc.name}, "/") records = append(records, s) } // If the addr is not an IP (i.e. an external service), add the record ... - s := msg.Service{ - Key: strings.Join([]string{zonePath, Svc, svc.namespace, svc.name}, "/"), - Host: svc.addr} + s := msg.Service{Key: strings.Join([]string{zonePath, Svc, svc.namespace, svc.name}, "/"), Host: svc.addr} if t, _ := s.HostType(); t == dns.TypeCNAME { - if r.federation != "" { - s.Key = strings.Join([]string{zonePath, Svc, r.federation, svc.namespace, svc.name}, "/") - } else { - s.Key = strings.Join([]string{zonePath, Svc, svc.namespace, svc.name}, "/") - } + s.Key = strings.Join([]string{zonePath, Svc, svc.namespace, svc.name}, "/") + records = append(records, s) } } for _, p := range pods { - s := msg.Service{ - Key: strings.Join([]string{zonePath, Pod, p.namespace, p.name}, "/"), - Host: p.addr, - } + s := msg.Service{Key: strings.Join([]string{zonePath, Pod, p.namespace, p.name}, "/"), Host: p.addr} records = append(records, s) } diff --git a/middleware/kubernetes/kubernetes_test.go b/middleware/kubernetes/kubernetes_test.go index d9a731aef..7af7d10ec 100644 --- a/middleware/kubernetes/kubernetes_test.go +++ b/middleware/kubernetes/kubernetes_test.go @@ -189,10 +189,6 @@ func (APIConnServiceTest) GetNodeByName(name string) (api.Node, error) { return api.Node{ ObjectMeta: api.ObjectMeta{ Name: "test.node.foo.bar", - Labels: map[string]string{ - labelRegion: "fd-r", - labelAvailabilityZone: "fd-az", - }, }, }, nil } @@ -200,7 +196,6 @@ func (APIConnServiceTest) GetNodeByName(name string) (api.Node, error) { func TestServices(t *testing.T) { k := Kubernetes{Zones: []string{"interwebs.test."}} - k.Federations = []Federation{{name: "fed", zone: "era.tion.com"}} k.interfaceAddrsFunc = localPodIP k.APIConn = &APIConnServiceTest{} @@ -221,10 +216,6 @@ func TestServices(t *testing.T) { // External Services {qname: "external.testns.svc.interwebs.test.", qtype: dns.TypeCNAME, answer: svcAns{host: "coredns.io", key: "/coredns/test/interwebs/svc/testns/external"}}, - - // Federated Services - {qname: "svc1.testns.fed.svc.interwebs.test.", qtype: dns.TypeA, answer: svcAns{host: "10.0.0.1", key: "/coredns/test/interwebs/svc/fed/testns/svc1"}}, - {qname: "svc0.testns.fed.svc.interwebs.test.", qtype: dns.TypeA, answer: svcAns{host: "svc0.testns.fed.svc.fd-az.fd-r.era.tion.com", key: "/coredns/test/interwebs/svc/fed/testns/svc0"}}, } for _, test := range tests { diff --git a/middleware/kubernetes/parse.go b/middleware/kubernetes/parse.go index 1ab8fd1c6..c582f904e 100644 --- a/middleware/kubernetes/parse.go +++ b/middleware/kubernetes/parse.go @@ -19,14 +19,13 @@ type recordRequest struct { namespace string // A each name can be for a pod or a service, here we track what we've seen. This value is true for // pods and false for services. If we ever need to extend this well use a typed value. - podOrSvc string - zone string - federation string + podOrSvc string + zone string } // parseRequest parses the qname to find all the elements we need for querying k8s. func (k *Kubernetes) parseRequest(state request.Request) (r recordRequest, err error) { - // 3 Possible cases + // 3 Possible cases: TODO(chris): remove federations comments here. // SRV Request: _port._protocol.service.namespace.[federation.]type.zone // A Request (endpoint): endpoint.service.namespace.[federation.]type.zone // A Request (service): service.namespace.[federation.]type.zone @@ -35,7 +34,6 @@ func (k *Kubernetes) parseRequest(state request.Request) (r recordRequest, err e segs := dns.SplitDomainName(base) r.zone = state.Zone - r.federation, segs = k.stripFederation(segs) if state.QType() == dns.TypeNS { return r, nil @@ -112,6 +110,5 @@ func (r recordRequest) String() string { s += "." + r.namespace s += "." + r.podOrSvc s += "." + r.zone - s += "." + r.federation return s } diff --git a/middleware/kubernetes/parse_test.go b/middleware/kubernetes/parse_test.go index 010b9e542..951a47554 100644 --- a/middleware/kubernetes/parse_test.go +++ b/middleware/kubernetes/parse_test.go @@ -18,21 +18,21 @@ func TestParseRequest(t *testing.T) { { // valid SRV request "_http._tcp.webs.mynamespace.svc.inter.webs.test.", dns.TypeSRV, - "http.tcp..webs.mynamespace.svc.intern.webs.tests..", + "http.tcp..webs.mynamespace.svc.intern.webs.tests.", }, { // wildcard acceptance "*.any.*.any.svc.inter.webs.test.", dns.TypeSRV, - "*.any..*.any.svc.intern.webs.tests..", + "*.any..*.any.svc.intern.webs.tests.", }, { // A request of endpoint "1-2-3-4.webs.mynamespace.svc.inter.webs.test.", dns.TypeA, - "..1-2-3-4.webs.mynamespace.svc.intern.webs.tests..", + "..1-2-3-4.webs.mynamespace.svc.intern.webs.tests.", }, { "inter.webs.test.", dns.TypeNS, - "......intern.webs.tests..", + "......intern.webs.tests.", }, } for i, tc := range tests { diff --git a/middleware/kubernetes/reverse.go b/middleware/kubernetes/reverse.go index 3edb026f8..b7392343d 100644 --- a/middleware/kubernetes/reverse.go +++ b/middleware/kubernetes/reverse.go @@ -1,8 +1,6 @@ package kubernetes import ( - "net" - "github.com/coredns/coredns/middleware" "github.com/coredns/coredns/middleware/etcd/msg" "github.com/coredns/coredns/middleware/pkg/dnsutil" @@ -20,13 +18,3 @@ func (k *Kubernetes) Reverse(state request.Request, exact bool, opt middleware.O records := k.getServiceRecordForIP(ip, state.Name()) return records, nil, nil } - -func (k *Kubernetes) isRequestInReverseRange(name string) bool { - ip := dnsutil.ExtractAddressFromReverse(name) - for _, c := range k.ReverseCidrs { - if c.Contains(net.ParseIP(ip)) { - return true - } - } - return false -} diff --git a/middleware/kubernetes/reverse_test.go b/middleware/kubernetes/reverse_test.go deleted file mode 100644 index 75bc7da72..000000000 --- a/middleware/kubernetes/reverse_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package kubernetes - -import ( - "net" - "testing" -) - -func TestIsRequestInReverseRange(t *testing.T) { - - tests := []struct { - cidr string - name string - expected bool - }{ - {"1.2.3.0/24", "4.3.2.1.in-addr.arpa.", true}, - {"1.2.3.0/24", "5.3.2.1.in-addr.arpa.", true}, - {"5.6.0.0/16", "5.4.6.5.in-addr.arpa.", true}, - {"1.2.3.0/24", "5.4.2.1.in-addr.arpa.", false}, - {"5.6.0.0/16", "5.4.2.1.in-addr.arpa.", false}, - {"5.6.0.0/16", "5.6.0.1.in-addr.arpa.", false}, - } - - k := Kubernetes{} - - for _, test := range tests { - _, cidr, _ := net.ParseCIDR(test.cidr) - k.ReverseCidrs = []net.IPNet{*cidr} - result := k.isRequestInReverseRange(test.name) - if result != test.expected { - t.Errorf("Expected '%v' for '%v' in %v.", test.expected, test.name, test.cidr) - } - } -} diff --git a/middleware/kubernetes/setup.go b/middleware/kubernetes/setup.go index 071db851a..2e531e859 100644 --- a/middleware/kubernetes/setup.go +++ b/middleware/kubernetes/setup.go @@ -3,8 +3,6 @@ package kubernetes import ( "errors" "fmt" - "log" - "net" "strings" "time" @@ -74,141 +72,113 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, error) { k8s.autoPathSearch = searchFromResolvConf() for c.Next() { - if c.Val() == "kubernetes" { - zones := c.RemainingArgs() + zones := c.RemainingArgs() - if len(zones) != 0 { - k8s.Zones = zones - middleware.Zones(k8s.Zones).Normalize() - } else { - k8s.Zones = make([]string, len(c.ServerBlockKeys)) - for i := 0; i < len(c.ServerBlockKeys); i++ { - k8s.Zones[i] = middleware.Host(c.ServerBlockKeys[i]).Normalize() - } + if len(zones) != 0 { + k8s.Zones = zones + middleware.Zones(k8s.Zones).Normalize() + } else { + k8s.Zones = make([]string, len(c.ServerBlockKeys)) + for i := 0; i < len(c.ServerBlockKeys); i++ { + k8s.Zones[i] = middleware.Host(c.ServerBlockKeys[i]).Normalize() } + } - k8s.primaryZoneIndex = -1 - for i, z := range k8s.Zones { - if strings.HasSuffix(z, "in-addr.arpa.") || strings.HasSuffix(z, "ip6.arpa.") { + k8s.primaryZoneIndex = -1 + for i, z := range k8s.Zones { + if strings.HasSuffix(z, "in-addr.arpa.") || strings.HasSuffix(z, "ip6.arpa.") { + continue + } + k8s.primaryZoneIndex = i + break + } + + if k8s.primaryZoneIndex == -1 { + return nil, errors.New("non-reverse zone name must be used") + } + + for c.NextBlock() { + switch c.Val() { + case "pods": + args := c.RemainingArgs() + if len(args) == 1 { + switch args[0] { + case PodModeDisabled, PodModeInsecure, PodModeVerified: + k8s.PodMode = args[0] + default: + return nil, fmt.Errorf("wrong value for pods: %s, must be one of: disabled, verified, insecure", args[0]) + } continue } - k8s.primaryZoneIndex = i - break - } - - if k8s.primaryZoneIndex == -1 { - return nil, errors.New("non-reverse zone name must be given for Kubernetes") - } - - for c.NextBlock() { - switch c.Val() { - case "cidrs": - - // DEPRECATION WARNING - log.Printf("[WARNING] \"cidrs\" will be removed for CoreDNS soon. See https://coredns.io/2017/07/23/corefile-explained#reverse-zones for the replacement") - - args := c.RemainingArgs() - if len(args) > 0 { - for _, cidrStr := range args { - _, cidr, err := net.ParseCIDR(cidrStr) - if err != nil { - return nil, fmt.Errorf("invalid cidr: %s", cidrStr) - } - k8s.ReverseCidrs = append(k8s.ReverseCidrs, *cidr) - - } - continue - } - return nil, c.ArgErr() - case "pods": - args := c.RemainingArgs() - if len(args) == 1 { - switch args[0] { - case PodModeDisabled, PodModeInsecure, PodModeVerified: - k8s.PodMode = args[0] - default: - return nil, fmt.Errorf("wrong value for pods: %s, must be one of: disabled, verified, insecure", args[0]) - } - continue - } - return nil, c.ArgErr() - case "namespaces": - args := c.RemainingArgs() - if len(args) > 0 { - k8s.Namespaces = append(k8s.Namespaces, args...) - continue - } - return nil, c.ArgErr() - case "endpoint": - args := c.RemainingArgs() - if len(args) > 0 { - for _, endpoint := range strings.Split(args[0], ",") { - k8s.APIServerList = append(k8s.APIServerList, strings.TrimSpace(endpoint)) - } - continue - } - return nil, c.ArgErr() - case "tls": // cert key cacertfile - args := c.RemainingArgs() - if len(args) == 3 { - k8s.APIClientCert, k8s.APIClientKey, k8s.APICertAuth = args[0], args[1], args[2] - continue - } - return nil, c.ArgErr() - case "resyncperiod": - args := c.RemainingArgs() - if len(args) > 0 { - rp, err := time.ParseDuration(args[0]) - if err != nil { - return nil, fmt.Errorf("unable to parse resync duration value: '%v': %v", args[0], err) - } - k8s.ResyncPeriod = rp - continue - } - return nil, c.ArgErr() - case "labels": - args := c.RemainingArgs() - if len(args) > 0 { - labelSelectorString := strings.Join(args, " ") - ls, err := unversionedapi.ParseToLabelSelector(labelSelectorString) - if err != nil { - return nil, fmt.Errorf("unable to parse label selector value: '%v': %v", labelSelectorString, err) - } - k8s.LabelSelector = ls - continue - } - return nil, c.ArgErr() - case "fallthrough": - args := c.RemainingArgs() - if len(args) == 0 { - k8s.Fallthrough = true - continue - } - return nil, c.ArgErr() - case "upstream": - args := c.RemainingArgs() - if len(args) == 0 { - return nil, c.ArgErr() - } - ups, err := dnsutil.ParseHostPortOrFile(args...) - if err != nil { - return nil, err - } - k8s.Proxy = proxy.NewLookup(ups) - case "federation": // name zone - args := c.RemainingArgs() - if len(args) == 2 { - k8s.Federations = append(k8s.Federations, Federation{ - name: args[0], - zone: args[1], - }) - continue - } - return nil, fmt.Errorf("incorrect number of arguments for federation, got %v, expected 2", len(args)) + return nil, c.ArgErr() + case "namespaces": + args := c.RemainingArgs() + if len(args) > 0 { + k8s.Namespaces = append(k8s.Namespaces, args...) + continue } + return nil, c.ArgErr() + case "endpoint": + args := c.RemainingArgs() + if len(args) > 0 { + for _, endpoint := range strings.Split(args[0], ",") { + k8s.APIServerList = append(k8s.APIServerList, strings.TrimSpace(endpoint)) + } + continue + } + return nil, c.ArgErr() + case "tls": // cert key cacertfile + args := c.RemainingArgs() + if len(args) == 3 { + k8s.APIClientCert, k8s.APIClientKey, k8s.APICertAuth = args[0], args[1], args[2] + continue + } + return nil, c.ArgErr() + case "resyncperiod": + args := c.RemainingArgs() + if len(args) > 0 { + rp, err := time.ParseDuration(args[0]) + if err != nil { + return nil, fmt.Errorf("unable to parse resync duration value: '%v': %v", args[0], err) + } + k8s.ResyncPeriod = rp + continue + } + return nil, c.ArgErr() + case "labels": + args := c.RemainingArgs() + if len(args) > 0 { + labelSelectorString := strings.Join(args, " ") + ls, err := unversionedapi.ParseToLabelSelector(labelSelectorString) + if err != nil { + return nil, fmt.Errorf("unable to parse label selector value: '%v': %v", labelSelectorString, err) + } + k8s.LabelSelector = ls + continue + } + return nil, c.ArgErr() + case "fallthrough": + args := c.RemainingArgs() + if len(args) == 0 { + k8s.Fallthrough = true + continue + } + return nil, c.ArgErr() + case "upstream": + args := c.RemainingArgs() + if len(args) == 0 { + return nil, c.ArgErr() + } + ups, err := dnsutil.ParseHostPortOrFile(args...) + if err != nil { + return nil, err + } + k8s.Proxy = proxy.NewLookup(ups) + default: + return nil, c.Errf("unknown property '%s'", c.Val()) } - return k8s, nil } + return k8s, nil } return nil, errors.New("kubernetes setup called without keyword 'kubernetes' in Corefile") } diff --git a/middleware/kubernetes/setup_test.go b/middleware/kubernetes/setup_test.go index 20a276a4c..09a617e42 100644 --- a/middleware/kubernetes/setup_test.go +++ b/middleware/kubernetes/setup_test.go @@ -1,20 +1,14 @@ package kubernetes import ( - "net" "strings" "testing" "time" "github.com/mholt/caddy" - unversionedapi "k8s.io/client-go/1.5/pkg/api/unversioned" + "k8s.io/client-go/1.5/pkg/api/unversioned" ) -func parseCidr(cidr string) net.IPNet { - _, ipnet, _ := net.ParseCIDR(cidr) - return *ipnet -} - func TestKubernetesParse(t *testing.T) { tests := []struct { input string // Corefile data as string @@ -25,7 +19,6 @@ func TestKubernetesParse(t *testing.T) { expectedResyncPeriod time.Duration // expected resync period value expectedLabelSelector string // expected label selector value expectedPodMode string - expectedCidrs []net.IPNet expectedFallthrough bool expectedUpstreams []string }{ @@ -39,7 +32,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -52,7 +44,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -66,7 +57,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -81,7 +71,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -96,7 +85,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -111,7 +99,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -126,7 +113,6 @@ func TestKubernetesParse(t *testing.T) { 30 * time.Second, "", PodModeDisabled, - nil, false, nil, }, @@ -141,7 +127,6 @@ func TestKubernetesParse(t *testing.T) { 15 * time.Minute, "", PodModeDisabled, - nil, false, nil, }, @@ -156,7 +141,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "environment=prod", PodModeDisabled, - nil, false, nil, }, @@ -171,7 +155,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "application=nginx,environment in (production,qa,staging)", PodModeDisabled, - nil, false, nil, }, @@ -190,7 +173,6 @@ func TestKubernetesParse(t *testing.T) { 15 * time.Minute, "application=nginx,environment in (production,qa,staging)", PodModeDisabled, - nil, true, nil, }, @@ -204,7 +186,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -219,7 +200,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -234,7 +214,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -249,7 +228,6 @@ func TestKubernetesParse(t *testing.T) { 0 * time.Minute, "", PodModeDisabled, - nil, false, nil, }, @@ -264,7 +242,6 @@ func TestKubernetesParse(t *testing.T) { 0 * time.Second, "", PodModeDisabled, - nil, false, nil, }, @@ -279,7 +256,6 @@ func TestKubernetesParse(t *testing.T) { 0 * time.Second, "", PodModeDisabled, - nil, false, nil, }, @@ -294,7 +270,6 @@ func TestKubernetesParse(t *testing.T) { 0 * time.Second, "", PodModeDisabled, - nil, false, nil, }, @@ -309,7 +284,6 @@ func TestKubernetesParse(t *testing.T) { 0 * time.Second, "", PodModeDisabled, - nil, false, nil, }, @@ -325,7 +299,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -341,7 +314,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeInsecure, - nil, false, nil, }, @@ -357,7 +329,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeVerified, - nil, false, nil, }, @@ -373,39 +344,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeVerified, - nil, - false, - nil, - }, - // cidrs ok - { - `kubernetes coredns.local { - cidrs 10.0.0.0/24 10.0.1.0/24 -}`, - false, - "", - 1, - 0, - defaultResyncPeriod, - "", - PodModeDisabled, - []net.IPNet{parseCidr("10.0.0.0/24"), parseCidr("10.0.1.0/24")}, - false, - nil, - }, - // cidrs ok - { - `kubernetes coredns.local { - cidrs hard dry -}`, - true, - "invalid cidr: hard", - -1, - 0, - defaultResyncPeriod, - "", - PodModeDisabled, - nil, false, nil, }, @@ -421,7 +359,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -437,7 +374,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, []string{"13.14.15.16:53"}, }, @@ -453,7 +389,6 @@ func TestKubernetesParse(t *testing.T) { defaultResyncPeriod, "", PodModeDisabled, - nil, false, nil, }, @@ -508,7 +443,7 @@ func TestKubernetesParse(t *testing.T) { // Labels if k8sController.LabelSelector != nil { - foundLabelSelectorString := unversionedapi.FormatLabelSelector(k8sController.LabelSelector) + foundLabelSelectorString := unversioned.FormatLabelSelector(k8sController.LabelSelector) if foundLabelSelectorString != test.expectedLabelSelector { t.Errorf("Test %d: Expected kubernetes controller to be initialized with label selector '%s'. Instead found selector '%s' for input '%s'", i, test.expectedLabelSelector, foundLabelSelectorString, test.input) } @@ -519,16 +454,6 @@ func TestKubernetesParse(t *testing.T) { t.Errorf("Test %d: Expected kubernetes controller to be initialized with pod mode '%s'. Instead found pod mode '%s' for input '%s'", i, test.expectedPodMode, foundPodMode, test.input) } - // Cidrs - foundCidrs := k8sController.ReverseCidrs - if len(foundCidrs) != len(test.expectedCidrs) { - t.Errorf("Test %d: Expected kubernetes controller to be initialized with %d cidrs. Instead found %d cidrs for input '%s'", i, len(test.expectedCidrs), len(foundCidrs), test.input) - } - for j, cidr := range test.expectedCidrs { - if cidr.String() != foundCidrs[j].String() { - t.Errorf("Test %d: Expected kubernetes controller to be initialized with cidr '%s'. Instead found cidr '%s' for input '%s'", i, test.expectedCidrs[j].String(), foundCidrs[j].String(), test.input) - } - } // fallthrough foundFallthrough := k8sController.Fallthrough if foundFallthrough != test.expectedFallthrough { @@ -558,70 +483,3 @@ func TestKubernetesParse(t *testing.T) { } } } - -func TestKubernetesParseFederation(t *testing.T) { - tests := []struct { - input string // Corefile data as string - shouldErr bool // true if test case is exected to produce an error. - expectedErrContent string // substring from the expected error. Empty for positive cases. - expectedFederations []Federation - }{ - // Valid federations - { - `kubernetes coredns.local { - federation foo bar.crawl.com - federation fed era.tion.com -}`, - false, - "", - []Federation{ - {name: "foo", zone: "bar.crawl.com"}, - {name: "fed", zone: "era.tion.com"}, - }, - }, - // Invalid federations - { - `kubernetes coredns.local { - federation starship -}`, - true, - `incorrect number of arguments for federation`, - []Federation{}, - }, - } - - for i, test := range tests { - c := caddy.NewTestController("dns", test.input) - k8sController, err := kubernetesParse(c) - - if test.shouldErr && err == nil { - t.Errorf("Test %d: Expected error, but did not find error for input '%s'. Error was: '%v'", i, test.input, err) - } - - if err != nil { - if !test.shouldErr { - t.Errorf("Test %d: Expected no error but found one for input %s. Error was: %v", i, test.input, err) - continue - } - - if test.shouldErr && (len(test.expectedErrContent) < 1) { - t.Fatalf("Test %d: Test marked as expecting an error, but no expectedErrContent provided for input '%s'. Error was: '%v'", i, test.input, err) - } - - if !strings.Contains(err.Error(), test.expectedErrContent) { - t.Errorf("Test %d: Expected error to contain: %v, found error: %v, input: %s", i, test.expectedErrContent, err, test.input) - } - continue - } - - foundFed := k8sController.Federations - if len(foundFed) != len(test.expectedFederations) { - t.Errorf("Test %d: Expected kubernetes controller to be initialized with %d fedrations. Instead found %d fedrations for input '%s'", i, len(test.expectedFederations), len(foundFed), test.input) - } - for j, fed := range test.expectedFederations { - if fed != foundFed[j] { - t.Errorf("Test %d: Expected kubernetes controller to be initialized with federation '%s'. Instead found federation '%s' for input '%s'", i, test.expectedFederations[j], foundFed[j], test.input) - } - } - } -} diff --git a/middleware/metrics/setup.go b/middleware/metrics/setup.go index b6b8e5291..af2b3e815 100644 --- a/middleware/metrics/setup.go +++ b/middleware/metrics/setup.go @@ -89,7 +89,7 @@ func prometheusParse(c *caddy.Controller) (*Metrics, error) { return met, e } default: - return met, c.Errf("unknown item: %s", c.Val()) + return met, c.Errf("unknown property: %s", c.Val()) } } diff --git a/middleware/pkg/healthcheck/policy_test.go b/middleware/pkg/healthcheck/policy_test.go index 16cae7266..4c667952c 100644 --- a/middleware/pkg/healthcheck/policy_test.go +++ b/middleware/pkg/healthcheck/policy_test.go @@ -53,7 +53,9 @@ func TestRegisterPolicy(t *testing.T) { } -func TestHealthCheck(t *testing.T) { +// TODO(miek): Disabled for now, we should get out of the habit of using +// realtime in these tests . +func testHealthCheck(t *testing.T) { log.SetOutput(ioutil.Discard) u := &HealthCheck{ diff --git a/middleware/secondary/setup.go b/middleware/secondary/setup.go index e6bc3858a..adba86f98 100644 --- a/middleware/secondary/setup.go +++ b/middleware/secondary/setup.go @@ -88,6 +88,8 @@ func secondaryParse(c *caddy.Controller) (file.Zones, error) { return file.Zones{}, err } prxy = proxy.NewLookup(ups) + default: + return file.Zones{}, c.Errf("unknown property '%s'", c.Val()) } for _, origin := range origins { diff --git a/test/etcd_test.go b/test/etcd_test.go index 8808f5583..f8a699661 100644 --- a/test/etcd_test.go +++ b/test/etcd_test.go @@ -42,6 +42,7 @@ func TestEtcdStubAndProxyLookup(t *testing.T) { path /skydns endpoint http://localhost:2379 upstream 8.8.8.8:53 8.8.4.4:53 + fallthrough } proxy . 8.8.8.8:53 }` diff --git a/test/kubernetes_test.go b/test/kubernetes_test.go index d99ca1618..f9a0b00c4 100644 --- a/test/kubernetes_test.go +++ b/test/kubernetes_test.go @@ -3,6 +3,8 @@ package test import ( + "io/ioutil" + "log" "os" "testing" "time" @@ -13,6 +15,10 @@ import ( "github.com/miekg/dns" ) +func init() { + log.SetOutput(ioutil.Discard) +} + // Test data // TODO: Fix the actual RR values @@ -218,25 +224,6 @@ var dnsTestCases = []test.Case{ Rcode: dns.RcodeServerFailure, Answer: []dns.RR{}, }, - { - Qname: "123.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{}, - }, - { - Qname: "100.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("100.0.0.10.in-addr.arpa. 303 IN PTR svc-1-a.test-1.svc.cluster.local."), - }, - }, - { - Qname: "115.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("115.0.0.10.in-addr.arpa. 303 IN PTR svc-c.test-1.svc.cluster.local."), - }, - }, { Qname: "dns-version.cluster.local.", Qtype: dns.TypeTXT, Rcode: dns.RcodeSuccess, @@ -244,13 +231,6 @@ var dnsTestCases = []test.Case{ test.TXT("dns-version.cluster.local. 28800 IN TXT \"1.0.0\""), }, }, - { - Qname: "next-in-chain.", Qtype: dns.TypeA, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.A("next-in-chain. 0 IN A 192.0.2.53"), - }, - }, { Qname: "cluster.local.", Qtype: dns.TypeNS, Rcode: dns.RcodeSuccess, @@ -303,80 +283,6 @@ var dnsTestCasesPodsVerified = []test.Case{ }, } -var dnsTestCasesCidrReverseZone = []test.Case{ - { - Qname: "123.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{}, - }, - { - Qname: "100.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("100.0.0.10.in-addr.arpa. 303 IN PTR svc-1-a.test-1.svc.cluster.local."), - }, - }, - { - Qname: "110.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("115.0.0.10.in-addr.arpa. 303 IN PTR svc-1-b.test-1.svc.cluster.local."), - }, - }, - { - Qname: "115.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("115.0.0.10.in-addr.arpa. 303 IN PTR svc-c.test-1.svc.cluster.local."), - }, - }, - { - Qname: "next-in-chain.", Qtype: dns.TypeA, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.A("next-in-chain. 0 IN A 192.0.2.53"), - }, - }, -} - -var dnsTestCasesPartialCidrReverseZone = []test.Case{ - { - // In exposed range, record not present = OK + No data - Qname: "99.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{}, - }, - { - // In exposed range, record present = OK + Data - Qname: "100.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("100.0.0.10.in-addr.arpa. 303 IN PTR svc-1-a.test-1.svc.cluster.local."), - }, - }, - { - // In exposed range, record present = OK + Data - Qname: "110.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("115.0.0.10.in-addr.arpa. 303 IN PTR svc-1-b.test-1.svc.cluster.local."), - }, - }, - { - // Out of exposed range, record present = pass to next middleware (not existing in test) = FAIL - Qname: "115.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeServerFailure, - Answer: []dns.RR{}, - }, - { - Qname: "next-in-chain.", Qtype: dns.TypeA, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.A("next-in-chain. 0 IN A 192.0.2.53"), - }, - }, -} - var dnsTestCasesAllNSExposed = []test.Case{ { Qname: "svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeA, @@ -392,25 +298,6 @@ var dnsTestCasesAllNSExposed = []test.Case{ test.A("svc-c.test-1.svc.cluster.local. 303 IN A 10.0.0.120"), }, }, - { - Qname: "123.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{}, - }, - { - Qname: "100.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("100.0.0.10.in-addr.arpa. 303 IN PTR svc-1-a.test-1.svc.cluster.local."), - }, - }, - { - Qname: "120.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR, - Rcode: dns.RcodeSuccess, - Answer: []dns.RR{ - test.PTR("120.0.0.10.in-addr.arpa. 303 IN PTR svc-c.test-2.svc.cluster.local."), - }, - }, } var dnsTestCasesFallthrough = []test.Case{ @@ -558,42 +445,11 @@ func TestKubernetesIntegrationPodsVerified(t *testing.T) { doIntegrationTests(t, corefile, dnsTestCasesPodsVerified) } -func TestKubernetesIntegrationCidrReverseZone(t *testing.T) { - corefile := - `.:0 { - kubernetes cluster.local { - endpoint http://localhost:8080 - namespaces test-1 - cidrs 10.0.0.0/24 - } - erratic . { - drop 0 - } -` - doIntegrationTests(t, corefile, dnsTestCasesCidrReverseZone) -} - -func TestKubernetesIntegrationPartialCidrReverseZone(t *testing.T) { - corefile := - `.:0 { - kubernetes cluster.local { - endpoint http://localhost:8080 - namespaces test-1 - cidrs 10.0.0.96/28 10.0.0.120/32 - } - erratic . { - drop 0 - } -` - doIntegrationTests(t, corefile, dnsTestCasesPartialCidrReverseZone) -} - func TestKubernetesIntegrationAllNSExposed(t *testing.T) { corefile := `.:0 { kubernetes cluster.local { endpoint http://localhost:8080 - cidrs 10.0.0.0/24 } ` doIntegrationTests(t, corefile, dnsTestCasesAllNSExposed) @@ -615,7 +471,6 @@ func TestKubernetesIntegrationFallthrough(t *testing.T) { file ` + dbfile + ` cluster.local kubernetes cluster.local { endpoint http://localhost:8080 - cidrs 10.0.0.0/24 namespaces test-1 upstream ` + udp + ` fallthrough