From f287e0a220193e2e5f89002e9ec12855e6642953 Mon Sep 17 00:00:00 2001
From: Jim Bugwadia
Date: Mon, 8 May 2023 00:34:23 -0700
Subject: [PATCH] Conditions message (#7113)
* add message to conditions
Signed-off-by: Jim Bugwadia
* add tests
Signed-off-by: Jim Bugwadia
* extend tests
Signed-off-by: Jim Bugwadia
---------
Signed-off-by: Jim Bugwadia
---
api/kyverno/v1/common_types.go | 3 +
charts/kyverno/templates/crds/crds.yaml | 192 ++++++++++++++++++
config/crds/kyverno.io_clusterpolicies.yaml | 96 +++++++++
config/crds/kyverno.io_policies.yaml | 96 +++++++++
config/install-latest-testing.yaml | 192 ++++++++++++++++++
docs/user/crd/index.html | 11 +
pkg/engine/attestation_test.go | 2 +-
pkg/engine/background.go | 7 +-
pkg/engine/engine.go | 6 +-
pkg/engine/handlers/mutation/common.go | 4 +-
.../handlers/mutation/mutate_existing.go | 6 +-
.../handlers/validation/validate_resource.go | 23 ++-
pkg/engine/image_verify_test.go | 3 +-
pkg/engine/internal/imageverifier.go | 20 +-
pkg/engine/internal/preconditions.go | 20 +-
pkg/engine/variables/evaluate.go | 46 +++--
pkg/engine/variables/evaluate_test.go | 75 ++++++-
pkg/utils/strings/join.go | 20 ++
pkg/utils/strings/join_test.go | 14 ++
19 files changed, 775 insertions(+), 61 deletions(-)
create mode 100644 pkg/utils/strings/join.go
create mode 100644 pkg/utils/strings/join_test.go
diff --git a/api/kyverno/v1/common_types.go b/api/kyverno/v1/common_types.go
index 103f674ee9..5a5ddd5176 100644
--- a/api/kyverno/v1/common_types.go
+++ b/api/kyverno/v1/common_types.go
@@ -197,6 +197,9 @@ type Condition struct {
// or can be variables declared using JMESPath.
// +optional
RawValue *apiextv1.JSON `json:"value,omitempty" yaml:"value,omitempty"`
+
+ // Message is an optional display message
+ Message string `json:"message,omitempty" yaml:"message,omitempty"`
}
func (c *Condition) GetKey() apiextensions.JSON {
diff --git a/charts/kyverno/templates/crds/crds.yaml b/charts/kyverno/templates/crds/crds.yaml
index 82c293ac24..fd9eb76199 100644
--- a/charts/kyverno/templates/crds/crds.yaml
+++ b/charts/kyverno/templates/crds/crds.yaml
@@ -5710,6 +5710,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -5759,6 +5763,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6210,6 +6218,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6259,6 +6271,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6885,6 +6901,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6936,6 +6956,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9278,6 +9302,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9329,6 +9357,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9802,6 +9834,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9853,6 +9889,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10511,6 +10551,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10563,6 +10607,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12505,6 +12553,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12554,6 +12606,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13173,6 +13229,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13222,6 +13282,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13833,6 +13897,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13884,6 +13952,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -16201,6 +16273,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -16252,6 +16328,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -16725,6 +16805,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -16776,6 +16860,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -17434,6 +17522,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -17486,6 +17578,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -19881,6 +19977,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -19930,6 +20030,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -20381,6 +20485,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -20430,6 +20538,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -21056,6 +21168,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -21107,6 +21223,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -23450,6 +23570,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -23501,6 +23625,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -23974,6 +24102,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -24025,6 +24157,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -24683,6 +24819,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -24735,6 +24875,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -26678,6 +26822,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -26727,6 +26875,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -27346,6 +27498,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -27395,6 +27551,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -28006,6 +28166,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -28057,6 +28221,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -30374,6 +30542,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -30425,6 +30597,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -30898,6 +31074,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -30949,6 +31129,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -31607,6 +31791,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -31659,6 +31847,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
diff --git a/config/crds/kyverno.io_clusterpolicies.yaml b/config/crds/kyverno.io_clusterpolicies.yaml
index a78c662bdf..b174c21a32 100644
--- a/config/crds/kyverno.io_clusterpolicies.yaml
+++ b/config/crds/kyverno.io_clusterpolicies.yaml
@@ -1968,6 +1968,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -2017,6 +2021,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -2468,6 +2476,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -2517,6 +2529,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -3143,6 +3159,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -3194,6 +3214,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -5536,6 +5560,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -5587,6 +5615,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6060,6 +6092,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6111,6 +6147,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6769,6 +6809,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6821,6 +6865,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -8763,6 +8811,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -8812,6 +8864,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9431,6 +9487,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9480,6 +9540,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10091,6 +10155,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10142,6 +10210,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12459,6 +12531,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12510,6 +12586,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12983,6 +13063,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13034,6 +13118,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13692,6 +13780,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13744,6 +13836,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
diff --git a/config/crds/kyverno.io_policies.yaml b/config/crds/kyverno.io_policies.yaml
index 73b4366bcd..78f122c931 100644
--- a/config/crds/kyverno.io_policies.yaml
+++ b/config/crds/kyverno.io_policies.yaml
@@ -1969,6 +1969,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -2018,6 +2022,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -2469,6 +2477,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -2518,6 +2530,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -3144,6 +3160,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -3195,6 +3215,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -5538,6 +5562,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -5589,6 +5617,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6062,6 +6094,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6113,6 +6149,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6771,6 +6811,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6823,6 +6867,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -8766,6 +8814,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -8815,6 +8867,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9434,6 +9490,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9483,6 +9543,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10094,6 +10158,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10145,6 +10213,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12462,6 +12534,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12513,6 +12589,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12986,6 +13066,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13037,6 +13121,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13695,6 +13783,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13747,6 +13839,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
diff --git a/config/install-latest-testing.yaml b/config/install-latest-testing.yaml
index 7282293afe..cdab31a9c9 100644
--- a/config/install-latest-testing.yaml
+++ b/config/install-latest-testing.yaml
@@ -5914,6 +5914,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -5963,6 +5967,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6414,6 +6422,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -6463,6 +6475,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -7089,6 +7105,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -7140,6 +7160,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9482,6 +9506,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -9533,6 +9561,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10006,6 +10038,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10057,6 +10093,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10715,6 +10755,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -10767,6 +10811,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12709,6 +12757,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -12758,6 +12810,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13377,6 +13433,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -13426,6 +13486,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -14037,6 +14101,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -14088,6 +14156,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -16405,6 +16477,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -16456,6 +16532,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -16929,6 +17009,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -16980,6 +17064,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -17638,6 +17726,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -17690,6 +17782,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -20085,6 +20181,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -20134,6 +20234,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -20585,6 +20689,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -20634,6 +20742,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -21260,6 +21372,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -21311,6 +21427,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -23654,6 +23774,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -23705,6 +23829,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -24178,6 +24306,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -24229,6 +24361,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -24887,6 +25023,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -24939,6 +25079,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -26882,6 +27026,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -26931,6 +27079,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -27550,6 +27702,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -27599,6 +27755,10 @@ spec:
description: Key is the context entry (using
JMESPath) for conditional rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional display
+ message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -28210,6 +28370,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -28261,6 +28425,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -30578,6 +30746,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -30629,6 +30801,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -31102,6 +31278,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -31153,6 +31333,10 @@ spec:
(using JMESPath) for conditional rule
evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -31811,6 +31995,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
@@ -31863,6 +32051,10 @@ spec:
entry (using JMESPath) for conditional
rule evaluation.
x-kubernetes-preserve-unknown-fields: true
+ message:
+ description: Message is an optional
+ display message
+ type: string
operator:
description: 'Operator is the conditional
operation to perform. Valid operators
diff --git a/docs/user/crd/index.html b/docs/user/crd/index.html
index 73ebc82e52..a01206c581 100644
--- a/docs/user/crd/index.html
+++ b/docs/user/crd/index.html
@@ -1120,6 +1120,17 @@ Kubernetes apiextensions/v1.JSON
or can be variables declared using JMESPath.
+
+
+message
+
+string
+
+ |
+
+ Message is an optional display message
+ |
+
diff --git a/pkg/engine/attestation_test.go b/pkg/engine/attestation_test.go
index 5768649ec7..e48b99c00d 100644
--- a/pkg/engine/attestation_test.go
+++ b/pkg/engine/attestation_test.go
@@ -260,7 +260,7 @@ func Test_Conditions(t *testing.T) {
err := json.Unmarshal([]byte(scanPredicate), &dataMap)
assert.NilError(t, err)
- pass, err := internal.EvaluateConditions(conditions, ctx, dataMap, logr.Discard())
+ pass, _, err := internal.EvaluateConditions(conditions, ctx, dataMap, logr.Discard())
assert.NilError(t, err)
assert.Equal(t, pass, true)
}
diff --git a/pkg/engine/background.go b/pkg/engine/background.go
index 73726d1a6a..17116fdea3 100644
--- a/pkg/engine/background.go
+++ b/pkg/engine/background.go
@@ -9,7 +9,6 @@ import (
"github.com/kyverno/kyverno/pkg/autogen"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/internal"
- "github.com/kyverno/kyverno/pkg/engine/utils"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/engine/variables"
)
@@ -104,15 +103,15 @@ func (e *engine) filterRule(
}
// operate on the copy of the conditions, as we perform variable substitution
- copyConditions, err := utils.TransformConditions(ruleCopy.GetAnyAllConditions())
+ copyConditions, err := engineutils.TransformConditions(ruleCopy.GetAnyAllConditions())
if err != nil {
logger.V(4).Info("cannot copy AnyAllConditions", "reason", err.Error())
return nil
}
// evaluate pre-conditions
- if !variables.EvaluateConditions(logger, ctx, copyConditions) {
- logger.V(4).Info("skip rule as preconditions are not met", "rule", ruleCopy.Name)
+ if val, msg := variables.EvaluateConditions(logger, ctx, copyConditions); !val {
+ logger.V(4).Info("skip rule as preconditions are not met", "rule", ruleCopy.Name, "message", msg)
return engineapi.RuleSkip(ruleCopy.Name, ruleType, "")
}
diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go
index 94287c188b..f29753a58b 100644
--- a/pkg/engine/engine.go
+++ b/pkg/engine/engine.go
@@ -20,6 +20,7 @@ import (
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/registryclient"
"github.com/kyverno/kyverno/pkg/tracing"
+ stringutils "github.com/kyverno/kyverno/pkg/utils/strings"
"go.opentelemetry.io/otel/metric/global"
"go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/trace"
@@ -256,12 +257,13 @@ func (e *engine) invokeRuleHandler(
return resource, handlers.WithError(rule, ruleType, "failed to load context", err)
}
// check preconditions
- preconditionsPassed, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), rule.GetAnyAllConditions())
+ preconditionsPassed, msg, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), rule.GetAnyAllConditions())
if err != nil {
return resource, handlers.WithError(rule, ruleType, "failed to evaluate preconditions", err)
}
if !preconditionsPassed {
- return resource, handlers.WithSkip(rule, ruleType, "preconditions not met")
+ s := stringutils.JoinNonEmpty([]string{"preconditions not met", msg}, "; ")
+ return resource, handlers.WithSkip(rule, ruleType, s)
}
// process handler
return handler.Process(ctx, logger, policyContext, resource, rule, contextLoader)
diff --git a/pkg/engine/handlers/mutation/common.go b/pkg/engine/handlers/mutation/common.go
index f88a2772ac..7d6486bf01 100644
--- a/pkg/engine/handlers/mutation/common.go
+++ b/pkg/engine/handlers/mutation/common.go
@@ -97,13 +97,13 @@ func (f *forEachMutator) mutateElements(ctx context.Context, foreach kyvernov1.F
return mutate.NewErrorResponse(fmt.Sprintf("failed to load to mutate.foreach[%d].context", index), err)
}
- preconditionsPassed, err := internal.CheckPreconditions(f.logger, policyContext.JSONContext(), foreach.AnyAllConditions)
+ preconditionsPassed, msg, err := internal.CheckPreconditions(f.logger, policyContext.JSONContext(), foreach.AnyAllConditions)
if err != nil {
return mutate.NewErrorResponse(fmt.Sprintf("failed to evaluate mutate.foreach[%d].preconditions", index), err)
}
if !preconditionsPassed {
- f.logger.Info("mutate.foreach.preconditions not met", "elementIndex", index)
+ f.logger.Info("mutate.foreach.preconditions not met", "elementIndex", index, "message", msg)
continue
}
diff --git a/pkg/engine/handlers/mutation/mutate_existing.go b/pkg/engine/handlers/mutation/mutate_existing.go
index ddc0b42d79..2a8bdd56b7 100644
--- a/pkg/engine/handlers/mutation/mutate_existing.go
+++ b/pkg/engine/handlers/mutation/mutate_existing.go
@@ -10,6 +10,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/handlers"
"github.com/kyverno/kyverno/pkg/engine/internal"
"github.com/kyverno/kyverno/pkg/engine/mutate"
+ stringutils "github.com/kyverno/kyverno/pkg/utils/strings"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
@@ -57,14 +58,15 @@ func (h mutateExistingHandler) Process(
continue
}
// load target specific preconditions
- preconditionsPassed, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), target.preconditions)
+ preconditionsPassed, msg, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), target.preconditions)
if err != nil {
rr := engineapi.RuleError(rule.Name, engineapi.Mutation, "failed to evaluate preconditions", err)
responses = append(responses, *rr)
continue
}
if !preconditionsPassed {
- rr := engineapi.RuleSkip(rule.Name, engineapi.Mutation, "preconditions not met")
+ s := stringutils.JoinNonEmpty([]string{"preconditions not met", msg}, "; ")
+ rr := engineapi.RuleSkip(rule.Name, engineapi.Mutation, s)
responses = append(responses, *rr)
continue
}
diff --git a/pkg/engine/handlers/validation/validate_resource.go b/pkg/engine/handlers/validation/validate_resource.go
index 7205c191f9..bacec36bf1 100644
--- a/pkg/engine/handlers/validation/validate_resource.go
+++ b/pkg/engine/handlers/validation/validate_resource.go
@@ -17,6 +17,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/utils/api"
datautils "github.com/kyverno/kyverno/pkg/utils/data"
+ stringutils "github.com/kyverno/kyverno/pkg/utils/strings"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
@@ -101,12 +102,13 @@ func (v *validator) validate(ctx context.Context) *engineapi.RuleResponse {
if err := v.loadContext(ctx); err != nil {
return engineapi.RuleError(v.rule.Name, engineapi.Validation, "failed to load context", err)
}
- preconditionsPassed, err := internal.CheckPreconditions(v.log, v.policyContext.JSONContext(), v.anyAllConditions)
+ preconditionsPassed, msg, err := internal.CheckPreconditions(v.log, v.policyContext.JSONContext(), v.anyAllConditions)
if err != nil {
return engineapi.RuleError(v.rule.Name, engineapi.Validation, "failed to evaluate preconditions", err)
}
if !preconditionsPassed {
- return engineapi.RuleSkip(v.rule.Name, engineapi.Validation, "preconditions not met")
+ s := stringutils.JoinNonEmpty([]string{"preconditions not met", msg}, "; ")
+ return engineapi.RuleSkip(v.rule.Name, engineapi.Validation, s)
}
if v.deny != nil {
@@ -217,28 +219,31 @@ func (v *validator) loadContext(ctx context.Context) error {
}
func (v *validator) validateDeny() *engineapi.RuleResponse {
- if deny, err := internal.CheckDenyPreconditions(v.log, v.policyContext.JSONContext(), v.deny.GetAnyAllConditions()); err != nil {
+ if deny, msg, err := internal.CheckDenyPreconditions(v.log, v.policyContext.JSONContext(), v.deny.GetAnyAllConditions()); err != nil {
return engineapi.RuleError(v.rule.Name, engineapi.Validation, "failed to check deny preconditions", err)
} else {
if deny {
- return engineapi.RuleFail(v.rule.Name, engineapi.Validation, v.getDenyMessage(deny))
+ return engineapi.RuleFail(v.rule.Name, engineapi.Validation, v.getDenyMessage(deny, msg))
}
- return engineapi.RulePass(v.rule.Name, engineapi.Validation, v.getDenyMessage(deny))
+ return engineapi.RulePass(v.rule.Name, engineapi.Validation, v.getDenyMessage(deny, msg))
}
}
-func (v *validator) getDenyMessage(deny bool) string {
+func (v *validator) getDenyMessage(deny bool, msg string) string {
if !deny {
return fmt.Sprintf("validation rule '%s' passed.", v.rule.Name)
}
- msg := v.rule.Validation.Message
- if msg == "" {
+
+ if v.rule.Validation.Message == "" && msg == "" {
return fmt.Sprintf("validation error: rule %s failed", v.rule.Name)
}
- raw, err := variables.SubstituteAll(v.log, v.policyContext.JSONContext(), msg)
+
+ s := stringutils.JoinNonEmpty([]string{v.rule.Validation.Message, msg}, "; ")
+ raw, err := variables.SubstituteAll(v.log, v.policyContext.JSONContext(), s)
if err != nil {
return msg
}
+
switch typed := raw.(type) {
case string:
return typed
diff --git a/pkg/engine/image_verify_test.go b/pkg/engine/image_verify_test.go
index b6207b3275..aaf79ecd27 100644
--- a/pkg/engine/image_verify_test.go
+++ b/pkg/engine/image_verify_test.go
@@ -17,7 +17,6 @@ import (
"github.com/kyverno/kyverno/pkg/engine/internal"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/engine/policycontext"
- "github.com/kyverno/kyverno/pkg/engine/utils"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/registryclient"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@@ -799,7 +798,7 @@ func Test_MarkImageVerified(t *testing.T) {
}
func testApplyPatches(t *testing.T, patches [][]byte) unstructured.Unstructured {
- patchedResource, err := utils.ApplyPatches([]byte(testResource), patches)
+ patchedResource, err := engineutils.ApplyPatches([]byte(testResource), patches)
assert.NilError(t, err)
assert.Assert(t, patchedResource != nil)
diff --git a/pkg/engine/internal/imageverifier.go b/pkg/engine/internal/imageverifier.go
index bdd42ef6b2..2a4cac58f4 100644
--- a/pkg/engine/internal/imageverifier.go
+++ b/pkg/engine/internal/imageverifier.go
@@ -162,20 +162,20 @@ func EvaluateConditions(
ctx enginecontext.Interface,
s map[string]interface{},
log logr.Logger,
-) (bool, error) {
+) (bool, string, error) {
predicate, ok := s["predicate"].(map[string]interface{})
if !ok {
- return false, fmt.Errorf("failed to extract predicate from statement: %v", s)
+ return false, "", fmt.Errorf("failed to extract predicate from statement: %v", s)
}
if err := enginecontext.AddJSONObject(ctx, predicate); err != nil {
- return false, fmt.Errorf("failed to add Statement to the context %v: %w", s, err)
+ return false, "", fmt.Errorf("failed to add Statement to the context %v: %w", s, err)
}
c, err := variables.SubstituteAllInConditions(log, ctx, conditions)
if err != nil {
- return false, fmt.Errorf("failed to substitute variables in attestation conditions: %w", err)
+ return false, "", fmt.Errorf("failed to substitute variables in attestation conditions: %w", err)
}
- pass := variables.EvaluateAnyAllConditions(log, ctx, c)
- return pass, nil
+ pass, msg := variables.EvaluateAnyAllConditions(log, ctx, c)
+ return pass, msg, nil
}
// verify applies policy rules to each matching image. The policy rule results and annotation patches are
@@ -545,20 +545,20 @@ func (iv *ImageVerifier) verifyAttestation(statements []map[string]interface{},
}
for _, s := range statements {
iv.logger.Info("checking attestation", "predicates", types, "image", imageInfo.String())
- val, err := iv.checkAttestations(attestation, s)
+ val, msg, err := iv.checkAttestations(attestation, s)
if err != nil {
return fmt.Errorf("failed to check attestations: %w", err)
}
if !val {
- return fmt.Errorf("attestation checks failed for %s and predicate %s", imageInfo.String(), attestation.PredicateType)
+ return fmt.Errorf("attestation checks failed for %s and predicate %s: %s", imageInfo.String(), attestation.PredicateType, msg)
}
}
return nil
}
-func (iv *ImageVerifier) checkAttestations(a kyvernov1.Attestation, s map[string]interface{}) (bool, error) {
+func (iv *ImageVerifier) checkAttestations(a kyvernov1.Attestation, s map[string]interface{}) (bool, string, error) {
if len(a.Conditions) == 0 {
- return true, nil
+ return true, "", nil
}
iv.policyContext.JSONContext().Checkpoint()
defer iv.policyContext.JSONContext().Restore()
diff --git a/pkg/engine/internal/preconditions.go b/pkg/engine/internal/preconditions.go
index 3c5a7e9c25..54c0ed1c81 100644
--- a/pkg/engine/internal/preconditions.go
+++ b/pkg/engine/internal/preconditions.go
@@ -10,26 +10,30 @@ import (
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
)
-func CheckPreconditions(logger logr.Logger, jsonContext enginecontext.Interface, anyAllConditions apiextensions.JSON) (bool, error) {
+func CheckPreconditions(logger logr.Logger, jsonContext enginecontext.Interface, anyAllConditions apiextensions.JSON) (bool, string, error) {
preconditions, err := variables.SubstituteAllInPreconditions(logger, jsonContext, anyAllConditions)
if err != nil {
- return false, fmt.Errorf("failed to substitute variables in preconditions: %w", err)
+ return false, "", fmt.Errorf("failed to substitute variables in preconditions: %w", err)
}
typeConditions, err := utils.TransformConditions(preconditions)
if err != nil {
- return false, fmt.Errorf("failed to parse preconditions: %w", err)
+ return false, "", fmt.Errorf("failed to parse preconditions: %w", err)
}
- return variables.EvaluateConditions(logger, jsonContext, typeConditions), nil
+
+ val, msg := variables.EvaluateConditions(logger, jsonContext, typeConditions)
+ return val, msg, nil
}
-func CheckDenyPreconditions(logger logr.Logger, jsonContext enginecontext.Interface, anyAllConditions apiextensions.JSON) (bool, error) {
+func CheckDenyPreconditions(logger logr.Logger, jsonContext enginecontext.Interface, anyAllConditions apiextensions.JSON) (bool, string, error) {
preconditions, err := variables.SubstituteAll(logger, jsonContext, anyAllConditions)
if err != nil {
- return false, fmt.Errorf("failed to substitute variables in deny conditions: %w", err)
+ return false, "", fmt.Errorf("failed to substitute variables in deny conditions: %w", err)
}
typeConditions, err := utils.TransformConditions(preconditions)
if err != nil {
- return false, fmt.Errorf("failed to parse deny conditions: %w", err)
+ return false, "", fmt.Errorf("failed to parse deny conditions: %w", err)
}
- return variables.EvaluateConditions(logger, jsonContext, typeConditions), nil
+
+ val, msg := variables.EvaluateConditions(logger, jsonContext, typeConditions)
+ return val, msg, nil
}
diff --git a/pkg/engine/variables/evaluate.go b/pkg/engine/variables/evaluate.go
index 03ff1e8d73..b97a2bd8bf 100644
--- a/pkg/engine/variables/evaluate.go
+++ b/pkg/engine/variables/evaluate.go
@@ -1,6 +1,8 @@
package variables
import (
+ "strings"
+
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/context"
@@ -8,48 +10,54 @@ import (
)
// Evaluate evaluates the condition
-func Evaluate(log logr.Logger, ctx context.EvalInterface, condition kyvernov1.Condition) bool {
+func Evaluate(log logr.Logger, ctx context.EvalInterface, condition kyvernov1.Condition) (bool, string) {
// get handler for the operator
handle := operator.CreateOperatorHandler(log, ctx, condition.Operator)
if handle == nil {
- return false
+ return false, condition.Message
}
- return handle.Evaluate(condition.GetKey(), condition.GetValue())
+
+ return handle.Evaluate(condition.GetKey(), condition.GetValue()), condition.Message
}
// EvaluateConditions evaluates all the conditions present in a slice, in a backwards compatible way
-func EvaluateConditions(log logr.Logger, ctx context.EvalInterface, conditions interface{}) bool {
+func EvaluateConditions(log logr.Logger, ctx context.EvalInterface, conditions interface{}) (bool, string) {
switch typedConditions := conditions.(type) {
case kyvernov1.AnyAllConditions:
return evaluateAnyAllConditions(log, ctx, typedConditions)
case []kyvernov1.Condition: // backwards compatibility
return evaluateOldConditions(log, ctx, typedConditions)
}
- return false
+ return false, "invalid condition"
}
-func EvaluateAnyAllConditions(log logr.Logger, ctx context.EvalInterface, conditions []kyvernov1.AnyAllConditions) bool {
+func EvaluateAnyAllConditions(log logr.Logger, ctx context.EvalInterface, conditions []kyvernov1.AnyAllConditions) (bool, string) {
for _, c := range conditions {
- if !evaluateAnyAllConditions(log, ctx, c) {
- return false
+ if val, msg := evaluateAnyAllConditions(log, ctx, c); !val {
+ return false, msg
}
}
- return true
+ return true, ""
}
// evaluateAnyAllConditions evaluates multiple conditions as a logical AND (all) or OR (any) operation depending on the conditions
-func evaluateAnyAllConditions(log logr.Logger, ctx context.EvalInterface, conditions kyvernov1.AnyAllConditions) bool {
+func evaluateAnyAllConditions(log logr.Logger, ctx context.EvalInterface, conditions kyvernov1.AnyAllConditions) (bool, string) {
anyConditions, allConditions := conditions.AnyConditions, conditions.AllConditions
anyConditionsResult, allConditionsResult := true, true
+ var messages []string
// update the anyConditionsResult if they are present
if anyConditions != nil {
anyConditionsResult = false
for _, condition := range anyConditions {
- if Evaluate(log, ctx, condition) {
+ if val, msg := Evaluate(log, ctx, condition); val {
anyConditionsResult = true
break
+ } else {
+ if msg != "" {
+ messages = append(messages, msg)
+ }
}
}
@@ -60,24 +68,26 @@ func evaluateAnyAllConditions(log logr.Logger, ctx context.EvalInterface, condit
// update the allConditionsResult if they are present
for _, condition := range allConditions {
- if !Evaluate(log, ctx, condition) {
+ if val, msg := Evaluate(log, ctx, condition); !val {
allConditionsResult = false
- log.V(3).Info("a condition failed in 'all' block", "condition", condition)
+ messages = append(messages, msg)
+ log.V(3).Info("a condition failed in 'all' block", "condition", condition, "message", msg)
break
}
}
finalResult := anyConditionsResult && allConditionsResult
- return finalResult
+ message := strings.Join(messages, "; ")
+ return finalResult, message
}
// evaluateOldConditions evaluates multiple conditions when those conditions are provided in the old manner i.e. without 'any' or 'all'
-func evaluateOldConditions(log logr.Logger, ctx context.EvalInterface, conditions []kyvernov1.Condition) bool {
+func evaluateOldConditions(log logr.Logger, ctx context.EvalInterface, conditions []kyvernov1.Condition) (bool, string) {
for _, condition := range conditions {
- if !Evaluate(log, ctx, condition) {
- return false
+ if val, msg := Evaluate(log, ctx, condition); !val {
+ return false, msg
}
}
- return true
+ return true, ""
}
diff --git a/pkg/engine/variables/evaluate_test.go b/pkg/engine/variables/evaluate_test.go
index de0acaefba..98d05ca293 100644
--- a/pkg/engine/variables/evaluate_test.go
+++ b/pkg/engine/variables/evaluate_test.go
@@ -380,7 +380,7 @@ func TestEvaluate(t *testing.T) {
ctx := context.NewContext(jmespath.New(config.NewDefaultConfiguration(false)))
for _, tc := range testCases {
- if Evaluate(logr.Discard(), ctx, tc.Condition) != tc.Result {
+ if val, _ := Evaluate(logr.Discard(), ctx, tc.Condition); val != tc.Result {
t.Errorf("%v - expected result to be %v", tc.Condition, tc.Result)
}
}
@@ -427,7 +427,9 @@ func Test_Eval_Equal_Var_Pass(t *testing.T) {
err = json.Unmarshal(conditionJSON, &condition)
assert.Nil(t, err)
- assert.True(t, Evaluate(logr.Discard(), ctx, condition))
+
+ val, _ := Evaluate(logr.Discard(), ctx, condition)
+ assert.True(t, val)
}
func Test_Eval_Equal_Var_Fail(t *testing.T) {
@@ -456,7 +458,74 @@ func Test_Eval_Equal_Var_Fail(t *testing.T) {
RawValue: kyverno.ToJSON("temp1"),
}
- if Evaluate(logr.Discard(), ctx, condition) {
+ if val, _ := Evaluate(logr.Discard(), ctx, condition); val {
t.Error("expected to fail")
}
}
+
+func Test_Condition_Messages(t *testing.T) {
+ resourceRaw := []byte(`
+ {
+ "metadata": {
+ "name": "temp",
+ "namespace": "n1"
+ },
+ "spec": {
+ "foo": "bar",
+ "foo2": "bar2"
+ }
+ }
+ `)
+
+ ctx := context.NewContext(jmespath.New(config.NewDefaultConfiguration(false)))
+ err := context.AddResource(ctx, resourceRaw)
+ if err != nil {
+ t.Error(err)
+ }
+
+ conditions := []kyverno.AnyAllConditions{
+ {
+ AnyConditions: []kyverno.Condition{
+ {
+ RawKey: kyverno.ToJSON("{{request.object.metadata.name}}"),
+ Operator: kyverno.ConditionOperators["Equal"],
+ RawValue: kyverno.ToJSON("temp"),
+ Message: "invalid name",
+ },
+ {
+ RawKey: kyverno.ToJSON("{{request.object.spec.foo}}"),
+ Operator: kyverno.ConditionOperators["Equal"],
+ RawValue: kyverno.ToJSON("bar2"),
+ Message: "invalid foo",
+ },
+ },
+ },
+ }
+
+ val, msg := EvaluateAnyAllConditions(logr.Discard(), ctx, conditions)
+ assert.Equal(t, false, val)
+ assert.Contains(t, msg, "invalid name; invalid foo")
+
+ conditions[0].AnyConditions[1].RawValue = kyverno.ToJSON("bar")
+ conditions, err = SubstituteAllInConditions(logr.Discard(), ctx, conditions)
+ assert.Nil(t, err)
+
+ val, msg = EvaluateAnyAllConditions(logr.Discard(), ctx, conditions)
+ assert.Equal(t, true, val)
+ assert.Equal(t, msg, "")
+
+ conditions[0].AllConditions = append(conditions[0].AllConditions, conditions[0].AnyConditions[0])
+ conditions[0].AllConditions = append(conditions[0].AllConditions, conditions[0].AnyConditions[1])
+ conditions[0].AllConditions[1].RawValue = kyverno.ToJSON("bar2")
+
+ val, msg = EvaluateAnyAllConditions(logr.Discard(), ctx, conditions)
+ assert.Equal(t, false, val)
+ assert.Contains(t, msg, "invalid foo")
+
+ conditions[0].AnyConditions[0].RawValue = kyverno.ToJSON("temp1")
+ conditions[0].AnyConditions[1].RawValue = kyverno.ToJSON("bar2")
+ conditions[0].AllConditions[1].Message = "invalid foo2"
+ val, msg = EvaluateAnyAllConditions(logr.Discard(), ctx, conditions)
+ assert.Equal(t, false, val)
+ assert.Contains(t, msg, "invalid name; invalid foo; invalid foo2")
+}
diff --git a/pkg/utils/strings/join.go b/pkg/utils/strings/join.go
new file mode 100644
index 0000000000..36f4c3dbb1
--- /dev/null
+++ b/pkg/utils/strings/join.go
@@ -0,0 +1,20 @@
+package strings
+
+import "strings"
+
+func JoinNonEmpty(elems []string, sep string) string {
+ var bldr strings.Builder
+ var idx int = 0
+ for _, s := range elems {
+ if s != "" {
+ if idx > 0 {
+ bldr.WriteString(sep)
+ }
+
+ bldr.WriteString(s)
+ idx++
+ }
+ }
+
+ return bldr.String()
+}
diff --git a/pkg/utils/strings/join_test.go b/pkg/utils/strings/join_test.go
new file mode 100644
index 0000000000..0321a821dd
--- /dev/null
+++ b/pkg/utils/strings/join_test.go
@@ -0,0 +1,14 @@
+package strings
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestJoins(t *testing.T) {
+ assert.Equal(t, "test", JoinNonEmpty([]string{"test", ""}, ","))
+ assert.Equal(t, "test,test", JoinNonEmpty([]string{"test", "test"}, ","))
+ assert.Equal(t, "test; test", JoinNonEmpty([]string{"test", "", "test", ""}, "; "))
+ assert.Equal(t, "fi fo fum", JoinNonEmpty([]string{"", "fi", "", "fo", "", "fum"}, " "))
+}