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

refactor: original resource tracking in engine response (#6293)

* refactor: original resource tracking in engine response

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-02-10 15:04:41 +01:00 committed by GitHub
parent dc8874fea7
commit 43924e131c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 201 additions and 247 deletions

View file

@ -433,9 +433,9 @@ func buildPolicyResults(engineResponses []*engineapi.EngineResponse, testResults
for _, resp := range engineResponses { for _, resp := range engineResponses {
policyName := resp.Policy.GetName() policyName := resp.Policy.GetName()
resourceName := resp.PolicyResponse.Resource.Name resourceName := resp.Resource.GetName()
resourceKind := resp.PolicyResponse.Resource.Kind resourceKind := resp.Resource.GetKind()
resourceNamespace := resp.PolicyResponse.Resource.Namespace resourceNamespace := resp.Resource.GetNamespace()
policyNamespace := resp.Policy.GetNamespace() policyNamespace := resp.Policy.GetNamespace()
var rules []string var rules []string

View file

@ -1117,10 +1117,10 @@ func handleGeneratePolicy(generateResponse *engineapi.EngineResponse, policyCont
Type: kyvernov1beta1.Generate, Type: kyvernov1beta1.Generate,
Policy: generateResponse.Policy.GetName(), Policy: generateResponse.Policy.GetName(),
Resource: kyvernov1.ResourceSpec{ Resource: kyvernov1.ResourceSpec{
Kind: generateResponse.PolicyResponse.Resource.Kind, Kind: generateResponse.Resource.GetKind(),
Namespace: generateResponse.PolicyResponse.Resource.Namespace, Namespace: generateResponse.Resource.GetNamespace(),
Name: generateResponse.PolicyResponse.Resource.Name, Name: generateResponse.Resource.GetName(),
APIVersion: generateResponse.PolicyResponse.Resource.APIVersion, APIVersion: generateResponse.Resource.GetAPIVersion(),
}, },
}, },
} }

View file

@ -185,13 +185,13 @@ func (c *GenerateController) applyGenerate(resource unstructured.Unstructured, u
logger.V(4).Info("querying all update requests") logger.V(4).Info("querying all update requests")
selector := labels.SelectorFromSet(labels.Set(map[string]string{ selector := labels.SelectorFromSet(labels.Set(map[string]string{
kyvernov1beta1.URGeneratePolicyLabel: engineResponse.Policy.GetName(), kyvernov1beta1.URGeneratePolicyLabel: engineResponse.Policy.GetName(),
kyvernov1beta1.URGenerateResourceNameLabel: engineResponse.PolicyResponse.Resource.Name, kyvernov1beta1.URGenerateResourceNameLabel: engineResponse.Resource.GetName(),
kyvernov1beta1.URGenerateResourceKindLabel: engineResponse.PolicyResponse.Resource.Kind, kyvernov1beta1.URGenerateResourceKindLabel: engineResponse.Resource.GetKind(),
kyvernov1beta1.URGenerateResourceNSLabel: engineResponse.PolicyResponse.Resource.Namespace, kyvernov1beta1.URGenerateResourceNSLabel: engineResponse.Resource.GetNamespace(),
})) }))
urList, err := c.urLister.List(selector) urList, err := c.urLister.List(selector)
if err != nil { if err != nil {
logger.Error(err, "failed to get update request for the resource", "kind", engineResponse.PolicyResponse.Resource.Kind, "name", engineResponse.PolicyResponse.Resource.Name, "namespace", engineResponse.PolicyResponse.Resource.Namespace) logger.Error(err, "failed to get update request for the resource", "kind", engineResponse.Resource.GetKind(), "name", engineResponse.Resource.GetName(), "namespace", engineResponse.Resource.GetNamespace())
continue continue
} }

View file

@ -23,7 +23,7 @@ func GenerateEvents(logger logr.Logger, eventGen event.Interface, config config.
func generateSuccessEvents(log logr.Logger, ers ...*engineapi.EngineResponse) (eventInfos []event.Info) { func generateSuccessEvents(log logr.Logger, ers ...*engineapi.EngineResponse) (eventInfos []event.Info) {
for _, er := range ers { for _, er := range ers {
logger := log.WithValues("policy", er.Policy.GetName(), "kind", er.PolicyResponse.Resource.Kind, "namespace", er.PolicyResponse.Resource.Namespace, "name", er.PolicyResponse.Resource.Name) logger := log.WithValues("policy", er.Policy.GetName(), "kind", er.Resource.GetKind(), "namespace", er.Resource.GetNamespace(), "name", er.Resource.GetName())
if !er.IsFailed() { if !er.IsFailed() {
logger.V(4).Info("generating event on policy for success rules") logger.V(4).Info("generating event on policy for success rules")
e := event.NewPolicyAppliedEvent(event.PolicyController, er) e := event.NewPolicyAppliedEvent(event.PolicyController, er)
@ -56,9 +56,9 @@ func generateFailEventsPerEr(log logr.Logger, er *engineapi.EngineResponse) []ev
var eventInfos []event.Info var eventInfos []event.Info
logger := log.WithValues( logger := log.WithValues(
"policy", er.Policy.GetName(), "policy", er.Policy.GetName(),
"kind", er.PolicyResponse.Resource.Kind, "kind", er.Resource.GetKind(),
"namespace", er.PolicyResponse.Resource.Namespace, "namespace", er.Resource.GetNamespace(),
"name", er.PolicyResponse.Resource.Name, "name", er.Resource.GetName(),
) )
for i, rule := range er.PolicyResponse.Rules { for i, rule := range er.PolicyResponse.Rules {
if rule.Status != engineapi.RuleStatusPass && rule.Status != engineapi.RuleStatusSkip { if rule.Status != engineapi.RuleStatusPass && rule.Status != engineapi.RuleStatusSkip {

View file

@ -11,22 +11,53 @@ import (
// EngineResponse engine response to the action // EngineResponse engine response to the action
type EngineResponse struct { type EngineResponse struct {
// PatchedResource is the resource patched with the engine action changes // Resource is the original resource
PatchedResource unstructured.Unstructured Resource unstructured.Unstructured
// Policy is the original policy // Policy is the original policy
Policy kyvernov1.PolicyInterface Policy kyvernov1.PolicyInterface
// PolicyResponse contains the engine policy response
PolicyResponse PolicyResponse
// NamespaceLabels given by policy context // NamespaceLabels given by policy context
NamespaceLabels map[string]string NamespaceLabels map[string]string
// PatchedResource is the resource patched with the engine action changes
PatchedResource unstructured.Unstructured
// PolicyResponse contains the engine policy response
PolicyResponse PolicyResponse
}
func Resource(policyContext PolicyContext) unstructured.Unstructured {
resource := policyContext.NewResource()
if resource.Object == nil {
resource = policyContext.OldResource()
}
return resource
}
func NewEngineResponseFromPolicyContext(
policyContext PolicyContext,
policyResponse *PolicyResponse,
) *EngineResponse {
return NewEngineResponse(
Resource(policyContext),
policyContext.Policy(),
policyContext.NamespaceLabels(),
policyResponse,
)
} }
func NewEngineResponse( func NewEngineResponse(
resource unstructured.Unstructured,
policy kyvernov1.PolicyInterface, policy kyvernov1.PolicyInterface,
namespaceLabels map[string]string,
policyResponse *PolicyResponse,
) *EngineResponse { ) *EngineResponse {
return &EngineResponse{ response := &EngineResponse{
Resource: resource,
Policy: policy, Policy: policy,
NamespaceLabels: namespaceLabels,
} }
if policyResponse != nil {
response.PolicyResponse = *policyResponse
}
return response
} }
// IsOneOf checks if any rule has status in a given list // IsOneOf checks if any rule has status in a given list

View file

@ -13,8 +13,6 @@ type ValidationFailureActionOverride struct {
// PolicyResponse policy application response // PolicyResponse policy application response
type PolicyResponse struct { type PolicyResponse struct {
// Resource contains resource details
Resource ResourceSpec
// PolicyStats contains policy statistics // PolicyStats contains policy statistics
PolicyStats PolicyStats
// Rules contains policy rules responses // Rules contains policy rules responses

View file

@ -36,20 +36,13 @@ func (e *engine) filterRules(
kind := newResource.GetKind() kind := newResource.GetKind()
name := newResource.GetName() name := newResource.GetName()
namespace := newResource.GetNamespace() namespace := newResource.GetNamespace()
apiVersion := newResource.GetAPIVersion() resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil)
resp := engineapi.NewEngineResponse(policy)
resp.PolicyResponse = engineapi.PolicyResponse{ resp.PolicyResponse = engineapi.PolicyResponse{
PolicyStats: engineapi.PolicyStats{ PolicyStats: engineapi.PolicyStats{
ExecutionStats: engineapi.ExecutionStats{ ExecutionStats: engineapi.ExecutionStats{
Timestamp: startTime.Unix(), Timestamp: startTime.Unix(),
}, },
}, },
Resource: engineapi.ResourceSpec{
Kind: kind,
Name: name,
Namespace: namespace,
APIVersion: apiVersion,
},
} }
if e.configuration.ToFilter(kind, namespace, name) { if e.configuration.ToFilter(kind, namespace, name) {

View file

@ -31,20 +31,13 @@ func (e *engine) filterGenerateRules(
kind := newResource.GetKind() kind := newResource.GetKind()
name := newResource.GetName() name := newResource.GetName()
namespace := newResource.GetNamespace() namespace := newResource.GetNamespace()
apiVersion := newResource.GetAPIVersion() resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil)
resp := engineapi.NewEngineResponse(policyContext.Policy())
resp.PolicyResponse = engineapi.PolicyResponse{ resp.PolicyResponse = engineapi.PolicyResponse{
PolicyStats: engineapi.PolicyStats{ PolicyStats: engineapi.PolicyStats{
ExecutionStats: engineapi.ExecutionStats{ ExecutionStats: engineapi.ExecutionStats{
Timestamp: startTime.Unix(), Timestamp: startTime.Unix(),
}, },
}, },
Resource: engineapi.ResourceSpec{
Kind: kind,
Name: name,
Namespace: namespace,
APIVersion: apiVersion,
},
} }
if e.configuration.ToFilter(kind, namespace, name) { if e.configuration.ToFilter(kind, namespace, name) {
logger.Info("resource excluded") logger.Info("resource excluded")

View file

@ -25,7 +25,7 @@ func (e *engine) verifyAndPatchImages(
policyContext engineapi.PolicyContext, policyContext engineapi.PolicyContext,
) (*engineapi.EngineResponse, *engineapi.ImageVerificationMetadata) { ) (*engineapi.EngineResponse, *engineapi.ImageVerificationMetadata) {
policy := policyContext.Policy() policy := policyContext.Policy()
resp := engineapi.NewEngineResponse(policy) resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil)
startTime := time.Now() startTime := time.Now()
defer func() { defer func() {
internal.BuildResponse(policyContext, resp, startTime) internal.BuildResponse(policyContext, resp, startTime)

View file

@ -44,10 +44,6 @@ func AddRuleResponse(resp *engineapi.PolicyResponse, ruleResp *engineapi.RuleRes
} }
func BuildResponse(ctx engineapi.PolicyContext, resp *engineapi.EngineResponse, startTime time.Time) *engineapi.EngineResponse { func BuildResponse(ctx engineapi.PolicyContext, resp *engineapi.EngineResponse, startTime time.Time) *engineapi.EngineResponse {
resp.NamespaceLabels = ctx.NamespaceLabels()
if reflect.DeepEqual(resp, engineapi.EngineResponse{}) {
return resp
}
if reflect.DeepEqual(resp.PatchedResource, unstructured.Unstructured{}) { if reflect.DeepEqual(resp.PatchedResource, unstructured.Unstructured{}) {
// for delete requests patched resource will be oldResource since newResource is empty // for delete requests patched resource will be oldResource since newResource is empty
resource := ctx.NewResource() resource := ctx.NewResource()
@ -57,11 +53,6 @@ func BuildResponse(ctx engineapi.PolicyContext, resp *engineapi.EngineResponse,
resp.PatchedResource = resource resp.PatchedResource = resource
} }
policy := ctx.Policy() policy := ctx.Policy()
resp.Policy = policy
resp.PolicyResponse.Resource.Name = resp.PatchedResource.GetName()
resp.PolicyResponse.Resource.Namespace = resp.PatchedResource.GetNamespace()
resp.PolicyResponse.Resource.Kind = resp.PatchedResource.GetKind()
resp.PolicyResponse.Resource.APIVersion = resp.PatchedResource.GetAPIVersion()
resp.PolicyResponse.ValidationFailureAction = policy.GetSpec().ValidationFailureAction resp.PolicyResponse.ValidationFailureAction = policy.GetSpec().ValidationFailureAction
for _, v := range policy.GetSpec().ValidationFailureActionOverrides { for _, v := range policy.GetSpec().ValidationFailureActionOverrides {
newOverrides := engineapi.ValidationFailureActionOverride{Action: v.Action, Namespaces: v.Namespaces, NamespaceSelector: v.NamespaceSelector} newOverrides := engineapi.ValidationFailureActionOverride{Action: v.Action, Namespaces: v.Namespaces, NamespaceSelector: v.NamespaceSelector}

View file

@ -28,7 +28,7 @@ func (e *engine) mutate(
) (resp *engineapi.EngineResponse) { ) (resp *engineapi.EngineResponse) {
startTime := time.Now() startTime := time.Now()
policy := policyContext.Policy() policy := policyContext.Policy()
resp = engineapi.NewEngineResponse(policy) resp = engineapi.NewEngineResponseFromPolicyContext(policyContext, nil)
matchedResource := policyContext.NewResource() matchedResource := policyContext.NewResource()
enginectx := policyContext.JSONContext() enginectx := policyContext.JSONContext()
var skippedRules []string var skippedRules []string
@ -348,10 +348,6 @@ func startMutateResultResponse(resp *engineapi.EngineResponse, policy kyvernov1.
if resp == nil { if resp == nil {
return return
} }
resp.PolicyResponse.Resource.Name = resource.GetName()
resp.PolicyResponse.Resource.Namespace = resource.GetNamespace()
resp.PolicyResponse.Resource.Kind = resource.GetKind()
resp.PolicyResponse.Resource.APIVersion = resource.GetAPIVersion()
} }
func endMutateResultResponse(logger logr.Logger, resp *engineapi.EngineResponse, startTime time.Time) { func endMutateResultResponse(logger logr.Logger, resp *engineapi.EngineResponse, startTime time.Time) {

View file

@ -39,7 +39,8 @@ func (e *engine) validate(
logger.V(4).Info("start validate policy processing", "startTime", startTime) logger.V(4).Info("start validate policy processing", "startTime", startTime)
policyResponse := e.validateResource(ctx, logger, policyContext) policyResponse := e.validateResource(ctx, logger, policyContext)
defer logger.V(4).Info("finished policy processing", "processingTime", policyResponse.ProcessingTime.String(), "validationRulesApplied", policyResponse.RulesAppliedCount) defer logger.V(4).Info("finished policy processing", "processingTime", policyResponse.ProcessingTime.String(), "validationRulesApplied", policyResponse.RulesAppliedCount)
engineResponse := &engineapi.EngineResponse{PolicyResponse: *policyResponse} engineResponse := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil)
engineResponse.PolicyResponse = *policyResponse
return internal.BuildResponse(policyContext, engineResponse, startTime) return internal.BuildResponse(policyContext, engineResponse, startTime)
} }

View file

@ -48,14 +48,14 @@ func getPolicyKind(policy kyvernov1.PolicyInterface) string {
} }
func NewPolicyAppliedEvent(source Source, engineResponse *engineapi.EngineResponse) Info { func NewPolicyAppliedEvent(source Source, engineResponse *engineapi.EngineResponse) Info {
resource := engineResponse.PolicyResponse.Resource resource := engineResponse.Resource
var bldr strings.Builder var bldr strings.Builder
defer bldr.Reset() defer bldr.Reset()
if resource.Namespace != "" { if resource.GetNamespace() != "" {
fmt.Fprintf(&bldr, "%s %s/%s: pass", resource.Kind, resource.Namespace, resource.Name) fmt.Fprintf(&bldr, "%s %s/%s: pass", resource.GetKind(), resource.GetNamespace(), resource.GetName())
} else { } else {
fmt.Fprintf(&bldr, "%s %s: pass", resource.Kind, resource.Name) fmt.Fprintf(&bldr, "%s %s: pass", resource.GetKind(), resource.GetName())
} }
return Info{ return Info{

View file

@ -37,8 +37,8 @@ func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager,
if err != nil { if err != nil {
return err return err
} }
resourceSpec := engineResponse.PolicyResponse.Resource resourceSpec := engineResponse.Resource
resourceNamespace := resourceSpec.Namespace resourceNamespace := resourceSpec.GetNamespace()
ruleResponses := engineResponse.PolicyResponse.Rules ruleResponses := engineResponse.PolicyResponse.Rules
for _, rule := range ruleResponses { for _, rule := range ruleResponses {
ruleName := rule.Name ruleName := rule.Name

View file

@ -37,9 +37,9 @@ func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager,
if err != nil { if err != nil {
return err return err
} }
resourceSpec := engineResponse.PolicyResponse.Resource resourceSpec := engineResponse.Resource
resourceKind := resourceSpec.Kind resourceKind := resourceSpec.GetKind()
resourceNamespace := resourceSpec.Namespace resourceNamespace := resourceSpec.GetNamespace()
ruleResponses := engineResponse.PolicyResponse.Rules ruleResponses := engineResponse.PolicyResponse.Rules
for _, rule := range ruleResponses { for _, rule := range ruleResponses {
ruleName := rule.Name ruleName := rule.Name

View file

@ -29,21 +29,21 @@ func newPolicyResponse(rule string, patchesStr []string, status engineapi.RuleSt
} }
func newEngineResponse(policy, rule string, patchesStr []string, status engineapi.RuleStatus, annotation map[string]interface{}) *engineapi.EngineResponse { func newEngineResponse(policy, rule string, patchesStr []string, status engineapi.RuleStatus, annotation map[string]interface{}) *engineapi.EngineResponse {
return &engineapi.EngineResponse{ p := &kyvernov1.ClusterPolicy{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: policy, Name: policy,
}, },
}, }
PatchedResource: unstructured.Unstructured{ policyResponse := newPolicyResponse(rule, patchesStr, status)
response := engineapi.NewEngineResponse(unstructured.Unstructured{}, p, nil, &policyResponse)
response.PatchedResource = unstructured.Unstructured{
Object: map[string]interface{}{ Object: map[string]interface{}{
"metadata": map[string]interface{}{ "metadata": map[string]interface{}{
"annotations": annotation, "annotations": annotation,
}, },
}, },
},
PolicyResponse: newPolicyResponse(rule, patchesStr, status),
} }
return response
} }
func Test_empty_annotation(t *testing.T) { func Test_empty_annotation(t *testing.T) {

View file

@ -244,14 +244,14 @@ func (h *generationHandler) deleteGR(ctx context.Context, engineResponse *engine
h.log.V(4).Info("querying all update requests") h.log.V(4).Info("querying all update requests")
selector := labels.SelectorFromSet(labels.Set(map[string]string{ selector := labels.SelectorFromSet(labels.Set(map[string]string{
kyvernov1beta1.URGeneratePolicyLabel: engineResponse.Policy.GetName(), kyvernov1beta1.URGeneratePolicyLabel: engineResponse.Policy.GetName(),
kyvernov1beta1.URGenerateResourceNameLabel: engineResponse.PolicyResponse.Resource.Name, kyvernov1beta1.URGenerateResourceNameLabel: engineResponse.Resource.GetName(),
kyvernov1beta1.URGenerateResourceKindLabel: engineResponse.PolicyResponse.Resource.Kind, kyvernov1beta1.URGenerateResourceKindLabel: engineResponse.Resource.GetKind(),
kyvernov1beta1.URGenerateResourceNSLabel: engineResponse.PolicyResponse.Resource.Namespace, kyvernov1beta1.URGenerateResourceNSLabel: engineResponse.Resource.GetNamespace(),
})) }))
urList, err := h.urLister.List(selector) urList, err := h.urLister.List(selector)
if err != nil { if err != nil {
h.log.Error(err, "failed to get update request for the resource", "kind", engineResponse.PolicyResponse.Resource.Kind, "name", engineResponse.PolicyResponse.Resource.Name, "namespace", engineResponse.PolicyResponse.Resource.Namespace) h.log.Error(err, "failed to get update request for the resource", "kind", engineResponse.Resource.GetKind(), "name", engineResponse.Resource.GetName(), "namespace", engineResponse.Resource.GetNamespace())
return return
} }

View file

@ -153,10 +153,10 @@ func transform(admissionRequestInfo kyvernov1beta1.AdmissionRequestInfoObject, u
Type: ruleType, Type: ruleType,
Policy: PolicyNameNamespaceKey, Policy: PolicyNameNamespaceKey,
Resource: kyvernov1.ResourceSpec{ Resource: kyvernov1.ResourceSpec{
Kind: er.PolicyResponse.Resource.Kind, Kind: er.Resource.GetKind(),
Namespace: er.PolicyResponse.Resource.Namespace, Namespace: er.Resource.GetNamespace(),
Name: er.PolicyResponse.Resource.Name, Name: er.Resource.GetName(),
APIVersion: er.PolicyResponse.Resource.APIVersion, APIVersion: er.Resource.GetAPIVersion(),
}, },
Context: kyvernov1beta1.UpdateRequestSpecContext{ Context: kyvernov1beta1.UpdateRequestSpecContext{
UserRequestInfo: userRequestInfo, UserRequestInfo: userRequestInfo,

View file

@ -81,10 +81,10 @@ func transform(admissionRequestInfo kyvernov1beta1.AdmissionRequestInfoObject, u
Type: ruleType, Type: ruleType,
Policy: PolicyNameNamespaceKey, Policy: PolicyNameNamespaceKey,
Resource: kyvernov1.ResourceSpec{ Resource: kyvernov1.ResourceSpec{
Kind: er.PolicyResponse.Resource.Kind, Kind: er.Resource.GetKind(),
Namespace: er.PolicyResponse.Resource.Namespace, Namespace: er.Resource.GetNamespace(),
Name: er.PolicyResponse.Resource.Name, Name: er.Resource.GetName(),
APIVersion: er.PolicyResponse.Resource.APIVersion, APIVersion: er.Resource.GetAPIVersion(),
}, },
Context: kyvernov1beta1.UpdateRequestSpecContext{ Context: kyvernov1beta1.UpdateRequestSpecContext{
UserRequestInfo: userRequestInfo, UserRequestInfo: userRequestInfo,

View file

@ -58,8 +58,8 @@ func GetBlockedMessages(engineResponses []*engineapi.EngineResponse) string {
if len(failures) == 0 { if len(failures) == 0 {
return "" return ""
} }
r := engineResponses[0].PolicyResponse.Resource r := engineResponses[0].Resource
resourceName := fmt.Sprintf("%s/%s/%s", r.Kind, r.Namespace, r.Name) resourceName := fmt.Sprintf("%s/%s/%s", r.GetKind(), r.GetNamespace(), r.GetName())
action := getAction(hasViolations, len(failures)) action := getAction(hasViolations, len(failures))
results, _ := yaml.Marshal(failures) results, _ := yaml.Marshal(failures)
msg := fmt.Sprintf("\n\npolicy %s for resource %s: \n\n%s", resourceName, action, results) msg := fmt.Sprintf("\n\npolicy %s for resource %s: \n\n%s", resourceName, action, results)

View file

@ -8,6 +8,7 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api" engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
) )
func Test_getAction(t *testing.T) { func Test_getAction(t *testing.T) {
@ -45,6 +46,20 @@ func Test_getAction(t *testing.T) {
} }
func TestBlockRequest(t *testing.T) { func TestBlockRequest(t *testing.T) {
policy := &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
}
resource := unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "foo",
"metadata": map[string]interface{}{
"namespace": "bar",
"name": "baz",
},
},
}
type args struct { type args struct {
engineResponses []*engineapi.EngineResponse engineResponses []*engineapi.EngineResponse
failurePolicy kyvernov1.FailurePolicyType failurePolicy kyvernov1.FailurePolicyType
@ -58,13 +73,7 @@ func TestBlockRequest(t *testing.T) {
name: "failure - enforce", name: "failure - enforce",
args: args{ args: args{
engineResponses: []*engineapi.EngineResponse{ engineResponses: []*engineapi.EngineResponse{
{ engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Enforce", ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{ Rules: []engineapi.RuleResponse{
{ {
@ -73,8 +82,7 @@ func TestBlockRequest(t *testing.T) {
Message: "message fail", Message: "message fail",
}, },
}, },
}, }),
},
}, },
failurePolicy: kyvernov1.Fail, failurePolicy: kyvernov1.Fail,
log: logr.Discard(), log: logr.Discard(),
@ -84,13 +92,7 @@ func TestBlockRequest(t *testing.T) {
name: "failure - audit", name: "failure - audit",
args: args{ args: args{
engineResponses: []*engineapi.EngineResponse{ engineResponses: []*engineapi.EngineResponse{
{ engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit", ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{ Rules: []engineapi.RuleResponse{
{ {
@ -99,8 +101,7 @@ func TestBlockRequest(t *testing.T) {
Message: "message fail", Message: "message fail",
}, },
}, },
}, }),
},
}, },
failurePolicy: kyvernov1.Fail, failurePolicy: kyvernov1.Fail,
log: logr.Discard(), log: logr.Discard(),
@ -110,13 +111,7 @@ func TestBlockRequest(t *testing.T) {
name: "error - fail", name: "error - fail",
args: args{ args: args{
engineResponses: []*engineapi.EngineResponse{ engineResponses: []*engineapi.EngineResponse{
{ engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit", ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{ Rules: []engineapi.RuleResponse{
{ {
@ -125,8 +120,7 @@ func TestBlockRequest(t *testing.T) {
Message: "message error", Message: "message error",
}, },
}, },
}, }),
},
}, },
failurePolicy: kyvernov1.Fail, failurePolicy: kyvernov1.Fail,
log: logr.Discard(), log: logr.Discard(),
@ -136,13 +130,7 @@ func TestBlockRequest(t *testing.T) {
name: "error - ignore", name: "error - ignore",
args: args{ args: args{
engineResponses: []*engineapi.EngineResponse{ engineResponses: []*engineapi.EngineResponse{
{ engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit", ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{ Rules: []engineapi.RuleResponse{
{ {
@ -151,8 +139,7 @@ func TestBlockRequest(t *testing.T) {
Message: "message error", Message: "message error",
}, },
}, },
}, }),
},
}, },
failurePolicy: kyvernov1.Ignore, failurePolicy: kyvernov1.Ignore,
log: logr.Discard(), log: logr.Discard(),
@ -162,13 +149,7 @@ func TestBlockRequest(t *testing.T) {
name: "warning - ignore", name: "warning - ignore",
args: args{ args: args{
engineResponses: []*engineapi.EngineResponse{ engineResponses: []*engineapi.EngineResponse{
{ engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit", ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{ Rules: []engineapi.RuleResponse{
{ {
@ -177,8 +158,7 @@ func TestBlockRequest(t *testing.T) {
Message: "message warning", Message: "message warning",
}, },
}, },
}, }),
},
}, },
failurePolicy: kyvernov1.Ignore, failurePolicy: kyvernov1.Ignore,
log: logr.Discard(), log: logr.Discard(),
@ -188,13 +168,7 @@ func TestBlockRequest(t *testing.T) {
name: "warning - fail", name: "warning - fail",
args: args{ args: args{
engineResponses: []*engineapi.EngineResponse{ engineResponses: []*engineapi.EngineResponse{
{ engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit", ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{ Rules: []engineapi.RuleResponse{
{ {
@ -203,8 +177,7 @@ func TestBlockRequest(t *testing.T) {
Message: "message warning", Message: "message warning",
}, },
}, },
}, }),
},
}, },
failurePolicy: kyvernov1.Fail, failurePolicy: kyvernov1.Fail,
log: logr.Discard(), log: logr.Discard(),
@ -220,6 +193,20 @@ func TestBlockRequest(t *testing.T) {
} }
func TestGetBlockedMessages(t *testing.T) { func TestGetBlockedMessages(t *testing.T) {
policy := &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
}
resource := unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "foo",
"metadata": map[string]interface{}{
"namespace": "bar",
"name": "baz",
},
},
}
type args struct { type args struct {
engineResponses []*engineapi.EngineResponse engineResponses []*engineapi.EngineResponse
} }
@ -231,13 +218,7 @@ func TestGetBlockedMessages(t *testing.T) {
name: "failure - enforce", name: "failure - enforce",
args: args{ args: args{
engineResponses: []*engineapi.EngineResponse{ engineResponses: []*engineapi.EngineResponse{
{ engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Enforce", ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{ Rules: []engineapi.RuleResponse{
{ {
@ -246,13 +227,7 @@ func TestGetBlockedMessages(t *testing.T) {
Message: "message fail", Message: "message fail",
}, },
}, },
Resource: engineapi.ResourceSpec{ }),
Kind: "foo",
Namespace: "bar",
Name: "baz",
},
},
},
}, },
}, },
want: "\n\npolicy foo/bar/baz for resource violation: \n\ntest:\n rule-fail: message fail\n", want: "\n\npolicy foo/bar/baz for resource violation: \n\ntest:\n rule-fail: message fail\n",
@ -260,13 +235,7 @@ func TestGetBlockedMessages(t *testing.T) {
name: "error - enforce", name: "error - enforce",
args: args{ args: args{
engineResponses: []*engineapi.EngineResponse{ engineResponses: []*engineapi.EngineResponse{
{ engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Enforce", ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{ Rules: []engineapi.RuleResponse{
{ {
@ -275,13 +244,7 @@ func TestGetBlockedMessages(t *testing.T) {
Message: "message error", Message: "message error",
}, },
}, },
Resource: engineapi.ResourceSpec{ }),
Kind: "foo",
Namespace: "bar",
Name: "baz",
},
},
},
}, },
}, },
want: "\n\npolicy foo/bar/baz for resource error: \n\ntest:\n rule-error: message error\n", want: "\n\npolicy foo/bar/baz for resource error: \n\ntest:\n rule-error: message error\n",
@ -289,13 +252,7 @@ func TestGetBlockedMessages(t *testing.T) {
name: "error and failure - enforce", name: "error and failure - enforce",
args: args{ args: args{
engineResponses: []*engineapi.EngineResponse{ engineResponses: []*engineapi.EngineResponse{
{ engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Enforce", ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{ Rules: []engineapi.RuleResponse{
{ {
@ -309,13 +266,7 @@ func TestGetBlockedMessages(t *testing.T) {
Message: "message error", Message: "message error",
}, },
}, },
Resource: engineapi.ResourceSpec{ }),
Kind: "foo",
Namespace: "bar",
Name: "baz",
},
},
},
}, },
}, },
want: "\n\npolicy foo/bar/baz for resource violation: \n\ntest:\n rule-error: message error\n rule-fail: message fail\n", want: "\n\npolicy foo/bar/baz for resource violation: \n\ntest:\n rule-error: message error\n rule-fail: message fail\n",

View file

@ -13,7 +13,7 @@ func GetErrorMsg(engineReponses []*engineapi.EngineResponse) string {
for _, er := range engineReponses { for _, er := range engineReponses {
if !er.IsSuccessful() { if !er.IsSuccessful() {
// resource in engineReponses is identical as this was called per admission request // resource in engineReponses is identical as this was called per admission request
resourceInfo = fmt.Sprintf("%s/%s/%s", er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name) resourceInfo = fmt.Sprintf("%s/%s/%s", er.Resource.GetKind(), er.Resource.GetNamespace(), er.Resource.GetName())
str = append(str, fmt.Sprintf("failed policy %s:", er.Policy.GetName())) str = append(str, fmt.Sprintf("failed policy %s:", er.Policy.GetName()))
for _, rule := range er.PolicyResponse.Rules { for _, rule := range er.PolicyResponse.Rules {
if rule.Status != engineapi.RuleStatusPass { if rule.Status != engineapi.RuleStatusPass {