1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

refactor: use the typed ns informer in GR controller (#3554)

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>
This commit is contained in:
Prateek Pandey 2022-04-21 11:42:34 +05:30 committed by GitHub
parent 2e1a87d149
commit 5054148fec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 107 deletions

View file

@ -340,7 +340,7 @@ func main() {
pInformer.Kyverno().V1().Policies(),
pInformer.Kyverno().V1().GenerateRequests(),
eventGenerator,
kubedynamicInformer,
kubeInformer.Core().V1().Namespaces(),
log.Log.WithName("GenerateController"),
configData,
)
@ -358,7 +358,7 @@ func main() {
pInformer.Kyverno().V1().ClusterPolicies(),
pInformer.Kyverno().V1().Policies(),
pInformer.Kyverno().V1().GenerateRequests(),
kubedynamicInformer,
kubeInformer.Core().V1().Namespaces(),
log.Log.WithName("GenerateCleanUpController"),
)
if err != nil {

View file

@ -15,12 +15,11 @@ import (
"github.com/kyverno/kyverno/pkg/config"
dclient "github.com/kyverno/kyverno/pkg/dclient"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/dynamic/dynamicinformer"
"k8s.io/client-go/informers"
coreinformers "k8s.io/client-go/informers/core/v1"
corelister "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
)
@ -56,6 +55,9 @@ type Controller struct {
// grLister can list/get generate request from the shared informer's store
grLister kyvernolister.GenerateRequestNamespaceLister
// nsLister can list/get namespaces from the shared informer's store
nsLister corelister.NamespaceLister
// pSynced returns true if the cluster policy has been synced at least once
pSynced cache.InformerSynced
@ -65,11 +67,11 @@ type Controller struct {
// grSynced returns true if the generate request store has been synced at least once
grSynced cache.InformerSynced
// dynamic sharedinformer factory
dynamicInformer dynamicinformer.DynamicSharedInformerFactory
// nsListerSynced returns true if the namespace store has been synced at least once
nsListerSynced cache.InformerSynced
// namespace informer
nsInformer informers.GenericInformer
// namespaceInformer for re-evaluation on namespace updates
namespaceInformer coreinformers.NamespaceInformer
// logger
log logr.Logger
@ -83,17 +85,17 @@ func NewController(
pInformer kyvernoinformer.ClusterPolicyInformer,
npInformer kyvernoinformer.PolicyInformer,
grInformer kyvernoinformer.GenerateRequestInformer,
dynamicInformer dynamicinformer.DynamicSharedInformerFactory,
namespaceInformer coreinformers.NamespaceInformer,
log logr.Logger,
) (*Controller, error) {
c := Controller{
kyvernoClient: kyvernoclient,
client: client,
pInformer: pInformer,
grInformer: grInformer,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "generate-request-cleanup"),
dynamicInformer: dynamicInformer,
log: log,
kyvernoClient: kyvernoclient,
client: client,
pInformer: pInformer,
grInformer: grInformer,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "generate-request-cleanup"),
namespaceInformer: namespaceInformer,
log: log,
}
c.control = Control{client: kyvernoclient}
@ -101,36 +103,16 @@ func NewController(
c.pLister = pInformer.Lister()
c.npLister = npInformer.Lister()
c.grLister = grInformer.Lister().GenerateRequests(config.KyvernoNamespace)
c.nsLister = namespaceInformer.Lister()
c.pSynced = pInformer.Informer().HasSynced
c.npSynced = npInformer.Informer().HasSynced
c.grSynced = grInformer.Informer().HasSynced
gvr, err := client.DiscoveryClient.GetGVRFromKind("Namespace")
if err != nil {
return nil, err
}
nsInformer := dynamicInformer.ForResource(gvr)
c.nsInformer = nsInformer
c.nsListerSynced = namespaceInformer.Informer().HasSynced
return &c, nil
}
func (c *Controller) deleteGenericResource(obj interface{}) {
logger := c.log
r := obj.(*unstructured.Unstructured)
grs, err := c.grLister.GetGenerateRequestsForResource(r.GetKind(), r.GetNamespace(), r.GetName())
if err != nil {
logger.Error(err, "failed to get generate request CR for resource", "kind", r.GetKind(), "namespace", r.GetNamespace(), "name", r.GetName())
return
}
// re-evaluate the GR as the resource was deleted
for _, gr := range grs {
c.enqueue(gr)
}
}
func (c *Controller) deletePolicy(obj interface{}) {
logger := c.log
p, ok := obj.(*kyverno.ClusterPolicy)
@ -273,10 +255,6 @@ func (c *Controller) Run(workers int, stopCh <-chan struct{}) {
DeleteFunc: c.deleteGR,
})
c.nsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
DeleteFunc: c.deleteGenericResource,
})
for i := 0; i < workers; i++ {
go wait.Until(c.worker, time.Second, stopCh)
}

View file

@ -32,8 +32,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/dynamic/dynamicinformer"
"k8s.io/client-go/informers"
coreinformers "k8s.io/client-go/informers/core/v1"
corelister "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
)
@ -55,8 +55,8 @@ type GenerateController struct {
// grLister can list/get generate request from the shared informer's store
grLister kyvernolister.GenerateRequestNamespaceLister
// only support Namespaces for re-evaluation on resource updates
nsInformer informers.GenericInformer
// nsLister can list/get namespaces from the shared informer's store
nsLister corelister.NamespaceLister
// policyLister can list/get cluster policy from the shared informer's store
policyLister kyvernolister.ClusterPolicyLister
@ -75,7 +75,7 @@ func NewGenerateController(
npolicyLister kyvernolister.PolicyLister,
grLister kyvernolister.GenerateRequestNamespaceLister,
eventGen event.Interface,
dynamicInformer dynamicinformer.DynamicSharedInformerFactory,
namespaceInformer coreinformers.NamespaceInformer,
log logr.Logger,
dynamicConfig config.Interface,
) (*GenerateController, error) {
@ -92,13 +92,7 @@ func NewGenerateController(
}
c.statusControl = common.StatusControl{Client: kyvernoClient}
gvr, err := client.DiscoveryClient.GetGVRFromKind("Namespace")
if err != nil {
return nil, err
}
c.nsInformer = dynamicInformer.ForResource(gvr)
c.nsLister = namespaceInformer.Lister()
return &c, nil
}
@ -164,7 +158,7 @@ func (c *GenerateController) ProcessGR(gr *kyverno.GenerateRequest) error {
}
// 2 - Apply the generate policy on the resource
namespaceLabels := pkgcommon.GetNamespaceSelectorsFromGenericInformer(resource.GetKind(), resource.GetNamespace(), c.nsInformer, logger)
namespaceLabels := pkgcommon.GetNamespaceSelectorsFromNamespaceLister(resource.GetKind(), resource.GetNamespace(), c.nsLister, logger)
genResources, precreatedResource, err = c.applyGenerate(*resource, *gr, namespaceLabels)
if err != nil {
@ -566,8 +560,7 @@ func applyRule(log logr.Logger, client *dclient.Client, rule kyverno.Rule, resou
}
}
}
logger.V(2).Info("updated generate target resource")
logger.V(3).Info("updated generate target resource")
}
return newGenResource, nil

