1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

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

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
Signed-off-by: ShutingZhao <shuting@nirmata.com>
Co-authored-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
shuting 2023-10-20 17:48:30 +08:00 committed by GitHub
parent 452392c05b
commit de673f07e6
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,
servicePort int32,
configuration config.Configuration,
eventGenerator event.Interface,
) ([]internal.Controller, func(context.Context) error, error) {
var leaderControllers []internal.Controller
@ -188,6 +189,7 @@ func createrLeaderControllers(
kyvernoInformer.Kyverno().V1().ClusterPolicies(),
kubeInformer.Admissionregistration().V1alpha1().ValidatingAdmissionPolicies(),
kubeInformer.Admissionregistration().V1alpha1().ValidatingAdmissionPolicyBindings(),
eventGenerator,
)
leaderControllers = append(leaderControllers, internal.NewController(vapcontroller.ControllerName, vapController, vapcontroller.Workers))
}
@ -409,6 +411,7 @@ func main() {
runtime,
int32(servicePort),
setup.Configuration,
eventGenerator,
)
if err != nil {
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"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/controllers"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/logging"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
datautils "github.com/kyverno/kyverno/pkg/utils/data"
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"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
admissionregistrationv1alpha1informers "k8s.io/client-go/informers/admissionregistration/v1alpha1"
@ -45,6 +46,8 @@ type controller struct {
// queue
queue workqueue.RateLimitingInterface
eventGen event.Interface
}
func NewController(
@ -55,6 +58,7 @@ func NewController(
cpolInformer kyvernov1informers.ClusterPolicyInformer,
vapInformer admissionregistrationv1alpha1informers.ValidatingAdmissionPolicyInformer,
vapbindingInformer admissionregistrationv1alpha1informers.ValidatingAdmissionPolicyBindingInformer,
eventGen event.Interface,
) controllers.Controller {
queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName)
c := &controller{
@ -65,6 +69,7 @@ func NewController(
vapLister: vapInformer.Lister(),
vapbindingLister: vapbindingInformer.Lister(),
queue: queue,
eventGen: eventGen,
}
// 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)
}
func (c *controller) addVAP(obj *v1alpha1.ValidatingAdmissionPolicy) {
func (c *controller) addVAP(obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) {
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) {
return
}
c.enqueueVAP(obj)
}
func (c *controller) deleteVAP(obj *v1alpha1.ValidatingAdmissionPolicy) {
func (c *controller) deleteVAP(obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) {
c.enqueueVAP(obj)
}
func (c *controller) enqueueVAP(v *v1alpha1.ValidatingAdmissionPolicy) {
func (c *controller) enqueueVAP(v *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) {
if len(v.OwnerReferences) == 1 {
if v.OwnerReferences[0].Kind == "ClusterPolicy" {
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)
}
func (c *controller) updateVAPbinding(old, obj *v1alpha1.ValidatingAdmissionPolicyBinding) {
func (c *controller) updateVAPbinding(old, obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding) {
if datautils.DeepEqual(old.Spec, obj.Spec) {
return
}
c.enqueueVAPbinding(obj)
}
func (c *controller) deleteVAPbinding(obj *v1alpha1.ValidatingAdmissionPolicyBinding) {
func (c *controller) deleteVAPbinding(obj *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding) {
c.enqueueVAPbinding(obj)
}
func (c *controller) enqueueVAPbinding(vb *v1alpha1.ValidatingAdmissionPolicyBinding) {
func (c *controller) enqueueVAPbinding(vb *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding) {
if len(vb.OwnerReferences) == 1 {
if vb.OwnerReferences[0].Kind == "ClusterPolicy" {
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
}
func (c *controller) getValidatingAdmissionPolicy(name string) (*v1alpha1.ValidatingAdmissionPolicy, error) {
func (c *controller) getValidatingAdmissionPolicy(name string) (*admissionregistrationv1alpha1.ValidatingAdmissionPolicy, error) {
vap, err := c.vapLister.Get(name)
if err != nil {
return nil, err
@ -196,7 +201,7 @@ func (c *controller) getValidatingAdmissionPolicy(name string) (*v1alpha1.Valida
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)
if err != nil {
return nil, err
@ -204,7 +209,7 @@ func (c *controller) getValidatingAdmissionPolicyBinding(name string) (*v1alpha1
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
vap.OwnerReferences = []metav1.OwnerReference{
{
@ -216,8 +221,8 @@ func (c *controller) buildValidatingAdmissionPolicy(vap *v1alpha1.ValidatingAdmi
}
// construct validating admission policy resource rules
var matchResources v1alpha1.MatchResources
var matchRules []v1alpha1.NamedRuleWithOperations
var matchResources admissionregistrationv1alpha1.MatchResources
var matchRules []admissionregistrationv1alpha1.NamedRuleWithOperations
rule := cpol.GetSpec().Rules[0]
match := rule.MatchResources
@ -239,7 +244,7 @@ func (c *controller) buildValidatingAdmissionPolicy(vap *v1alpha1.ValidatingAdmi
}
// set validating admission policy spec
vap.Spec = v1alpha1.ValidatingAdmissionPolicySpec{
vap.Spec = admissionregistrationv1alpha1.ValidatingAdmissionPolicySpec{
MatchConstraints: &matchResources,
ParamKind: rule.Validation.CEL.ParamKind,
Variables: rule.Validation.CEL.Variables,
@ -253,7 +258,7 @@ func (c *controller) buildValidatingAdmissionPolicy(vap *v1alpha1.ValidatingAdmi
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
vapbinding.OwnerReferences = []metav1.OwnerReference{
{
@ -265,18 +270,18 @@ func (c *controller) buildValidatingAdmissionPolicyBinding(vapbinding *v1alpha1.
}
// set validation action for vap binding
var validationActions []v1alpha1.ValidationAction
var validationActions []admissionregistrationv1alpha1.ValidationAction
action := cpol.GetSpec().ValidationFailureAction
if action.Enforce() {
validationActions = append(validationActions, v1alpha1.Deny)
validationActions = append(validationActions, admissionregistrationv1alpha1.Deny)
} else if action.Audit() {
validationActions = append(validationActions, v1alpha1.Audit)
validationActions = append(validationActions, v1alpha1.Warn)
validationActions = append(validationActions, admissionregistrationv1alpha1.Audit)
validationActions = append(validationActions, admissionregistrationv1alpha1.Warn)
}
// set validating admission policy binding spec
rule := cpol.GetSpec().Rules[0]
vapbinding.Spec = v1alpha1.ValidatingAdmissionPolicyBindingSpec{
vapbinding.Spec = admissionregistrationv1alpha1.ValidatingAdmissionPolicyBindingSpec{
PolicyName: cpol.GetName(),
ParamRef: rule.Validation.CEL.ParamRef,
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())
return err
}
observedVAP = &v1alpha1.ValidatingAdmissionPolicy{
observedVAP = &admissionregistrationv1alpha1.ValidatingAdmissionPolicy{
ObjectMeta: metav1.ObjectMeta{
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())
return err
}
observedVAPbinding = &v1alpha1.ValidatingAdmissionPolicyBinding{
observedVAPbinding = &admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding{
ObjectMeta: metav1.ObjectMeta{
Name: polName + "-binding",
},
@ -350,7 +355,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
ctx,
observedVAP,
c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies(),
func(observed *v1alpha1.ValidatingAdmissionPolicy) error {
func(observed *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) error {
return c.buildValidatingAdmissionPolicy(observed, policy)
})
if err != nil {
@ -375,7 +380,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
ctx,
observedVAPbinding,
c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings(),
func(observed *v1alpha1.ValidatingAdmissionPolicyBinding) error {
func(observed *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding) error {
return c.buildValidatingAdmissionPolicyBinding(observed, policy)
})
if err != nil {
@ -385,6 +390,9 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
}
c.updateClusterPolicyStatus(ctx, *policy, true, "")
// generate events
e := event.NewValidatingAdmissionPolicyEvent(policy, observedVAP.Name, observedVAPbinding.Name)
c.eventGen.Add(e...)
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 {
return Info{
Kind: resource.GetKind(),