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

feat: generate events for CEL policies that generate VAPs (#8564)

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
Mariam Fahmy 2023-10-09 13:16:35 +03:00 committed by GitHub
parent 5882ed32a3
commit 8cbe66a06a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 25 deletions

View file

@ -116,6 +116,7 @@ func createrLeaderControllers(
runtime runtimeutils.Runtime, runtime runtimeutils.Runtime,
servicePort int32, servicePort int32,
configuration config.Configuration, configuration config.Configuration,
eventGenerator event.Interface,
) ([]internal.Controller, func(context.Context) error, error) { ) ([]internal.Controller, func(context.Context) error, error) {
var leaderControllers []internal.Controller var leaderControllers []internal.Controller
@ -188,6 +189,7 @@ func createrLeaderControllers(
kyvernoInformer.Kyverno().V1().ClusterPolicies(), kyvernoInformer.Kyverno().V1().ClusterPolicies(),
kubeInformer.Admissionregistration().V1alpha1().ValidatingAdmissionPolicies(), kubeInformer.Admissionregistration().V1alpha1().ValidatingAdmissionPolicies(),
kubeInformer.Admissionregistration().V1alpha1().ValidatingAdmissionPolicyBindings(), kubeInformer.Admissionregistration().V1alpha1().ValidatingAdmissionPolicyBindings(),
eventGenerator,
) )
leaderControllers = append(leaderControllers, internal.NewController(vapcontroller.ControllerName, vapController, vapcontroller.Workers)) leaderControllers = append(leaderControllers, internal.NewController(vapcontroller.ControllerName, vapController, vapcontroller.Workers))
} }
@ -409,6 +411,7 @@ func main() {
runtime, runtime,
int32(servicePort), int32(servicePort),
setup.Configuration, setup.Configuration,
eventGenerator,
) )
if err != nil { if err != nil {
logger.Error(err, "failed to create leader controllers") logger.Error(err, "failed to create leader controllers")

View file

@ -11,11 +11,12 @@ import (
kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
"github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/controllers" "github.com/kyverno/kyverno/pkg/controllers"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/logging" "github.com/kyverno/kyverno/pkg/logging"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
datautils "github.com/kyverno/kyverno/pkg/utils/data" datautils "github.com/kyverno/kyverno/pkg/utils/data"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"k8s.io/api/admissionregistration/v1alpha1" admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
admissionregistrationv1alpha1informers "k8s.io/client-go/informers/admissionregistration/v1alpha1" admissionregistrationv1alpha1informers "k8s.io/client-go/informers/admissionregistration/v1alpha1"
@ -45,6 +46,8 @@ type controller struct {
// queue // queue
queue workqueue.RateLimitingInterface queue workqueue.RateLimitingInterface
eventGen event.Interface
} }
func NewController( func NewController(
@ -55,6 +58,7 @@ func NewController(
cpolInformer kyvernov1informers.ClusterPolicyInformer, cpolInformer kyvernov1informers.ClusterPolicyInformer,
vapInformer admissionregistrationv1alpha1informers.ValidatingAdmissionPolicyInformer, vapInformer admissionregistrationv1alpha1informers.ValidatingAdmissionPolicyInformer,
vapbindingInformer admissionregistrationv1alpha1informers.ValidatingAdmissionPolicyBindingInformer, vapbindingInformer admissionregistrationv1alpha1informers.ValidatingAdmissionPolicyBindingInformer,
eventGen event.Interface,
) controllers.Controller { ) controllers.Controller {
queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName) queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName)
c := &controller{ c := &controller{
@ -65,6 +69,7 @@ func NewController(
vapLister: vapInformer.Lister(), vapLister: vapInformer.Lister(),
vapbindingLister: vapbindingInformer.Lister(), vapbindingLister: vapbindingInformer.Lister(),
queue: queue, queue: queue,
eventGen: eventGen,
} }
// Set up an event handler for when Kyverno policies change // Set up an event handler for when Kyverno policies change
@ -126,22 +131,22 @@ func (c *controller) enqueuePolicy(obj kyvernov1.PolicyInterface) {
c.queue.Add(key) c.queue.Add(key)
} }
func (c *controller) addVAP(obj *v1alpha1.ValidatingAdmissionPolicy) { func (c *controller) addVAP(obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) {
c.enqueueVAP(obj) c.enqueueVAP(obj)
} }
func (c *controller) updateVAP(old, obj *v1alpha1.ValidatingAdmissionPolicy) { func (c *controller) updateVAP(old, obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) {
if datautils.DeepEqual(old.Spec, obj.Spec) { if datautils.DeepEqual(old.Spec, obj.Spec) {
return return
} }
c.enqueueVAP(obj) c.enqueueVAP(obj)
} }
func (c *controller) deleteVAP(obj *v1alpha1.ValidatingAdmissionPolicy) { func (c *controller) deleteVAP(obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) {
c.enqueueVAP(obj) c.enqueueVAP(obj)
} }
func (c *controller) enqueueVAP(v *v1alpha1.ValidatingAdmissionPolicy) { func (c *controller) enqueueVAP(v *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) {
if len(v.OwnerReferences) == 1 { if len(v.OwnerReferences) == 1 {
if v.OwnerReferences[0].Kind == "ClusterPolicy" { if v.OwnerReferences[0].Kind == "ClusterPolicy" {
cpol, err := c.cpolLister.Get(v.OwnerReferences[0].Name) cpol, err := c.cpolLister.Get(v.OwnerReferences[0].Name)
@ -153,22 +158,22 @@ func (c *controller) enqueueVAP(v *v1alpha1.ValidatingAdmissionPolicy) {
} }
} }
func (c *controller) addVAPbinding(obj *v1alpha1.ValidatingAdmissionPolicyBinding) { func (c *controller) addVAPbinding(obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding) {
c.enqueueVAPbinding(obj) c.enqueueVAPbinding(obj)
} }
func (c *controller) updateVAPbinding(old, obj *v1alpha1.ValidatingAdmissionPolicyBinding) { func (c *controller) updateVAPbinding(old, obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding) {
if datautils.DeepEqual(old.Spec, obj.Spec) { if datautils.DeepEqual(old.Spec, obj.Spec) {
return return
} }
c.enqueueVAPbinding(obj) c.enqueueVAPbinding(obj)
} }
func (c *controller) deleteVAPbinding(obj *v1alpha1.ValidatingAdmissionPolicyBinding) { func (c *controller) deleteVAPbinding(obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding) {
c.enqueueVAPbinding(obj) c.enqueueVAPbinding(obj)
} }
func (c *controller) enqueueVAPbinding(vb *v1alpha1.ValidatingAdmissionPolicyBinding) { func (c *controller) enqueueVAPbinding(vb *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding) {
if len(vb.OwnerReferences) == 1 { if len(vb.OwnerReferences) == 1 {
if vb.OwnerReferences[0].Kind == "ClusterPolicy" { if vb.OwnerReferences[0].Kind == "ClusterPolicy" {
cpol, err := c.cpolLister.Get(vb.OwnerReferences[0].Name) cpol, err := c.cpolLister.Get(vb.OwnerReferences[0].Name)
@ -188,7 +193,7 @@ func (c *controller) getClusterPolicy(name string) (*kyvernov1.ClusterPolicy, er
return cpolicy, nil return cpolicy, nil
} }
func (c *controller) getValidatingAdmissionPolicy(name string) (*v1alpha1.ValidatingAdmissionPolicy, error) { func (c *controller) getValidatingAdmissionPolicy(name string) (*admissionregistrationv1alpha1.ValidatingAdmissionPolicy, error) {
vap, err := c.vapLister.Get(name) vap, err := c.vapLister.Get(name)
if err != nil { if err != nil {
return nil, err return nil, err
@ -196,7 +201,7 @@ func (c *controller) getValidatingAdmissionPolicy(name string) (*v1alpha1.Valida
return vap, nil return vap, nil
} }
func (c *controller) getValidatingAdmissionPolicyBinding(name string) (*v1alpha1.ValidatingAdmissionPolicyBinding, error) { func (c *controller) getValidatingAdmissionPolicyBinding(name string) (*admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding, error) {
vapbinding, err := c.vapbindingLister.Get(name) vapbinding, err := c.vapbindingLister.Get(name)
if err != nil { if err != nil {
return nil, err return nil, err
@ -204,7 +209,7 @@ func (c *controller) getValidatingAdmissionPolicyBinding(name string) (*v1alpha1
return vapbinding, nil return vapbinding, nil
} }
func (c *controller) buildValidatingAdmissionPolicy(vap *v1alpha1.ValidatingAdmissionPolicy, cpol kyvernov1.PolicyInterface) error { func (c *controller) buildValidatingAdmissionPolicy(vap *admissionregistrationv1alpha1.ValidatingAdmissionPolicy, cpol kyvernov1.PolicyInterface) error {
// set owner reference // set owner reference
vap.OwnerReferences = []metav1.OwnerReference{ vap.OwnerReferences = []metav1.OwnerReference{
{ {
@ -216,8 +221,8 @@ func (c *controller) buildValidatingAdmissionPolicy(vap *v1alpha1.ValidatingAdmi
} }
// construct validating admission policy resource rules // construct validating admission policy resource rules
var matchResources v1alpha1.MatchResources var matchResources admissionregistrationv1alpha1.MatchResources
var matchRules []v1alpha1.NamedRuleWithOperations var matchRules []admissionregistrationv1alpha1.NamedRuleWithOperations
rule := cpol.GetSpec().Rules[0] rule := cpol.GetSpec().Rules[0]
match := rule.MatchResources match := rule.MatchResources
@ -239,7 +244,7 @@ func (c *controller) buildValidatingAdmissionPolicy(vap *v1alpha1.ValidatingAdmi
} }
// set validating admission policy spec // set validating admission policy spec
vap.Spec = v1alpha1.ValidatingAdmissionPolicySpec{ vap.Spec = admissionregistrationv1alpha1.ValidatingAdmissionPolicySpec{
MatchConstraints: &matchResources, MatchConstraints: &matchResources,
ParamKind: rule.Validation.CEL.ParamKind, ParamKind: rule.Validation.CEL.ParamKind,
Variables: rule.Validation.CEL.Variables, Variables: rule.Validation.CEL.Variables,
@ -253,7 +258,7 @@ func (c *controller) buildValidatingAdmissionPolicy(vap *v1alpha1.ValidatingAdmi
return nil return nil
} }
func (c *controller) buildValidatingAdmissionPolicyBinding(vapbinding *v1alpha1.ValidatingAdmissionPolicyBinding, cpol kyvernov1.PolicyInterface) error { func (c *controller) buildValidatingAdmissionPolicyBinding(vapbinding *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding, cpol kyvernov1.PolicyInterface) error {
// set owner reference // set owner reference
vapbinding.OwnerReferences = []metav1.OwnerReference{ vapbinding.OwnerReferences = []metav1.OwnerReference{
{ {
@ -265,18 +270,18 @@ func (c *controller) buildValidatingAdmissionPolicyBinding(vapbinding *v1alpha1.
} }
// set validation action for vap binding // set validation action for vap binding
var validationActions []v1alpha1.ValidationAction var validationActions []admissionregistrationv1alpha1.ValidationAction
action := cpol.GetSpec().ValidationFailureAction action := cpol.GetSpec().ValidationFailureAction
if action.Enforce() { if action.Enforce() {
validationActions = append(validationActions, v1alpha1.Deny) validationActions = append(validationActions, admissionregistrationv1alpha1.Deny)
} else if action.Audit() { } else if action.Audit() {
validationActions = append(validationActions, v1alpha1.Audit) validationActions = append(validationActions, admissionregistrationv1alpha1.Audit)
validationActions = append(validationActions, v1alpha1.Warn) validationActions = append(validationActions, admissionregistrationv1alpha1.Warn)
} }
// set validating admission policy binding spec // set validating admission policy binding spec
rule := cpol.GetSpec().Rules[0] rule := cpol.GetSpec().Rules[0]
vapbinding.Spec = v1alpha1.ValidatingAdmissionPolicyBindingSpec{ vapbinding.Spec = admissionregistrationv1alpha1.ValidatingAdmissionPolicyBindingSpec{
PolicyName: cpol.GetName(), PolicyName: cpol.GetName(),
ParamRef: rule.Validation.CEL.ParamRef, ParamRef: rule.Validation.CEL.ParamRef,
ValidationActions: validationActions, ValidationActions: validationActions,
@ -314,7 +319,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
c.updateClusterPolicyStatus(ctx, *policy, false, err.Error()) c.updateClusterPolicyStatus(ctx, *policy, false, err.Error())
return err return err
} }
observedVAP = &v1alpha1.ValidatingAdmissionPolicy{ observedVAP = &admissionregistrationv1alpha1.ValidatingAdmissionPolicy{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: polName, Name: polName,
}, },
@ -327,7 +332,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
c.updateClusterPolicyStatus(ctx, *policy, false, err.Error()) c.updateClusterPolicyStatus(ctx, *policy, false, err.Error())
return err return err
} }
observedVAPbinding = &v1alpha1.ValidatingAdmissionPolicyBinding{ observedVAPbinding = &admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: polName + "-binding", Name: polName + "-binding",
}, },
@ -350,7 +355,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
ctx, ctx,
observedVAP, observedVAP,
c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies(), c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies(),
func(observed *v1alpha1.ValidatingAdmissionPolicy) error { func(observed *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) error {
return c.buildValidatingAdmissionPolicy(observed, policy) return c.buildValidatingAdmissionPolicy(observed, policy)
}) })
if err != nil { if err != nil {
@ -375,7 +380,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
ctx, ctx,
observedVAPbinding, observedVAPbinding,
c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings(), c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings(),
func(observed *v1alpha1.ValidatingAdmissionPolicyBinding) error { func(observed *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding) error {
return c.buildValidatingAdmissionPolicyBinding(observed, policy) return c.buildValidatingAdmissionPolicyBinding(observed, policy)
}) })
if err != nil { if err != nil {
@ -385,6 +390,9 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
} }
c.updateClusterPolicyStatus(ctx, *policy, true, "") c.updateClusterPolicyStatus(ctx, *policy, true, "")
// generate events
e := event.NewValidatingAdmissionPolicyEvent(policy, observedVAP.Name, observedVAPbinding.Name)
c.eventGen.Add(e...)
return nil return nil
} }

View file

@ -248,6 +248,34 @@ func NewCleanupPolicyEvent(policy kyvernov2alpha1.CleanupPolicyInterface, resour
} }
} }
func NewValidatingAdmissionPolicyEvent(policy kyvernov1.PolicyInterface, vapName, vapBindingName string) []Info {
vapEvent := Info{
Kind: policy.GetKind(),
Namespace: policy.GetNamespace(),
Name: policy.GetName(),
RelatedAPIVersion: "admissionregistration.k8s.io/v1alpha1",
RelatedKind: "ValidatingAdmissionPolicy",
RelatedName: vapName,
Source: GeneratePolicyController,
Action: ResourceGenerated,
Reason: PolicyApplied,
Message: fmt.Sprintf("successfully generated validating admission policy %s from policy %s", vapName, policy.GetName()),
}
vapBindingEvent := Info{
Kind: policy.GetKind(),
Namespace: policy.GetNamespace(),
Name: policy.GetName(),
RelatedAPIVersion: "admissionregistration.k8s.io/v1alpha1",
RelatedKind: "ValidatingAdmissionPolicyBinding",
RelatedName: vapBindingName,
Source: GeneratePolicyController,
Action: ResourceGenerated,
Reason: PolicyApplied,
Message: fmt.Sprintf("successfully generated validating admission policy binding %s from policy %s", vapBindingName, policy.GetName()),
}
return []Info{vapEvent, vapBindingEvent}
}
func NewFailedEvent(err error, policy, rule string, source Source, resource kyvernov1.ResourceSpec) Info { func NewFailedEvent(err error, policy, rule string, source Source, resource kyvernov1.ResourceSpec) Info {
return Info{ return Info{
Kind: resource.GetKind(), Kind: resource.GetKind(),