View file

@ -7,7 +7,7 @@ import (
func (c *Controller) ProcessGR(gr *kyverno.GenerateRequest) error {
ctrl, _ := generate.NewGenerateController(c.kyvernoClient, c.client,
c.policyLister, c.npolicyLister, c.grLister, c.eventGen, c.dynamicInformer, c.log, c.Config,
c.policyLister, c.npolicyLister, c.grLister, c.eventGen, c.namespaceInformer, c.log, c.Config,
)
return ctrl.ProcessGR(gr)
}

View file

@ -16,12 +16,11 @@ import (
"github.com/kyverno/kyverno/pkg/event"
admissionv1 "k8s.io/api/admission/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/dynamic/dynamicinformer"
"k8s.io/client-go/informers"
coreinformers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
corelister "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
)
@ -58,6 +57,9 @@ type Controller struct {
// grLister can list/get generate request from the shared informer's store
grLister kyvernolister.GenerateRequestNamespaceLister
// nsLister can list/get namespaces from the shared informer's store
nsLister corelister.NamespaceLister
// policySynced returns true if the Cluster policy store has been synced at least once
policySynced cache.InformerSynced
@ -67,12 +69,10 @@ type Controller struct {
// grSynced returns true if the Generate Request store has been synced at least once
grSynced cache.InformerSynced
// dynamic shared informer factory
dynamicInformer dynamicinformer.DynamicSharedInformerFactory
// namespaceInformer for re-evaluation on namespace updates
namespaceInformer coreinformers.NamespaceInformer
// only support Namespaces for re-evaluation on resource updates
nsInformer informers.GenericInformer
log logr.Logger
log logr.Logger
Config config.Interface
}
@ -86,20 +86,20 @@ func NewController(
npolicyInformer kyvernoinformer.PolicyInformer,
grInformer kyvernoinformer.GenerateRequestInformer,
eventGen event.Interface,
dynamicInformer dynamicinformer.DynamicSharedInformerFactory,
namespaceInformer coreinformers.NamespaceInformer,
log logr.Logger,
dynamicConfig config.Interface,
) (*Controller, error) {
c := Controller{
client: client,
kyvernoClient: kyvernoClient,
policyInformer: policyInformer,
eventGen: eventGen,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "generate-request"),
dynamicInformer: dynamicInformer,
log: log,
Config: dynamicConfig,
client: client,
kyvernoClient: kyvernoClient,
policyInformer: policyInformer,
eventGen: eventGen,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "generate-request"),
namespaceInformer: namespaceInformer,
log: log,
Config: dynamicConfig,
}
c.statusControl = common.StatusControl{Client: kyvernoClient}
@ -109,6 +109,7 @@ func NewController(
c.npolicySynced = npolicyInformer.Informer().HasSynced
c.grSynced = grInformer.Informer().HasSynced
grInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: c.addGR,
UpdateFunc: c.updateGR,
@ -118,13 +119,7 @@ func NewController(
c.policyLister = policyInformer.Lister()
c.npolicyLister = npolicyInformer.Lister()
c.grLister = grInformer.Lister().GenerateRequests(config.KyvernoNamespace)
gvr, err := client.DiscoveryClient.GetGVRFromKind("Namespace")
if err != nil {
return nil, err
}
c.nsInformer = dynamicInformer.ForResource(gvr)
c.nsLister = namespaceInformer.Lister()
return &c, nil
}
@ -145,10 +140,6 @@ func (c *Controller) Run(workers int, stopCh <-chan struct{}) {
// Deletion of policy will be handled by cleanup controller
})
c.nsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
UpdateFunc: c.updateGenericResource,
})
for i := 0; i < workers; i++ {
go wait.Until(c.worker, time.Second, stopCh)
}
@ -225,23 +216,6 @@ func (c *Controller) syncGenerateRequest(key string) error {
return c.ProcessGR(gr)
}
func (c *Controller) updateGenericResource(old, cur interface{}) {
logger := c.log
curR := cur.(*unstructured.Unstructured)
grs, err := c.grLister.GetGenerateRequestsForResource(curR.GetKind(), curR.GetNamespace(), curR.GetName())
if err != nil {
logger.Error(err, "failed to get generate request CR for the resource", "kind", curR.GetKind(), "name", curR.GetName(), "namespace", curR.GetNamespace())
return
}
// re-evaluate the GR as the resource was updated
for _, gr := range grs {
gr.Spec.Context.AdmissionRequestInfo.Operation = admissionv1.Update
c.enqueueGenerateRequest(gr)
}
}
// EnqueueGenerateRequestFromWebhook - enqueueing generate requests from webhook
func (c *Controller) EnqueueGenerateRequestFromWebhook(gr *kyverno.GenerateRequest) {
c.enqueueGenerateRequest(gr)

View file

@ -12,6 +12,7 @@ import (
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/autogen"
gencommon "github.com/kyverno/kyverno/pkg/background/common"
gen "github.com/kyverno/kyverno/pkg/background/generate"
"github.com/kyverno/kyverno/pkg/common"
"github.com/kyverno/kyverno/pkg/config"
@ -24,6 +25,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/event"
kyvernoutils "github.com/kyverno/kyverno/pkg/utils"
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
"github.com/kyverno/kyverno/pkg/webhooks/generate"
admissionv1 "k8s.io/api/admission/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -186,12 +188,19 @@ func (ws *WebhookServer) updateAnnotationInGR(gr *kyverno.GenerateRequest, logge
grAnnotations = make(map[string]string)
}
ws.mu.Lock()
defer ws.mu.Unlock()
grAnnotations["generate.kyverno.io/updation-time"] = time.Now().String()
gr.SetAnnotations(grAnnotations)
_, err := ws.kyvernoClient.KyvernoV1().GenerateRequests(config.KyvernoNamespace).Update(contextdefault.TODO(), gr, metav1.UpdateOptions{})
ws.mu.Unlock()
patch := jsonutils.NewPatch(
"/metadata/annotations",
"replace",
gr.Annotations,
)
_, err := gencommon.PatchGenerateRequest(gr, patch, ws.kyvernoClient)
if err != nil {
logger.Error(err, "failed to update generate request for the resource", "generate request", gr.Name)
logger.Error(err, "failed to update generate request update-time annotations for the resource", "generate request", gr.Name)
return
}
}