mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Reduce throttling requests (GET) (#1522)
* add resource lister to even handler Signed-off-by: Shuting Zhao <shutting06@gmail.com> * use lister to get Kyverno deployment Signed-off-by: Shuting Zhao <shutting06@gmail.com> * add lister for webhook configs Signed-off-by: Shuting Zhao <shutting06@gmail.com>
This commit is contained in:
parent
7788ae3dba
commit
39b27a16ed
7 changed files with 59 additions and 36 deletions
|
@ -138,6 +138,7 @@ func main() {
|
|||
webhookCfg := webhookconfig.NewRegister(
|
||||
clientConfig,
|
||||
client,
|
||||
rCache,
|
||||
serverIP,
|
||||
int32(webhookTimeout),
|
||||
log.Log)
|
||||
|
@ -171,6 +172,7 @@ func main() {
|
|||
eventGenerator := event.NewEventGenerator(
|
||||
client,
|
||||
pInformer.Kyverno().V1().ClusterPolicies(),
|
||||
rCache,
|
||||
log.Log.WithName("EventGenerator"))
|
||||
|
||||
// Policy Status Handler - deals with all logic related to policy status
|
||||
|
|
|
@ -8,8 +8,6 @@ import (
|
|||
|
||||
"github.com/go-logr/logr"
|
||||
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
certificates "k8s.io/api/certificates/v1beta1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
helperv1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -78,19 +76,6 @@ func (c *Client) NewDynamicSharedInformerFactory(defaultResync time.Duration) dy
|
|||
return dynamicinformer.NewDynamicSharedInformerFactory(c.client, defaultResync)
|
||||
}
|
||||
|
||||
//GetKubePolicyDeployment returns kube policy depoyment value
|
||||
func (c *Client) GetKubePolicyDeployment() (*apps.Deployment, error) {
|
||||
kubePolicyDeployment, err := c.GetResource("", "Deployment", config.KyvernoNamespace, config.KyvernoDeploymentName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deploy := apps.Deployment{}
|
||||
if err = runtime.DefaultUnstructuredConverter.FromUnstructured(kubePolicyDeployment.UnstructuredContent(), &deploy); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &deploy, nil
|
||||
}
|
||||
|
||||
//GetEventsInterface provides typed interface for events
|
||||
//TODO: can we use dynamic client to fetch the typed interface
|
||||
// or generate a kube client value to access the interface
|
||||
|
|
|
@ -117,11 +117,3 @@ func TestCSRInterface(t *testing.T) {
|
|||
t.Errorf("Testing CSR interface not working: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubePolicyDeployment(t *testing.T) {
|
||||
f := newFixture(t)
|
||||
_, err := f.client.GetKubePolicyDeployment()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,10 @@ import (
|
|||
kyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1"
|
||||
kyvernolister "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
|
||||
client "github.com/kyverno/kyverno/pkg/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/resourcecache"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
errors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
@ -35,6 +37,7 @@ type Generator struct {
|
|||
admissionCtrRecorder record.EventRecorder
|
||||
// events generated at namespaced policy controller to process 'generate' rule
|
||||
genPolicyRecorder record.EventRecorder
|
||||
resCache resourcecache.ResourceCache
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
|
@ -44,7 +47,7 @@ type Interface interface {
|
|||
}
|
||||
|
||||
//NewEventGenerator to generate a new event controller
|
||||
func NewEventGenerator(client *client.Client, pInformer kyvernoinformer.ClusterPolicyInformer, log logr.Logger) *Generator {
|
||||
func NewEventGenerator(client *client.Client, pInformer kyvernoinformer.ClusterPolicyInformer, resCache resourcecache.ResourceCache, log logr.Logger) *Generator {
|
||||
|
||||
gen := Generator{
|
||||
client: client,
|
||||
|
@ -54,6 +57,7 @@ func NewEventGenerator(client *client.Client, pInformer kyvernoinformer.ClusterP
|
|||
policyCtrRecorder: initRecorder(client, PolicyController, log),
|
||||
admissionCtrRecorder: initRecorder(client, AdmissionController, log),
|
||||
genPolicyRecorder: initRecorder(client, GeneratePolicyController, log),
|
||||
resCache: resCache,
|
||||
log: log,
|
||||
}
|
||||
return &gen
|
||||
|
@ -185,7 +189,7 @@ func (gen *Generator) syncHandler(key Info) error {
|
|||
return err
|
||||
}
|
||||
default:
|
||||
robj, err = gen.client.GetResource("", key.Kind, key.Namespace, key.Name)
|
||||
robj, err = gen.getResource(key)
|
||||
if err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
logger.Error(err, "failed to get resource", "kind", key.Kind, "name", key.Name, "namespace", key.Namespace)
|
||||
|
@ -211,6 +215,21 @@ func (gen *Generator) syncHandler(key Info) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (gen *Generator) getResource(key Info) (obj *unstructured.Unstructured, err error) {
|
||||
lister, ok := gen.resCache.GetGVRCache(key.Kind)
|
||||
if !ok {
|
||||
if lister, err = gen.resCache.CreateResourceInformer(key.Kind); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if key.Namespace == "" {
|
||||
return lister.Lister().Get(key.Name)
|
||||
}
|
||||
|
||||
return lister.Lister().Namespace(key.Namespace).Get(key.Name)
|
||||
}
|
||||
|
||||
//NewEvent builds a event creation request
|
||||
func NewEvent(
|
||||
log logr.Logger,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package resourcecache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
dclient "github.com/kyverno/kyverno/pkg/dclient"
|
||||
cmap "github.com/orcaman/concurrent-map"
|
||||
|
@ -27,6 +29,8 @@ type resourceCache struct {
|
|||
log logr.Logger
|
||||
}
|
||||
|
||||
var KyvernoDefaultInformer = []string{"ConfigMap", "Secret", "Deployment", "MutatingWebhookConfiguration", "ValidatingWebhookConfiguration"}
|
||||
|
||||
// NewResourceCache - initializes the ResourceCache
|
||||
func NewResourceCache(dclient *dclient.Client, dInformer dynamicinformer.DynamicSharedInformerFactory, logger logr.Logger) (ResourceCache, error) {
|
||||
rCache := &resourceCache{
|
||||
|
@ -36,8 +40,9 @@ func NewResourceCache(dclient *dclient.Client, dInformer dynamicinformer.Dynamic
|
|||
log: logger,
|
||||
}
|
||||
|
||||
if _, err := rCache.CreateResourceInformer("ConfigMap"); err != nil {
|
||||
return nil, err
|
||||
errs := rCache.CreateInformers(KyvernoDefaultInformer...)
|
||||
if len(errs) != 0 {
|
||||
return rCache, fmt.Errorf("failed to register default informers %v", errs)
|
||||
}
|
||||
|
||||
return rCache, nil
|
||||
|
|
|
@ -5,7 +5,9 @@ import (
|
|||
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
admregapi "k8s.io/api/admissionregistration/v1beta1"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
|
@ -47,7 +49,7 @@ func extractCA(config *rest.Config) (result []byte) {
|
|||
|
||||
func (wrc *Register) constructOwner() v1.OwnerReference {
|
||||
logger := wrc.log
|
||||
kubePolicyDeployment, err := wrc.client.GetKubePolicyDeployment()
|
||||
kubePolicyDeployment, err := wrc.getKubePolicyDeployment()
|
||||
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to construct OwnerReference")
|
||||
|
@ -62,6 +64,19 @@ func (wrc *Register) constructOwner() v1.OwnerReference {
|
|||
}
|
||||
}
|
||||
|
||||
func (wrc *Register) getKubePolicyDeployment() (*apps.Deployment, error) {
|
||||
lister, _ := wrc.resCache.GetGVRCache("Deployment")
|
||||
kubePolicyDeployment, err := lister.NamespacedLister(config.KyvernoNamespace).Get(config.KyvernoDeploymentName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deploy := apps.Deployment{}
|
||||
if err = runtime.DefaultUnstructuredConverter.FromUnstructured(kubePolicyDeployment.UnstructuredContent(), &deploy); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &deploy, nil
|
||||
}
|
||||
|
||||
// debug mutating webhook
|
||||
func generateDebugMutatingWebhook(name, url string, caData []byte, validate bool, timeoutSeconds int32, resources []string, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.MutatingWebhook {
|
||||
sideEffect := admregapi.SideEffectClassNoneOnDryRun
|
||||
|
|
|
@ -7,13 +7,13 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
client "github.com/kyverno/kyverno/pkg/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/resourcecache"
|
||||
admregapi "k8s.io/api/admissionregistration/v1beta1"
|
||||
errorsapi "k8s.io/apimachinery/pkg/api/errors"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
|
@ -31,6 +31,7 @@ const (
|
|||
type Register struct {
|
||||
client *client.Client
|
||||
clientConfig *rest.Config
|
||||
resCache resourcecache.ResourceCache
|
||||
serverIP string // when running outside a cluster
|
||||
timeoutSeconds int32
|
||||
log logr.Logger
|
||||
|
@ -40,12 +41,14 @@ type Register struct {
|
|||
func NewRegister(
|
||||
clientConfig *rest.Config,
|
||||
client *client.Client,
|
||||
resCache resourcecache.ResourceCache,
|
||||
serverIP string,
|
||||
webhookTimeout int32,
|
||||
log logr.Logger) *Register {
|
||||
return &Register{
|
||||
clientConfig: clientConfig,
|
||||
client: client,
|
||||
resCache: resCache,
|
||||
serverIP: serverIP,
|
||||
timeoutSeconds: webhookTimeout,
|
||||
log: log.WithName("Register"),
|
||||
|
@ -89,26 +92,28 @@ func (wrc *Register) Register() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// CheckWebhooks returns an error if any of the webhooks are not configured
|
||||
// Check returns an error if any of the webhooks are not configured
|
||||
func (wrc *Register) Check() error {
|
||||
mutatingCache, _ := wrc.resCache.GetGVRCache(kindMutating)
|
||||
validatingCache, _ := wrc.resCache.GetGVRCache(kindValidating)
|
||||
|
||||
if _, err := wrc.client.GetResource("", kindMutating, "", wrc.getVerifyWebhookMutatingWebhookName()); err != nil {
|
||||
if _, err := mutatingCache.Lister().Get(wrc.getVerifyWebhookMutatingWebhookName()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := wrc.client.GetResource("", kindMutating, "", wrc.getResourceMutatingWebhookConfigName()); err != nil {
|
||||
if _, err := mutatingCache.Lister().Get(wrc.getResourceMutatingWebhookConfigName()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := wrc.client.GetResource("", kindValidating, "", wrc.getResourceValidatingWebhookConfigName()); err != nil {
|
||||
if _, err := validatingCache.Lister().Get(wrc.getResourceValidatingWebhookConfigName()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := wrc.client.GetResource("", kindMutating, "", wrc.getPolicyMutatingWebhookConfigurationName()); err != nil {
|
||||
if _, err := mutatingCache.Lister().Get(wrc.getPolicyMutatingWebhookConfigurationName()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := wrc.client.GetResource("", kindValidating, "", wrc.getPolicyValidatingWebhookConfigurationName()); err != nil {
|
||||
if _, err := validatingCache.Lister().Get(wrc.getPolicyValidatingWebhookConfigurationName()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue