From c7bcd5fadf1a5e1387b5758593c9c7c9ede37c2d Mon Sep 17 00:00:00 2001
From: Vyankatesh Kudtarkar <vyankateshkd@gmail.com>
Date: Mon, 12 Sep 2022 13:44:28 +0530
Subject: [PATCH] Fix multiple crd slowness issue  (#4275)

Signed-off-by: Vyankatesh vyankateshkd@gmail.com

* fix multiple crd issue
---
 pkg/openapi/crdSync.go | 18 ++++++++++++++++--
 pkg/policy/validate.go |  5 ++++-
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/pkg/openapi/crdSync.go b/pkg/openapi/crdSync.go
index 6b4c0bccf9..ec00c00247 100644
--- a/pkg/openapi/crdSync.go
+++ b/pkg/openapi/crdSync.go
@@ -86,9 +86,8 @@ func (c *crdSync) Run(workers int, stopCh <-chan struct{}) {
 	}
 	// Sync CRD before kyverno starts
 	c.sync()
-
 	for i := 0; i < workers; i++ {
-		go wait.Until(c.sync, 15*time.Second, stopCh)
+		go wait.Until(c.CheckSync, 15*time.Second, stopCh)
 	}
 }
 
@@ -249,3 +248,18 @@ func addingDefaultFieldsToSchema(crdName string, schemaRaw []byte) ([]byte, erro
 
 	return schemaWithDefaultFields, nil
 }
+
+func (c *crdSync) CheckSync() {
+	crds, err := c.client.GetDynamicInterface().Resource(runtimeSchema.GroupVersionResource{
+		Group:    "apiextensions.k8s.io",
+		Version:  "v1",
+		Resource: "customresourcedefinitions",
+	}).List(context.TODO(), metav1.ListOptions{})
+	if err != nil {
+		log.Log.Error(err, "could not fetch crd's from server")
+		return
+	}
+	if len(c.controller.crdList) != len(crds.Items) {
+		c.sync()
+	}
+}
diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go
index 6211ce534d..e188d9d6c2 100644
--- a/pkg/policy/validate.go
+++ b/pkg/policy/validate.go
@@ -83,6 +83,9 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b
 	spec := policy.GetSpec()
 	background := spec.BackgroundProcessingEnabled()
 	onPolicyUpdate := spec.GetMutateExistingOnPolicyUpdate()
+	if !mock {
+		openapi.NewCRDSync(client, openAPIController).CheckSync()
+	}
 
 	var errs field.ErrorList
 	specPath := field.NewPath("spec")
@@ -1061,7 +1064,7 @@ func validateKinds(kinds []string, mock bool, client dclient.Interface, p kyvern
 		if !mock && !kubeutils.SkipSubResources(k) && !strings.Contains(kind, "*") {
 			_, _, err := client.Discovery().FindResource(gv, k)
 			if err != nil {
-				return fmt.Errorf("unable to convert GVK to GVR for kinds %s, err: %s", kinds, err)
+				return fmt.Errorf("unable to convert GVK to GVR for kinds %s, err: %s", k, err)
 			}
 		}
 	}