From 02955d7594c84c5cd320ff0190ecd26425db5217 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sat, 19 Aug 2017 15:22:09 +0100 Subject: [PATCH] Dns.join (#944) * Add dnsutil.Join * Create dnsutil.Join Create Join helper function and move bits in the code over. --- middleware/etcd/msg/path.go | 4 +++- middleware/etcd/stub.go | 4 ++-- middleware/federation/federation.go | 4 +--- middleware/file/dname.go | 4 ++-- middleware/kubernetes/federation.go | 7 +++---- middleware/kubernetes/kubernetes.go | 4 ++-- middleware/pkg/dnsutil/join.go | 19 +++++++++++++++++++ middleware/pkg/dnsutil/join_test.go | 20 ++++++++++++++++++++ 8 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 middleware/pkg/dnsutil/join.go create mode 100644 middleware/pkg/dnsutil/join_test.go diff --git a/middleware/etcd/msg/path.go b/middleware/etcd/msg/path.go index aeb52f665..2184b9fcd 100644 --- a/middleware/etcd/msg/path.go +++ b/middleware/etcd/msg/path.go @@ -4,6 +4,8 @@ import ( "path" "strings" + "github.com/coredns/coredns/middleware/pkg/dnsutil" + "github.com/miekg/dns" ) @@ -24,7 +26,7 @@ func Domain(s string) string { for i, j := 1, len(l)-1; i < j; i, j = i+1, j-1 { l[i], l[j] = l[j], l[i] } - return dns.Fqdn(strings.Join(l[1:len(l)-1], ".")) + return dnsutil.Join(l[1 : len(l)-1]) } // PathWithWildcard ascts as Path, but if a name contains wildcards (* or any), the name will be diff --git a/middleware/etcd/stub.go b/middleware/etcd/stub.go index 52488f53a..b40af6341 100644 --- a/middleware/etcd/stub.go +++ b/middleware/etcd/stub.go @@ -4,10 +4,10 @@ import ( "log" "net" "strconv" - "strings" "time" "github.com/coredns/coredns/middleware/etcd/msg" + "github.com/coredns/coredns/middleware/pkg/dnsutil" "github.com/coredns/coredns/middleware/proxy" "github.com/coredns/coredns/request" @@ -62,7 +62,7 @@ Services: // Chop of left most label, because that is used as the nameserver place holder // and drop the right most labels that belong to zone. // We must *also* chop of dns.stub. which means cutting two more labels. - domain = dns.Fqdn(strings.Join(labels[1:len(labels)-dns.CountLabel(z)-2], ".")) + domain = dnsutil.Join(labels[1 : len(labels)-dns.CountLabel(z)-2]) if domain == z { log.Printf("[WARNING] Skipping nameserver for domain we are authoritative for: %s", domain) continue Services diff --git a/middleware/federation/federation.go b/middleware/federation/federation.go index caf29e630..16c698ef8 100644 --- a/middleware/federation/federation.go +++ b/middleware/federation/federation.go @@ -14,8 +14,6 @@ Federation is only useful in conjunction with the kubernetes middleware, without package federation import ( - "strings" - "github.com/coredns/coredns/middleware" "github.com/coredns/coredns/middleware/etcd/msg" "github.com/coredns/coredns/middleware/pkg/dnsutil" @@ -133,7 +131,7 @@ func (f *Federation) isNameFederation(name, zone string) (string, string) { fed := labels[ll-2] if _, ok := f.f[fed]; ok { - without := strings.Join(labels[:ll-2], ".") + "." + labels[ll-1] + "." + zone + without := dnsutil.Join(labels[:ll-2]) + labels[ll-1] + "." + zone return without, fed } return "", "" diff --git a/middleware/file/dname.go b/middleware/file/dname.go index e4c29c77d..6bbfd9377 100644 --- a/middleware/file/dname.go +++ b/middleware/file/dname.go @@ -1,7 +1,7 @@ package file import ( - "strings" + "github.com/coredns/coredns/middleware/pkg/dnsutil" "github.com/miekg/dns" ) @@ -14,7 +14,7 @@ func substituteDNAME(qname, owner, target string) string { labels := dns.SplitDomainName(qname) labels = append(labels[0:len(labels)-dns.CountLabel(owner)], dns.SplitDomainName(target)...) - return strings.Join(labels, ".") + "." + return dnsutil.Join(labels) } return "" diff --git a/middleware/kubernetes/federation.go b/middleware/kubernetes/federation.go index 90f1cca39..0861f90a4 100644 --- a/middleware/kubernetes/federation.go +++ b/middleware/kubernetes/federation.go @@ -1,9 +1,8 @@ package kubernetes import ( - "strings" - "github.com/coredns/coredns/middleware/etcd/msg" + "github.com/coredns/coredns/middleware/pkg/dnsutil" "github.com/coredns/coredns/request" ) @@ -36,8 +35,8 @@ func (k *Kubernetes) Federations(state request.Request, fname, fzone string) (ms lr := node.Labels[LabelRegion] if r.endpoint == "" { - return msg.Service{Host: strings.Join([]string{r.service, r.namespace, fname, r.podOrSvc, lz, lr, fzone}, ".")}, nil + return msg.Service{Host: dnsutil.Join([]string{r.service, r.namespace, fname, r.podOrSvc, lz, lr, fzone})}, nil } - return msg.Service{Host: strings.Join([]string{r.endpoint, r.service, r.namespace, fname, r.podOrSvc, lz, lr, fzone}, ".")}, nil + return msg.Service{Host: dnsutil.Join([]string{r.endpoint, r.service, r.namespace, fname, r.podOrSvc, lz, lr, fzone})}, nil } diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go index 8673dab30..af92cf79f 100644 --- a/middleware/kubernetes/kubernetes.go +++ b/middleware/kubernetes/kubernetes.go @@ -508,7 +508,7 @@ func (k *Kubernetes) getServiceRecordForIP(ip, name string) []msg.Service { continue } if service.Spec.ClusterIP == ip { - domain := strings.Join([]string{service.Name, service.Namespace, Svc, k.primaryZone()}, ".") + domain := dnsutil.Join([]string{service.Name, service.Namespace, Svc, k.primaryZone()}) return []msg.Service{{Host: domain}} } } @@ -521,7 +521,7 @@ func (k *Kubernetes) getServiceRecordForIP(ip, name string) []msg.Service { for _, eps := range ep.Subsets { for _, addr := range eps.Addresses { if addr.IP == ip { - domain := strings.Join([]string{endpointHostname(addr), ep.ObjectMeta.Name, ep.ObjectMeta.Namespace, Svc, k.primaryZone()}, ".") + domain := dnsutil.Join([]string{endpointHostname(addr), ep.ObjectMeta.Name, ep.ObjectMeta.Namespace, Svc, k.primaryZone()}) return []msg.Service{{Host: domain}} } } diff --git a/middleware/pkg/dnsutil/join.go b/middleware/pkg/dnsutil/join.go new file mode 100644 index 000000000..515bf3dad --- /dev/null +++ b/middleware/pkg/dnsutil/join.go @@ -0,0 +1,19 @@ +package dnsutil + +import ( + "strings" + + "github.com/miekg/dns" +) + +// Join joins labels to form a fully qualified domain name. If the last label is +// the root label it is ignored. Not other syntax checks are performed. +func Join(labels []string) string { + ll := len(labels) + if labels[ll-1] == "." { + s := strings.Join(labels[:ll-1], ".") + return dns.Fqdn(s) + } + s := strings.Join(labels, ".") + return dns.Fqdn(s) +} diff --git a/middleware/pkg/dnsutil/join_test.go b/middleware/pkg/dnsutil/join_test.go new file mode 100644 index 000000000..26eeb5897 --- /dev/null +++ b/middleware/pkg/dnsutil/join_test.go @@ -0,0 +1,20 @@ +package dnsutil + +import "testing" + +func TestJoin(t *testing.T) { + tests := []struct { + in []string + out string + }{ + {[]string{"bla", "bliep", "example", "org"}, "bla.bliep.example.org."}, + {[]string{"example", "."}, "example."}, + {[]string{"."}, "."}, + } + + for i, tc := range tests { + if x := Join(tc.in); x != tc.out { + t.Errorf("Test %d, expected %s, got %s", i, tc.out, x) + } + } +}