diff --git a/go.mod b/go.mod index 9e4b02627..4670c219a 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/go-logr/logr v1.2.3 github.com/golang/mock v1.6.0 github.com/google/gnostic v0.5.7-v3refs + github.com/google/go-cmp v0.5.9 github.com/spf13/cobra v1.6.0 github.com/stretchr/testify v1.8.1 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 @@ -45,7 +46,6 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/btree v1.0.1 // indirect - github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.1.2 // indirect diff --git a/pkg/cache/cluster.go b/pkg/cache/cluster.go index 02ca18911..782fc2109 100644 --- a/pkg/cache/cluster.go +++ b/pkg/cache/cluster.go @@ -10,6 +10,7 @@ import ( "time" "github.com/go-logr/logr" + "github.com/google/go-cmp/cmp" "golang.org/x/sync/semaphore" authorizationv1 "k8s.io/api/authorization/v1" v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -659,8 +660,39 @@ func (c *clusterCache) watchEvents(ctx context.Context, api kube.APIResourceInfo return fmt.Errorf("Failed to convert to *unstructured.Unstructured: %v", event.Object) } - c.processEvent(event.Type, obj) + // skipCRD will be set to true if the resource is a CRD but the change is not important + skipCRD := true + if kube.IsCRD(obj) { + resourceKey := kube.GetResourceKey(obj) + crd := v1.CustomResourceDefinition{} + err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &crd) + if err != nil { + c.log.Error(err, "Failed to extract CRD resources") + } + + cachedCRD := v1.CustomResourceDefinition{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(c.resources[resourceKey].Resource.Object, &cachedCRD) + if err != nil { + c.log.Error(err, "Failed to extract CRD resources") + } + + // remove useless stuff before we diff + cachedCRD.ResourceVersion = "0" + crd.ResourceVersion = "0" + cachedCRD.ManagedFields = []metav1.ManagedFieldsEntry{} + crd.ManagedFields = []metav1.ManagedFieldsEntry{} + // fmt.Printf("got watchEvents for %s (%s/%s): %v \n", resourceKey, c.resources[resourceKey].ResourceVersion, crd.ResourceVersion, obj) + if diff := cmp.Diff(cachedCRD, crd); diff != "" { + fmt.Printf("watchEvents mismatch for CRD after cleanup %s (-want +got):\n%s\n", resourceKey, diff) + // the CRD is really different, process it + skipCRD = false + } + + } + c.processEvent(event.Type, obj) + if kube.IsCRD(obj) && !skipCRD { + fmt.Printf("processing CRD event\n") var resources []kube.APIResourceInfo crd := v1.CustomResourceDefinition{} err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &crd)