1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +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 {
policyName := resp.Policy.GetName()
resourceName := resp.PolicyResponse.Resource.Name
resourceKind := resp.PolicyResponse.Resource.Kind
resourceNamespace := resp.PolicyResponse.Resource.Namespace
resourceName := resp.Resource.GetName()
resourceKind := resp.Resource.GetKind()
resourceNamespace := resp.Resource.GetNamespace()
policyNamespace := resp.Policy.GetNamespace()
var rules []string

View file

@ -1117,10 +1117,10 @@ func handleGeneratePolicy(generateResponse *engineapi.EngineResponse, policyCont
Type: kyvernov1beta1.Generate,
Policy: generateResponse.Policy.GetName(),
Resource: kyvernov1.ResourceSpec{
Kind: generateResponse.PolicyResponse.Resource.Kind,
Namespace: generateResponse.PolicyResponse.Resource.Namespace,
Name: generateResponse.PolicyResponse.Resource.Name,
APIVersion: generateResponse.PolicyResponse.Resource.APIVersion,
Kind: generateResponse.Resource.GetKind(),
Namespace: generateResponse.Resource.GetNamespace(),
Name: generateResponse.Resource.GetName(),
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")
selector := labels.SelectorFromSet(labels.Set(map[string]string{
kyvernov1beta1.URGeneratePolicyLabel: engineResponse.Policy.GetName(),
kyvernov1beta1.URGenerateResourceNameLabel: engineResponse.PolicyResponse.Resource.Name,
kyvernov1beta1.URGenerateResourceKindLabel: engineResponse.PolicyResponse.Resource.Kind,
kyvernov1beta1.URGenerateResourceNSLabel: engineResponse.PolicyResponse.Resource.Namespace,
kyvernov1beta1.URGenerateResourceNameLabel: engineResponse.Resource.GetName(),
kyvernov1beta1.URGenerateResourceKindLabel: engineResponse.Resource.GetKind(),
kyvernov1beta1.URGenerateResourceNSLabel: engineResponse.Resource.GetNamespace(),
}))
urList, err := c.urLister.List(selector)
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
}

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

View file

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

View file

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

View file

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

View file

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

View file

@ -25,7 +25,7 @@ func (e *engine) verifyAndPatchImages(
policyContext engineapi.PolicyContext,
) (*engineapi.EngineResponse, *engineapi.ImageVerificationMetadata) {
policy := policyContext.Policy()
resp := engineapi.NewEngineResponse(policy)
resp := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil)
startTime := time.Now()
defer func() {
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 {
resp.NamespaceLabels = ctx.NamespaceLabels()
if reflect.DeepEqual(resp, engineapi.EngineResponse{}) {
return resp
}
if reflect.DeepEqual(resp.PatchedResource, unstructured.Unstructured{}) {
// for delete requests patched resource will be oldResource since newResource is empty
resource := ctx.NewResource()
@ -57,11 +53,6 @@ func BuildResponse(ctx engineapi.PolicyContext, resp *engineapi.EngineResponse,
resp.PatchedResource = resource
}
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
for _, v := range policy.GetSpec().ValidationFailureActionOverrides {
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) {
startTime := time.Now()
policy := policyContext.Policy()
resp = engineapi.NewEngineResponse(policy)
resp = engineapi.NewEngineResponseFromPolicyContext(policyContext, nil)
matchedResource := policyContext.NewResource()
enginectx := policyContext.JSONContext()
var skippedRules []string
@ -348,10 +348,6 @@ func startMutateResultResponse(resp *engineapi.EngineResponse, policy kyvernov1.
if resp == nil {
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) {

View file

@ -39,7 +39,8 @@ func (e *engine) validate(
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.ProcessingTime.String(), "validationRulesApplied", policyResponse.RulesAppliedCount)
engineResponse := &engineapi.EngineResponse{PolicyResponse: *policyResponse}
engineResponse := engineapi.NewEngineResponseFromPolicyContext(policyContext, nil)
engineResponse.PolicyResponse = *policyResponse
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 {
resource := engineResponse.PolicyResponse.Resource
resource := engineResponse.Resource
var bldr strings.Builder
defer bldr.Reset()
if resource.Namespace != "" {
fmt.Fprintf(&bldr, "%s %s/%s: pass", resource.Kind, resource.Namespace, resource.Name)
if resource.GetNamespace() != "" {
fmt.Fprintf(&bldr, "%s %s/%s: pass", resource.GetKind(), resource.GetNamespace(), resource.GetName())
} else {
fmt.Fprintf(&bldr, "%s %s: pass", resource.Kind, resource.Name)
fmt.Fprintf(&bldr, "%s %s: pass", resource.GetKind(), resource.GetName())
}
return Info{

View file

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

View file

@ -37,9 +37,9 @@ func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager,
if err != nil {
return err
}
resourceSpec := engineResponse.PolicyResponse.Resource
resourceKind := resourceSpec.Kind
resourceNamespace := resourceSpec.Namespace
resourceSpec := engineResponse.Resource
resourceKind := resourceSpec.GetKind()
resourceNamespace := resourceSpec.GetNamespace()
ruleResponses := engineResponse.PolicyResponse.Rules
for _, rule := range ruleResponses {
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 {
return &engineapi.EngineResponse{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: policy,
},
p := &kyvernov1.ClusterPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: policy,
},
PatchedResource: unstructured.Unstructured{
Object: map[string]interface{}{
"metadata": map[string]interface{}{
"annotations": annotation,
},
},
},
PolicyResponse: newPolicyResponse(rule, patchesStr, status),
}
policyResponse := newPolicyResponse(rule, patchesStr, status)
response := engineapi.NewEngineResponse(unstructured.Unstructured{}, p, nil, &policyResponse)
response.PatchedResource = unstructured.Unstructured{
Object: map[string]interface{}{
"metadata": map[string]interface{}{
"annotations": annotation,
},
},
}
return response
}
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")
selector := labels.SelectorFromSet(labels.Set(map[string]string{
kyvernov1beta1.URGeneratePolicyLabel: engineResponse.Policy.GetName(),
kyvernov1beta1.URGenerateResourceNameLabel: engineResponse.PolicyResponse.Resource.Name,
kyvernov1beta1.URGenerateResourceKindLabel: engineResponse.PolicyResponse.Resource.Kind,
kyvernov1beta1.URGenerateResourceNSLabel: engineResponse.PolicyResponse.Resource.Namespace,
kyvernov1beta1.URGenerateResourceNameLabel: engineResponse.Resource.GetName(),
kyvernov1beta1.URGenerateResourceKindLabel: engineResponse.Resource.GetKind(),
kyvernov1beta1.URGenerateResourceNSLabel: engineResponse.Resource.GetNamespace(),
}))
urList, err := h.urLister.List(selector)
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
}

View file

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

View file

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

View file

@ -58,8 +58,8 @@ func GetBlockedMessages(engineResponses []*engineapi.EngineResponse) string {
if len(failures) == 0 {
return ""
}
r := engineResponses[0].PolicyResponse.Resource
resourceName := fmt.Sprintf("%s/%s/%s", r.Kind, r.Namespace, r.Name)
r := engineResponses[0].Resource
resourceName := fmt.Sprintf("%s/%s/%s", r.GetKind(), r.GetNamespace(), r.GetName())
action := getAction(hasViolations, len(failures))
results, _ := yaml.Marshal(failures)
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"
"github.com/stretchr/testify/assert"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func Test_getAction(t *testing.T) {
@ -45,6 +46,20 @@ func Test_getAction(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 {
engineResponses []*engineapi.EngineResponse
failurePolicy kyvernov1.FailurePolicyType
@ -58,23 +73,16 @@ func TestBlockRequest(t *testing.T) {
name: "failure - enforce",
args: args{
engineResponses: []*engineapi.EngineResponse{
{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
},
},
},
}),
},
failurePolicy: kyvernov1.Fail,
log: logr.Discard(),
@ -84,23 +92,16 @@ func TestBlockRequest(t *testing.T) {
name: "failure - audit",
args: args{
engineResponses: []*engineapi.EngineResponse{
{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
},
},
},
}),
},
failurePolicy: kyvernov1.Fail,
log: logr.Discard(),
@ -110,23 +111,16 @@ func TestBlockRequest(t *testing.T) {
name: "error - fail",
args: args{
engineResponses: []*engineapi.EngineResponse{
{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-error",
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-error",
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
},
},
}),
},
failurePolicy: kyvernov1.Fail,
log: logr.Discard(),
@ -136,23 +130,16 @@ func TestBlockRequest(t *testing.T) {
name: "error - ignore",
args: args{
engineResponses: []*engineapi.EngineResponse{
{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-error",
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-error",
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
},
},
}),
},
failurePolicy: kyvernov1.Ignore,
log: logr.Discard(),
@ -162,23 +149,16 @@ func TestBlockRequest(t *testing.T) {
name: "warning - ignore",
args: args{
engineResponses: []*engineapi.EngineResponse{
{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-warning",
Status: engineapi.RuleStatusWarn,
Message: "message warning",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-warning",
Status: engineapi.RuleStatusWarn,
Message: "message warning",
},
},
},
},
}),
},
failurePolicy: kyvernov1.Ignore,
log: logr.Discard(),
@ -188,23 +168,16 @@ func TestBlockRequest(t *testing.T) {
name: "warning - fail",
args: args{
engineResponses: []*engineapi.EngineResponse{
{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-warning",
Status: engineapi.RuleStatusWarn,
Message: "message warning",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []engineapi.RuleResponse{
{
Name: "rule-warning",
Status: engineapi.RuleStatusWarn,
Message: "message warning",
},
},
},
},
}),
},
failurePolicy: kyvernov1.Fail,
log: logr.Discard(),
@ -220,6 +193,20 @@ func TestBlockRequest(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 {
engineResponses []*engineapi.EngineResponse
}
@ -231,28 +218,16 @@ func TestGetBlockedMessages(t *testing.T) {
name: "failure - enforce",
args: args{
engineResponses: []*engineapi.EngineResponse{
{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: engineapi.RuleStatusFail,
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",
@ -260,28 +235,16 @@ func TestGetBlockedMessages(t *testing.T) {
name: "error - enforce",
args: args{
engineResponses: []*engineapi.EngineResponse{
{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{
{
Name: "rule-error",
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{
{
Name: "rule-error",
Status: engineapi.RuleStatusError,
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",
@ -289,33 +252,21 @@ func TestGetBlockedMessages(t *testing.T) {
name: "error and failure - enforce",
args: args{
engineResponses: []*engineapi.EngineResponse{
{
Policy: &kyvernov1.ClusterPolicy{
ObjectMeta: v1.ObjectMeta{
Name: "test",
engineapi.NewEngineResponse(resource, policy, nil, &engineapi.PolicyResponse{
ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
{
Name: "rule-error",
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Enforce",
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
{
Name: "rule-error",
Status: engineapi.RuleStatusError,
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",

View file

@ -13,7 +13,7 @@ func GetErrorMsg(engineReponses []*engineapi.EngineResponse) string {
for _, er := range engineReponses {
if !er.IsSuccessful() {
// 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()))
for _, rule := range er.PolicyResponse.Rules {
if rule.Status != engineapi.RuleStatusPass {