diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index c4398777e1..f81bdcda44 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "net/http" - "reflect" "time" "k8s.io/apimachinery/pkg/api/meta" @@ -233,183 +232,6 @@ func New(config *rest.Config, opts Options) (Cache, error) { }, nil } -// BuilderWithOptions returns a Cache constructor that will build a cache -// honoring the options argument, this is useful to specify options like -// ByObjects, DefaultSelector, DefaultTransform, etc. -// WARNING: If ByObject selectors are specified, filtered out resources are not -// returned. -// WARNING: If ByObject UnsafeDisableDeepCopy is enabled, you must DeepCopy any object -// returned from cache get/list before mutating it. -func BuilderWithOptions(options Options) NewCacheFunc { - return func(config *rest.Config, inherited Options) (Cache, error) { - var err error - inherited, err = defaultOpts(config, inherited) - if err != nil { - return nil, err - } - options, err = defaultOpts(config, options) - if err != nil { - return nil, err - } - combined, err := options.inheritFrom(inherited) - if err != nil { - return nil, err - } - return New(config, *combined) - } -} - -func (options Options) inheritFrom(inherited Options) (*Options, error) { - var ( - combined Options - err error - ) - combined.Scheme = combineScheme(inherited.Scheme, options.Scheme) - combined.Mapper = selectMapper(inherited.Mapper, options.Mapper) - combined.SyncPeriod = selectResync(inherited.SyncPeriod, options.SyncPeriod) - combined.Namespaces = selectNamespaces(inherited.Namespaces, options.Namespaces) - combined.DefaultLabelSelector = combineSelector( - internal.Selector{Label: inherited.DefaultLabelSelector}, - internal.Selector{Label: options.DefaultLabelSelector}, - ).Label - combined.DefaultFieldSelector = combineSelector( - internal.Selector{Field: inherited.DefaultFieldSelector}, - internal.Selector{Field: options.DefaultFieldSelector}, - ).Field - combined.DefaultTransform = combineTransform(inherited.DefaultTransform, options.DefaultTransform) - combined.ByObject, err = combineByObject(inherited, options, combined.Scheme) - if options.UnsafeDisableDeepCopy != nil { - combined.UnsafeDisableDeepCopy = options.UnsafeDisableDeepCopy - } else { - combined.UnsafeDisableDeepCopy = inherited.UnsafeDisableDeepCopy - } - if err != nil { - return nil, err - } - return &combined, nil -} - -func combineScheme(schemes ...*runtime.Scheme) *runtime.Scheme { - var out *runtime.Scheme - for _, sch := range schemes { - if sch == nil { - continue - } - for gvk, t := range sch.AllKnownTypes() { - if out == nil { - out = runtime.NewScheme() - } - out.AddKnownTypeWithName(gvk, reflect.New(t).Interface().(runtime.Object)) - } - } - return out -} - -func selectMapper(def, override meta.RESTMapper) meta.RESTMapper { - if override != nil { - return override - } - return def -} - -func selectResync(def, override *time.Duration) *time.Duration { - if override != nil { - return override - } - return def -} - -func selectNamespaces(def, override []string) []string { - if len(override) > 0 { - return override - } - return def -} - -func combineByObject(inherited, options Options, scheme *runtime.Scheme) (map[client.Object]ByObject, error) { - optionsByGVK, err := convertToInformerOptsByGVK(options.ByObject, scheme) - if err != nil { - return nil, err - } - inheritedByGVK, err := convertToInformerOptsByGVK(inherited.ByObject, scheme) - if err != nil { - return nil, err - } - for gvk, inheritedByGVK := range inheritedByGVK { - unsafeDisableDeepCopy := options.UnsafeDisableDeepCopy - if current, ok := optionsByGVK[gvk]; ok { - unsafeDisableDeepCopy = current.UnsafeDisableDeepCopy - } - optionsByGVK[gvk] = internal.InformersOptsByGVK{ - Selector: combineSelector(inheritedByGVK.Selector, optionsByGVK[gvk].Selector), - Transform: combineTransform(inheritedByGVK.Transform, optionsByGVK[gvk].Transform), - UnsafeDisableDeepCopy: unsafeDisableDeepCopy, - } - } - return convertToByObject(optionsByGVK, scheme) -} - -func combineSelector(selectors ...internal.Selector) internal.Selector { - ls := make([]labels.Selector, 0, len(selectors)) - fs := make([]fields.Selector, 0, len(selectors)) - for _, s := range selectors { - ls = append(ls, s.Label) - fs = append(fs, s.Field) - } - return internal.Selector{ - Label: combineLabelSelectors(ls...), - Field: combineFieldSelectors(fs...), - } -} - -func combineLabelSelectors(ls ...labels.Selector) labels.Selector { - var combined labels.Selector - for _, l := range ls { - if l == nil { - continue - } - if combined == nil { - combined = labels.NewSelector() - } - reqs, _ := l.Requirements() - combined = combined.Add(reqs...) - } - return combined -} - -func combineFieldSelectors(fs ...fields.Selector) fields.Selector { - nonNil := fs[:0] - for _, f := range fs { - if f == nil { - continue - } - nonNil = append(nonNil, f) - } - if len(nonNil) == 0 { - return nil - } - if len(nonNil) == 1 { - return nonNil[0] - } - return fields.AndSelectors(nonNil...) -} - -func combineTransform(inherited, current toolscache.TransformFunc) toolscache.TransformFunc { - if inherited == nil { - return current - } - if current == nil { - return inherited - } - return func(in interface{}) (interface{}, error) { - mid, err := inherited(in) - if err != nil { - return nil, err - } - return current(mid) - } -} - func defaultOpts(config *rest.Config, opts Options) (Options, error) { logger := log.WithName("setup") @@ -466,28 +288,3 @@ func convertToInformerOptsByGVK(in map[client.Object]ByObject, scheme *runtime.S } return out, nil } - -func convertToByObject(in map[schema.GroupVersionKind]internal.InformersOptsByGVK, scheme *runtime.Scheme) (map[client.Object]ByObject, error) { - out := map[client.Object]ByObject{} - for gvk, opts := range in { - if gvk == (schema.GroupVersionKind{}) { - continue - } - obj, err := scheme.New(gvk) - if err != nil { - return nil, err - } - cObj, ok := obj.(client.Object) - if !ok { - return nil, fmt.Errorf("object %T for GVK %q does not implement client.Object", obj, gvk) - } - cObj.GetObjectKind().SetGroupVersionKind(gvk) - out[cObj] = ByObject{ - Field: opts.Selector.Field, - Label: opts.Selector.Label, - Transform: opts.Transform, - UnsafeDisableDeepCopy: opts.UnsafeDisableDeepCopy, - } - } - return out, nil -} diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go index 36213c6ffd..7f9ed975d6 100644 --- a/pkg/cache/cache_test.go +++ b/pkg/cache/cache_test.go @@ -1223,17 +1223,14 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca } DescribeTable(" and cache with selectors", func(tc selectorsTestCase) { By("creating the cache") - builder := cache.BuilderWithOptions( - cache.Options{ - ByObject: map[client.Object]cache.ByObject{ - &corev1.Pod{}: { - Label: labels.Set(tc.labelSelectors).AsSelector(), - Field: fields.Set(tc.fieldSelectors).AsSelector(), - }, + informer, err := cache.New(cfg, cache.Options{ + ByObject: map[client.Object]cache.ByObject{ + &corev1.Pod{}: { + Label: labels.Set(tc.labelSelectors).AsSelector(), + Field: fields.Set(tc.fieldSelectors).AsSelector(), }, }, - ) - informer, err := builder(cfg, cache.Options{}) + }) Expect(err).NotTo(HaveOccurred()) By("running the cache and waiting for it to sync") diff --git a/pkg/cache/cache_unit_test.go b/pkg/cache/cache_unit_test.go deleted file mode 100644 index 1be46e7f79..0000000000 --- a/pkg/cache/cache_unit_test.go +++ /dev/null @@ -1,563 +0,0 @@ -package cache - -import ( - "reflect" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/utils/pointer" - - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var _ = Describe("cache.inheritFrom", func() { - defer GinkgoRecover() - - var ( - inherited Options - specified Options - gv schema.GroupVersion - coreScheme *runtime.Scheme - ) - - BeforeEach(func() { - inherited = Options{} - specified = Options{} - gv = schema.GroupVersion{ - Group: "example.com", - Version: "v1alpha1", - } - coreScheme = runtime.NewScheme() - Expect(scheme.AddToScheme(coreScheme)).To(Succeed()) - }) - - Context("Scheme", func() { - It("is nil when specified and inherited are unset", func() { - Expect(checkError(specified.inheritFrom(inherited)).Scheme).To(BeNil()) - }) - It("is specified when only specified is set", func() { - specified.Scheme = runtime.NewScheme() - specified.Scheme.AddKnownTypes(gv, &unstructured.Unstructured{}) - Expect(specified.Scheme.KnownTypes(gv)).To(HaveLen(1)) - - Expect(checkError(specified.inheritFrom(inherited)).Scheme.KnownTypes(gv)).To(HaveLen(1)) - }) - It("is inherited when only inherited is set", func() { - inherited.Scheme = runtime.NewScheme() - inherited.Scheme.AddKnownTypes(gv, &unstructured.Unstructured{}) - Expect(inherited.Scheme.KnownTypes(gv)).To(HaveLen(1)) - - combined := checkError(specified.inheritFrom(inherited)) - Expect(combined.Scheme).NotTo(BeNil()) - Expect(combined.Scheme.KnownTypes(gv)).To(HaveLen(1)) - }) - It("is combined when both inherited and specified are set", func() { - specified.Scheme = runtime.NewScheme() - specified.Scheme.AddKnownTypes(gv, &unstructured.Unstructured{}) - Expect(specified.Scheme.AllKnownTypes()).To(HaveLen(1)) - - inherited.Scheme = runtime.NewScheme() - inherited.Scheme.AddKnownTypes(schema.GroupVersion{Group: "example.com", Version: "v1"}, &unstructured.Unstructured{}) - Expect(inherited.Scheme.AllKnownTypes()).To(HaveLen(1)) - - Expect(checkError(specified.inheritFrom(inherited)).Scheme.AllKnownTypes()).To(HaveLen(2)) - }) - }) - Context("Mapper", func() { - It("is nil when specified and inherited are unset", func() { - Expect(checkError(specified.inheritFrom(inherited)).Mapper).To(BeNil()) - }) - It("is unchanged when only specified is set", func() { - specified.Mapper = meta.NewDefaultRESTMapper(nil) - Expect(checkError(specified.inheritFrom(inherited)).Mapper).To(Equal(specified.Mapper)) - }) - It("is inherited when only inherited is set", func() { - inherited.Mapper = meta.NewDefaultRESTMapper(nil) - Expect(checkError(specified.inheritFrom(inherited)).Mapper).To(Equal(inherited.Mapper)) - }) - It("is unchanged when both inherited and specified are set", func() { - specified.Mapper = meta.NewDefaultRESTMapper(nil) - inherited.Mapper = meta.NewDefaultRESTMapper([]schema.GroupVersion{gv}) - Expect(checkError(specified.inheritFrom(inherited)).Mapper).To(Equal(specified.Mapper)) - }) - }) - Context("Resync", func() { - It("is nil when specified and inherited are unset", func() { - Expect(checkError(specified.inheritFrom(inherited)).SyncPeriod).To(BeNil()) - }) - It("is unchanged when only specified is set", func() { - specified.SyncPeriod = pointer.Duration(time.Second) - Expect(checkError(specified.inheritFrom(inherited)).SyncPeriod).To(Equal(specified.SyncPeriod)) - }) - It("is inherited when only inherited is set", func() { - inherited.SyncPeriod = pointer.Duration(time.Second) - Expect(checkError(specified.inheritFrom(inherited)).SyncPeriod).To(Equal(inherited.SyncPeriod)) - }) - It("is unchanged when both inherited and specified are set", func() { - specified.SyncPeriod = pointer.Duration(time.Second) - inherited.SyncPeriod = pointer.Duration(time.Minute) - Expect(checkError(specified.inheritFrom(inherited)).SyncPeriod).To(Equal(specified.SyncPeriod)) - }) - }) - Context("Namespace", func() { - It("has zero length when Namespaces specified and inherited are unset", func() { - Expect(checkError(specified.inheritFrom(inherited)).Namespaces).To(HaveLen(0)) - }) - It("is unchanged when only specified is set", func() { - specified.Namespaces = []string{"specified"} - Expect(checkError(specified.inheritFrom(inherited)).Namespaces).To(Equal(specified.Namespaces)) - }) - It("is inherited when only inherited is set", func() { - inherited.Namespaces = []string{"inherited"} - Expect(checkError(specified.inheritFrom(inherited)).Namespaces).To(Equal(inherited.Namespaces)) - }) - It("in unchanged when both inherited and specified are set", func() { - specified.Namespaces = []string{"specified"} - inherited.Namespaces = []string{"inherited"} - Expect(checkError(specified.inheritFrom(inherited)).Namespaces).To(Equal(specified.Namespaces)) - }) - }) - Context("ByObject", func() { - It("maintains GVKs of unstructured ByObject keys", func() { - gvk := gv.WithKind("Unstructured") - obj := &unstructured.Unstructured{} - obj.SetGroupVersionKind(gvk) - specified.Scheme = coreScheme - specified.Scheme.AddKnownTypeWithName(gvk, obj) - specified.ByObject = map[client.Object]ByObject{ - obj: {}, - } - byObject := checkError(specified.inheritFrom(inherited)).ByObject - Expect(byObject).To(HaveLen(1)) - for obj := range byObject { - Expect(obj.GetObjectKind().GroupVersionKind()).To(Equal(gvk)) - } - }) - }) - Context("SelectorsByObject", func() { - It("is unchanged when specified and inherited are unset", func() { - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(0)) - }) - It("is unchanged when only specified is set", func() { - specified.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: {}, - } - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(1)) - }) - It("is inherited when only inherited is set", func() { - inherited.Scheme = coreScheme - inherited.ByObject = map[client.Object]ByObject{ - &corev1.ConfigMap{}: {}, - } - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(1)) - }) - It("is combined when both inherited and specified are set", func() { - specified.Scheme = coreScheme - inherited.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: {}, - } - inherited.ByObject = map[client.Object]ByObject{ - &corev1.ConfigMap{}: {}, - } - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(2)) - }) - It("combines selectors if specified and inherited specify selectors for the same object", func() { - specified.Scheme = coreScheme - inherited.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - Label: labels.Set{"specified": "true"}.AsSelector(), - Field: fields.Set{"metadata.name": "specified"}.AsSelector(), - }, - } - inherited.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - Label: labels.Set{"inherited": "true"}.AsSelector(), - Field: fields.Set{"metadata.namespace": "inherited"}.AsSelector(), - }, - } - combined := checkError(specified.inheritFrom(inherited)).ByObject - Expect(combined).To(HaveLen(1)) - var ( - obj client.Object - byObject ByObject - ) - for obj, byObject = range combined { - } - Expect(obj).To(BeAssignableToTypeOf(&corev1.Pod{})) - - Expect(byObject.Label.Matches(labels.Set{"specified": "true"})).To(BeFalse()) - Expect(byObject.Label.Matches(labels.Set{"inherited": "true"})).To(BeFalse()) - Expect(byObject.Label.Matches(labels.Set{"specified": "true", "inherited": "true"})).To(BeTrue()) - - Expect(byObject.Field.Matches(fields.Set{"metadata.name": "specified", "metadata.namespace": "other"})).To(BeFalse()) - Expect(byObject.Field.Matches(fields.Set{"metadata.name": "other", "metadata.namespace": "inherited"})).To(BeFalse()) - Expect(byObject.Field.Matches(fields.Set{"metadata.name": "specified", "metadata.namespace": "inherited"})).To(BeTrue()) - }) - It("uses inherited scheme for inherited selectors", func() { - inherited.Scheme = coreScheme - inherited.ByObject = map[client.Object]ByObject{ - &corev1.ConfigMap{}: {}, - } - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(1)) - }) - It("uses inherited scheme for specified selectors", func() { - inherited.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.ConfigMap{}: {}, - } - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(1)) - }) - It("uses specified scheme for specified selectors", func() { - specified.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.ConfigMap{}: {}, - } - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(1)) - }) - }) - Context("DefaultSelector", func() { - It("is unchanged when specified and inherited are unset", func() { - Expect(specified.DefaultLabelSelector).To(BeNil()) - Expect(inherited.DefaultLabelSelector).To(BeNil()) - Expect(specified.DefaultFieldSelector).To(BeNil()) - Expect(inherited.DefaultFieldSelector).To(BeNil()) - Expect(checkError(specified.inheritFrom(inherited)).DefaultLabelSelector).To(BeNil()) - Expect(checkError(specified.inheritFrom(inherited)).DefaultFieldSelector).To(BeNil()) - }) - It("is unchanged when only specified is set", func() { - specified.DefaultLabelSelector = labels.Set{"specified": "true"}.AsSelector() - specified.DefaultFieldSelector = fields.Set{"specified": "true"}.AsSelector() - Expect(checkError(specified.inheritFrom(inherited)).DefaultLabelSelector).To(Equal(specified.DefaultLabelSelector)) - Expect(checkError(specified.inheritFrom(inherited)).DefaultFieldSelector).To(Equal(specified.DefaultFieldSelector)) - }) - It("is inherited when only inherited is set", func() { - inherited.DefaultLabelSelector = labels.Set{"inherited": "true"}.AsSelector() - inherited.DefaultFieldSelector = fields.Set{"inherited": "true"}.AsSelector() - Expect(checkError(specified.inheritFrom(inherited)).DefaultLabelSelector).To(Equal(inherited.DefaultLabelSelector)) - Expect(checkError(specified.inheritFrom(inherited)).DefaultFieldSelector).To(Equal(inherited.DefaultFieldSelector)) - }) - It("is combined when both inherited and specified are set", func() { - specified.DefaultLabelSelector = labels.Set{"specified": "true"}.AsSelector() - specified.DefaultFieldSelector = fields.Set{"metadata.name": "specified"}.AsSelector() - - inherited.DefaultLabelSelector = labels.Set{"inherited": "true"}.AsSelector() - inherited.DefaultFieldSelector = fields.Set{"metadata.namespace": "inherited"}.AsSelector() - { - combined := checkError(specified.inheritFrom(inherited)).DefaultLabelSelector - Expect(combined).NotTo(BeNil()) - Expect(combined.Matches(labels.Set{"specified": "true"})).To(BeFalse()) - Expect(combined.Matches(labels.Set{"inherited": "true"})).To(BeFalse()) - Expect(combined.Matches(labels.Set{"specified": "true", "inherited": "true"})).To(BeTrue()) - } - - { - combined := checkError(specified.inheritFrom(inherited)).DefaultFieldSelector - Expect(combined.Matches(fields.Set{"metadata.name": "specified", "metadata.namespace": "other"})).To(BeFalse()) - Expect(combined.Matches(fields.Set{"metadata.name": "other", "metadata.namespace": "inherited"})).To(BeFalse()) - Expect(combined.Matches(fields.Set{"metadata.name": "specified", "metadata.namespace": "inherited"})).To(BeTrue()) - } - - }) - }) - Context("UnsafeDisableDeepCopyByObject", func() { - It("is unchanged when specified and inherited are unset", func() { - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(0)) - }) - It("is unchanged when only specified is set", func() { - specified.Scheme = coreScheme - specified.UnsafeDisableDeepCopy = pointer.Bool(true) - Expect(*(checkError(specified.inheritFrom(inherited)).UnsafeDisableDeepCopy)).To(BeTrue()) - }) - It("is inherited when only inherited is set", func() { - inherited.Scheme = coreScheme - inherited.UnsafeDisableDeepCopy = pointer.Bool(true) - Expect(*(checkError(specified.inheritFrom(inherited)).UnsafeDisableDeepCopy)).To(BeTrue()) - }) - It("is combined when both inherited and specified are set for different keys", func() { - specified.Scheme = coreScheme - inherited.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - UnsafeDisableDeepCopy: pointer.Bool(true), - }, - } - inherited.ByObject = map[client.Object]ByObject{ - &corev1.ConfigMap{}: { - UnsafeDisableDeepCopy: pointer.Bool(true), - }, - } - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(2)) - }) - It("is true when inherited=false and specified=true for the same key", func() { - specified.Scheme = coreScheme - inherited.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - UnsafeDisableDeepCopy: pointer.Bool(true), - }, - } - inherited.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - UnsafeDisableDeepCopy: pointer.Bool(false), - }, - } - combined := checkError(specified.inheritFrom(inherited)).ByObject - Expect(combined).To(HaveLen(1)) - - var ( - obj client.Object - byObject ByObject - ) - for obj, byObject = range combined { - } - Expect(obj).To(BeAssignableToTypeOf(&corev1.Pod{})) - Expect(byObject.UnsafeDisableDeepCopy).ToNot(BeNil()) - Expect(*byObject.UnsafeDisableDeepCopy).To(BeTrue()) - }) - It("is false when inherited=true and specified=false for the same key", func() { - specified.Scheme = coreScheme - inherited.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - UnsafeDisableDeepCopy: pointer.Bool(false), - }, - } - inherited.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - UnsafeDisableDeepCopy: pointer.Bool(true), - }, - } - combined := checkError(specified.inheritFrom(inherited)).ByObject - Expect(combined).To(HaveLen(1)) - - var ( - obj client.Object - byObject ByObject - ) - for obj, byObject = range combined { - } - Expect(obj).To(BeAssignableToTypeOf(&corev1.Pod{})) - Expect(byObject.UnsafeDisableDeepCopy).ToNot(BeNil()) - Expect(*byObject.UnsafeDisableDeepCopy).To(BeFalse()) - }) - }) - Context("TransformByObject", func() { - type transformed struct { - podSpecified bool - podInherited bool - configmapSpecified bool - configmapInherited bool - } - var tx transformed - BeforeEach(func() { - tx = transformed{} - }) - It("is unchanged when specified and inherited are unset", func() { - Expect(checkError(specified.inheritFrom(inherited)).ByObject).To(HaveLen(0)) - }) - It("is unchanged when only specified is set", func() { - specified.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - Transform: func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.podSpecified = true - return ti, nil - }, - }, - } - combined := checkError(specified.inheritFrom(inherited)).ByObject - Expect(combined).To(HaveLen(1)) - for obj, byObject := range combined { - Expect(obj).To(BeAssignableToTypeOf(&corev1.Pod{})) - out, _ := byObject.Transform(tx) - Expect(out).To(And( - BeAssignableToTypeOf(tx), - WithTransform(func(i transformed) bool { return i.podSpecified }, BeTrue()), - WithTransform(func(i transformed) bool { return i.podInherited }, BeFalse()), - )) - } - }) - It("is inherited when only inherited is set", func() { - inherited.Scheme = coreScheme - inherited.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - Transform: func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.podInherited = true - return ti, nil - }, - }, - } - combined := checkError(specified.inheritFrom(inherited)).ByObject - Expect(combined).To(HaveLen(1)) - for obj, byObject := range combined { - Expect(obj).To(BeAssignableToTypeOf(&corev1.Pod{})) - out, _ := byObject.Transform(tx) - Expect(out).To(And( - BeAssignableToTypeOf(tx), - WithTransform(func(i transformed) bool { return i.podSpecified }, BeFalse()), - WithTransform(func(i transformed) bool { return i.podInherited }, BeTrue()), - )) - } - }) - It("is combined when both inherited and specified are set for different keys", func() { - specified.Scheme = coreScheme - inherited.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - Transform: func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.podSpecified = true - return ti, nil - }, - }, - } - inherited.ByObject = map[client.Object]ByObject{ - &corev1.ConfigMap{}: { - Transform: func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.configmapInherited = true - return ti, nil - }, - }, - } - combined := checkError(specified.inheritFrom(inherited)).ByObject - Expect(combined).To(HaveLen(2)) - for obj, byObject := range combined { - out, _ := byObject.Transform(tx) - if reflect.TypeOf(obj) == reflect.TypeOf(&corev1.Pod{}) { - Expect(out).To(And( - BeAssignableToTypeOf(tx), - WithTransform(func(i transformed) bool { return i.podSpecified }, BeTrue()), - WithTransform(func(i transformed) bool { return i.podInherited }, BeFalse()), - WithTransform(func(i transformed) bool { return i.configmapSpecified }, BeFalse()), - WithTransform(func(i transformed) bool { return i.configmapInherited }, BeFalse()), - )) - } - if reflect.TypeOf(obj) == reflect.TypeOf(&corev1.ConfigMap{}) { - Expect(out).To(And( - BeAssignableToTypeOf(tx), - WithTransform(func(i transformed) bool { return i.podSpecified }, BeFalse()), - WithTransform(func(i transformed) bool { return i.podInherited }, BeFalse()), - WithTransform(func(i transformed) bool { return i.configmapSpecified }, BeFalse()), - WithTransform(func(i transformed) bool { return i.configmapInherited }, BeTrue()), - )) - } - } - }) - It("is combined into a single transform function when both inherited and specified are set for the same key", func() { - specified.Scheme = coreScheme - inherited.Scheme = coreScheme - specified.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - Transform: func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.podSpecified = true - return ti, nil - }, - }, - } - inherited.ByObject = map[client.Object]ByObject{ - &corev1.Pod{}: { - Transform: func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.podInherited = true - return ti, nil - }, - }, - } - combined := checkError(specified.inheritFrom(inherited)).ByObject - Expect(combined).To(HaveLen(1)) - for obj, byObject := range combined { - Expect(obj).To(BeAssignableToTypeOf(&corev1.Pod{})) - out, _ := byObject.Transform(tx) - Expect(out).To(And( - BeAssignableToTypeOf(tx), - WithTransform(func(i transformed) bool { return i.podSpecified }, BeTrue()), - WithTransform(func(i transformed) bool { return i.podInherited }, BeTrue()), - WithTransform(func(i transformed) bool { return i.configmapSpecified }, BeFalse()), - WithTransform(func(i transformed) bool { return i.configmapInherited }, BeFalse()), - )) - } - }) - }) - Context("DefaultTransform", func() { - type transformed struct { - specified bool - inherited bool - } - var tx transformed - BeforeEach(func() { - tx = transformed{} - }) - It("is unchanged when specified and inherited are unset", func() { - Expect(checkError(specified.inheritFrom(inherited)).DefaultTransform).To(BeNil()) - }) - It("is unchanged when only specified is set", func() { - specified.DefaultTransform = func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.specified = true - return ti, nil - } - combined := checkError(specified.inheritFrom(inherited)).DefaultTransform - out, _ := combined(tx) - Expect(out).To(And( - BeAssignableToTypeOf(tx), - WithTransform(func(i transformed) bool { return i.specified }, BeTrue()), - WithTransform(func(i transformed) bool { return i.inherited }, BeFalse()), - )) - }) - It("is inherited when only inherited is set", func() { - inherited.DefaultTransform = func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.inherited = true - return ti, nil - } - combined := checkError(specified.inheritFrom(inherited)).DefaultTransform - out, _ := combined(tx) - Expect(out).To(And( - BeAssignableToTypeOf(tx), - WithTransform(func(i transformed) bool { return i.specified }, BeFalse()), - WithTransform(func(i transformed) bool { return i.inherited }, BeTrue()), - )) - }) - It("is combined when the transform function is defined in both inherited and specified", func() { - specified.DefaultTransform = func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.specified = true - return ti, nil - } - inherited.DefaultTransform = func(i interface{}) (interface{}, error) { - ti := i.(transformed) - ti.inherited = true - return ti, nil - } - combined := checkError(specified.inheritFrom(inherited)).DefaultTransform - Expect(combined).NotTo(BeNil()) - out, _ := combined(tx) - Expect(out).To(And( - BeAssignableToTypeOf(tx), - WithTransform(func(i transformed) bool { return i.specified }, BeTrue()), - WithTransform(func(i transformed) bool { return i.inherited }, BeTrue()), - )) - }) - }) -}) - -func checkError[T any](v T, err error) T { - Expect(err).To(BeNil()) - return v -}