diff --git a/pkg/controllers/report/background/controller.go b/pkg/controllers/report/background/controller.go index 99c23d58fc..a3e859a94f 100644 --- a/pkg/controllers/report/background/controller.go +++ b/pkg/controllers/report/background/controller.go @@ -309,8 +309,8 @@ func (c *controller) reconcileReport( if result.Error != nil { return result.Error } else { - ruleResults = append(ruleResults, reportutils.EngineResponseToReportResults(*result.EngineResponse)...) - utils.GenerateEvents(logger, c.eventGen, c.config, *result.EngineResponse) + ruleResults = append(ruleResults, reportutils.EngineResponseToReportResults(result.EngineResponse)...) + utils.GenerateEvents(logger, c.eventGen, c.config, result.EngineResponse) } } } diff --git a/pkg/controllers/report/utils/scanner.go b/pkg/controllers/report/utils/scanner.go index 10b0af8491..13b48db940 100644 --- a/pkg/controllers/report/utils/scanner.go +++ b/pkg/controllers/report/utils/scanner.go @@ -20,7 +20,7 @@ type scanner struct { } type ScanResult struct { - EngineResponse *engineapi.EngineResponse + EngineResponse engineapi.EngineResponse Error error } @@ -62,7 +62,7 @@ func (s *scanner) ScanResource(ctx context.Context, resource unstructured.Unstru response.PolicyResponse.Rules = append(response.PolicyResponse.Rules, ivResponse.PolicyResponse.Rules...) } } - results[policy] = ScanResult{response, multierr.Combine(errors...)} + results[policy] = ScanResult{*response, multierr.Combine(errors...)} } return results } diff --git a/pkg/engine/background.go b/pkg/engine/background.go index 7795d77415..c501010f5c 100644 --- a/pkg/engine/background.go +++ b/pkg/engine/background.go @@ -31,11 +31,7 @@ func (e *engine) filterRules( logger logr.Logger, startTime time.Time, ) engineapi.EngineResponse { - newResource := policyContext.NewResource() policy := policyContext.Policy() - kind := newResource.GetKind() - name := newResource.GetName() - namespace := newResource.GetNamespace() resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) resp.PolicyResponse = engineapi.PolicyResponse{ Stats: engineapi.PolicyStats{ @@ -44,12 +40,6 @@ func (e *engine) filterRules( }, }, } - - if e.configuration.ToFilter(kind, namespace, name) { - logger.Info("resource excluded") - return resp - } - applyRules := policy.GetSpec().GetApplyRules() for _, rule := range autogen.ComputeRules(policy) { logger := internal.LoggerWithRule(logger, rule) @@ -60,7 +50,6 @@ func (e *engine) filterRules( } } } - return resp } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 5a30185d09..a26f913229 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -43,6 +43,9 @@ func (e *engine) Validate( policyContext engineapi.PolicyContext, ) engineapi.EngineResponse { logger := internal.LoggerWithPolicyContext(logging.WithName("engine.validate"), policyContext) + if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { + return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + } return e.validate(ctx, logger, policyContext) } @@ -51,6 +54,9 @@ func (e *engine) Mutate( policyContext engineapi.PolicyContext, ) engineapi.EngineResponse { logger := internal.LoggerWithPolicyContext(logging.WithName("engine.mutate"), policyContext) + if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { + return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + } return e.mutate(ctx, logger, policyContext) } @@ -59,6 +65,9 @@ func (e *engine) VerifyAndPatchImages( policyContext engineapi.PolicyContext, ) (engineapi.EngineResponse, engineapi.ImageVerificationMetadata) { logger := internal.LoggerWithPolicyContext(logging.WithName("engine.verify"), policyContext) + if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { + return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil), engineapi.ImageVerificationMetadata{} + } return e.verifyAndPatchImages(ctx, logger, policyContext) } @@ -67,6 +76,9 @@ func (e *engine) ApplyBackgroundChecks( policyContext engineapi.PolicyContext, ) engineapi.EngineResponse { logger := internal.LoggerWithPolicyContext(logging.WithName("engine.background"), policyContext) + if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { + return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + } return e.applyBackgroundChecks(ctx, logger, policyContext) } @@ -76,6 +88,9 @@ func (e *engine) GenerateResponse( gr kyvernov1beta1.UpdateRequest, ) engineapi.EngineResponse { logger := internal.LoggerWithPolicyContext(logging.WithName("engine.generate"), policyContext) + if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { + return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + } return e.generateResponse(ctx, logger, policyContext, gr) } diff --git a/pkg/engine/generation.go b/pkg/engine/generation.go index d510885d96..d11f6f5146 100644 --- a/pkg/engine/generation.go +++ b/pkg/engine/generation.go @@ -27,10 +27,6 @@ func (e *engine) filterGenerateRules( policyNameKey string, startTime time.Time, ) engineapi.EngineResponse { - newResource := policyContext.NewResource() - kind := newResource.GetKind() - name := newResource.GetName() - namespace := newResource.GetNamespace() resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) resp.PolicyResponse = engineapi.PolicyResponse{ Stats: engineapi.PolicyStats{ @@ -39,10 +35,6 @@ func (e *engine) filterGenerateRules( }, }, } - if e.configuration.ToFilter(kind, namespace, name) { - logger.Info("resource excluded") - return resp - } for _, rule := range autogen.ComputeRules(policyContext.Policy()) { logger := internal.LoggerWithRule(logger, rule) if ruleResp := e.filterRule(rule, logger, policyContext); ruleResp != nil { diff --git a/pkg/engine/imageVerify.go b/pkg/engine/imageVerify.go index c199cf4799..7803f2dfa9 100644 --- a/pkg/engine/imageVerify.go +++ b/pkg/engine/imageVerify.go @@ -26,11 +26,12 @@ func (e *engine) verifyAndPatchImages( ) (engineapi.EngineResponse, engineapi.ImageVerificationMetadata) { policy := policyContext.Policy() resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + startTime := time.Now() defer func() { - logger.V(4).Info( - "processed image verification rules", + internal.BuildResponse(policyContext, &resp, startTime) + logger.V(4).Info("processed image verification rules", "time", resp.PolicyResponse.Stats.ProcessingTime.String(), "applied", resp.PolicyResponse.Stats.RulesAppliedCount, "successful", resp.IsSuccessful(), diff --git a/pkg/engine/internal/match.go b/pkg/engine/internal/match.go new file mode 100644 index 0000000000..a0f1ea246f --- /dev/null +++ b/pkg/engine/internal/match.go @@ -0,0 +1,51 @@ +package internal + +import ( + "github.com/go-logr/logr" + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + "github.com/kyverno/kyverno/pkg/config" + engineapi "github.com/kyverno/kyverno/pkg/engine/api" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func MatchPolicyContext(logger logr.Logger, policyContext engineapi.PolicyContext, configuration config.Configuration) bool { + policy := policyContext.Policy() + old := policyContext.OldResource() + new := policyContext.NewResource() + if !checkNamespacedPolicy(policy, new, old) { + logger.V(2).Info("policy namespace doesn't match resource namespace") + return false + } + if !checkResourceFilters(configuration, new, old) { + logger.V(2).Info("configuration resource filters doesn't match resource") + return false + } + return true +} + +func checkResourceFilters(configuration config.Configuration, resources ...unstructured.Unstructured) bool { + for _, resource := range resources { + if resource.Object != nil { + // TODO: account for generate name here ? + if configuration.ToFilter(resource.GetKind(), resource.GetNamespace(), resource.GetName()) { + return false + } + } + } + return true +} + +func checkNamespacedPolicy(policy kyvernov1.PolicyInterface, resources ...unstructured.Unstructured) bool { + if policy.IsNamespaced() { + policyNamespace := policy.GetNamespace() + for _, resource := range resources { + if resource.Object != nil { + resourceNamespace := resource.GetNamespace() + if resourceNamespace != policyNamespace || resourceNamespace == "" { + return false + } + } + } + } + return true +} diff --git a/pkg/engine/mutation.go b/pkg/engine/mutation.go index 0982136c86..50a8bf9a0e 100644 --- a/pkg/engine/mutation.go +++ b/pkg/engine/mutation.go @@ -25,9 +25,10 @@ func (e *engine) mutate( logger logr.Logger, policyContext engineapi.PolicyContext, ) engineapi.EngineResponse { - startTime := time.Now() policy := policyContext.Policy() resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + + startTime := time.Now() matchedResource := policyContext.NewResource() var skippedRules []string diff --git a/pkg/engine/validation.go b/pkg/engine/validation.go index 47d9aaaf79..a4ffe4544a 100644 --- a/pkg/engine/validation.go +++ b/pkg/engine/validation.go @@ -46,34 +46,22 @@ func (e *engine) validate( func (e *engine) validateResource( ctx context.Context, logger logr.Logger, - enginectx engineapi.PolicyContext, + policyContext engineapi.PolicyContext, ) *engineapi.PolicyResponse { resp := &engineapi.PolicyResponse{} - enginectx.JSONContext().Checkpoint() - defer enginectx.JSONContext().Restore() + policyContext.JSONContext().Checkpoint() + defer policyContext.JSONContext().Restore() - rules := autogen.ComputeRules(enginectx.Policy()) + rules := autogen.ComputeRules(policyContext.Policy()) matchCount := 0 - applyRules := enginectx.Policy().GetSpec().GetApplyRules() - newResource := enginectx.NewResource() - oldResource := enginectx.OldResource() - - if enginectx.Policy().IsNamespaced() { - polNs := enginectx.Policy().GetNamespace() - if enginectx.NewResource().Object != nil && (newResource.GetNamespace() != polNs || newResource.GetNamespace() == "") { - return resp - } - if enginectx.OldResource().Object != nil && (oldResource.GetNamespace() != polNs || oldResource.GetNamespace() == "") { - return resp - } - } + applyRules := policyContext.Policy().GetSpec().GetApplyRules() for i := range rules { rule := &rules[i] logger := internal.LoggerWithRule(logger, rules[i]) logger.V(3).Info("processing validation rule", "matchCount", matchCount) - enginectx.JSONContext().Reset() + policyContext.JSONContext().Reset() startTime := time.Now() ruleResp := tracing.ChildSpan1( ctx, @@ -86,22 +74,21 @@ func (e *engine) validateResource( if !hasValidate && !hasValidateImage { return nil } - - if !matches(logger, rule, enginectx, e.configuration) { + if !matches(logger, rule, policyContext, e.configuration) { return nil } // check if there is a corresponding policy exception - ruleResp := hasPolicyExceptions(logger, engineapi.Validation, e.exceptionSelector, enginectx, rule, e.configuration) + ruleResp := hasPolicyExceptions(logger, engineapi.Validation, e.exceptionSelector, policyContext, rule, e.configuration) if ruleResp != nil { return ruleResp } - enginectx.JSONContext().Reset() + policyContext.JSONContext().Reset() if hasValidate && !hasYAMLSignatureVerify { - return e.processValidationRule(ctx, logger, enginectx, rule) + return e.processValidationRule(ctx, logger, policyContext, rule) } else if hasValidateImage { - return e.processImageValidationRule(ctx, logger, enginectx, rule) + return e.processImageValidationRule(ctx, logger, policyContext, rule) } else if hasYAMLSignatureVerify { - return processYAMLValidationRule(e.client, logger, enginectx, rule) + return processYAMLValidationRule(e.client, logger, policyContext, rule) } return nil }, diff --git a/pkg/webhooks/resource/imageverification/handler.go b/pkg/webhooks/resource/imageverification/handler.go index b9d3165f3e..697b2eb840 100644 --- a/pkg/webhooks/resource/imageverification/handler.go +++ b/pkg/webhooks/resource/imageverification/handler.go @@ -90,8 +90,9 @@ func (h *imageVerificationHandler) handleVerifyImages( func(ctx context.Context, span trace.Span) { policyContext := policyContext.WithPolicy(policy) resp, ivm := h.engine.VerifyAndPatchImages(ctx, policyContext) - - engineResponses = append(engineResponses, resp) + if !resp.IsEmpty() { + engineResponses = append(engineResponses, resp) + } patches = append(patches, resp.GetPatches()...) verifiedImageData.Merge(ivm) },