From ecc5f2867153c1faad882d63954894ec4027fc09 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Mon, 21 Mar 2016 07:20:22 +0000 Subject: [PATCH] Path stuff copied over and tests added --- middleware/etcd/etcd.go | 26 ++++++++++--------- middleware/etcd/msg/service.go | 42 ------------------------------- middleware/etcd/path.go | 46 ++++++++++++++++++++++++++++++++++ middleware/etcd/path_test.go | 13 ++++++++++ 4 files changed, 73 insertions(+), 54 deletions(-) create mode 100644 middleware/etcd/path.go create mode 100644 middleware/etcd/path_test.go diff --git a/middleware/etcd/etcd.go b/middleware/etcd/etcd.go index 23bc931fe..3cc573e34 100644 --- a/middleware/etcd/etcd.go +++ b/middleware/etcd/etcd.go @@ -15,31 +15,33 @@ import ( type ( Etcd struct { - Next middleware.Handler - Zones []string - client etcdc.KeysAPI - ctx context.Context - inflight *singleflight.Group + Next middleware.Handler + Zones []string + client etcdc.KeysAPI + ctx context.Context + inflight *singleflight.Group + PathPrefix string } ) func NewEtcd(client etcdc.KeysAPI, next middleware.Handler, zones []string) Etcd { return Etcd{ - Next: next, - Zones: zones, - client: client, - ctx: context.Background(), - inflight: &singleflight.Group{}, + Next: next, + Zones: zones, + client: client, + ctx: context.Background(), + inflight: &singleflight.Group{}, + PathPrefix: "skydns", // TODO(miek): configurable } } func (g Etcd) Records(name string, exact bool) ([]msg.Service, error) { - path, star := msg.PathWithWildcard(name) + path, star := g.PathWithWildcard(name) r, err := g.Get(path, true) if err != nil { return nil, err } - segments := strings.Split(msg.Path(name), "/") + segments := strings.Split(g.Path(name), "/") switch { case exact && r.Node.Dir: return nil, nil diff --git a/middleware/etcd/msg/service.go b/middleware/etcd/msg/service.go index 540cc8806..ca3bd428c 100644 --- a/middleware/etcd/msg/service.go +++ b/middleware/etcd/msg/service.go @@ -2,15 +2,11 @@ package msg import ( "net" - "path" "strings" "github.com/miekg/dns" ) -// PathPrefix is the prefix used to store CoreDNS data in etcd. -var PathPrefix string = "skydns" - // This *is* the rdata from a SRV record, but with a twist. // Host (Target in SRV) must be a domain name, but if it looks like an IP // address (4/6), we will treat it like an IP address. @@ -85,44 +81,6 @@ func (s *Service) NewPTR(name string, ttl uint32) *dns.PTR { return &dns.PTR{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: ttl}, Ptr: dns.Fqdn(s.Host)} } -// As Path, but if a name contains wildcards (* or any), the name will be -// chopped of before the (first) wildcard, and we do a highler evel search and -// later find the matching names. So service.*.skydns.local, will look for all -// services under skydns.local and will later check for names that match -// service.*.skydns.local. If a wildcard is found the returned bool is true. -func PathWithWildcard(s string) (string, bool) { - l := dns.SplitDomainName(s) - for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 { - l[i], l[j] = l[j], l[i] - } - for i, k := range l { - if k == "*" || k == "any" { - return path.Join(append([]string{"/" + PathPrefix + "/"}, l[:i]...)...), true - } - } - return path.Join(append([]string{"/" + PathPrefix + "/"}, l...)...), false -} - -// Path converts a domainname to an etcd path. If s looks like service.staging.skydns.local., -// the resulting key will be /skydns/local/skydns/staging/service . -func Path(s string) string { - l := dns.SplitDomainName(s) - for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 { - l[i], l[j] = l[j], l[i] - } - return path.Join(append([]string{"/" + PathPrefix + "/"}, l...)...) -} - -// Domain is the opposite of Path. -func Domain(s string) string { - l := strings.Split(s, "/") - // start with 1, to strip /skydns - 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], ".")) -} - // Group checks the services in sx, it looks for a Group attribute on the shortest // keys. If there are multiple shortest keys *and* the group attribute disagrees (and // is not empty), we don't consider it a group. diff --git a/middleware/etcd/path.go b/middleware/etcd/path.go new file mode 100644 index 000000000..2cd87ac86 --- /dev/null +++ b/middleware/etcd/path.go @@ -0,0 +1,46 @@ +package etcd + +import ( + "path" + "strings" + + "github.com/miekg/dns" +) + +// Path converts a domainname to an etcd path. If s looks like service.staging.skydns.local., +// the resulting key will be /skydns/local/skydns/staging/service . +func (e Etcd) Path(s string) string { + l := dns.SplitDomainName(s) + for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 { + l[i], l[j] = l[j], l[i] + } + return path.Join(append([]string{"/" + e.PathPrefix + "/"}, l...)...) +} + +// Domain is the opposite of Path. +func (e Etcd) Domain(s string) string { + l := strings.Split(s, "/") + // start with 1, to strip /skydns + 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], ".")) +} + +// As Path, but if a name contains wildcards (* or any), the name will be +// chopped of before the (first) wildcard, and we do a highler evel search and +// later find the matching names. So service.*.skydns.local, will look for all +// services under skydns.local and will later check for names that match +// service.*.skydns.local. If a wildcard is found the returned bool is true. +func (e Etcd) PathWithWildcard(s string) (string, bool) { + l := dns.SplitDomainName(s) + for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 { + l[i], l[j] = l[j], l[i] + } + for i, k := range l { + if k == "*" || k == "any" { + return path.Join(append([]string{"/" + e.PathPrefix + "/"}, l[:i]...)...), true + } + } + return path.Join(append([]string{"/" + e.PathPrefix + "/"}, l...)...), false +} diff --git a/middleware/etcd/path_test.go b/middleware/etcd/path_test.go new file mode 100644 index 000000000..182675067 --- /dev/null +++ b/middleware/etcd/path_test.go @@ -0,0 +1,13 @@ +package etcd + +import "testing" + +func TestPath(t *testing.T) { + for path := range []string{"mydns", "skydns"} { + e := Etcd{PathPrefix: "mydns"} + result := e.Path("service.staging.skydns.local.") + if result != "/"+path+"/"+"/local/skydns/staging/service" { + t.Errorf("Failure to get domain's path with prefix: %s", path) + } + } +}