diff --git a/middleware/kubernetes/controller.go b/middleware/kubernetes/controller.go index 126d415ae..df3724ec4 100644 --- a/middleware/kubernetes/controller.go +++ b/middleware/kubernetes/controller.go @@ -5,8 +5,6 @@ import ( "sync" "time" - "github.com/miekg/coredns/middleware/kubernetes/util" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" @@ -19,6 +17,19 @@ var ( namespace = api.NamespaceAll ) +// storeToNamespaceLister makes a Store that lists Namespaces. +type storeToNamespaceLister struct { + cache.Store +} + +// List lists all Namespaces in the store. +func (s *storeToNamespaceLister) List() (ns api.NamespaceList, err error) { + for _, m := range s.Store.List() { + ns.Items = append(ns.Items, *(m.(*api.Namespace))) + } + return ns, nil +} + type dnsController struct { client *client.Client @@ -30,7 +41,7 @@ type dnsController struct { svcLister cache.StoreToServiceLister endpLister cache.StoreToEndpointsLister - nsLister util.StoreToNamespaceLister + nsLister storeToNamespaceLister // stopLock is used to enforce only a single call to Stop is active. // Needed because we allow stopping through an http endpoint and diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go index 7f5a86649..acf0d0e92 100644 --- a/middleware/kubernetes/kubernetes.go +++ b/middleware/kubernetes/kubernetes.go @@ -4,13 +4,14 @@ package kubernetes import ( "errors" "log" + "strings" "time" "github.com/miekg/coredns/middleware" "github.com/miekg/coredns/middleware/etcd/msg" "github.com/miekg/coredns/middleware/kubernetes/nametemplate" - "github.com/miekg/coredns/middleware/kubernetes/util" "github.com/miekg/coredns/middleware/pkg/dnsutil" + dns_strings "github.com/miekg/coredns/middleware/pkg/strings" "github.com/miekg/coredns/middleware/proxy" "github.com/miekg/dns" @@ -126,21 +127,21 @@ func (k *Kubernetes) Records(name string, exact bool) ([]msg.Service, error) { if namespace == "" { err := errors.New("Parsing query string did not produce a namespace value. Assuming wildcard namespace.") log.Printf("[WARN] %v\n", err) - namespace = util.WildcardStar + namespace = "*" } if serviceName == "" { err := errors.New("Parsing query string did not produce a serviceName value. Assuming wildcard serviceName.") log.Printf("[WARN] %v\n", err) - serviceName = util.WildcardStar + serviceName = "*" } - nsWildcard := util.SymbolContainsWildcard(namespace) - serviceWildcard := util.SymbolContainsWildcard(serviceName) + nsWildcard := symbolContainsWildcard(namespace) + serviceWildcard := symbolContainsWildcard(serviceName) // Abort if the namespace does not contain a wildcard, and namespace is not published per CoreFile // Case where namespace contains a wildcard is handled in Get(...) method. - if (!nsWildcard) && (len(k.Namespaces) > 0) && (!util.StringInSlice(namespace, k.Namespaces)) { + if (!nsWildcard) && (len(k.Namespaces) > 0) && (!dns_strings.StringInSlice(namespace, k.Namespaces)) { return nil, nil } @@ -190,7 +191,7 @@ func (k *Kubernetes) Get(namespace string, nsWildcard bool, servicename string, if symbolMatches(namespace, item.Namespace, nsWildcard) && symbolMatches(servicename, item.Name, serviceWildcard) { // If namespace has a wildcard, filter results against Corefile namespace list. // (Namespaces without a wildcard were filtered before the call to this function.) - if nsWildcard && (len(k.Namespaces) > 0) && (!util.StringInSlice(item.Namespace, k.Namespaces)) { + if nsWildcard && (len(k.Namespaces) > 0) && (!dns_strings.StringInSlice(item.Namespace, k.Namespaces)) { continue } resultItems = append(resultItems, item) @@ -205,9 +206,9 @@ func symbolMatches(queryString string, candidateString string, wildcard bool) bo switch { case !wildcard: result = (queryString == candidateString) - case queryString == util.WildcardStar: + case queryString == "*": result = true - case queryString == util.WildcardAny: + case queryString == "any": result = true } return result @@ -239,3 +240,8 @@ const ( hostmaster = "hostmaster" k8sTimeout = 5 * time.Second ) + +// symbolContainsWildcard checks whether symbol contains a wildcard value +func symbolContainsWildcard(symbol string) bool { + return (strings.Contains(symbol, "*") || (symbol == "any")) +} diff --git a/middleware/kubernetes/kubernetes_test.go b/middleware/kubernetes/kubernetes_test.go new file mode 100644 index 000000000..53404ecf5 --- /dev/null +++ b/middleware/kubernetes/kubernetes_test.go @@ -0,0 +1,25 @@ +package kubernetes + +import "testing" + +// Test data for TestSymbolContainsWildcard cases. +var testdataSymbolContainsWildcard = []struct { + Symbol string + ExpectedResult bool +}{ + {"mynamespace", false}, + {"*", true}, + {"any", true}, + {"my*space", true}, + {"*space", true}, + {"myname*", true}, +} + +func TestSymbolContainsWildcard(t *testing.T) { + for _, example := range testdataSymbolContainsWildcard { + actualResult := symbolContainsWildcard(example.Symbol) + if actualResult != example.ExpectedResult { + t.Errorf("Expected SymbolContainsWildcard result '%v' for example string='%v'. Instead got result '%v'.", example.ExpectedResult, example.Symbol, actualResult) + } + } +} diff --git a/middleware/kubernetes/nametemplate/nametemplate.go b/middleware/kubernetes/nametemplate/nametemplate.go index b9c2f20e4..930d4855e 100644 --- a/middleware/kubernetes/nametemplate/nametemplate.go +++ b/middleware/kubernetes/nametemplate/nametemplate.go @@ -4,7 +4,7 @@ import ( "errors" "strings" - "github.com/miekg/coredns/middleware/kubernetes/util" + dns_strings "github.com/miekg/coredns/middleware/pkg/strings" ) // Likely symbols that require support: @@ -125,7 +125,7 @@ func (t *NameTemplate) GetTypeFromSegmentArray(segments []string) string { typeSegment := t.GetSymbolFromSegmentArray("type", segments) // Limit type to known types symbols - if util.StringInSlice(typeSegment, types) { + if dns_strings.StringInSlice(typeSegment, types) { return "" } diff --git a/middleware/kubernetes/util/util.go b/middleware/kubernetes/util/util.go deleted file mode 100644 index 89cc2b592..000000000 --- a/middleware/kubernetes/util/util.go +++ /dev/null @@ -1,42 +0,0 @@ -// Package kubernetes/util provides helper functions for the kubernetes middleware -package util - -import ( - "strings" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/client/cache" -) - -// StringInSlice check whether string a is a member of slice. -func StringInSlice(a string, slice []string) bool { - for _, b := range slice { - if b == a { - return true - } - } - return false -} - -// SymbolContainsWildcard checks whether symbol contains a wildcard value -func SymbolContainsWildcard(symbol string) bool { - return (strings.Contains(symbol, WildcardStar) || (symbol == WildcardAny)) -} - -const ( - WildcardStar = "*" - WildcardAny = "any" -) - -// StoreToNamespaceLister makes a Store that lists Namespaces. -type StoreToNamespaceLister struct { - cache.Store -} - -// List lists all Namespaces in the store. -func (s *StoreToNamespaceLister) List() (ns api.NamespaceList, err error) { - for _, m := range s.Store.List() { - ns.Items = append(ns.Items, *(m.(*api.Namespace))) - } - return ns, nil -} diff --git a/middleware/pkg/strings/slice.go b/middleware/pkg/strings/slice.go new file mode 100644 index 000000000..3d4b1d481 --- /dev/null +++ b/middleware/pkg/strings/slice.go @@ -0,0 +1,11 @@ +package strings + +// StringInSlice check whether string a is a member of slice. +func StringInSlice(a string, slice []string) bool { + for _, b := range slice { + if b == a { + return true + } + } + return false +} diff --git a/middleware/kubernetes/util/util_test.go b/middleware/pkg/strings/slice_test.go similarity index 54% rename from middleware/kubernetes/util/util_test.go rename to middleware/pkg/strings/slice_test.go index 4af64ea50..9816852cd 100644 --- a/middleware/kubernetes/util/util_test.go +++ b/middleware/pkg/strings/slice_test.go @@ -1,4 +1,4 @@ -package util +package strings import ( "testing" @@ -31,25 +31,3 @@ func TestStringInSlice(t *testing.T) { } } } - -// Test data for TestSymbolContainsWildcard cases. -var testdataSymbolContainsWildcard = []struct { - Symbol string - ExpectedResult bool -}{ - {"mynamespace", false}, - {"*", true}, - {"any", true}, - {"my*space", true}, - {"*space", true}, - {"myname*", true}, -} - -func TestSymbolContainsWildcard(t *testing.T) { - for _, example := range testdataSymbolContainsWildcard { - actualResult := SymbolContainsWildcard(example.Symbol) - if actualResult != example.ExpectedResult { - t.Errorf("Expected SymbolContainsWildcard result '%v' for example string='%v'. Instead got result '%v'.", example.ExpectedResult, example.Symbol, actualResult) - } - } -}