diff options
Diffstat (limited to 'middleware/kubernetes')
-rw-r--r-- | middleware/kubernetes/controller.go | 56 | ||||
-rw-r--r-- | middleware/kubernetes/handler.go | 3 | ||||
-rw-r--r-- | middleware/kubernetes/kubernetes.go | 48 | ||||
-rw-r--r-- | middleware/kubernetes/nametemplate/nametemplate.go | 5 | ||||
-rw-r--r-- | middleware/kubernetes/setup.go | 140 | ||||
-rw-r--r-- | middleware/kubernetes/setup_test.go | 390 |
6 files changed, 565 insertions, 77 deletions
diff --git a/middleware/kubernetes/controller.go b/middleware/kubernetes/controller.go index 3fbea313e..5de16d61c 100644 --- a/middleware/kubernetes/controller.go +++ b/middleware/kubernetes/controller.go @@ -2,7 +2,6 @@ package kubernetes import ( "fmt" - "log" "sync" "time" @@ -12,7 +11,7 @@ import ( "k8s.io/kubernetes/pkg/client/cache" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/controller/framework" - "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/watch" ) @@ -24,7 +23,7 @@ var ( type dnsController struct { client *client.Client - selector *labels.Selector + selector *labels.Selector endpController *framework.Controller svcController *framework.Controller @@ -45,9 +44,9 @@ type dnsController struct { // newDNSController creates a controller for coredns func newdnsController(kubeClient *client.Client, resyncPeriod time.Duration, lselector *labels.Selector) *dnsController { dns := dnsController{ - client: kubeClient, - selector: lselector, - stopCh: make(chan struct{}), + client: kubeClient, + selector: lselector, + stopCh: make(chan struct{}), } dns.endpLister.Store, dns.endpController = framework.NewInformer( @@ -76,54 +75,54 @@ func newdnsController(kubeClient *client.Client, resyncPeriod time.Duration, lse func serviceListFunc(c *client.Client, ns string, s *labels.Selector) func(api.ListOptions) (runtime.Object, error) { return func(opts api.ListOptions) (runtime.Object, error) { - if s != nil { - opts.LabelSelector = *s - } + if s != nil { + opts.LabelSelector = *s + } return c.Services(ns).List(opts) } } func serviceWatchFunc(c *client.Client, ns string, s *labels.Selector) func(options api.ListOptions) (watch.Interface, error) { return func(options api.ListOptions) (watch.Interface, error) { - if s != nil { - options.LabelSelector = *s - } + if s != nil { + options.LabelSelector = *s + } return c.Services(ns).Watch(options) } } func endpointsListFunc(c *client.Client, ns string, s *labels.Selector) func(api.ListOptions) (runtime.Object, error) { return func(opts api.ListOptions) (runtime.Object, error) { - if s != nil { - opts.LabelSelector = *s - } + if s != nil { + opts.LabelSelector = *s + } return c.Endpoints(ns).List(opts) } } func endpointsWatchFunc(c *client.Client, ns string, s *labels.Selector) func(options api.ListOptions) (watch.Interface, error) { return func(options api.ListOptions) (watch.Interface, error) { - if s != nil { - options.LabelSelector = *s - } + if s != nil { + options.LabelSelector = *s + } return c.Endpoints(ns).Watch(options) } } func namespaceListFunc(c *client.Client, s *labels.Selector) func(api.ListOptions) (runtime.Object, error) { return func(opts api.ListOptions) (runtime.Object, error) { - if s != nil { - opts.LabelSelector = *s - } + if s != nil { + opts.LabelSelector = *s + } return c.Namespaces().List(opts) } } func namespaceWatchFunc(c *client.Client, s *labels.Selector) func(options api.ListOptions) (watch.Interface, error) { return func(options api.ListOptions) (watch.Interface, error) { - if s != nil { - options.LabelSelector = *s - } + if s != nil { + options.LabelSelector = *s + } return c.Namespaces().Watch(options) } } @@ -140,7 +139,6 @@ func (dns *dnsController) Stop() error { // Only try draining the workqueue if we haven't already. if !dns.shutdown { close(dns.stopCh) - log.Println("shutting down controller queues") dns.shutdown = true return nil @@ -151,14 +149,10 @@ func (dns *dnsController) Stop() error { // Run starts the controller. func (dns *dnsController) Run() { - log.Println("[debug] Starting k8s notification controllers") - go dns.endpController.Run(dns.stopCh) go dns.svcController.Run(dns.stopCh) go dns.nsController.Run(dns.stopCh) - <-dns.stopCh - log.Println("[debug] shutting down coredns controller") } func (dns *dnsController) GetNamespaceList() *api.NamespaceList { @@ -203,12 +197,12 @@ func (dns *dnsController) GetServiceInNamespace(namespace string, servicename st svcObj, svcExists, err := dns.svcLister.Store.GetByKey(svcKey) if err != nil { - log.Printf("error getting service %v from the cache: %v\n", svcKey, err) + // TODO(...): should return err here return nil } if !svcExists { - log.Printf("service %v does not exists\n", svcKey) + // TODO(...): should return err here return nil } diff --git a/middleware/kubernetes/handler.go b/middleware/kubernetes/handler.go index 05dfba934..1986820d5 100644 --- a/middleware/kubernetes/handler.go +++ b/middleware/kubernetes/handler.go @@ -2,7 +2,6 @@ package kubernetes import ( "fmt" - "log" "strings" "github.com/miekg/coredns/middleware" @@ -12,8 +11,6 @@ import ( ) func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - log.Printf("[debug] here entering ServeDNS: ctx:%v dnsmsg:%v\n", ctx, r) - state := middleware.State{W: w, Req: r} if state.QClass() != dns.ClassINET { return dns.RcodeServerFailure, fmt.Errorf("can only deal with ClassINET") diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go index 5e2a1bf53..59a044140 100644 --- a/middleware/kubernetes/kubernetes.go +++ b/middleware/kubernetes/kubernetes.go @@ -16,10 +16,10 @@ import ( "github.com/miekg/dns" "k8s.io/kubernetes/pkg/api" unversionedapi "k8s.io/kubernetes/pkg/api/unversioned" - "k8s.io/kubernetes/pkg/labels" unversionedclient "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" + "k8s.io/kubernetes/pkg/labels" ) type Kubernetes struct { @@ -32,10 +32,10 @@ type Kubernetes struct { NameTemplate *nametemplate.NameTemplate Namespaces []string LabelSelector *unversionedapi.LabelSelector - Selector *labels.Selector + Selector *labels.Selector } -func (g *Kubernetes) StartKubeCache() error { +func (g *Kubernetes) InitKubeCache() error { // For a custom api server or running outside a k8s cluster // set URL in env.KUBERNETES_MASTER or set endpoint in Corefile loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() @@ -46,7 +46,6 @@ func (g *Kubernetes) StartKubeCache() error { clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides) config, err := clientConfig.ClientConfig() if err != nil { - log.Printf("[debug] error connecting to the client: %v", err) return err } kubeClient, err := unversionedclient.New(config) @@ -58,20 +57,17 @@ func (g *Kubernetes) StartKubeCache() error { if g.LabelSelector == nil { log.Printf("[INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed.") } else { - var selector labels.Selector + var selector labels.Selector selector, err = unversionedapi.LabelSelectorAsSelector(g.LabelSelector) - g.Selector = &selector - if err != nil { - log.Printf("[ERROR] Unable to create Selector for LabelSelector '%s'.Error was: %s", g.LabelSelector, err) - return err - } + g.Selector = &selector + if err != nil { + log.Printf("[ERROR] Unable to create Selector for LabelSelector '%s'.Error was: %s", g.LabelSelector, err) + return err + } log.Printf("[INFO] Kubernetes middleware configured with the label selector '%s'. Only kubernetes objects matching this label selector will be exposed.", unversionedapi.FormatLabelSelector(g.LabelSelector)) } - log.Printf("[debug] Starting kubernetes middleware with k8s API resync period: %s", g.ResyncPeriod) g.APIConn = newdnsController(kubeClient, g.ResyncPeriod, g.Selector) - go g.APIConn.Run() - return err } @@ -115,7 +111,6 @@ func (g *Kubernetes) Records(name string, exact bool) ([]msg.Service, error) { typeName string ) - log.Printf("[debug] enter Records('%v', '%v')\n", name, exact) zone, serviceSegments := g.getZoneForName(name) // TODO: Implementation above globbed together segments for the serviceName if @@ -137,30 +132,18 @@ func (g *Kubernetes) Records(name string, exact bool) ([]msg.Service, error) { serviceName = util.WildcardStar } - log.Printf("[debug] published namespaces: %v\n", g.Namespaces) - - log.Printf("[debug] exact: %v\n", exact) - log.Printf("[debug] zone: %v\n", zone) - log.Printf("[debug] servicename: %v\n", serviceName) - log.Printf("[debug] namespace: %v\n", namespace) - log.Printf("[debug] typeName: %v\n", typeName) - log.Printf("[debug] APIconn: %v\n", g.APIConn) - nsWildcard := util.SymbolContainsWildcard(namespace) serviceWildcard := util.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(g.Namespaces) > 0) && (!util.StringInSlice(namespace, g.Namespaces)) { - log.Printf("[debug] Namespace '%v' is not published by Corefile\n", namespace) return nil, nil } - log.Printf("before g.Get(namespace, nsWildcard, serviceName, serviceWildcard): %v %v %v %v", namespace, nsWildcard, serviceName, serviceWildcard) + log.Printf("[debug] before g.Get(namespace, nsWildcard, serviceName, serviceWildcard): %v %v %v %v", namespace, nsWildcard, serviceName, serviceWildcard) k8sItems, err := g.Get(namespace, nsWildcard, serviceName, serviceWildcard) - log.Printf("[debug] k8s items: %v\n", k8sItems) if err != nil { - log.Printf("[ERROR] Got error while looking up ServiceItems. Error is: %v\n", err) return nil, err } if k8sItems == nil { @@ -178,7 +161,6 @@ func (g *Kubernetes) getRecordsForServiceItems(serviceItems []api.Service, value for _, item := range serviceItems { clusterIP := item.Spec.ClusterIP - log.Printf("[debug] clusterIP: %v\n", clusterIP) // Create records by constructing record name from template... //values.Namespace = item.Metadata.Namespace @@ -188,13 +170,11 @@ func (g *Kubernetes) getRecordsForServiceItems(serviceItems []api.Service, value // Create records for each exposed port... for _, p := range item.Spec.Ports { - log.Printf("[debug] port: %v\n", p.Port) s := msg.Service{Host: clusterIP, Port: int(p.Port)} records = append(records, s) } } - log.Printf("[debug] records from getRecordsForServiceItems(): %v\n", records) return records } @@ -202,13 +182,6 @@ func (g *Kubernetes) getRecordsForServiceItems(serviceItems []api.Service, value func (g *Kubernetes) Get(namespace string, nsWildcard bool, servicename string, serviceWildcard bool) ([]api.Service, error) { serviceList := g.APIConn.GetServiceList() - /* TODO: Remove? - if err != nil { - log.Printf("[ERROR] Getting service list produced error: %v", err) - return nil, err - } - */ - var resultItems []api.Service for _, item := range serviceList.Items { @@ -216,7 +189,6 @@ func (g *Kubernetes) Get(namespace string, nsWildcard bool, servicename string, // 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(g.Namespaces) > 0) && (!util.StringInSlice(item.Namespace, g.Namespaces)) { - log.Printf("[debug] Namespace '%v' is not published by Corefile\n", item.Namespace) continue } resultItems = append(resultItems, item) diff --git a/middleware/kubernetes/nametemplate/nametemplate.go b/middleware/kubernetes/nametemplate/nametemplate.go index 5a34ae4ad..3e1ac4bb3 100644 --- a/middleware/kubernetes/nametemplate/nametemplate.go +++ b/middleware/kubernetes/nametemplate/nametemplate.go @@ -2,7 +2,6 @@ package nametemplate import ( "errors" - "log" "strings" "github.com/miekg/coredns/middleware/kubernetes/util" @@ -87,17 +86,13 @@ func (t *NameTemplate) SetTemplate(s string) error { if !elementPositionSet { if strings.Contains(v, "{") { err = errors.New("Record name template contains the unknown symbol '" + v + "'") - log.Printf("[debug] %v\n", err) return err - } else { - log.Printf("[debug] Template string has static element '%v'\n", v) } } } if err == nil && !t.IsValid() { err = errors.New("Record name template does not pass NameTemplate validation") - log.Printf("[debug] %v\n", err) return err } diff --git a/middleware/kubernetes/setup.go b/middleware/kubernetes/setup.go new file mode 100644 index 000000000..fc3c036b8 --- /dev/null +++ b/middleware/kubernetes/setup.go @@ -0,0 +1,140 @@ +package kubernetes + +import ( + "errors" + "fmt" + "strings" + "time" + + "github.com/miekg/coredns/core/dnsserver" + "github.com/miekg/coredns/middleware" + "github.com/miekg/coredns/middleware/kubernetes/nametemplate" + + "github.com/mholt/caddy" + unversionedapi "k8s.io/kubernetes/pkg/api/unversioned" +) + +func init() { + caddy.RegisterPlugin("kubernetes", caddy.Plugin{ + ServerType: "dns", + Action: setup, + }) +} + +func setup(c *caddy.Controller) error { + kubernetes, err := kubernetesParse(c) + if err != nil { + return err + } + + err = kubernetes.InitKubeCache() + if err != nil { + return err + } + + // Register KubeCache start and stop functions with Caddy + c.OnStartup(func() error { + go kubernetes.APIConn.Run() + return nil + }) + + c.OnShutdown(func() error { + return kubernetes.APIConn.Stop() + }) + + dnsserver.GetConfig(c).AddMiddleware(func(next dnsserver.Handler) dnsserver.Handler { + kubernetes.Next = next + return kubernetes + }) + + return nil +} + +func kubernetesParse(c *caddy.Controller) (Kubernetes, error) { + var err error + template := defaultNameTemplate + + k8s := Kubernetes{ResyncPeriod: defaultResyncPeriod} + k8s.NameTemplate = new(nametemplate.NameTemplate) + k8s.NameTemplate.SetTemplate(template) + + for c.Next() { + if c.Val() == "kubernetes" { + zones := c.RemainingArgs() + + if len(zones) == 0 { + k8s.Zones = make([]string, len(c.ServerBlockKeys)) + copy(k8s.Zones, c.ServerBlockKeys) + } + + k8s.Zones = NormalizeZoneList(zones) + middleware.Zones(k8s.Zones).FullyQualify() + + if k8s.Zones == nil || len(k8s.Zones) < 1 { + err = errors.New("Zone name must be provided for kubernetes middleware.") + return Kubernetes{}, err + } + + for c.NextBlock() { + switch c.Val() { + case "template": + args := c.RemainingArgs() + if len(args) != 0 { + template := strings.Join(args, "") + err = k8s.NameTemplate.SetTemplate(template) + if err != nil { + return Kubernetes{}, err + } + } else { + return Kubernetes{}, c.ArgErr() + } + case "namespaces": + args := c.RemainingArgs() + if len(args) != 0 { + k8s.Namespaces = append(k8s.Namespaces, args...) + } else { + return Kubernetes{}, c.ArgErr() + } + case "endpoint": + args := c.RemainingArgs() + if len(args) != 0 { + k8s.APIEndpoint = args[0] + } else { + return Kubernetes{}, c.ArgErr() + } + case "resyncperiod": + args := c.RemainingArgs() + if len(args) != 0 { + k8s.ResyncPeriod, err = time.ParseDuration(args[0]) + if err != nil { + err = errors.New(fmt.Sprintf("Unable to parse resync duration value. Value provided was '%v'. Example valid values: '15s', '5m', '1h'. Error was: %v", args[0], err)) + return Kubernetes{}, err + } + } else { + return Kubernetes{}, c.ArgErr() + } + case "labels": + args := c.RemainingArgs() + if len(args) != 0 { + labelSelectorString := strings.Join(args, " ") + k8s.LabelSelector, err = unversionedapi.ParseToLabelSelector(labelSelectorString) + if err != nil { + err = errors.New(fmt.Sprintf("Unable to parse label selector. Value provided was '%v'. Error was: %v", labelSelectorString, err)) + return Kubernetes{}, err + } + } else { + return Kubernetes{}, c.ArgErr() + } + } + } + return k8s, nil + } + } + err = errors.New("Kubernetes setup called without keyword 'kubernetes' in Corefile") + return Kubernetes{}, err +} + +const ( + defaultNameTemplate = "{service}.{namespace}.{zone}" + defaultResyncPeriod = 5 * time.Minute +) diff --git a/middleware/kubernetes/setup_test.go b/middleware/kubernetes/setup_test.go new file mode 100644 index 000000000..6e0918a3b --- /dev/null +++ b/middleware/kubernetes/setup_test.go @@ -0,0 +1,390 @@ +package kubernetes + +import ( + "strings" + "testing" + "time" + + "github.com/mholt/caddy" + unversionedapi "k8s.io/kubernetes/pkg/api/unversioned" +) + +func TestKubernetesParse(t *testing.T) { + tests := []struct { + description string // Human-facing description of test case + 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. + expectedZoneCount int // expected count of defined zones. + expectedNTValid bool // NameTemplate to be initialized and valid + expectedNSCount int // expected count of namespaces. + expectedResyncPeriod time.Duration // expected resync period value + expectedLabelSelector string // expected label selector value + }{ + // positive + { + "kubernetes keyword with one zone", + `kubernetes coredns.local`, + false, + "", + 1, + true, + 0, + defaultResyncPeriod, + "", + }, + { + "kubernetes keyword with multiple zones", + `kubernetes coredns.local test.local`, + false, + "", + 2, + true, + 0, + defaultResyncPeriod, + "", + }, + { + "kubernetes keyword with zone and empty braces", + `kubernetes coredns.local { +}`, + false, + "", + 1, + true, + 0, + defaultResyncPeriod, + "", + }, + { + "endpoint keyword with url", + `kubernetes coredns.local { + endpoint http://localhost:9090 +}`, + false, + "", + 1, + true, + 0, + defaultResyncPeriod, + "", + }, + { + "template keyword with valid template", + `kubernetes coredns.local { + template {service}.{namespace}.{zone} +}`, + false, + "", + 1, + true, + 0, + defaultResyncPeriod, + "", + }, + { + "namespaces keyword with one namespace", + `kubernetes coredns.local { + namespaces demo +}`, + false, + "", + 1, + true, + 1, + defaultResyncPeriod, + "", + }, + { + "namespaces keyword with multiple namespaces", + `kubernetes coredns.local { + namespaces demo test +}`, + false, + "", + 1, + true, + 2, + defaultResyncPeriod, + "", + }, + { + "resync period in seconds", + `kubernetes coredns.local { + resyncperiod 30s +}`, + false, + "", + 1, + true, + 0, + 30 * time.Second, + "", + }, + { + "resync period in minutes", + `kubernetes coredns.local { + resyncperiod 15m +}`, + false, + "", + 1, + true, + 0, + 15 * time.Minute, + "", + }, + { + "basic label selector", + `kubernetes coredns.local { + labels environment=prod +}`, + false, + "", + 1, + true, + 0, + defaultResyncPeriod, + "environment=prod", + }, + { + "multi-label selector", + `kubernetes coredns.local { + labels environment in (production, staging, qa),application=nginx +}`, + false, + "", + 1, + true, + 0, + defaultResyncPeriod, + "application=nginx,environment in (production,qa,staging)", + }, + { + "fully specified valid config", + `kubernetes coredns.local test.local { + resyncperiod 15m + endpoint http://localhost:8080 + template {service}.{namespace}.{zone} + namespaces demo test + labels environment in (production, staging, qa),application=nginx +}`, + false, + "", + 2, + true, + 2, + 15 * time.Minute, + "application=nginx,environment in (production,qa,staging)", + }, + // negative + { + "no kubernetes keyword", + "", + true, + "Kubernetes setup called without keyword 'kubernetes' in Corefile", + -1, + false, + -1, + defaultResyncPeriod, + "", + }, + { + "kubernetes keyword without a zone", + `kubernetes`, + true, + "Zone name must be provided for kubernetes middleware", + -1, + true, + 0, + defaultResyncPeriod, + "", + }, + { + "endpoint keyword without an endpoint value", + `kubernetes coredns.local { + endpoint +}`, + true, + "Wrong argument count or unexpected line ending after 'endpoint'", + -1, + true, + -1, + defaultResyncPeriod, + "", + }, + { + "template keyword without a template value", + `kubernetes coredns.local { + template +}`, + true, + "Wrong argument count or unexpected line ending after 'template'", + -1, + false, + 0, + defaultResyncPeriod, + "", + }, + { + "template keyword with an invalid template value", + `kubernetes coredns.local { + template {namespace}.{zone} +}`, + true, + "Record name template does not pass NameTemplate validation", + -1, + false, + 0, + defaultResyncPeriod, + "", + }, + { + "namespace keyword without a namespace value", + `kubernetes coredns.local { + namespaces +}`, + true, + "Parse error: Wrong argument count or unexpected line ending after 'namespaces'", + -1, + true, + -1, + defaultResyncPeriod, + "", + }, + { + "resyncperiod keyword without a duration value", + `kubernetes coredns.local { + resyncperiod +}`, + true, + "Wrong argument count or unexpected line ending after 'resyncperiod'", + -1, + true, + 0, + 0 * time.Minute, + "", + }, + { + "resync period no units", + `kubernetes coredns.local { + resyncperiod 15 +}`, + true, + "Unable to parse resync duration value. Value provided was ", + -1, + true, + 0, + 0 * time.Second, + "", + }, + { + "resync period invalid", + `kubernetes coredns.local { + resyncperiod abc +}`, + true, + "Unable to parse resync duration value. Value provided was ", + -1, + true, + 0, + 0 * time.Second, + "", + }, + { + "labels with no selector value", + `kubernetes coredns.local { + labels +}`, + true, + "Wrong argument count or unexpected line ending after 'labels'", + -1, + true, + 0, + 0 * time.Second, + "", + }, + { + "labels with invalid selector value", + `kubernetes coredns.local { + labels environment in (production, qa +}`, + true, + "Unable to parse label selector. Value provided was", + -1, + true, + 0, + 0 * time.Second, + "", + }, + } + + t.Logf("Parser test cases count: %v", len(tests)) + for i, test := range tests { + c := caddy.NewTestController("dns", test.input) + k8sController, err := kubernetesParse(c) + t.Logf("setup test: %2v -- %v\n", i, test.description) + //t.Logf("controller: %v\n", k8sController) + + 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 test.shouldErr && (test.expectedZoneCount >= 0) { + t.Errorf("Test %d: Test marked as expecting an error, but provides value for expectedZoneCount!=-1 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 + } + + // No error was raised, so validate initialization of k8sController + // Zones + foundZoneCount := len(k8sController.Zones) + if foundZoneCount != test.expectedZoneCount { + t.Errorf("Test %d: Expected kubernetes controller to be initialized with %d zones, instead found %d zones: '%v' for input '%s'", i, test.expectedZoneCount, foundZoneCount, k8sController.Zones, test.input) + } + + // NameTemplate + if k8sController.NameTemplate == nil { + t.Errorf("Test %d: Expected kubernetes controller to be initialized with a NameTemplate. Instead found '%v' for input '%s'", i, k8sController.NameTemplate, test.input) + } else { + foundNTValid := k8sController.NameTemplate.IsValid() + if foundNTValid != test.expectedNTValid { + t.Errorf("Test %d: Expected NameTemplate validity to be '%v', instead found '%v' for input '%s'", i, test.expectedNTValid, foundNTValid, test.input) + } + } + + // Namespaces + foundNSCount := len(k8sController.Namespaces) + if foundNSCount != test.expectedNSCount { + t.Errorf("Test %d: Expected kubernetes controller to be initialized with %d namespaces. Instead found %d namespaces: '%v' for input '%s'", i, test.expectedNSCount, foundNSCount, k8sController.Namespaces, test.input) + } + + // ResyncPeriod + foundResyncPeriod := k8sController.ResyncPeriod + if foundResyncPeriod != test.expectedResyncPeriod { + t.Errorf("Test %d: Expected kubernetes controller to be initialized with resync period '%s'. Instead found period '%s' for input '%s'", i, test.expectedResyncPeriod, foundResyncPeriod, test.input) + } + + // Labels + if k8sController.LabelSelector != nil { + foundLabelSelectorString := unversionedapi.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) + } + } + } +} |