From 62b68f90343127028c0c79da6581d6da4c4b51ae Mon Sep 17 00:00:00 2001 From: varshaprasad96 Date: Mon, 20 Jul 2020 15:58:59 -0700 Subject: [PATCH 1/4] handler: Update hander/enqueue_annotation This commit updates the implementation in enqueue_annotation, to watch dependent resources based on the presence of an annotation on them. Co-Authored-by: Camila Macedo --- go.mod | 2 + handler/enqueue_annotation.go | 57 ++++++++++++++---- handler/enqueue_annotation_suite_test.go | 34 +++++++++++ handler/enqueue_annotation_test.go | 75 ++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 13 deletions(-) create mode 100644 handler/enqueue_annotation_suite_test.go create mode 100644 handler/enqueue_annotation_test.go diff --git a/go.mod b/go.mod index 42516c1..eb4203b 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/operator-framework/operator-lib go 1.13 require ( + github.com/onsi/ginkgo v1.11.0 + github.com/onsi/gomega v1.8.1 github.com/stretchr/testify v1.5.1 k8s.io/api v0.18.2 k8s.io/apimachinery v0.18.2 diff --git a/handler/enqueue_annotation.go b/handler/enqueue_annotation.go index 29184cf..af8eb68 100644 --- a/handler/enqueue_annotation.go +++ b/handler/enqueue_annotation.go @@ -15,10 +15,11 @@ package handler import ( + "fmt" "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/workqueue" "sigs.k8s.io/controller-runtime/pkg/event" @@ -31,8 +32,12 @@ var log = logf.Log.WithName("event_handler") const ( // NamespacedNameAnnotation - annotation that will be used to get the primary resource namespaced name. + // The handler will use this value to build the types.NamespacedName Object used to enqueue a Request when an event + // to update, create or delete the observed object is raised. + // Note: If only one value is provided without "/", then it will be used as the name of primary resource NamespacedNameAnnotation = "operator-sdk/primary-resource" // TypeAnnotation - annotation that will be used to verify that the primary resource is the primary resource to use. + // It is of the form type:schema.GroupKind, eg: operator-sdk/owner-type:core.Pods TypeAnnotation = "operator-sdk/primary-resource-type" ) @@ -44,7 +49,8 @@ const ( // 2. cluster scoped primary object. // 3. namespaced primary object and dependent namespaced scoped but in a different namespace object. type EnqueueRequestForAnnotation struct { - Type string + // Type string + Type schema.GroupKind } var _ crtHandler.EventHandler = &EnqueueRequestForAnnotation{} @@ -81,12 +87,12 @@ func (e *EnqueueRequestForAnnotation) Generic(evt event.GenericEvent, q workqueu } func (e *EnqueueRequestForAnnotation) getAnnotationRequests(object metav1.Object) (bool, reconcile.Request) { - if typeString, ok := object.GetAnnotations()[TypeAnnotation]; ok && typeString == e.Type { + if typeString, ok := object.GetAnnotations()[TypeAnnotation]; ok && typeString == e.Type.String() { namespacedNameString, ok := object.GetAnnotations()[NamespacedNameAnnotation] if !ok { log.Info("Unable to find namespaced name annotation for resource", "resource", object) } - if namespacedNameString == "" { + if len(namespacedNameString) < 1 { return false, reconcile.Request{} } nsn := parseNamespacedName(namespacedNameString) @@ -96,7 +102,7 @@ func (e *EnqueueRequestForAnnotation) getAnnotationRequests(object metav1.Object } func parseNamespacedName(namespacedNameString string) types.NamespacedName { - values := strings.Split(namespacedNameString, "/") + values := strings.SplitN(namespacedNameString, "/", 2) if len(values) == 1 { return types.NamespacedName{ Name: values[0], @@ -113,15 +119,40 @@ func parseNamespacedName(namespacedNameString string) types.NamespacedName { } // SetOwnerAnnotation sets annotations for dependent resources that needs to be watched by namespaced Owners. -func SetOwnerAnnotation(u *unstructured.Unstructured, owner *unstructured.Unstructured) { - a := u.GetAnnotations() - if a == nil { - a = map[string]string{} +// func SetOwnerAnnotation(u *unstructured.Unstructured, owner *unstructured.Unstructured) { +// a := u.GetAnnotations() +// if a == nil { +// a = map[string]string{} +// } + +// nn := types.NamespacedName{Namespace: owner.GetNamespace(), Name: owner.GetName()} +// a[NamespacedNameAnnotation] = nn.String() + +// a[TypeAnnotation] = owner.GetObjectKind().GroupVersionKind().GroupKind().String() +// u.SetAnnotations(a) +// } + +func SetOwnerAnnotation(owner, object metav1.Object, ownerGK schema.GroupKind) error { + if len(owner.GetName()) < 1 { + return fmt.Errorf("%T does not have a name, cannot call SetOwnerAnnotation", owner) } - nn := types.NamespacedName{Namespace: owner.GetNamespace(), Name: owner.GetName()} - a[NamespacedNameAnnotation] = nn.String() + if len(ownerGK.Kind) < 1 { + return fmt.Errorf("Owner Kind not found, cannot call SetOwnerAnnotation") + } + + if len(ownerGK.Group) < 1 { + return fmt.Errorf("Owner Group not found, cannot call SetOwnerAnnotation") + } + + annotations := object.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + } + annotations[NamespacedNameAnnotation] = fmt.Sprintf("%v/%v", owner.GetNamespace(), owner.GetName()) + annotations[TypeAnnotation] = ownerGK.String() + + object.SetAnnotations(annotations) - a[TypeAnnotation] = owner.GetObjectKind().GroupVersionKind().GroupKind().String() - u.SetAnnotations(a) + return nil } diff --git a/handler/enqueue_annotation_suite_test.go b/handler/enqueue_annotation_suite_test.go new file mode 100644 index 0000000..be80c9c --- /dev/null +++ b/handler/enqueue_annotation_suite_test.go @@ -0,0 +1,34 @@ +package handler + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func TestEventhandler(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecsWithDefaultAndCustomReporters(t, "Eventhandler Suite", []Reporter{printer.NewlineReporter{}}) +} + +var testenv *envtest.Environment +var cfg *rest.Config + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.LoggerTo(GinkgoWriter, true)) + + testenv = &envtest.Environment{} + var err error + cfg, err = testenv.Start() + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + Expect(testenv.Stop()).To(Succeed()) +}) diff --git a/handler/enqueue_annotation_test.go b/handler/enqueue_annotation_test.go new file mode 100644 index 0000000..e388fa9 --- /dev/null +++ b/handler/enqueue_annotation_test.go @@ -0,0 +1,75 @@ +package handler + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/controller/controllertest" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + "k8s.io/client-go/util/workqueue" +) + +var _ = Describe("EventHandler", func() { + var q workqueue.RateLimitingInterface + var instance EnqueueRequestForAnnotation + var mapper meta.RESTMapper + var pod *corev1.Pod + var podOwner = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "podOwnerNs", + Name: "podOwnerName", + }, + } + + // t := true + BeforeEach(func() { + q = controllertest.Queue{Interface: workqueue.New()} + pod = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "biz", + Name: "biz", + }, + } + + err := SetOwnerAnnotation(podOwner, pod, schema.GroupKind{Group: "Pods", Kind: "core"}) + Expect(err).To(BeNil()) + Expect(cfg).NotTo(BeNil()) + mapper, err = apiutil.NewDiscoveryRESTMapper(cfg) + Expect(err).NotTo(HaveOccurred()) + Expect(mapper).NotTo(BeNil()) + }) + + Describe("EnqueueRequestForAnnotation", func() { + It("should enqueue a Request with the annotations of the object in the CreateEvent", func() { + instance = EnqueueRequestForAnnotation{ + Type: schema.GroupKind{ + Group: "Pods", + Kind: "core", + }} + + evt := event.CreateEvent{ + Object: pod, + Meta: pod.GetObjectMeta(), + } + + instance.Create(evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: podOwner.Namespace, + Name: podOwner.Name, + }, + })) + + }) + }) +}) From 60417232c82329c3070e64c90027c2541f4e5e5f Mon Sep 17 00:00:00 2001 From: varshaprasad96 Date: Tue, 21 Jul 2020 11:39:07 -0700 Subject: [PATCH 2/4] handler: add tests for enqueue_annotation --- go.mod | 10 +- go.sum | 41 +++ handler/enqueue_annotation.go | 1 - handler/enqueue_annotation_suite_test.go | 16 +- handler/enqueue_annotation_test.go | 363 ++++++++++++++++++++++- 5 files changed, 424 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index eb4203b..68a858e 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,14 @@ module github.com/operator-framework/operator-lib go 1.13 require ( - github.com/onsi/ginkgo v1.11.0 - github.com/onsi/gomega v1.8.1 + github.com/go-logr/zapr v0.1.1 // indirect + github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect + github.com/hashicorp/golang-lru v0.5.3 // indirect + github.com/imdario/mergo v0.3.8 // indirect + github.com/onsi/ginkgo v1.12.0 + github.com/onsi/gomega v1.9.0 + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.5.1 // indirect github.com/stretchr/testify v1.5.1 k8s.io/api v0.18.2 k8s.io/apimachinery v0.18.2 diff --git a/go.sum b/go.sum index cc25ba5..3896288 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxB github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -18,7 +19,9 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -26,9 +29,13 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -69,11 +76,15 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-logr/zapr v0.1.1 h1:qXBXPDdNncunGs7XeEpsJt8wCjYBygluzfdLO0G5baE= +github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -126,6 +137,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= +github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -138,6 +151,9 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -161,18 +177,24 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -215,22 +237,31 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA= +github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -238,9 +269,13 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -345,6 +380,9 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -369,6 +407,8 @@ golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -403,6 +443,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= diff --git a/handler/enqueue_annotation.go b/handler/enqueue_annotation.go index af8eb68..c5dc5b8 100644 --- a/handler/enqueue_annotation.go +++ b/handler/enqueue_annotation.go @@ -49,7 +49,6 @@ const ( // 2. cluster scoped primary object. // 3. namespaced primary object and dependent namespaced scoped but in a different namespace object. type EnqueueRequestForAnnotation struct { - // Type string Type schema.GroupKind } diff --git a/handler/enqueue_annotation_suite_test.go b/handler/enqueue_annotation_suite_test.go index be80c9c..94223a7 100644 --- a/handler/enqueue_annotation_suite_test.go +++ b/handler/enqueue_annotation_suite_test.go @@ -1,3 +1,17 @@ +// Copyright 2020 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package handler import ( @@ -14,7 +28,7 @@ import ( func TestEventhandler(t *testing.T) { RegisterFailHandler(Fail) - RunSpecsWithDefaultAndCustomReporters(t, "Eventhandler Suite", []Reporter{printer.NewlineReporter{}}) + RunSpecsWithDefaultAndCustomReporters(t, "Enqueue_anootation Suite", []Reporter{printer.NewlineReporter{}}) } var testenv *envtest.Environment diff --git a/handler/enqueue_annotation_test.go b/handler/enqueue_annotation_test.go index e388fa9..b1d4126 100644 --- a/handler/enqueue_annotation_test.go +++ b/handler/enqueue_annotation_test.go @@ -1,8 +1,25 @@ +// Copyright 2020 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package handler import ( + "fmt" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -16,7 +33,7 @@ import ( "k8s.io/client-go/util/workqueue" ) -var _ = Describe("EventHandler", func() { +var _ = Describe("Enqueue_anootation", func() { var q workqueue.RateLimitingInterface var instance EnqueueRequestForAnnotation var mapper meta.RESTMapper @@ -28,7 +45,6 @@ var _ = Describe("EventHandler", func() { }, } - // t := true BeforeEach(func() { q = controllertest.Queue{Interface: workqueue.New()} pod = &corev1.Pod{ @@ -47,13 +63,15 @@ var _ = Describe("EventHandler", func() { }) Describe("EnqueueRequestForAnnotation", func() { - It("should enqueue a Request with the annotations of the object in the CreateEvent", func() { + BeforeEach(func() { instance = EnqueueRequestForAnnotation{ Type: schema.GroupKind{ Group: "Pods", Kind: "core", }} + }) + It("should enqueue a Request with the annotations of the object in the CreateEvent", func() { evt := event.CreateEvent{ Object: pod, Meta: pod.GetObjectMeta(), @@ -71,5 +89,344 @@ var _ = Describe("EventHandler", func() { })) }) + + It("should enqueue a Request with the annotations of the object in the DeleteEvent", func() { + evt := event.DeleteEvent{ + Object: pod, + Meta: pod.GetObjectMeta(), + } + instance.Delete(evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: podOwner.Namespace, + Name: podOwner.Name, + }, + })) + }) + + It("should enqueue a Request with annotations applied to both objects in UpdateEvent", func() { + newPod := pod.DeepCopy() + newPod.Name = pod.Name + "2" + newPod.Namespace = pod.Namespace + "2" + + evt := event.UpdateEvent{ + ObjectOld: pod, + MetaOld: pod.GetObjectMeta(), + ObjectNew: newPod, + MetaNew: newPod.GetObjectMeta(), + } + + instance.Update(evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: podOwner.Namespace, + Name: podOwner.Name, + }, + })) + }) + + It("should enqueue a Request with the annotations applied in one of the objects in UpdateEvent", func() { + newPod := pod.DeepCopy() + newPod.Name = pod.Name + "2" + newPod.Namespace = pod.Namespace + "2" + newPod.Annotations = map[string]string{} + + evt := event.UpdateEvent{ + ObjectOld: pod, + MetaOld: pod.GetObjectMeta(), + ObjectNew: newPod, + MetaNew: newPod.GetObjectMeta(), + } + + instance.Update(evt, q) + Expect(q.Len()).To(Equal(1)) + i, _ := q.Get() + + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: podOwner.Namespace, + Name: podOwner.Name, + }, + })) + }) + + It("should enqueue a Request when the annotations are applied in new object in UpdateEvent", func() { + var repl *appsv1.ReplicaSet + + repl = &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "foo", + Name: "faz", + }, + } + instance = EnqueueRequestForAnnotation{Type: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}} + + evt := event.CreateEvent{ + Object: repl, + Meta: repl.GetObjectMeta(), + } + + instance.Create(evt, q) + Expect(q.Len()).To(Equal(0)) + + newRepl := repl.DeepCopy() + newRepl.Name = pod.Name + "2" + newRepl.Namespace = pod.Namespace + "2" + + newRepl.Annotations = map[string]string{ + TypeAnnotation: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}.String(), + NamespacedNameAnnotation: "foo/faz", + } + + instance2 := EnqueueRequestForAnnotation{Type: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}} + + evt2 := event.UpdateEvent{ + ObjectOld: repl, + MetaOld: repl.GetObjectMeta(), + ObjectNew: newRepl, + MetaNew: newRepl.GetObjectMeta(), + } + + instance2.Update(evt2, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: "foo", + Name: "faz", + }, + })) + }) + It("should enqueue a Request to the owner resource when the annotations are applied in child object"+ + "in the Create Event", func() { + var repl *appsv1.ReplicaSet + + repl = &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "foo", + Name: "faz", + }, + } + + err := SetOwnerAnnotation(podOwner, repl, schema.GroupKind{Group: "Pods", Kind: "core"}) + Expect(err).To(BeNil()) + + evt := event.CreateEvent{ + Object: repl, + Meta: repl.GetObjectMeta(), + } + + instance.Create(evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: podOwner.Namespace, + Name: podOwner.Name, + }, + })) + }) + + It("should enqueue a Request with the annotations of the object in the GenericEvent", func() { + evt := event.GenericEvent{ + Object: pod, + Meta: pod.GetObjectMeta(), + } + instance.Generic(evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: podOwner.Namespace, + Name: podOwner.Name, + }, + })) + }) + + It("should not enqueue a request if there are no annotations matching with the object", func() { + var repl *appsv1.ReplicaSet + + repl = &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "foo", + Name: "faz", + }, + } + + evt := event.CreateEvent{ + Object: repl, + Meta: repl.GetObjectMeta(), + } + + instance.Create(evt, q) + Expect(q.Len()).To(Equal(0)) + }) + + It("should not enqueue a Request if there is no Namespace and name annotation matching the specified object", func() { + var repl *appsv1.ReplicaSet + + repl = &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "foo", + Name: "faz", + Annotations: map[string]string{ + TypeAnnotation: schema.GroupKind{Group: "Pods", Kind: "core"}.String(), + }, + }, + } + + evt := event.CreateEvent{ + Object: repl, + Meta: repl.GetObjectMeta(), + } + + instance.Create(evt, q) + Expect(q.Len()).To(Equal(0)) + }) + + It("should not enqueue a Request if there is no TypeAnnotation matching Group and Kind", func() { + var repl *appsv1.ReplicaSet + + repl = &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "foo", + Name: "faz", + + Annotations: map[string]string{ + NamespacedNameAnnotation: "AppService", + }, + }, + } + + evt := event.CreateEvent{ + Object: repl, + Meta: repl.GetObjectMeta(), + } + + instance.Create(evt, q) + Expect(q.Len()).To(Equal(0)) + }) + + It("should enqueue a Request if there are no Namespace annotation matching for the object", func() { + var repl *appsv1.ReplicaSet + + repl = &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "foo", + Name: "faz", + Annotations: map[string]string{ + NamespacedNameAnnotation: "AppService", + TypeAnnotation: schema.GroupKind{Group: "Pods", Kind: "core"}.String(), + }, + }, + } + + evt := event.CreateEvent{ + Object: repl, + Meta: repl.GetObjectMeta(), + } + + instance.Create(evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "", Name: "AppService"}})) + }) + + It("should enqueue a Request for a object that is cluster scoped which has the annotations", func() { + var nd *corev1.Node + + nd = &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node-1", + Annotations: map[string]string{ + NamespacedNameAnnotation: "myapp", + TypeAnnotation: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}.String(), + }, + }, + } + + instance = EnqueueRequestForAnnotation{Type: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}} + + evt := event.CreateEvent{ + Object: nd, + Meta: nd.GetObjectMeta(), + } + + instance.Create(evt, q) + Expect(q.Len()).To(Equal(1)) + + i, _ := q.Get() + Expect(i).To(Equal(reconcile.Request{ + NamespacedName: types.NamespacedName{Namespace: "", Name: "myapp"}})) + }) + + It("should not enqueue a Request for a object that is cluster scoped which does not have annotations", func() { + var nd *corev1.Node + + nd = &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "node-1"}, + } + + instance = EnqueueRequestForAnnotation{Type: nd.GetObjectKind().GroupVersionKind().GroupKind()} + evt := event.CreateEvent{ + Object: nd, + Meta: nd.GetObjectMeta(), + } + + instance.Create(evt, q) + Expect(q.Len()).To(Equal(0)) + }) + }) + + Describe("EnqueueRequestForAnnotation.SetWatchOwnerAnnotation", func() { + It("should add the watch owner annotations without losing existing ones", func() { + var nd *corev1.Node + nd = &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node-1", + Annotations: map[string]string{ + "my-test-annotation": "should-keep", + }, + }, + } + + err := SetOwnerAnnotation(podOwner, nd, schema.GroupKind{Group: "Pods", Kind: "core"}) + Expect(err).To(BeNil()) + + expected := map[string]string{ + "my-test-annotation": "should-keep", + NamespacedNameAnnotation: fmt.Sprintf("%v/%v", podOwner.GetNamespace(), podOwner.GetName()), + TypeAnnotation: schema.GroupKind{Group: "Pods", Kind: "core"}.String(), + } + + Expect(len(nd.GetAnnotations())).To(Equal(3)) + Expect(nd.GetAnnotations()).To(Equal(expected)) + }) + + It("should return error when the owner Group or Kind is not informed", func() { + var nd *corev1.Node + nd = &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node-1", + }, + } + + err := SetOwnerAnnotation(podOwner, nd, schema.GroupKind{Group: "", Kind: "core"}) + Expect(err).NotTo(BeNil()) + + err = SetOwnerAnnotation(podOwner, nd, schema.GroupKind{Group: "Pod", Kind: ""}) + Expect(err).NotTo(BeNil()) + }) }) }) From 4ecafff60d4c67f5cfa56a5b12e51ab812a51f8d Mon Sep 17 00:00:00 2001 From: varshaprasad96 Date: Tue, 21 Jul 2020 11:47:17 -0700 Subject: [PATCH 3/4] handler: comment enqueue_annotation.go --- go.mod | 6 -- go.sum | 35 +--------- handler/enqueue_annotation.go | 87 ++++++++++++++++++------ handler/enqueue_annotation_suite_test.go | 2 +- 4 files changed, 67 insertions(+), 63 deletions(-) diff --git a/go.mod b/go.mod index 68a858e..fe37534 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,8 @@ module github.com/operator-framework/operator-lib go 1.13 require ( - github.com/go-logr/zapr v0.1.1 // indirect - github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect - github.com/hashicorp/golang-lru v0.5.3 // indirect - github.com/imdario/mergo v0.3.8 // indirect github.com/onsi/ginkgo v1.12.0 github.com/onsi/gomega v1.9.0 - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.5.1 // indirect github.com/stretchr/testify v1.5.1 k8s.io/api v0.18.2 k8s.io/apimachinery v0.18.2 diff --git a/go.sum b/go.sum index 3896288..68f7186 100644 --- a/go.sum +++ b/go.sum @@ -19,9 +19,7 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -29,13 +27,9 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -76,15 +70,11 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= -github.com/go-logr/zapr v0.1.1 h1:qXBXPDdNncunGs7XeEpsJt8wCjYBygluzfdLO0G5baE= -github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -137,8 +127,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -151,9 +139,6 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -177,24 +162,18 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -252,16 +231,12 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA= -github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -269,13 +244,9 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -380,9 +351,8 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -407,8 +377,6 @@ golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -443,7 +411,6 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= diff --git a/handler/enqueue_annotation.go b/handler/enqueue_annotation.go index c5dc5b8..d2aa4d3 100644 --- a/handler/enqueue_annotation.go +++ b/handler/enqueue_annotation.go @@ -32,22 +32,73 @@ var log = logf.Log.WithName("event_handler") const ( // NamespacedNameAnnotation - annotation that will be used to get the primary resource namespaced name. - // The handler will use this value to build the types.NamespacedName Object used to enqueue a Request when an event + // The handler will use this value to build types.NamespacedName Object used to enqueue a Request when an event // to update, create or delete the observed object is raised. - // Note: If only one value is provided without "/", then it will be used as the name of primary resource + // Note: If only one value is provided without "/", then it will be used as the name of primary resource. NamespacedNameAnnotation = "operator-sdk/primary-resource" - // TypeAnnotation - annotation that will be used to verify that the primary resource is the primary resource to use. - // It is of the form type:schema.GroupKind, eg: operator-sdk/owner-type:core.Pods + // TypeAnnotation - annotation that will be used to verify that the primary resource is the one to use. + // It is of the form type:schema.GroupKind, eg: operator-sdk/primary-resource-type:core.Pods TypeAnnotation = "operator-sdk/primary-resource-type" ) // EnqueueRequestForAnnotation enqueues Requests based on the presence of an annotation that contains the // namespaced name of the primary resource. +// The purpose of this handler is to support cross-scope ownership +// relationships that are not supported by native owner references. // -// The primary usecase for this, is to have a controller enqueue requests for the following scenarios -// 1. namespaced primary object and dependent cluster scoped resource -// 2. cluster scoped primary object. -// 3. namespaced primary object and dependent namespaced scoped but in a different namespace object. +// This handler should ALWAYS be paired with a finalizer on the primary resource. While the +// annotation-based watch handler does not have the same scope restrictions that owner references +// do, they also do not have the garbage collection guarantees that owner references do. Therefore, +// if the reconciler of a primary resource creates a child resource across scopes not supported by +// owner references, it is up to the reconciler to clean up that child resource. + +// **Examples:** +// +// The following code will enqueue a Request to the `primary-resource-namespace` when some change occurs in a Pod +// resource: +// +// ... +// annotation := schema.GroupKind{Group: "ReplicaSet", Kind: "apps"} +// if err := c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForAnnotation{annotation}); err != nil { +// entryLog.Error(err, "unable to watch Pods") +// os.Exit(1) +// } +// ... +// +// With the annotations: +// +// ... +// annotations: +// operator-sdk/primary-resource:my-namespace/my-replicaset +// operator-sdk/primary-resource-type:apps.ReplicaSet +// ... +// +// The following code will enqueue a Request to the `primary-resource-namespace`, ReplicaSet reconcile, +// when some change occurs in a ClusterRole resource +// +// ... +// if err := c.Watch(&source.Kind{ +// // Watch cluster roles +// Type: &rbacv1.ClusterRole{}}, +// +// // Enqueue ReplicaSet reconcile requests using the +// // namespacedName annotation value in the request. +// &handler.EnqueueRequestForAnnotation{schema.GroupKind{Group:"ReplicaSet", Kind:"apps"}}); err != nil { +// entryLog.Error(err, "unable to watch ClusterRole") +// os.Exit(1) +// } +// } +// ... +// With the annotations: +// +// ... +// annotations: +// operator-sdk/primary-resource:my-namespace/my-replicaset +// operator-sdk/primary-resource-type:apps.ReplicaSet +// ... +// +// **NOTE** Cluster-scoped resources will have the NamespacedNameAnnotation such as: +// `operator-sdk/primary-resource:my-replicaset type EnqueueRequestForAnnotation struct { Type schema.GroupKind } @@ -85,6 +136,7 @@ func (e *EnqueueRequestForAnnotation) Generic(evt event.GenericEvent, q workqueu } } +// getAnnotationRequests will check if the object has the annotations for the watch handler and requeue. func (e *EnqueueRequestForAnnotation) getAnnotationRequests(object metav1.Object) (bool, reconcile.Request) { if typeString, ok := object.GetAnnotations()[TypeAnnotation]; ok && typeString == e.Type.String() { namespacedNameString, ok := object.GetAnnotations()[NamespacedNameAnnotation] @@ -100,6 +152,8 @@ func (e *EnqueueRequestForAnnotation) getAnnotationRequests(object metav1.Object return false, reconcile.Request{} } +// parseNamespacedName will parse the value informed in the NamespacedNameAnnotation and return types.NamespacedName. +// Note that if just one value is informed, then it will be set as the name. func parseNamespacedName(namespacedNameString string) types.NamespacedName { values := strings.SplitN(namespacedNameString, "/", 2) if len(values) == 1 { @@ -117,20 +171,9 @@ func parseNamespacedName(namespacedNameString string) types.NamespacedName { return types.NamespacedName{} } -// SetOwnerAnnotation sets annotations for dependent resources that needs to be watched by namespaced Owners. -// func SetOwnerAnnotation(u *unstructured.Unstructured, owner *unstructured.Unstructured) { -// a := u.GetAnnotations() -// if a == nil { -// a = map[string]string{} -// } - -// nn := types.NamespacedName{Namespace: owner.GetNamespace(), Name: owner.GetName()} -// a[NamespacedNameAnnotation] = nn.String() - -// a[TypeAnnotation] = owner.GetObjectKind().GroupVersionKind().GroupKind().String() -// u.SetAnnotations(a) -// } - +// SetWatchOwnerAnnotation is a helper method to add watch annotation-based with the owner NamespacedName and +// schema.GroupKind to the object provided. This allows you to declare the watch annotations of an owner to an object. +// If a annotation to the same object already exists, it'll be overwritten with the newly provided version. func SetOwnerAnnotation(owner, object metav1.Object, ownerGK schema.GroupKind) error { if len(owner.GetName()) < 1 { return fmt.Errorf("%T does not have a name, cannot call SetOwnerAnnotation", owner) diff --git a/handler/enqueue_annotation_suite_test.go b/handler/enqueue_annotation_suite_test.go index 94223a7..33257f2 100644 --- a/handler/enqueue_annotation_suite_test.go +++ b/handler/enqueue_annotation_suite_test.go @@ -28,7 +28,7 @@ import ( func TestEventhandler(t *testing.T) { RegisterFailHandler(Fail) - RunSpecsWithDefaultAndCustomReporters(t, "Enqueue_anootation Suite", []Reporter{printer.NewlineReporter{}}) + RunSpecsWithDefaultAndCustomReporters(t, "Enqueue_annotation Suite", []Reporter{printer.NewlineReporter{}}) } var testenv *envtest.Environment From bc589e5f51243ef30460d4afd496c82cf304926c Mon Sep 17 00:00:00 2001 From: varshaprasad96 Date: Wed, 22 Jul 2020 11:44:15 -0700 Subject: [PATCH 4/4] handler: address review comments, remove unused code --- go.mod | 12 +- go.sum | 82 +++++++-- handler/enqueue_annotation.go | 137 +++++++-------- ...on_suite_test.go => handler_suite_test.go} | 22 +-- ...eue_annotation_test.go => handler_test.go} | 164 ++++++++++-------- 5 files changed, 226 insertions(+), 191 deletions(-) rename handler/{enqueue_annotation_suite_test.go => handler_suite_test.go} (57%) rename handler/{enqueue_annotation_test.go => handler_test.go} (73%) diff --git a/go.mod b/go.mod index fe37534..5de892e 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,11 @@ module github.com/operator-framework/operator-lib go 1.13 require ( - github.com/onsi/ginkgo v1.12.0 - github.com/onsi/gomega v1.9.0 + github.com/onsi/ginkgo v1.12.1 + github.com/onsi/gomega v1.10.1 github.com/stretchr/testify v1.5.1 - k8s.io/api v0.18.2 - k8s.io/apimachinery v0.18.2 - k8s.io/client-go v0.18.2 - sigs.k8s.io/controller-runtime v0.6.0 + k8s.io/api v0.18.4 + k8s.io/apimachinery v0.18.4 + k8s.io/client-go v0.18.4 + sigs.k8s.io/controller-runtime v0.6.1 ) diff --git a/go.sum b/go.sum index 68f7186..cb497ce 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,8 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -65,6 +67,8 @@ github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -134,11 +138,21 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -162,18 +176,22 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -211,20 +229,20 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= -github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -247,6 +265,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI= +github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -325,6 +345,8 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= @@ -349,15 +371,22 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= @@ -377,6 +406,8 @@ golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -392,6 +423,13 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -413,34 +451,48 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= -k8s.io/apiextensions-apiserver v0.18.2 h1:I4v3/jAuQC+89L3Z7dDgAiN4EOjN6sbm6iBqQwHTah8= -k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= +k8s.io/api v0.18.4 h1:8x49nBRxuXGUlDlwlWd3RMY1SayZrzFfxea3UZSkFw4= +k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4= +k8s.io/apiextensions-apiserver v0.18.4 h1:Y3HGERmS8t9u12YNUFoOISqefaoGRuTc43AYCLzWmWE= +k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio= k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= +k8s.io/apimachinery v0.18.4 h1:ST2beySjhqwJoIFk6p7Hp5v5O0hYY6Gngq/gUYXTPIA= +k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8= k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE= k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= -k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= -k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= +k8s.io/client-go v0.18.4 h1:un55V1Q/B3JO3A76eS0kUSywgGK/WR3BQ8fHQjNa6Zc= +k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g= +k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0 h1:Foj74zO6RbjjP4hBEKjnYtjjAhGg4jNynUdYF6fJrok= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDNZ16KJtb49HfR3ZHB9qYXM= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 h1:v8ud2Up6QK1lNOKFgiIVrZdMg7MpmSnvtrOieolJKoE= +k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= -sigs.k8s.io/controller-runtime v0.6.0 h1:Fzna3DY7c4BIP6KwfSlrfnj20DJ+SeMBK8HSFvOk9NM= -sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= +sigs.k8s.io/controller-runtime v0.6.1 h1:LcK2+nk0kmaOnKGN+vBcWHqY5WDJNJNB/c5pW+sU8fc= +sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= diff --git a/handler/enqueue_annotation.go b/handler/enqueue_annotation.go index d2aa4d3..79b7a31 100644 --- a/handler/enqueue_annotation.go +++ b/handler/enqueue_annotation.go @@ -22,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/event" crtHandler "sigs.k8s.io/controller-runtime/pkg/handler" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -31,74 +32,53 @@ import ( var log = logf.Log.WithName("event_handler") const ( - // NamespacedNameAnnotation - annotation that will be used to get the primary resource namespaced name. - // The handler will use this value to build types.NamespacedName Object used to enqueue a Request when an event - // to update, create or delete the observed object is raised. - // Note: If only one value is provided without "/", then it will be used as the name of primary resource. + // NamespacedNameAnnotation is an annotation whose value encodes the name and namespace of a resource to reconcile + // when a resource containing this annotation changes. Valid values are of the form `/` for + // namespace-scoped owners and `` for cluster-scoped owners. NamespacedNameAnnotation = "operator-sdk/primary-resource" - // TypeAnnotation - annotation that will be used to verify that the primary resource is the one to use. - // It is of the form type:schema.GroupKind, eg: operator-sdk/primary-resource-type:core.Pods + // TypeAnnotation is an annotation whose value encodes the group and kind of a resource to reconcil when a + // resource containing this annotation changes. Valid values are of the form `` for resource in the + // core group, and `.` for all other resources. TypeAnnotation = "operator-sdk/primary-resource-type" ) -// EnqueueRequestForAnnotation enqueues Requests based on the presence of an annotation that contains the -// namespaced name of the primary resource. -// The purpose of this handler is to support cross-scope ownership -// relationships that are not supported by native owner references. -// -// This handler should ALWAYS be paired with a finalizer on the primary resource. While the -// annotation-based watch handler does not have the same scope restrictions that owner references -// do, they also do not have the garbage collection guarantees that owner references do. Therefore, -// if the reconciler of a primary resource creates a child resource across scopes not supported by -// owner references, it is up to the reconciler to clean up that child resource. +// EnqueueRequestForAnnotation enqueues Request containing the Name and Namespace specified in the +// annotations of the object that is the source of the Event. The source of the event triggers reconciliation +// of the parent resource which is identified by annotations. `NamespacedNameAnnotation` and `TypeAnnotation` together uniquely +// identify an owner resource to reconcile. +// handler.EnqueueRequestForAnnotation can be used to trigger reconciliation of resources which are cross-referenced. +// This allows a namespace-scoped dependent to trigger reconciliation of an owner which is in a different namespace, and +// a cluster-scoped dependent can trigger the reconciliation of a namespace(scoped)-owner. + +// As an example, consider the case where we would like to watch clusterroles based on which we reconcile namespace-scoped replicasets. +// With native owner references, this would not be possible since the cluster-scoped dependent (clusterroles) is trying to +// specify a namespace-scoped owner (replicasets). Whereas in case of annotations-based handlers, we could implement the following: -// **Examples:** -// -// The following code will enqueue a Request to the `primary-resource-namespace` when some change occurs in a Pod -// resource: -// -// ... -// annotation := schema.GroupKind{Group: "ReplicaSet", Kind: "apps"} -// if err := c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForAnnotation{annotation}); err != nil { -// entryLog.Error(err, "unable to watch Pods") -// os.Exit(1) -// } -// ... -// -// With the annotations: -// -// ... -// annotations: -// operator-sdk/primary-resource:my-namespace/my-replicaset -// operator-sdk/primary-resource-type:apps.ReplicaSet -// ... -// -// The following code will enqueue a Request to the `primary-resource-namespace`, ReplicaSet reconcile, -// when some change occurs in a ClusterRole resource -// // ... // if err := c.Watch(&source.Kind{ -// // Watch cluster roles +// // Watch clusterroles // Type: &rbacv1.ClusterRole{}}, // -// // Enqueue ReplicaSet reconcile requests using the -// // namespacedName annotation value in the request. -// &handler.EnqueueRequestForAnnotation{schema.GroupKind{Group:"ReplicaSet", Kind:"apps"}}); err != nil { +// // Enqueue ReplicaSet reconcile requests using the namespacedName annotation value in the request. +// &handler.EnqueueRequestForAnnotation{schema.GroupKind{Group:"apps", Kind:"ReplicaSet"}}); err != nil { // entryLog.Error(err, "unable to watch ClusterRole") // os.Exit(1) // } // } // ... -// With the annotations: + +// With this watch, the ReplicaSet reconciler would receive a request to reconcile "my-namespace/my-replicaset" based +// on a change to a ClusterRole that has the following annotations: // -// ... // annotations: -// operator-sdk/primary-resource:my-namespace/my-replicaset -// operator-sdk/primary-resource-type:apps.ReplicaSet -// ... +// operator-sdk/primary-resource:"my-namespace/my-replicaset" +// operator-sdk/primary-resource-type:"ReplicaSet.apps" // -// **NOTE** Cluster-scoped resources will have the NamespacedNameAnnotation such as: -// `operator-sdk/primary-resource:my-replicaset +// Though an annotation-based watch handler removes the boundaries set by native owner reference implementation, +// the garbage collector still respects the scope restrictions. For example, +// if a parent creates a child resource across scopes not supported by owner references, it becomes the +// responsibility of the reconciler to clean up the child resource. Hence, the resource utilizing this handler +// SHOULD ALWAYS BE IMPLEMENTED WITH A FINALIZER. type EnqueueRequestForAnnotation struct { Type schema.GroupKind } @@ -136,14 +116,18 @@ func (e *EnqueueRequestForAnnotation) Generic(evt event.GenericEvent, q workqueu } } -// getAnnotationRequests will check if the object has the annotations for the watch handler and requeue. +// getAnnotationRequests checks if the provided object has the annotations so as to enqueue the reconcile request. func (e *EnqueueRequestForAnnotation) getAnnotationRequests(object metav1.Object) (bool, reconcile.Request) { + if len(object.GetAnnotations()) == 0 { + return false, reconcile.Request{} + } + if typeString, ok := object.GetAnnotations()[TypeAnnotation]; ok && typeString == e.Type.String() { namespacedNameString, ok := object.GetAnnotations()[NamespacedNameAnnotation] if !ok { log.Info("Unable to find namespaced name annotation for resource", "resource", object) } - if len(namespacedNameString) < 1 { + if strings.TrimSpace(namespacedNameString) == "" { return false, reconcile.Request{} } nsn := parseNamespacedName(namespacedNameString) @@ -152,46 +136,41 @@ func (e *EnqueueRequestForAnnotation) getAnnotationRequests(object metav1.Object return false, reconcile.Request{} } -// parseNamespacedName will parse the value informed in the NamespacedNameAnnotation and return types.NamespacedName. -// Note that if just one value is informed, then it will be set as the name. +// parseNamespacedName parses the provided string to extract the namespace and name into a +// types.NamespacedName. The edge case of empty string is handled prior to calling this function. func parseNamespacedName(namespacedNameString string) types.NamespacedName { values := strings.SplitN(namespacedNameString, "/", 2) - if len(values) == 1 { - return types.NamespacedName{ - Name: values[0], - Namespace: "", - } - } - if len(values) >= 2 { - return types.NamespacedName{ - Name: values[1], - Namespace: values[0], - } + + switch len(values) { + case 1: + return types.NamespacedName{Name: values[0]} + default: + return types.NamespacedName{Namespace: values[0], Name: values[1]} } - return types.NamespacedName{} } -// SetWatchOwnerAnnotation is a helper method to add watch annotation-based with the owner NamespacedName and -// schema.GroupKind to the object provided. This allows you to declare the watch annotations of an owner to an object. -// If a annotation to the same object already exists, it'll be overwritten with the newly provided version. -func SetOwnerAnnotation(owner, object metav1.Object, ownerGK schema.GroupKind) error { - if len(owner.GetName()) < 1 { - return fmt.Errorf("%T does not have a name, cannot call SetOwnerAnnotation", owner) +// SetOwnerAnnotations helps in adding 'NamespacedNameAnnotation' and 'TypeAnnotation' to object based on the values +// obtained from owner. The object gets the annotations from owner's namespace, name, group and kind. In other terms, +// object can be said to be the dependent having annotations from the owner. When a watch is set on the object, the +// annotations help to identify the owner and trigger reconciliation. +// Annotations are ALWAYS overwritten. +func SetOwnerAnnotations(owner, object controllerutil.Object) error { + if owner.GetName() == "" { + return fmt.Errorf("%T does not have a name, cannot call SetOwnerAnnotations", owner) } - if len(ownerGK.Kind) < 1 { - return fmt.Errorf("Owner Kind not found, cannot call SetOwnerAnnotation") - } + ownerGK := owner.GetObjectKind().GroupVersionKind().GroupKind() - if len(ownerGK.Group) < 1 { - return fmt.Errorf("Owner Group not found, cannot call SetOwnerAnnotation") + if ownerGK.Kind == "" { + return fmt.Errorf("Owner %s Kind not found, cannot call SetOwnerAnnotations", owner.GetName()) } annotations := object.GetAnnotations() if annotations == nil { annotations = map[string]string{} } - annotations[NamespacedNameAnnotation] = fmt.Sprintf("%v/%v", owner.GetNamespace(), owner.GetName()) + + annotations[NamespacedNameAnnotation] = fmt.Sprintf("%s/%s", owner.GetNamespace(), owner.GetName()) annotations[TypeAnnotation] = ownerGK.String() object.SetAnnotations(annotations) diff --git a/handler/enqueue_annotation_suite_test.go b/handler/handler_suite_test.go similarity index 57% rename from handler/enqueue_annotation_suite_test.go rename to handler/handler_suite_test.go index 33257f2..7a9c9f7 100644 --- a/handler/enqueue_annotation_suite_test.go +++ b/handler/handler_suite_test.go @@ -19,30 +19,10 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" "sigs.k8s.io/controller-runtime/pkg/envtest/printer" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" ) func TestEventhandler(t *testing.T) { RegisterFailHandler(Fail) - RunSpecsWithDefaultAndCustomReporters(t, "Enqueue_annotation Suite", []Reporter{printer.NewlineReporter{}}) + RunSpecsWithDefaultAndCustomReporters(t, "Handler Suite", []Reporter{printer.NewlineReporter{}}) } - -var testenv *envtest.Environment -var cfg *rest.Config - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.LoggerTo(GinkgoWriter, true)) - - testenv = &envtest.Environment{} - var err error - cfg, err = testenv.Start() - Expect(err).NotTo(HaveOccurred()) -}) - -var _ = AfterSuite(func() { - Expect(testenv.Stop()).To(Succeed()) -}) diff --git a/handler/enqueue_annotation_test.go b/handler/handler_test.go similarity index 73% rename from handler/enqueue_annotation_test.go rename to handler/handler_test.go index b1d4126..5df3194 100644 --- a/handler/enqueue_annotation_test.go +++ b/handler/handler_test.go @@ -15,17 +15,13 @@ package handler import ( - "fmt" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/controller/controllertest" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -33,17 +29,11 @@ import ( "k8s.io/client-go/util/workqueue" ) -var _ = Describe("Enqueue_anootation", func() { +var _ = Describe("EnqueueRequestForAnnotation", func() { var q workqueue.RateLimitingInterface var instance EnqueueRequestForAnnotation - var mapper meta.RESTMapper var pod *corev1.Pod - var podOwner = &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "podOwnerNs", - Name: "podOwnerName", - }, - } + var podOwner *corev1.Pod BeforeEach(func() { q = controllertest.Queue{Interface: workqueue.New()} @@ -53,25 +43,29 @@ var _ = Describe("Enqueue_anootation", func() { Name: "biz", }, } + podOwner = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "podOwnerNs", + Name: "podOwnerName", + }, + } + + podOwner.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Kind: "Pod"}) - err := SetOwnerAnnotation(podOwner, pod, schema.GroupKind{Group: "Pods", Kind: "core"}) + err := SetOwnerAnnotations(podOwner, pod) Expect(err).To(BeNil()) - Expect(cfg).NotTo(BeNil()) - mapper, err = apiutil.NewDiscoveryRESTMapper(cfg) - Expect(err).NotTo(HaveOccurred()) - Expect(mapper).NotTo(BeNil()) }) Describe("EnqueueRequestForAnnotation", func() { BeforeEach(func() { instance = EnqueueRequestForAnnotation{ Type: schema.GroupKind{ - Group: "Pods", - Kind: "core", + Group: "", + Kind: "Pod", }} }) - It("should enqueue a Request with the annotations of the object in the CreateEvent", func() { + It("should enqueue a Request with the annotations of the object in case of CreateEvent", func() { evt := event.CreateEvent{ Object: pod, Meta: pod.GetObjectMeta(), @@ -90,7 +84,7 @@ var _ = Describe("Enqueue_anootation", func() { }) - It("should enqueue a Request with the annotations of the object in the DeleteEvent", func() { + It("should enqueue a Request with the annotations of the object in case of DeleteEvent", func() { evt := event.DeleteEvent{ Object: pod, Meta: pod.GetObjectMeta(), @@ -112,6 +106,9 @@ var _ = Describe("Enqueue_anootation", func() { newPod.Name = pod.Name + "2" newPod.Namespace = pod.Namespace + "2" + err := SetOwnerAnnotations(podOwner, pod) + Expect(err).To(BeNil()) + evt := event.UpdateEvent{ ObjectOld: pod, MetaOld: pod.GetObjectMeta(), @@ -131,7 +128,36 @@ var _ = Describe("Enqueue_anootation", func() { })) }) - It("should enqueue a Request with the annotations applied in one of the objects in UpdateEvent", func() { + It("should enqueue multiple Update Requests when different annotations are applied to multiple objects", func() { + newPod := pod.DeepCopy() + newPod.Name = pod.Name + "2" + newPod.Namespace = pod.Namespace + "2" + + err := SetOwnerAnnotations(podOwner, pod) + Expect(err).To(BeNil()) + + var podOwner2 = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "podOwnerNsTest", + Name: "podOwnerNameTest", + }, + } + podOwner2.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Kind: "Pod"}) + + err = SetOwnerAnnotations(podOwner2, newPod) + Expect(err).To(BeNil()) + + evt := event.UpdateEvent{ + ObjectOld: pod, + MetaOld: pod.GetObjectMeta(), + ObjectNew: newPod, + MetaNew: newPod.GetObjectMeta(), + } + instance.Update(evt, q) + Expect(q.Len()).To(Equal(2)) + }) + + It("should enqueue a Request with the annotations applied in one of the objects in case of UpdateEvent", func() { newPod := pod.DeepCopy() newPod.Name = pod.Name + "2" newPod.Namespace = pod.Namespace + "2" @@ -156,16 +182,14 @@ var _ = Describe("Enqueue_anootation", func() { })) }) - It("should enqueue a Request when the annotations are applied in new object in UpdateEvent", func() { - var repl *appsv1.ReplicaSet - - repl = &appsv1.ReplicaSet{ + It("should enqueue a Request when the annotations are applied in a different resource in case of UpdateEvent", func() { + repl := &appsv1.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Namespace: "foo", Name: "faz", }, } - instance = EnqueueRequestForAnnotation{Type: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}} + instance = EnqueueRequestForAnnotation{Type: schema.GroupKind{Group: "apps", Kind: "ReplicaSet"}} evt := event.CreateEvent{ Object: repl, @@ -180,11 +204,11 @@ var _ = Describe("Enqueue_anootation", func() { newRepl.Namespace = pod.Namespace + "2" newRepl.Annotations = map[string]string{ - TypeAnnotation: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}.String(), + TypeAnnotation: schema.GroupKind{Group: "apps", Kind: "ReplicaSet"}.String(), NamespacedNameAnnotation: "foo/faz", } - instance2 := EnqueueRequestForAnnotation{Type: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}} + instance2 := EnqueueRequestForAnnotation{Type: schema.GroupKind{Group: "apps", Kind: "ReplicaSet"}} evt2 := event.UpdateEvent{ ObjectOld: repl, @@ -206,16 +230,14 @@ var _ = Describe("Enqueue_anootation", func() { }) It("should enqueue a Request to the owner resource when the annotations are applied in child object"+ "in the Create Event", func() { - var repl *appsv1.ReplicaSet - - repl = &appsv1.ReplicaSet{ + repl := &appsv1.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Namespace: "foo", Name: "faz", }, } - err := SetOwnerAnnotation(podOwner, repl, schema.GroupKind{Group: "Pods", Kind: "core"}) + err := SetOwnerAnnotations(podOwner, repl) Expect(err).To(BeNil()) evt := event.CreateEvent{ @@ -235,7 +257,7 @@ var _ = Describe("Enqueue_anootation", func() { })) }) - It("should enqueue a Request with the annotations of the object in the GenericEvent", func() { + It("should enqueue a Request with the annotations of the object in case of GenericEvent", func() { evt := event.GenericEvent{ Object: pod, Meta: pod.GetObjectMeta(), @@ -253,9 +275,7 @@ var _ = Describe("Enqueue_anootation", func() { }) It("should not enqueue a request if there are no annotations matching with the object", func() { - var repl *appsv1.ReplicaSet - - repl = &appsv1.ReplicaSet{ + repl := &appsv1.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Namespace: "foo", Name: "faz", @@ -271,15 +291,13 @@ var _ = Describe("Enqueue_anootation", func() { Expect(q.Len()).To(Equal(0)) }) - It("should not enqueue a Request if there is no Namespace and name annotation matching the specified object", func() { - var repl *appsv1.ReplicaSet - - repl = &appsv1.ReplicaSet{ + It("should not enqueue a Request if there is no Namespace and name annotation matching the specified object are found", func() { + repl := &appsv1.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Namespace: "foo", Name: "faz", Annotations: map[string]string{ - TypeAnnotation: schema.GroupKind{Group: "Pods", Kind: "core"}.String(), + TypeAnnotation: schema.GroupKind{Group: "", Kind: "Pod"}.String(), }, }, } @@ -293,10 +311,8 @@ var _ = Describe("Enqueue_anootation", func() { Expect(q.Len()).To(Equal(0)) }) - It("should not enqueue a Request if there is no TypeAnnotation matching Group and Kind", func() { - var repl *appsv1.ReplicaSet - - repl = &appsv1.ReplicaSet{ + It("should not enqueue a Request if there is no TypeAnnotation matching the specified Group and Kind", func() { + repl := &appsv1.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Namespace: "foo", Name: "faz", @@ -316,16 +332,14 @@ var _ = Describe("Enqueue_anootation", func() { Expect(q.Len()).To(Equal(0)) }) - It("should enqueue a Request if there are no Namespace annotation matching for the object", func() { - var repl *appsv1.ReplicaSet - - repl = &appsv1.ReplicaSet{ + It("should enqueue a Request if there are no Namespace annotation matching the object", func() { + repl := &appsv1.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ Namespace: "foo", Name: "faz", Annotations: map[string]string{ NamespacedNameAnnotation: "AppService", - TypeAnnotation: schema.GroupKind{Group: "Pods", Kind: "core"}.String(), + TypeAnnotation: schema.GroupKind{Group: "", Kind: "Pod"}.String(), }, }, } @@ -344,19 +358,17 @@ var _ = Describe("Enqueue_anootation", func() { }) It("should enqueue a Request for a object that is cluster scoped which has the annotations", func() { - var nd *corev1.Node - - nd = &corev1.Node{ + nd := &corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: "node-1", Annotations: map[string]string{ NamespacedNameAnnotation: "myapp", - TypeAnnotation: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}.String(), + TypeAnnotation: schema.GroupKind{Group: "apps", Kind: "ReplicaSet"}.String(), }, }, } - instance = EnqueueRequestForAnnotation{Type: schema.GroupKind{Group: "ReplicaSet", Kind: "apps"}} + instance = EnqueueRequestForAnnotation{Type: schema.GroupKind{Group: "apps", Kind: "ReplicaSet"}} evt := event.CreateEvent{ Object: nd, @@ -372,9 +384,7 @@ var _ = Describe("Enqueue_anootation", func() { }) It("should not enqueue a Request for a object that is cluster scoped which does not have annotations", func() { - var nd *corev1.Node - - nd = &corev1.Node{ + nd := &corev1.Node{ ObjectMeta: metav1.ObjectMeta{Name: "node-1"}, } @@ -389,10 +399,9 @@ var _ = Describe("Enqueue_anootation", func() { }) }) - Describe("EnqueueRequestForAnnotation.SetWatchOwnerAnnotation", func() { + Describe("SetWatchOwnerAnnotation", func() { It("should add the watch owner annotations without losing existing ones", func() { - var nd *corev1.Node - nd = &corev1.Node{ + nd := &corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: "node-1", Annotations: map[string]string{ @@ -401,32 +410,47 @@ var _ = Describe("Enqueue_anootation", func() { }, } - err := SetOwnerAnnotation(podOwner, nd, schema.GroupKind{Group: "Pods", Kind: "core"}) + err := SetOwnerAnnotations(podOwner, nd) Expect(err).To(BeNil()) expected := map[string]string{ "my-test-annotation": "should-keep", - NamespacedNameAnnotation: fmt.Sprintf("%v/%v", podOwner.GetNamespace(), podOwner.GetName()), - TypeAnnotation: schema.GroupKind{Group: "Pods", Kind: "core"}.String(), + NamespacedNameAnnotation: "podOwnerNs/podOwnerName", + TypeAnnotation: schema.GroupKind{Group: "", Kind: "Pod"}.String(), } Expect(len(nd.GetAnnotations())).To(Equal(3)) Expect(nd.GetAnnotations()).To(Equal(expected)) }) - It("should return error when the owner Group or Kind is not informed", func() { - var nd *corev1.Node - nd = &corev1.Node{ + It("should return error when the owner Kind is not present", func() { + nd := &corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: "node-1", }, } - err := SetOwnerAnnotation(podOwner, nd, schema.GroupKind{Group: "", Kind: "core"}) + podOwner.SetGroupVersionKind(schema.GroupVersionKind{Group: "Pod", Kind: ""}) + err := SetOwnerAnnotations(podOwner, nd) Expect(err).NotTo(BeNil()) + }) + It("should return an error when the owner Name is not set", func() { + nd := &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node-1", + }, + } - err = SetOwnerAnnotation(podOwner, nd, schema.GroupKind{Group: "Pod", Kind: ""}) + ownerNew := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "newpodOwnerNs", + }, + } + + ownerNew.SetGroupVersionKind(schema.GroupVersionKind{Group: "Pod", Kind: ""}) + err := SetOwnerAnnotations(ownerNew, nd) Expect(err).NotTo(BeNil()) }) + }) })