From eaaa8a0236e4bff0e30713e01abe360250d1fa58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 30 Mar 2023 13:59:32 +0200 Subject: [PATCH] refactor: engine responses (#6738) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: engine responses Signed-off-by: Charles-Edouard Brétéché * fix Signed-off-by: Charles-Edouard Brétéché * fix Signed-off-by: Charles-Edouard Brétéché * fix Signed-off-by: Charles-Edouard Brétéché --------- Signed-off-by: Charles-Edouard Brétéché --- pkg/engine/api/engineresponse.go | 33 +++++++++++++++++++----- pkg/engine/api/policyresponse.go | 13 ++++++++++ pkg/engine/api/stats.go | 12 +++++++-- pkg/engine/background.go | 15 +++-------- pkg/engine/engine.go | 44 +++++++++++++++++++++----------- pkg/engine/generation.go | 15 +++-------- pkg/engine/imageVerify.go | 33 ++++++++---------------- pkg/engine/internal/response.go | 4 +-- pkg/engine/mutation.go | 33 +++++------------------- pkg/engine/validation.go | 18 ++----------- pkg/utils/annotations_test.go | 3 ++- pkg/webhooks/utils/block_test.go | 19 +++++++------- 12 files changed, 120 insertions(+), 122 deletions(-) diff --git a/pkg/engine/api/engineresponse.go b/pkg/engine/api/engineresponse.go index 3f8d573a9c..1b68d87006 100644 --- a/pkg/engine/api/engineresponse.go +++ b/pkg/engine/api/engineresponse.go @@ -2,6 +2,7 @@ package api import ( "fmt" + "time" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" datautils "github.com/kyverno/kyverno/pkg/utils/data" @@ -22,6 +23,8 @@ type EngineResponse struct { PatchedResource unstructured.Unstructured // PolicyResponse contains the engine policy response PolicyResponse PolicyResponse + // Stats contains engine statistics + Stats ExecutionStats } func Resource(policyContext PolicyContext) unstructured.Unstructured { @@ -32,15 +35,13 @@ func Resource(policyContext PolicyContext) unstructured.Unstructured { return resource } -func NewEngineResponseFromPolicyContext( - policyContext PolicyContext, - policyResponse *PolicyResponse, -) EngineResponse { +func NewEngineResponseFromPolicyContext(policyContext PolicyContext, timestamp time.Time) EngineResponse { return NewEngineResponse( Resource(policyContext), policyContext.Policy(), policyContext.NamespaceLabels(), - policyResponse, + nil, + timestamp, ) } @@ -49,18 +50,36 @@ func NewEngineResponse( policy kyvernov1.PolicyInterface, namespaceLabels map[string]string, policyResponse *PolicyResponse, + timestamp time.Time, ) EngineResponse { response := EngineResponse{ Resource: resource, Policy: policy, NamespaceLabels: namespaceLabels, + PatchedResource: resource, + Stats: NewExecutionStats(timestamp), } if policyResponse != nil { - response.PolicyResponse = *policyResponse + response = response.WithPolicyResponse(*policyResponse) } return response } +func (er EngineResponse) WithPolicyResponse(policyResponse PolicyResponse) EngineResponse { + er.PolicyResponse = policyResponse + return er +} + +func (er EngineResponse) WithPatchedResource(patchedResource unstructured.Unstructured) EngineResponse { + er.PatchedResource = patchedResource + return er +} + +func (er EngineResponse) Done(timestamp time.Time) EngineResponse { + er.Stats.Done(timestamp) + return er +} + // IsOneOf checks if any rule has status in a given list func (er EngineResponse) IsOneOf(status ...RuleStatus) bool { for _, r := range er.PolicyResponse.Rules { @@ -158,7 +177,7 @@ func (er EngineResponse) getRulesWithErrors(predicate func(RuleResponse) bool) [ return rules } -func (er *EngineResponse) GetValidationFailureAction() kyvernov1.ValidationFailureAction { +func (er EngineResponse) GetValidationFailureAction() kyvernov1.ValidationFailureAction { spec := er.Policy.GetSpec() for _, v := range spec.ValidationFailureActionOverrides { if !v.Action.IsValid() { diff --git a/pkg/engine/api/policyresponse.go b/pkg/engine/api/policyresponse.go index 3cebdbbe08..e31ee327a2 100644 --- a/pkg/engine/api/policyresponse.go +++ b/pkg/engine/api/policyresponse.go @@ -7,3 +7,16 @@ type PolicyResponse struct { // Rules contains policy rules responses Rules []RuleResponse } + +func (pr *PolicyResponse) Add(rr RuleResponse) { + pr.Rules = append(pr.Rules, rr) + if rr.Status == RuleStatusPass || rr.Status == RuleStatusFail { + pr.Stats.RulesAppliedCount++ + } else if rr.Status == RuleStatusError { + pr.Stats.RulesErrorCount++ + } +} + +func NewPolicyResponse() PolicyResponse { + return PolicyResponse{} +} diff --git a/pkg/engine/api/stats.go b/pkg/engine/api/stats.go index a7acb72f51..55231c2e50 100644 --- a/pkg/engine/api/stats.go +++ b/pkg/engine/api/stats.go @@ -12,10 +12,18 @@ type ExecutionStats struct { Timestamp int64 } +func NewExecutionStats(timestamp time.Time) ExecutionStats { + return ExecutionStats{ + Timestamp: timestamp.Unix(), + } +} + +func (s *ExecutionStats) Done(timestamp time.Time) { + s.ProcessingTime = timestamp.Sub(time.Unix(s.Timestamp, 0)) +} + // PolicyStats stores statistics for the single policy application type PolicyStats struct { - // ExecutionStats policy execution stats - ExecutionStats // RulesAppliedCount is the count of rules that were applied successfully RulesAppliedCount int // RulesErrorCount is the count of rules that with execution errors diff --git a/pkg/engine/background.go b/pkg/engine/background.go index 15e1fd5d32..a1b05ece66 100644 --- a/pkg/engine/background.go +++ b/pkg/engine/background.go @@ -23,7 +23,7 @@ func (e *engine) applyBackgroundChecks( ctx context.Context, logger logr.Logger, policyContext engineapi.PolicyContext, -) engineapi.EngineResponse { +) engineapi.PolicyResponse { return e.filterRules(policyContext, logger, time.Now()) } @@ -31,21 +31,14 @@ func (e *engine) filterRules( policyContext engineapi.PolicyContext, logger logr.Logger, startTime time.Time, -) engineapi.EngineResponse { +) engineapi.PolicyResponse { policy := policyContext.Policy() - resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) - resp.PolicyResponse = engineapi.PolicyResponse{ - Stats: engineapi.PolicyStats{ - ExecutionStats: engineapi.ExecutionStats{ - Timestamp: startTime.Unix(), - }, - }, - } + resp := engineapi.NewPolicyResponse() applyRules := policy.GetSpec().GetApplyRules() for _, rule := range autogen.ComputeRules(policy) { logger := internal.LoggerWithRule(logger, rule) if ruleResp := e.filterRule(rule, logger, policyContext); ruleResp != nil { - resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *ruleResp) + resp.Rules = append(resp.Rules, *ruleResp) if applyRules == kyvernov1.ApplyOne && ruleResp.Status != engineapi.RuleStatusSkip { break } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index c4e7e183dc..0c39850705 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -3,6 +3,7 @@ package engine import ( "context" "fmt" + "time" "github.com/go-logr/logr" gojmespath "github.com/jmespath/go-jmespath" @@ -76,44 +77,55 @@ func (e *engine) Validate( ctx context.Context, policyContext engineapi.PolicyContext, ) engineapi.EngineResponse { + response := engineapi.NewEngineResponseFromPolicyContext(policyContext, time.Now()) logger := internal.LoggerWithPolicyContext(logging.WithName("engine.validate"), policyContext) - if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { - return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + if internal.MatchPolicyContext(logger, policyContext, e.configuration) { + policyResponse := e.validate(ctx, logger, policyContext) + response = response.WithPolicyResponse(policyResponse) } - return e.validate(ctx, logger, policyContext) + return response.Done(time.Now()) } func (e *engine) Mutate( ctx context.Context, policyContext engineapi.PolicyContext, ) engineapi.EngineResponse { + response := engineapi.NewEngineResponseFromPolicyContext(policyContext, time.Now()) logger := internal.LoggerWithPolicyContext(logging.WithName("engine.mutate"), policyContext) - if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { - return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + if internal.MatchPolicyContext(logger, policyContext, e.configuration) { + policyResponse, patchedResource := e.mutate(ctx, logger, policyContext) + response = response. + WithPolicyResponse(policyResponse). + WithPatchedResource(patchedResource) } - return e.mutate(ctx, logger, policyContext) + return response.Done(time.Now()) } func (e *engine) VerifyAndPatchImages( ctx context.Context, policyContext engineapi.PolicyContext, ) (engineapi.EngineResponse, engineapi.ImageVerificationMetadata) { + response := engineapi.NewEngineResponseFromPolicyContext(policyContext, time.Now()) + ivm := engineapi.ImageVerificationMetadata{} logger := internal.LoggerWithPolicyContext(logging.WithName("engine.verify"), policyContext) - if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { - return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil), engineapi.ImageVerificationMetadata{} + if internal.MatchPolicyContext(logger, policyContext, e.configuration) { + policyResponse, innerIvm := e.verifyAndPatchImages(ctx, logger, policyContext) + response, ivm = response.WithPolicyResponse(policyResponse), innerIvm } - return e.verifyAndPatchImages(ctx, logger, policyContext) + return response.Done(time.Now()), ivm } func (e *engine) ApplyBackgroundChecks( ctx context.Context, policyContext engineapi.PolicyContext, ) engineapi.EngineResponse { + response := engineapi.NewEngineResponseFromPolicyContext(policyContext, time.Now()) logger := internal.LoggerWithPolicyContext(logging.WithName("engine.background"), policyContext) - if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { - return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + if internal.MatchPolicyContext(logger, policyContext, e.configuration) { + policyResponse := e.applyBackgroundChecks(ctx, logger, policyContext) + response = response.WithPolicyResponse(policyResponse) } - return e.applyBackgroundChecks(ctx, logger, policyContext) + return response.Done(time.Now()) } func (e *engine) GenerateResponse( @@ -121,11 +133,13 @@ func (e *engine) GenerateResponse( policyContext engineapi.PolicyContext, gr kyvernov1beta1.UpdateRequest, ) engineapi.EngineResponse { + response := engineapi.NewEngineResponseFromPolicyContext(policyContext, time.Now()) logger := internal.LoggerWithPolicyContext(logging.WithName("engine.generate"), policyContext) - if !internal.MatchPolicyContext(logger, policyContext, e.configuration) { - return engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) + if internal.MatchPolicyContext(logger, policyContext, e.configuration) { + policyResponse := e.generateResponse(ctx, logger, policyContext, gr) + response = response.WithPolicyResponse(policyResponse) } - return e.generateResponse(ctx, logger, policyContext, gr) + return response.Done(time.Now()) } func (e *engine) ContextLoader( diff --git a/pkg/engine/generation.go b/pkg/engine/generation.go index d11f6f5146..cf09ea0ab1 100644 --- a/pkg/engine/generation.go +++ b/pkg/engine/generation.go @@ -17,7 +17,7 @@ func (e *engine) generateResponse( logger logr.Logger, policyContext engineapi.PolicyContext, gr kyvernov1beta1.UpdateRequest, -) engineapi.EngineResponse { +) engineapi.PolicyResponse { return e.filterGenerateRules(policyContext, logger, gr.Spec.Policy, time.Now()) } @@ -26,19 +26,12 @@ func (e *engine) filterGenerateRules( logger logr.Logger, policyNameKey string, startTime time.Time, -) engineapi.EngineResponse { - resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) - resp.PolicyResponse = engineapi.PolicyResponse{ - Stats: engineapi.PolicyStats{ - ExecutionStats: engineapi.ExecutionStats{ - Timestamp: startTime.Unix(), - }, - }, - } +) engineapi.PolicyResponse { + resp := engineapi.NewPolicyResponse() for _, rule := range autogen.ComputeRules(policyContext.Policy()) { logger := internal.LoggerWithRule(logger, rule) if ruleResp := e.filterRule(rule, logger, policyContext); ruleResp != nil { - resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *ruleResp) + resp.Rules = append(resp.Rules, *ruleResp) } } return resp diff --git a/pkg/engine/imageVerify.go b/pkg/engine/imageVerify.go index fc62c06ee6..c796b7c19d 100644 --- a/pkg/engine/imageVerify.go +++ b/pkg/engine/imageVerify.go @@ -21,20 +21,9 @@ func (e *engine) verifyAndPatchImages( ctx context.Context, logger logr.Logger, policyContext engineapi.PolicyContext, -) (engineapi.EngineResponse, engineapi.ImageVerificationMetadata) { +) (engineapi.PolicyResponse, engineapi.ImageVerificationMetadata) { policy := policyContext.Policy() - resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) - - startTime := time.Now() - - defer func() { - 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(), - ) - }() + resp := engineapi.NewPolicyResponse() policyContext.JSONContext().Checkpoint() defer policyContext.JSONContext().Restore() @@ -52,11 +41,11 @@ func (e *engine) verifyAndPatchImages( }, ) - if applyRules == kyvernov1.ApplyOne && resp.PolicyResponse.Stats.RulesAppliedCount > 0 { + if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 { break } } - internal.BuildResponse(policyContext, &resp, startTime) + // TODO: i doesn't make sense to not return the patched resource here return resp, ivm } @@ -65,7 +54,7 @@ func (e *engine) doVerifyAndPatch( logger logr.Logger, policyContext engineapi.PolicyContext, rule kyvernov1.Rule, - resp *engineapi.EngineResponse, + resp *engineapi.PolicyResponse, ivm *engineapi.ImageVerificationMetadata, ) { if len(rule.VerifyImages) == 0 { @@ -82,7 +71,7 @@ func (e *engine) doVerifyAndPatch( // check if there is a corresponding policy exception ruleResp := e.hasPolicyExceptions(logger, engineapi.ImageVerify, policyContext, rule) if ruleResp != nil { - resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *ruleResp) + resp.Rules = append(resp.Rules, *ruleResp) return } @@ -96,7 +85,7 @@ func (e *engine) doVerifyAndPatch( ) if err != nil { internal.AddRuleResponse( - &resp.PolicyResponse, + resp, internal.RuleError(rule, engineapi.ImageVerify, "failed to extract images", err), startTime, ) @@ -104,7 +93,7 @@ func (e *engine) doVerifyAndPatch( } if len(ruleImages) == 0 { internal.AddRuleResponse( - &resp.PolicyResponse, + resp, internal.RuleSkip( rule, engineapi.ImageVerify, @@ -117,7 +106,7 @@ func (e *engine) doVerifyAndPatch( policyContext.JSONContext().Restore() if err := internal.LoadContext(ctx, e, policyContext, rule); err != nil { internal.AddRuleResponse( - &resp.PolicyResponse, + resp, internal.RuleError(rule, engineapi.ImageVerify, "failed to load context", err), startTime, ) @@ -126,7 +115,7 @@ func (e *engine) doVerifyAndPatch( ruleCopy, err := substituteVariables(&rule, policyContext.JSONContext(), logger) if err != nil { internal.AddRuleResponse( - &resp.PolicyResponse, + resp, internal.RuleError(rule, engineapi.ImageVerify, "failed to substitute variables", err), startTime, ) @@ -141,7 +130,7 @@ func (e *engine) doVerifyAndPatch( ) for _, imageVerify := range ruleCopy.VerifyImages { for _, r := range iv.Verify(ctx, imageVerify, ruleImages, e.configuration) { - internal.AddRuleResponse(&resp.PolicyResponse, r, startTime) + internal.AddRuleResponse(resp, r, startTime) } } } diff --git a/pkg/engine/internal/response.go b/pkg/engine/internal/response.go index 1f02e7491a..38fd9e5041 100644 --- a/pkg/engine/internal/response.go +++ b/pkg/engine/internal/response.go @@ -50,7 +50,7 @@ func BuildResponse(ctx engineapi.PolicyContext, resp *engineapi.EngineResponse, } resp.PatchedResource = resource } - resp.PolicyResponse.Stats.ProcessingTime = time.Since(startTime) - resp.PolicyResponse.Stats.Timestamp = startTime.Unix() + resp.Stats.ProcessingTime = time.Since(startTime) + resp.Stats.Timestamp = startTime.Unix() return resp } diff --git a/pkg/engine/mutation.go b/pkg/engine/mutation.go index 073f038090..89f2b45046 100644 --- a/pkg/engine/mutation.go +++ b/pkg/engine/mutation.go @@ -12,25 +12,23 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) -// Mutate performs mutation. Overlay first and then mutation patches +// mutate performs mutation. Overlay first and then mutation patches func (e *engine) mutate( ctx context.Context, logger logr.Logger, policyContext engineapi.PolicyContext, -) engineapi.EngineResponse { - startTime := time.Now() - resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) +) (engineapi.PolicyResponse, unstructured.Unstructured) { + resp := engineapi.NewPolicyResponse() policy := policyContext.Policy() matchedResource := policyContext.NewResource() - startMutateResultResponse(&resp, policy, matchedResource) - policyContext.JSONContext().Checkpoint() defer policyContext.JSONContext().Restore() applyRules := policy.GetSpec().GetApplyRules() for _, rule := range autogen.ComputeRules(policy) { + startTime := time.Now() logger := internal.LoggerWithRule(logger, rule) if !rule.HasMutate() { continue @@ -43,29 +41,12 @@ func (e *engine) mutate( matchedResource = resource for _, ruleResp := range ruleResp { ruleResp := ruleResp - internal.AddRuleResponse(&resp.PolicyResponse, &ruleResp, startTime) + internal.AddRuleResponse(&resp, &ruleResp, startTime) logger.V(4).Info("finished processing rule", "processingTime", ruleResp.Stats.ProcessingTime.String()) } - if applyRules == kyvernov1.ApplyOne && resp.PolicyResponse.Stats.RulesAppliedCount > 0 { + if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 { break } } - resp.PatchedResource = matchedResource - endMutateResultResponse(logger, &resp, startTime) - return resp -} - -func startMutateResultResponse(resp *engineapi.EngineResponse, policy kyvernov1.PolicyInterface, resource unstructured.Unstructured) { - if resp == nil { - return - } -} - -func endMutateResultResponse(logger logr.Logger, resp *engineapi.EngineResponse, startTime time.Time) { - if resp == nil { - return - } - resp.PolicyResponse.Stats.ProcessingTime = time.Since(startTime) - resp.PolicyResponse.Stats.Timestamp = startTime.Unix() - logger.V(5).Info("finished processing policy", "processingTime", resp.PolicyResponse.Stats.ProcessingTime.String(), "mutationRulesApplied", resp.PolicyResponse.Stats.RulesAppliedCount) + return resp, matchedResource } diff --git a/pkg/engine/validation.go b/pkg/engine/validation.go index ae08d0084d..69583ae794 100644 --- a/pkg/engine/validation.go +++ b/pkg/engine/validation.go @@ -16,21 +16,7 @@ func (e *engine) validate( ctx context.Context, logger logr.Logger, policyContext engineapi.PolicyContext, -) engineapi.EngineResponse { - startTime := time.Now() - logger.V(4).Info("start validate policy processing", "startTime", startTime) - policyResponse := e.validateResource(ctx, logger, policyContext) - defer logger.V(4).Info("finished policy processing", "processingTime", policyResponse.Stats.ProcessingTime.String(), "validationRulesApplied", policyResponse.Stats.RulesAppliedCount) - engineResponse := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil) - engineResponse.PolicyResponse = *policyResponse - return *internal.BuildResponse(policyContext, &engineResponse, startTime) -} - -func (e *engine) validateResource( - ctx context.Context, - logger logr.Logger, - policyContext engineapi.PolicyContext, -) *engineapi.PolicyResponse { +) engineapi.PolicyResponse { resp := &engineapi.PolicyResponse{} policyContext.JSONContext().Checkpoint() @@ -72,5 +58,5 @@ func (e *engine) validateResource( break } } - return resp + return *resp } diff --git a/pkg/utils/annotations_test.go b/pkg/utils/annotations_test.go index 6e3828f1ed..0e64b67611 100644 --- a/pkg/utils/annotations_test.go +++ b/pkg/utils/annotations_test.go @@ -2,6 +2,7 @@ package utils import ( "testing" + "time" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" engineapi "github.com/kyverno/kyverno/pkg/engine/api" @@ -35,7 +36,7 @@ func newEngineResponse(policy, rule string, patchesStr []string, status engineap }, } policyResponse := newPolicyResponse(rule, patchesStr, status) - response := engineapi.NewEngineResponse(unstructured.Unstructured{}, p, nil, &policyResponse) + response := engineapi.NewEngineResponse(unstructured.Unstructured{}, p, nil, &policyResponse, time.Now()) response.PatchedResource = unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ diff --git a/pkg/webhooks/utils/block_test.go b/pkg/webhooks/utils/block_test.go index 0f33f5318c..6a272c0d14 100644 --- a/pkg/webhooks/utils/block_test.go +++ b/pkg/webhooks/utils/block_test.go @@ -2,6 +2,7 @@ package utils import ( "testing" + "time" "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" @@ -92,7 +93,7 @@ func TestBlockRequest(t *testing.T) { Message: "message fail", }, }, - }), + }, time.Now()), }, failurePolicy: kyvernov1.Fail, log: logr.Discard(), @@ -110,7 +111,7 @@ func TestBlockRequest(t *testing.T) { Message: "message fail", }, }, - }), + }, time.Now()), }, failurePolicy: kyvernov1.Fail, log: logr.Discard(), @@ -128,7 +129,7 @@ func TestBlockRequest(t *testing.T) { Message: "message error", }, }, - }), + }, time.Now()), }, failurePolicy: kyvernov1.Fail, log: logr.Discard(), @@ -146,7 +147,7 @@ func TestBlockRequest(t *testing.T) { Message: "message error", }, }, - }), + }, time.Now()), }, failurePolicy: kyvernov1.Ignore, log: logr.Discard(), @@ -164,7 +165,7 @@ func TestBlockRequest(t *testing.T) { Message: "message warning", }, }, - }), + }, time.Now()), }, failurePolicy: kyvernov1.Ignore, log: logr.Discard(), @@ -182,7 +183,7 @@ func TestBlockRequest(t *testing.T) { Message: "message warning", }, }, - }), + }, time.Now()), }, failurePolicy: kyvernov1.Fail, log: logr.Discard(), @@ -234,7 +235,7 @@ func TestGetBlockedMessages(t *testing.T) { Message: "message fail", }, }, - }), + }, time.Now()), }, }, want: "\n\npolicy foo/bar/baz for resource violation: \n\ntest:\n rule-fail: message fail\n", @@ -250,7 +251,7 @@ func TestGetBlockedMessages(t *testing.T) { Message: "message error", }, }, - }), + }, time.Now()), }, }, want: "\n\npolicy foo/bar/baz for resource error: \n\ntest:\n rule-error: message error\n", @@ -271,7 +272,7 @@ func TestGetBlockedMessages(t *testing.T) { Message: "message error", }, }, - }), + }, time.Now()), }, }, want: "\n\npolicy foo/bar/baz for resource violation: \n\ntest:\n rule-error: message error\n rule-fail: message fail\n",