Skip to content

Commit

Permalink
Merge branch 'main' into 10556
Browse files Browse the repository at this point in the history
  • Loading branch information
anushkamittal2001 authored Aug 13, 2024
2 parents 2f9f479 + e0ff371 commit 297b854
Show file tree
Hide file tree
Showing 64 changed files with 1,317 additions and 59 deletions.
20 changes: 11 additions & 9 deletions pkg/controllers/validatingadmissionpolicy-generate/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,18 +266,19 @@ func (c *controller) getValidatingAdmissionPolicyBinding(name string) (*admissio
return vapbinding, nil
}

// hasExceptions checks if there is an exception that match both the policy and the rule.
func (c *controller) hasExceptions(policyName, rule string) (bool, error) {
// getExceptions get exceptions that match both the policy and the rule if exists.
func (c *controller) getExceptions(policyName, rule string) ([]kyvernov2.PolicyException, error) {
var exceptions []kyvernov2.PolicyException
polexs, err := c.polexLister.List(labels.Everything())
if err != nil {
return false, err
return nil, err
}
for _, polex := range polexs {
if polex.Contains(policyName, rule) {
return true, nil
exceptions = append(exceptions, *polex)
}
}
return false, nil
return exceptions, nil
}

func constructVapBindingName(vapName string) string {
Expand Down Expand Up @@ -319,11 +320,12 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
observedVAP, vapErr := c.getValidatingAdmissionPolicy(vapName)
observedVAPbinding, vapBindingErr := c.getValidatingAdmissionPolicyBinding(vapBindingName)

hasExceptions, err := c.hasExceptions(name, spec.Rules[0].Name)
exceptions, err := c.getExceptions(name, spec.Rules[0].Name)
if err != nil {
return err
}
if ok, msg := validatingadmissionpolicy.CanGenerateVAP(spec); !ok || hasExceptions {

if ok, msg := validatingadmissionpolicy.CanGenerateVAP(spec, exceptions); !ok {
// delete the ValidatingAdmissionPolicy if exist
if vapErr == nil {
err = c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().Delete(ctx, vapName, metav1.DeleteOptions{})
Expand Down Expand Up @@ -371,7 +373,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
}

if observedVAP.ResourceVersion == "" {
err := validatingadmissionpolicy.BuildValidatingAdmissionPolicy(c.discoveryClient, observedVAP, policy)
err := validatingadmissionpolicy.BuildValidatingAdmissionPolicy(c.discoveryClient, observedVAP, policy, exceptions)
if err != nil {
c.updateClusterPolicyStatus(ctx, *policy, false, err.Error())
return err
Expand All @@ -387,7 +389,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
observedVAP,
c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies(),
func(observed *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) error {
return validatingadmissionpolicy.BuildValidatingAdmissionPolicy(c.discoveryClient, observed, policy)
return validatingadmissionpolicy.BuildValidatingAdmissionPolicy(c.discoveryClient, observed, policy, exceptions)
})
if err != nil {
c.updateClusterPolicyStatus(ctx, *policy, false, err.Error())
Expand Down
18 changes: 18 additions & 0 deletions pkg/validatingadmissionpolicy/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"slices"

kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
"github.com/kyverno/kyverno/pkg/clients/dclient"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
Expand All @@ -18,6 +19,7 @@ func BuildValidatingAdmissionPolicy(
discoveryClient dclient.IDiscovery,
vap *admissionregistrationv1alpha1.ValidatingAdmissionPolicy,
cpol kyvernov1.PolicyInterface,
exceptions []kyvernov2.PolicyException,
) error {
// set owner reference
vap.OwnerReferences = []metav1.OwnerReference{
Expand Down Expand Up @@ -73,6 +75,22 @@ func BuildValidatingAdmissionPolicy(
}
}

// convert the exceptions if exist
for _, exception := range exceptions {
match := exception.Spec.Match
if match.Any != nil {
if err := translateResourceFilters(discoveryClient, &matchResources, &excludeRules, match.Any, false); err != nil {
return err
}
}

if match.All != nil {
if err := translateResourceFilters(discoveryClient, &matchResources, &excludeRules, match.All, false); err != nil {
return err
}
}
}

// set policy spec
vap.Spec = admissionregistrationv1alpha1.ValidatingAdmissionPolicySpec{
MatchConstraints: &matchResources,
Expand Down
50 changes: 48 additions & 2 deletions pkg/validatingadmissionpolicy/kyvernopolicy_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,57 @@ package validatingadmissionpolicy

import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
"github.com/kyverno/kyverno/ext/wildcard"
)

// CanGenerateVAP check if Kyverno policy can be translated to a Kubernetes ValidatingAdmissionPolicy
func CanGenerateVAP(spec *kyvernov1.Spec) (bool, string) {
// CanGenerateVAP check if Kyverno policy and a PolicyException can be translated to a Kubernetes ValidatingAdmissionPolicy
func CanGenerateVAP(spec *kyvernov1.Spec, exceptions []kyvernov2.PolicyException) (bool, string) {
var msg string
if ok, msg := checkPolicy(spec); !ok {
return false, msg
}

if ok, msg := checkExceptions(exceptions); !ok {
return false, msg
}

return true, msg
}

func checkExceptions(exceptions []kyvernov2.PolicyException) (bool, string) {
var msg string
for _, exception := range exceptions {
spec := exception.Spec
for _, exception := range spec.Exceptions {
if len(exception.RuleNames) > 1 {
msg = "skip generating ValidatingAdmissionPolicy: multiple ruleNames in PolicyException is not applicable."
return false, msg
}
}

if spec.Conditions != nil {
msg = "skip generating ValidatingAdmissionPolicy: Conditions in PolicyException is not applicable."
return false, msg
}

exclude := spec.Match
if ok, msg := checkResourceFilter(exclude.Any, false); !ok {
return false, msg
}

if len(exclude.All) > 1 {
msg = "skip generating ValidatingAdmissionPolicy: multiple 'all' in the PolicyException's match block is not applicable."
return false, msg
}
if ok, msg := checkResourceFilter(exclude.All, false); !ok {
return false, msg
}
}
return true, msg
}

func checkPolicy(spec *kyvernov1.Spec) (bool, string) {
var msg string
if ok, msg := checkRuleCount(spec); !ok {
return false, msg
Expand Down
Loading

0 comments on commit 297b854

Please sign in to comment.