diff --git a/pkg/dclient/discovery.go b/pkg/dclient/discovery.go index 59cac6e331..5192f72800 100644 --- a/pkg/dclient/discovery.go +++ b/pkg/dclient/discovery.go @@ -21,6 +21,7 @@ type IDiscovery interface { GetServerVersion() (*version.Info, error) OpenAPISchema() (*openapiv2.Document, error) DiscoveryCache() discovery.CachedDiscoveryInterface + DiscoveryInterface() discovery.DiscoveryInterface } // serverPreferredResources stores the cachedClient instance for discovery client @@ -33,6 +34,11 @@ func (c serverPreferredResources) DiscoveryCache() discovery.CachedDiscoveryInte return c.cachedClient } +// DiscoveryInterface gets the discovery client +func (c serverPreferredResources) DiscoveryInterface() discovery.DiscoveryInterface { + return c.cachedClient +} + // Poll will keep invalidate the local cache func (c serverPreferredResources) Poll(resync time.Duration, stopCh <-chan struct{}) { logger := logger.WithName("Poll") @@ -56,6 +62,7 @@ func (c serverPreferredResources) Poll(resync time.Duration, stopCh <-chan struc // OpenAPISchema returns the API server OpenAPI schema document func (c serverPreferredResources) OpenAPISchema() (*openapiv2.Document, error) { return c.cachedClient.OpenAPISchema() + } // GetGVRFromKind get the Group Version Resource from kind @@ -111,12 +118,12 @@ func (c serverPreferredResources) findResource(apiVersion string, kind string) ( var serverResources []*metav1.APIResourceList var err error if apiVersion == "" { - serverResources, err = c.cachedClient.ServerPreferredResources() + serverResources, err = discovery.ServerPreferredResources(c.DiscoveryInterface()) } else { - _, serverResources, err = c.cachedClient.ServerGroupsAndResources() + _, serverResources, err = discovery.ServerGroupsAndResources(c.DiscoveryInterface()) } - if err != nil { + if err != nil && !strings.Contains(err.Error(), "Got empty response for") { if discovery.IsGroupDiscoveryFailedError(err) { logDiscoveryErrors(err, c) } else if isMetricsServerUnavailable(kind, err) { diff --git a/pkg/dclient/fake.go b/pkg/dclient/fake.go index 3f5768695e..7e2cc9db8f 100644 --- a/pkg/dclient/fake.go +++ b/pkg/dclient/fake.go @@ -67,3 +67,6 @@ func (c *fakeDiscoveryClient) OpenAPISchema() (*openapiv2.Document, error) { func (c *fakeDiscoveryClient) DiscoveryCache() discovery.CachedDiscoveryInterface { return nil } +func (c *fakeDiscoveryClient) DiscoveryInterface() discovery.DiscoveryInterface { + return nil +} diff --git a/pkg/openapi/crdSync.go b/pkg/openapi/crdSync.go index 8c9693d160..23ed2c7f99 100644 --- a/pkg/openapi/crdSync.go +++ b/pkg/openapi/crdSync.go @@ -10,12 +10,14 @@ import ( "github.com/googleapis/gnostic/compiler" openapiv2 "github.com/googleapis/gnostic/openapiv2" "github.com/kyverno/kyverno/pkg/dclient" + util "github.com/kyverno/kyverno/pkg/utils" "github.com/pkg/errors" "gopkg.in/yaml.v3" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" runtimeSchema "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/discovery" "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -24,6 +26,10 @@ type crdSync struct { controller *Controller } +const ( + skipErrorMsg = "Got empty response for" +) + // crdDefinitionPrior represents CRDs version prior to 1.16 var crdDefinitionPrior struct { Spec struct { @@ -68,7 +74,7 @@ func (c *crdSync) Run(workers int, stopCh <-chan struct{}) { log.Log.Error(err, "failed to update in-cluster api versions") } - newDoc, err := c.client.Discovery().DiscoveryCache().OpenAPISchema() + newDoc, err := c.client.Discovery().OpenAPISchema() if err != nil { log.Log.Error(err, "cannot get OpenAPI schema") } @@ -107,7 +113,7 @@ func (c *crdSync) sync() { log.Log.Error(err, "sync failed, unable to update in-cluster api versions") } - newDoc, err := c.client.Discovery().DiscoveryCache().OpenAPISchema() + newDoc, err := c.client.Discovery().OpenAPISchema() if err != nil { log.Log.Error(err, "cannot get OpenAPI schema") } @@ -119,13 +125,14 @@ func (c *crdSync) sync() { } func (c *crdSync) updateInClusterKindToAPIVersions() error { - _, apiResourceLists, err := c.client.Discovery().DiscoveryCache().ServerGroupsAndResources() - if err != nil { + util.OverrideRuntimeErrorHandler() + _, apiResourceLists, err := discovery.ServerGroupsAndResources(c.client.Discovery().DiscoveryInterface()) + + if err != nil && !strings.Contains(err.Error(), skipErrorMsg) { return errors.Wrapf(err, "fetching API server groups and resources") } - - preferredAPIResourcesLists, err := c.client.Discovery().DiscoveryCache().ServerPreferredResources() - if err != nil { + preferredAPIResourcesLists, err := discovery.ServerPreferredResources(c.client.Discovery().DiscoveryInterface()) + if err != nil && !strings.Contains(err.Error(), skipErrorMsg) { return errors.Wrapf(err, "fetching API server preferreds resources") } diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go index 318dac9a3c..3c5dd4c937 100644 --- a/pkg/policy/validate.go +++ b/pkg/policy/validate.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/client-go/discovery" "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -103,7 +104,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b clusterResources := sets.NewString() if !mock && namespaced { // Get all the cluster type kind supported by cluster - res, err := client.Discovery().DiscoveryCache().ServerPreferredResources() + res, err := discovery.ServerPreferredResources(client.Discovery().DiscoveryInterface()) if err != nil { return nil, err } diff --git a/pkg/utils/util.go b/pkg/utils/util.go index 999ebc2d02..d2d83281a6 100644 --- a/pkg/utils/util.go +++ b/pkg/utils/util.go @@ -17,6 +17,7 @@ import ( "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/discovery" "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -338,3 +339,19 @@ func ApiextensionsJsonToKyvernoConditions(original apiextensions.JSON) (interfac } return nil, fmt.Errorf("error occurred while parsing %s: %+v", path, err) } + +func OverrideRuntimeErrorHandler() { + logger := log.Log.WithName("RuntimeErrorHandler") + if len(runtime.ErrorHandlers) > 0 { + runtime.ErrorHandlers[0] = func(err error) { + logger.V(6).Info("runtime error: %s", err) + } + + } else { + runtime.ErrorHandlers = []func(err error){ + func(err error) { + logger.V(6).Info("runtime error: %s", err) + }, + } + } +}