mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
* feat: mutate existing, replace GR by UR in webhook server (#3601) * add attributes for post mutation Signed-off-by: ShutingZhao <shuting@nirmata.com> * add UR informer to webhook server Signed-off-by: ShutingZhao <shuting@nirmata.com> * - replace gr with ur in the webhook server; - create ur for mutateExsiting policies Signed-off-by: ShutingZhao <shuting@nirmata.com> * replace gr by ur across entire packages Signed-off-by: ShutingZhao <shuting@nirmata.com> * add YAMLs Signed-off-by: ShutingZhao <shuting@nirmata.com> * update api docs & fix unit tests Signed-off-by: ShutingZhao <shuting@nirmata.com> * add UR deletion handler Signed-off-by: ShutingZhao <shuting@nirmata.com> * add api docs for v1beta1 Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix clientset method Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix v1beta1 client registration Signed-off-by: ShutingZhao <shuting@nirmata.com> * feat: mutate existing - generates UR for admission requests (#3623) Signed-off-by: ShutingZhao <shuting@nirmata.com> * replace with UR in policy controller generate rules (#3635) Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com> * - enable mutate engine to process mutateExisting rules; - add unit tests Signed-off-by: ShutingZhao <shuting@nirmata.com> * implemented ur background reconciliation for mutateExisting policies Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix webhook update error Signed-off-by: ShutingZhao <shuting@nirmata.com> * temporary comment out new unit tests Signed-off-by: ShutingZhao <shuting@nirmata.com> * feat: mutate existing, replace GR by UR in webhook server (#3601) * add attributes for post mutation Signed-off-by: ShutingZhao <shuting@nirmata.com> * add UR informer to webhook server Signed-off-by: ShutingZhao <shuting@nirmata.com> * - replace gr with ur in the webhook server; - create ur for mutateExsiting policies Signed-off-by: ShutingZhao <shuting@nirmata.com> * replace gr by ur across entire packages Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix missing policy.kyverno.io/policy-name label (#3599) Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com> * refactor cli code from pkg to cmd (#3591) * refactor cli code from pkg to cmd Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com> * fixes in imports Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com> * fixes tests Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com> * fixed conflicts Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com> * moved non-commands to utils Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com> Co-authored-by: Vyankatesh Kudtarkar <vyankateshkd@gmail.com> * add YAMLs Signed-off-by: ShutingZhao <shuting@nirmata.com> * update api docs & fix unit tests Signed-off-by: ShutingZhao <shuting@nirmata.com> * add UR deletion handler Signed-off-by: ShutingZhao <shuting@nirmata.com> * add api docs for v1beta1 Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix clientset method Signed-off-by: ShutingZhao <shuting@nirmata.com> * add-kms-libraries for cosign (#3603) * add-kms-libraries Signed-off-by: anushkamittal20 <anumittal4641@gmail.com> * Shifted providers to cosign package Signed-off-by: anushkamittal20 <anumittal4641@gmail.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> * Add support for custom image extractors (#3596) Signed-off-by: Sambhav Kothari <skothari44@bloomberg.net> * Update vulnerable dependencies (#3577) Signed-off-by: Shubham Gupta <shubham.gupta2956@gmail.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix v1beta1 client registration Signed-off-by: ShutingZhao <shuting@nirmata.com> * feat: mutate existing - generates UR for admission requests (#3623) Signed-off-by: ShutingZhao <shuting@nirmata.com> * updating version in Chart.yaml (#3618) * updatimg version in Chart.yaml Signed-off-by: Prateeknandle <prateeknandle@gmail.com> * changes from, make gen-helm Signed-off-by: Prateeknandle <prateeknandle@gmail.com> Co-authored-by: Vyankatesh Kudtarkar <vyankateshkd@gmail.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> * Allow kyverno-policies to have preconditions defined (#3606) * Allow kyverno-policies to have preconditions defined Signed-off-by: Trey Dockendorf <tdockendorf@osc.edu> * Fix docs Signed-off-by: Trey Dockendorf <tdockendorf@osc.edu> Signed-off-by: ShutingZhao <shuting@nirmata.com> * replace with UR in policy controller generate rules (#3635) Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> * - enable mutate engine to process mutateExisting rules; - add unit tests Signed-off-by: ShutingZhao <shuting@nirmata.com> * implemented ur background reconciliation for mutateExisting policies Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix webhook update error Signed-off-by: ShutingZhao <shuting@nirmata.com> * temporary comment out new unit tests Signed-off-by: ShutingZhao <shuting@nirmata.com> * Image verify attestors (#3614) * fix logs Signed-off-by: Jim Bugwadia <jim@nirmata.com> * fix logs Signed-off-by: Jim Bugwadia <jim@nirmata.com> * support multiple attestors Signed-off-by: Jim Bugwadia <jim@nirmata.com> * rm CLI tests (not currently supported) Signed-off-by: Jim Bugwadia <jim@nirmata.com> * apply attestor repo Signed-off-by: Jim Bugwadia <jim@nirmata.com> * fix linter issues Signed-off-by: Jim Bugwadia <jim@nirmata.com> * fix entryError assignment Signed-off-by: Jim Bugwadia <jim@nirmata.com> * fix tests Signed-off-by: Jim Bugwadia <jim@nirmata.com> * format Signed-off-by: Jim Bugwadia <jim@nirmata.com> * add intermediary certs Signed-off-by: Jim Bugwadia <jim@nirmata.com> * Allow defining imagePullSecrets (#3633) * Allow defining imagePullSecrets Signed-off-by: Trey Dockendorf <tdockendorf@osc.edu> * Use dict for imagePullSecrets Signed-off-by: Trey Dockendorf <tdockendorf@osc.edu> * Simplify how imagePullSecrets is defined Signed-off-by: Trey Dockendorf <tdockendorf@osc.edu> Signed-off-by: ShutingZhao <shuting@nirmata.com> * Fix race condition in pCache (#3632) * fix race condition in pCache Signed-off-by: ShutingZhao <shuting@nirmata.com> * refact: remove unused Run function from generate (#3638) Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com> * Remove helm mode setting (#3628) Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> * refactor: image utils (#3630) Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> * -resolve lift comments; -fix informer sync issue Signed-off-by: ShutingZhao <shuting@nirmata.com> * refact the update request cleanup controller Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com> * - fix delete request for mutateExisting; - fix context variable substitution; - improve logging Signed-off-by: ShutingZhao <shuting@nirmata.com> * - enable events; - add last applied annotation Signed-off-by: ShutingZhao <shuting@nirmata.com> * enable mutate existing on policy creation Signed-off-by: ShutingZhao <shuting@nirmata.com> * update autogen code Signed-off-by: ShutingZhao <shuting@nirmata.com> * merge main Signed-off-by: ShutingZhao <shuting@nirmata.com> * add unit tests Signed-off-by: ShutingZhao <shuting@nirmata.com> * address list comments Signed-off-by: ShutingZhao <shuting@nirmata.com> * update api docs Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix "Implicit memory aliasing in for loop" Signed-off-by: ShutingZhao <shuting@nirmata.com> * remove unused definitions Signed-off-by: ShutingZhao <shuting@nirmata.com> * update api docs Signed-off-by: ShutingZhao <shuting@nirmata.com> Co-authored-by: Prateek Pandey <prateek.pandey@nirmata.com> Co-authored-by: Mritunjay Kumar Sharma <mritunjaysharma394@gmail.com> Co-authored-by: Vyankatesh Kudtarkar <vyankateshkd@gmail.com> Co-authored-by: Anushka Mittal <55237170+anushkamittal20@users.noreply.github.com> Co-authored-by: Sambhav Kothari <sambhavs.email@gmail.com> Co-authored-by: Shubham Gupta <shubham.gupta2956@gmail.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com> Co-authored-by: Prateek Nandle <56027872+Prateeknandle@users.noreply.github.com> Co-authored-by: treydock <tdockendorf@osc.edu> Co-authored-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
261 lines
7.4 KiB
Go
261 lines
7.4 KiB
Go
package event
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/go-logr/logr"
|
|
"github.com/kyverno/kyverno/pkg/client/clientset/versioned/scheme"
|
|
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"
|
|
v1 "k8s.io/api/core/v1"
|
|
errors "k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
|
"k8s.io/apimachinery/pkg/util/wait"
|
|
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
|
"k8s.io/client-go/tools/cache"
|
|
"k8s.io/client-go/tools/record"
|
|
"k8s.io/client-go/util/workqueue"
|
|
"k8s.io/klog/v2"
|
|
)
|
|
|
|
//Generator generate events
|
|
type Generator struct {
|
|
client *client.Client
|
|
// list/get cluster policy
|
|
cpLister kyvernolister.ClusterPolicyLister
|
|
// returns true if the cluster policy store has been synced at least once
|
|
cpSynced cache.InformerSynced
|
|
// list/get policy
|
|
pLister kyvernolister.PolicyLister
|
|
// returns true if the policy store has been synced at least once
|
|
pSynced cache.InformerSynced
|
|
// queue to store event generation requests
|
|
queue workqueue.RateLimitingInterface
|
|
// events generated at policy controller
|
|
policyCtrRecorder record.EventRecorder
|
|
// events generated at admission control
|
|
admissionCtrRecorder record.EventRecorder
|
|
// events generated at namespaced policy controller to process 'generate' rule
|
|
genPolicyRecorder record.EventRecorder
|
|
// events generated at mutateExisting controller
|
|
mutateExistingRecorder record.EventRecorder
|
|
|
|
log logr.Logger
|
|
}
|
|
|
|
//Interface to generate event
|
|
type Interface interface {
|
|
Add(infoList ...Info)
|
|
}
|
|
|
|
//NewEventGenerator to generate a new event controller
|
|
func NewEventGenerator(client *client.Client, cpInformer kyvernoinformer.ClusterPolicyInformer, pInformer kyvernoinformer.PolicyInformer, log logr.Logger) *Generator {
|
|
gen := Generator{
|
|
client: client,
|
|
cpLister: cpInformer.Lister(),
|
|
cpSynced: cpInformer.Informer().HasSynced,
|
|
pLister: pInformer.Lister(),
|
|
pSynced: pInformer.Informer().HasSynced,
|
|
queue: workqueue.NewNamedRateLimitingQueue(rateLimiter(), eventWorkQueueName),
|
|
policyCtrRecorder: initRecorder(client, PolicyController, log),
|
|
admissionCtrRecorder: initRecorder(client, AdmissionController, log),
|
|
genPolicyRecorder: initRecorder(client, GeneratePolicyController, log),
|
|
mutateExistingRecorder: initRecorder(client, MutateExistingController, log),
|
|
log: log,
|
|
}
|
|
return &gen
|
|
}
|
|
|
|
func rateLimiter() workqueue.RateLimiter {
|
|
return workqueue.DefaultItemBasedRateLimiter()
|
|
}
|
|
|
|
func initRecorder(client *client.Client, eventSource Source, log logr.Logger) record.EventRecorder {
|
|
// Initliaze Event Broadcaster
|
|
err := scheme.AddToScheme(scheme.Scheme)
|
|
if err != nil {
|
|
log.Error(err, "failed to add to scheme")
|
|
return nil
|
|
}
|
|
eventBroadcaster := record.NewBroadcaster()
|
|
eventBroadcaster.StartLogging(klog.V(5).Infof)
|
|
eventInterface, err := client.GetEventsInterface()
|
|
if err != nil {
|
|
log.Error(err, "failed to get event interface for logging")
|
|
return nil
|
|
}
|
|
eventBroadcaster.StartRecordingToSink(
|
|
&typedcorev1.EventSinkImpl{
|
|
Interface: eventInterface,
|
|
},
|
|
)
|
|
recorder := eventBroadcaster.NewRecorder(
|
|
scheme.Scheme,
|
|
v1.EventSource{
|
|
Component: eventSource.String(),
|
|
},
|
|
)
|
|
return recorder
|
|
}
|
|
|
|
//Add queues an event for generation
|
|
func (gen *Generator) Add(infos ...Info) {
|
|
logger := gen.log
|
|
for _, info := range infos {
|
|
if info.Name == "" {
|
|
// dont create event for resources with generateName
|
|
// as the name is not generated yet
|
|
logger.V(4).Info("not creating an event as the resource has not been assigned a name yet", "kind", info.Kind, "name", info.Name, "namespace", info.Namespace)
|
|
continue
|
|
}
|
|
gen.queue.Add(info)
|
|
}
|
|
}
|
|
|
|
// Run begins generator
|
|
func (gen *Generator) Run(workers int, stopCh <-chan struct{}) {
|
|
logger := gen.log
|
|
defer utilruntime.HandleCrash()
|
|
|
|
logger.Info("start")
|
|
defer logger.Info("shutting down")
|
|
|
|
if !cache.WaitForCacheSync(stopCh, gen.cpSynced, gen.pSynced) {
|
|
logger.Info("failed to sync informer cache")
|
|
}
|
|
|
|
for i := 0; i < workers; i++ {
|
|
go wait.Until(gen.runWorker, time.Second, stopCh)
|
|
}
|
|
<-stopCh
|
|
}
|
|
|
|
func (gen *Generator) runWorker() {
|
|
for gen.processNextWorkItem() {
|
|
}
|
|
}
|
|
|
|
func (gen *Generator) handleErr(err error, key interface{}) {
|
|
logger := gen.log
|
|
if err == nil {
|
|
gen.queue.Forget(key)
|
|
return
|
|
}
|
|
// This controller retries if something goes wrong. After that, it stops trying.
|
|
if gen.queue.NumRequeues(key) < workQueueRetryLimit {
|
|
logger.V(4).Info("retrying event generation", "key", key, "reason", err.Error())
|
|
// Re-enqueue the key rate limited. Based on the rate limiter on the
|
|
// queue and the re-enqueue history, the key will be processed later again.
|
|
gen.queue.AddRateLimited(key)
|
|
return
|
|
}
|
|
|
|
gen.queue.Forget(key)
|
|
if !errors.IsNotFound(err) {
|
|
logger.Error(err, "failed to generate event", "key", key)
|
|
}
|
|
}
|
|
|
|
func (gen *Generator) processNextWorkItem() bool {
|
|
logger := gen.log
|
|
obj, shutdown := gen.queue.Get()
|
|
if shutdown {
|
|
return false
|
|
}
|
|
|
|
err := func(obj interface{}) error {
|
|
defer gen.queue.Done(obj)
|
|
var key Info
|
|
var ok bool
|
|
|
|
if key, ok = obj.(Info); !ok {
|
|
gen.queue.Forget(obj)
|
|
logger.Info("Incorrect type; expected type 'info'", "obj", obj)
|
|
return nil
|
|
}
|
|
err := gen.syncHandler(key)
|
|
gen.handleErr(err, obj)
|
|
return nil
|
|
}(obj)
|
|
if err != nil {
|
|
logger.Error(err, "failed to process next work item")
|
|
return true
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (gen *Generator) syncHandler(key Info) error {
|
|
logger := gen.log
|
|
var robj runtime.Object
|
|
var err error
|
|
switch key.Kind {
|
|
case "ClusterPolicy":
|
|
robj, err = gen.cpLister.Get(key.Name)
|
|
if err != nil {
|
|
logger.Error(err, "failed to get cluster policy", "name", key.Name)
|
|
return err
|
|
}
|
|
case "Policy":
|
|
robj, err = gen.pLister.Policies(key.Namespace).Get(key.Name)
|
|
if err != nil {
|
|
logger.Error(err, "failed to get policy", "name", key.Name)
|
|
return err
|
|
}
|
|
default:
|
|
robj, err = gen.client.GetResource("", key.Kind, key.Namespace, key.Name)
|
|
if err != nil {
|
|
if !errors.IsNotFound(err) {
|
|
logger.Error(err, "failed to get resource", "kind", key.Kind, "name", key.Name, "namespace", key.Namespace)
|
|
}
|
|
return err
|
|
}
|
|
}
|
|
|
|
// set the event type based on reason
|
|
eventType := v1.EventTypeWarning
|
|
if key.Reason == PolicyApplied.String() {
|
|
eventType = v1.EventTypeNormal
|
|
}
|
|
|
|
// based on the source of event generation, use different event recorders
|
|
switch key.Source {
|
|
case AdmissionController:
|
|
gen.admissionCtrRecorder.Event(robj, eventType, key.Reason, key.Message)
|
|
case PolicyController:
|
|
gen.policyCtrRecorder.Event(robj, eventType, key.Reason, key.Message)
|
|
case GeneratePolicyController:
|
|
gen.genPolicyRecorder.Event(robj, eventType, key.Reason, key.Message)
|
|
case MutateExistingController:
|
|
gen.mutateExistingRecorder.Event(robj, eventType, key.Reason, key.Message)
|
|
default:
|
|
logger.Info("info.source not defined for the request")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
//NewEvent builds a event creation request
|
|
func NewEvent(
|
|
log logr.Logger,
|
|
rkind,
|
|
rapiVersion,
|
|
rnamespace,
|
|
rname,
|
|
reason string,
|
|
source Source,
|
|
message MsgKey,
|
|
args ...interface{}) Info {
|
|
msgText, err := getEventMsg(message, args...)
|
|
if err != nil {
|
|
log.Error(err, "failed to get event message")
|
|
}
|
|
return Info{
|
|
Kind: rkind,
|
|
Name: rname,
|
|
Namespace: rnamespace,
|
|
Reason: reason,
|
|
Source: source,
|
|
Message: msgText,
|
|
}
|
|
}
|