From 44b5bf0b57e67d59eff848c8aa76e6878462c2df Mon Sep 17 00:00:00 2001
From: Sambhav Kothari
Date: Mon, 25 Apr 2022 12:06:07 +0100
Subject: [PATCH] Allow definition of inline variables in context (#3658)
Signed-off-by: Sambhav Kothari
---
api/kyverno/v1/common_types.go | 20 ++
api/kyverno/v1/zz_generated.deepcopy.go | 30 +++
charts/kyverno/templates/crds.yaml | 156 ++++++++++++
config/crds/kyverno.io_clusterpolicies.yaml | 116 +++++++++
config/crds/kyverno.io_policies.yaml | 116 +++++++++
config/install.yaml | 232 ++++++++++++++++++
config/install_debug.yaml | 232 ++++++++++++++++++
docs/crd/v1/index.html | 101 ++++++--
pkg/engine/context/context.go | 17 ++
pkg/engine/jsonContext.go | 71 +++++-
pkg/policy/validate.go | 72 +++---
.../test/context-entries/kyverno-test.yaml | 46 ++++
test/cli/test/context-entries/policies.yaml | 148 +++++++++++
test/cli/test/context-entries/resources.yaml | 6 +
14 files changed, 1301 insertions(+), 62 deletions(-)
create mode 100644 test/cli/test/context-entries/kyverno-test.yaml
create mode 100644 test/cli/test/context-entries/policies.yaml
create mode 100644 test/cli/test/context-entries/resources.yaml
diff --git a/api/kyverno/v1/common_types.go b/api/kyverno/v1/common_types.go
index f36394b7b5..5e31ec1130 100755
--- a/api/kyverno/v1/common_types.go
+++ b/api/kyverno/v1/common_types.go
@@ -56,6 +56,26 @@ type ContextEntry struct {
// ImageRegistry defines requests to an OCI/Docker V2 registry to fetch image
// details.
ImageRegistry *ImageRegistry `json:"imageRegistry,omitempty" yaml:"imageRegistry,omitempty"`
+
+ // Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ Variable *Variable `json:"variable,omitempty" yaml:"variable,omitempty"`
+}
+
+// Variable defines an arbitrary JMESPath context variable that can be defined inline.
+type Variable struct {
+ // Value is any arbitrary JSON object representable in YAML or JSON form.
+ // +optional
+ Value *apiextv1.JSON `json:"value,omitempty" yaml:"value,omitempty"`
+
+ // JMESPath is an optional JMESPath Expression that can be used to
+ // transform the variable.
+ // +optional
+ JMESPath string `json:"jmesPath,omitempty" yaml:"jmesPath,omitempty"`
+
+ // Default is an optional arbitrary JSON object that the variable may take if the JMESPath
+ // expression evaluates to nil
+ // +optional
+ Default *apiextv1.JSON `json:"default,omitempty" yaml:"default,omitempty"`
}
// ImageRegistry defines requests to an OCI/Docker V2 registry to fetch image
diff --git a/api/kyverno/v1/zz_generated.deepcopy.go b/api/kyverno/v1/zz_generated.deepcopy.go
index e7a9f70164..abc739f855 100755
--- a/api/kyverno/v1/zz_generated.deepcopy.go
+++ b/api/kyverno/v1/zz_generated.deepcopy.go
@@ -357,6 +357,11 @@ func (in *ContextEntry) DeepCopyInto(out *ContextEntry) {
*out = new(ImageRegistry)
**out = **in
}
+ if in.Variable != nil {
+ in, out := &in.Variable, &out.Variable
+ *out = new(Variable)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContextEntry.
@@ -1196,6 +1201,31 @@ func (in *ValidationFailureActionOverride) DeepCopy() *ValidationFailureActionOv
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Variable) DeepCopyInto(out *Variable) {
+ *out = *in
+ if in.Value != nil {
+ in, out := &in.Value, &out.Value
+ *out = new(apiextensionsv1.JSON)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Default != nil {
+ in, out := &in.Default, &out.Default
+ *out = new(apiextensionsv1.JSON)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Variable.
+func (in *Variable) DeepCopy() *Variable {
+ if in == nil {
+ return nil
+ }
+ out := new(Variable)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ViolatedRule) DeepCopyInto(out *ViolatedRule) {
*out = *in
diff --git a/charts/kyverno/templates/crds.yaml b/charts/kyverno/templates/crds.yaml
index 65d305bffe..af40189b88 100644
--- a/charts/kyverno/templates/crds.yaml
+++ b/charts/kyverno/templates/crds.yaml
@@ -113,6 +113,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -972,6 +985,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -1135,6 +1161,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -1580,6 +1619,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -2439,6 +2491,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -2602,6 +2667,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -3758,6 +3836,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -4617,6 +4708,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -4780,6 +4884,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -5225,6 +5342,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -6084,6 +6214,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -6247,6 +6390,19 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON object that the variable may take if the JMESPath expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
diff --git a/config/crds/kyverno.io_clusterpolicies.yaml b/config/crds/kyverno.io_clusterpolicies.yaml
index 8bd831b98c..a66d449f61 100644
--- a/config/crds/kyverno.io_clusterpolicies.yaml
+++ b/config/crds/kyverno.io_clusterpolicies.yaml
@@ -140,6 +140,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -1567,6 +1585,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -1820,6 +1858,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -2520,6 +2578,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -3947,6 +4023,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -4200,6 +4296,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
diff --git a/config/crds/kyverno.io_policies.yaml b/config/crds/kyverno.io_policies.yaml
index 9165c6f5a4..979424a889 100644
--- a/config/crds/kyverno.io_policies.yaml
+++ b/config/crds/kyverno.io_policies.yaml
@@ -141,6 +141,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -1568,6 +1586,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -1821,6 +1859,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -2522,6 +2580,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -3949,6 +4025,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -4202,6 +4298,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
diff --git a/config/install.yaml b/config/install.yaml
index fc18086c6e..5727912e4a 100644
--- a/config/install.yaml
+++ b/config/install.yaml
@@ -157,6 +157,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -1584,6 +1602,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -1837,6 +1875,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -2537,6 +2595,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -3964,6 +4040,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -4217,6 +4313,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -5807,6 +5923,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -7234,6 +7368,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -7487,6 +7641,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -8188,6 +8362,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -9615,6 +9807,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -9868,6 +10080,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
diff --git a/config/install_debug.yaml b/config/install_debug.yaml
index d377392aaf..f7bdded60e 100755
--- a/config/install_debug.yaml
+++ b/config/install_debug.yaml
@@ -146,6 +146,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -1573,6 +1591,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -1826,6 +1864,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -2526,6 +2584,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -3953,6 +4029,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -4206,6 +4302,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -5772,6 +5888,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -7199,6 +7333,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -7452,6 +7606,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
@@ -8153,6 +8327,24 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath context
+ variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary JSON
+ object that the variable may take if the JMESPath
+ expression evaluates to nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath Expression
+ that can be used to transform the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON object representable
+ in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
exclude:
@@ -9580,6 +9772,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
list:
@@ -9833,6 +10045,26 @@ spec:
name:
description: Name is the variable name.
type: string
+ variable:
+ description: Variable defines an arbitrary JMESPath
+ context variable that can be defined inline.
+ properties:
+ default:
+ description: Default is an optional arbitrary
+ JSON object that the variable may take
+ if the JMESPath expression evaluates to
+ nil
+ x-kubernetes-preserve-unknown-fields: true
+ jmesPath:
+ description: JMESPath is an optional JMESPath
+ Expression that can be used to transform
+ the variable.
+ type: string
+ value:
+ description: Value is any arbitrary JSON
+ object representable in YAML or JSON form.
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
type: object
type: array
deny:
diff --git a/docs/crd/v1/index.html b/docs/crd/v1/index.html
index 1c94df8bb1..52e1df85c7 100644
--- a/docs/crd/v1/index.html
+++ b/docs/crd/v1/index.html
@@ -209,8 +209,8 @@ string
conditions
-
-[]*github.com/kyverno/kyverno/api/kyverno/v1.AnyAllConditions
+
+[]*./api/kyverno/v1.AnyAllConditions
|
@@ -330,8 +330,8 @@ value N, then N must be less than or equal to the size of entries, and at least
entries
-
-[]*github.com/kyverno/kyverno/api/kyverno/v1.Attestor
+
+[]*./api/kyverno/v1.Attestor
|
@@ -817,6 +817,19 @@ ImageRegistry
details.
+
+
+variable
+
+
+Variable
+
+
+ |
+
+ Variable defines an arbitrary JMESPath context variable that can be defined inline.
+ |
+
@@ -1560,8 +1573,8 @@ Deprecated.
attestors
-
-[]*github.com/kyverno/kyverno/api/kyverno/v1.AttestorSet
+
+[]*./api/kyverno/v1.AttestorSet
|
@@ -1573,8 +1586,8 @@ Deprecated.
attestations
-
-[]*github.com/kyverno/kyverno/api/kyverno/v1.Attestation
+
+[]*./api/kyverno/v1.Attestation
|
@@ -1848,8 +1861,8 @@ See https://tools.ietf.org/html/rf
foreach
-
-[]*github.com/kyverno/kyverno/api/kyverno/v1.ForEachMutation
+
+[]*./api/kyverno/v1.ForEachMutation
|
@@ -2331,7 +2344,7 @@ ResourceDescription
ResourceFilters
-([]github.com/kyverno/kyverno/api/kyverno/v1.ResourceFilter
alias)
+([]./api/kyverno/v1.ResourceFilter
alias)
(Appears on:
MatchResources)
@@ -2559,8 +2572,8 @@ Generation
verifyImages
-
-[]*github.com/kyverno/kyverno/api/kyverno/v1.ImageVerification
+
+[]*./api/kyverno/v1.ImageVerification
|
@@ -2845,8 +2858,8 @@ string
foreach
-
-[]*github.com/kyverno/kyverno/api/kyverno/v1.ForEachValidation
+
+[]*./api/kyverno/v1.ForEachValidation
|
@@ -2948,6 +2961,64 @@ ValidationFailureAction
+Variable
+
+
+(Appears on:
+ContextEntry)
+
+
+
Variable defines an arbitrary JMESPath context variable that can be defined inline.
+
+
+
+
+Field |
+Description |
+
+
+
+
+
+value
+
+k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON
+
+ |
+
+(Optional)
+ Value is any arbitrary JSON object representable in YAML or JSON form.
+ |
+
+
+
+jmesPath
+
+string
+
+ |
+
+(Optional)
+ JMESPath is an optional JMESPath Expression that can be used to
+transform the variable.
+ |
+
+
+
+default
+
+k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON
+
+ |
+
+(Optional)
+ Default is an optional arbitrary JSON object that the variable may take if the JMESPath
+expression evaluates to nil
+ |
+
+
+
+
ViolatedRule
diff --git a/pkg/engine/context/context.go b/pkg/engine/context/context.go
index 2003f79037..4f1dfe5fba 100644
--- a/pkg/engine/context/context.go
+++ b/pkg/engine/context/context.go
@@ -40,6 +40,9 @@ type Interface interface {
// AddContextEntry adds a context entry to the context
AddContextEntry(name string, dataRaw []byte) error
+ // ReplaceContextEntry replaces a context entry to the context
+ ReplaceContextEntry(name string, dataRaw []byte) error
+
// AddResource merges resource json under request.object
AddResource(data map[string]interface{}) error
@@ -138,6 +141,20 @@ func (ctx *context) AddContextEntry(name string, dataRaw []byte) error {
return addToContext(ctx, data, name)
}
+func (ctx *context) ReplaceContextEntry(name string, dataRaw []byte) error {
+ var data interface{}
+ if err := json.Unmarshal(dataRaw, &data); err != nil {
+ logger.Error(err, "failed to unmarshal the resource")
+ return err
+ }
+ // Adding a nil entry to clean out any existing data in the context with the entry name
+ if err := addToContext(ctx, nil, name); err != nil {
+ logger.Error(err, "unable to replace context entry", "context entry name", name)
+ return err
+ }
+ return addToContext(ctx, data, name)
+}
+
// AddResource data at path: request.object
func (ctx *context) AddResource(data map[string]interface{}) error {
return addToContext(ctx, data, "request", "object")
diff --git a/pkg/engine/jsonContext.go b/pkg/engine/jsonContext.go
index eb5cbd7bd7..961cedf958 100644
--- a/pkg/engine/jsonContext.go
+++ b/pkg/engine/jsonContext.go
@@ -23,12 +23,15 @@ func LoadContext(logger logr.Logger, contextEntries []kyverno.ContextEntry, ctx
policyName := ctx.Policy.GetName()
if store.GetMock() {
- if store.GetRegistryAccess() {
- for _, entry := range contextEntries {
- if entry.ImageRegistry != nil {
- if err := loadImageData(logger, entry, ctx); err != nil {
- return err
- }
+ hasRegistryAccess := store.GetRegistryAccess()
+ for _, entry := range contextEntries {
+ if entry.ImageRegistry != nil && hasRegistryAccess {
+ if err := loadImageData(logger, entry, ctx); err != nil {
+ return err
+ }
+ } else if entry.Variable != nil {
+ if err := loadVariable(logger, entry, ctx); err != nil {
+ return err
}
}
}
@@ -62,12 +65,68 @@ func LoadContext(logger logr.Logger, contextEntries []kyverno.ContextEntry, ctx
if err := loadImageData(logger, entry, ctx); err != nil {
return err
}
+ } else if entry.Variable != nil {
+ if err := loadVariable(logger, entry, ctx); err != nil {
+ return err
+ }
}
}
}
return nil
}
+func loadVariable(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyContext) (err error) {
+ path := ""
+ if entry.Variable.JMESPath != "" {
+ jp, err := variables.SubstituteAll(logger, ctx.JSONContext, entry.Variable.JMESPath)
+ if err != nil {
+ return fmt.Errorf("failed to substitute variables in context entry %s %s: %v", entry.Name, entry.Variable.JMESPath, err)
+ }
+ path = jp.(string)
+ }
+ var defaultValue interface{} = nil
+ if entry.Variable.Default != nil {
+ value, err := variables.DocumentToUntyped(entry.Variable.Default)
+ if err != nil {
+ return fmt.Errorf("invalid default for variable %s", entry.Name)
+ }
+ defaultValue, err = variables.SubstituteAll(logger, ctx.JSONContext, value)
+ if err != nil {
+ return fmt.Errorf("failed to substitute variables in context entry %s %s: %v", entry.Name, entry.Variable.Default, err)
+ }
+ }
+ var output interface{} = defaultValue
+ if entry.Variable.Value != nil {
+ value, _ := variables.DocumentToUntyped(entry.Variable.Value)
+ variable, err := variables.SubstituteAll(logger, ctx.JSONContext, value)
+ if err != nil {
+ return fmt.Errorf("failed to substitute variables in context entry %s %s: %v", entry.Name, entry.Variable.Value, err)
+ }
+ if path != "" {
+ variable, err := applyJMESPath(path, variable)
+ if err == nil {
+ output = variable
+ }
+ } else {
+ output = variable
+ }
+ } else {
+ if path != "" {
+ if variable, err := ctx.JSONContext.Query(path); err == nil {
+ output = variable
+ }
+ }
+ }
+ if output == nil {
+ return fmt.Errorf("unable to add context entry for variable %s since it evaluated to nil", entry.Name)
+ }
+ if outputBytes, err := json.Marshal(output); err == nil {
+ return ctx.JSONContext.ReplaceContextEntry(entry.Name, outputBytes)
+ } else {
+ return fmt.Errorf("unable to add context entry for variable %s: %w", entry.Name, err)
+ }
+}
+
func loadImageData(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyContext) error {
if len(registryclient.Secrets) > 0 {
if err := registryclient.UpdateKeychain(); err != nil {
diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go
index 69dc4a1fc4..c9c650d8f2 100644
--- a/pkg/policy/validate.go
+++ b/pkg/policy/validate.go
@@ -489,7 +489,7 @@ func getAllowedVariables(background bool) *regexp.Regexp {
func addContextVariables(entries []kyverno.ContextEntry, ctx *context.MockContext) {
for _, contextEntry := range entries {
- if contextEntry.APICall != nil || contextEntry.ImageRegistry != nil {
+ if contextEntry.APICall != nil || contextEntry.ImageRegistry != nil || contextEntry.Variable != nil {
ctx.AddVariable(contextEntry.Name + "*")
}
@@ -819,17 +819,24 @@ func validateRuleContext(rule kyverno.Rule) error {
if entry.Name == "" {
return fmt.Errorf("a name is required for context entries")
}
+ for _, v := range []string{"images", "request", "serviceAccountName", "serviceAccountNamespace", "element", "elementIndex"} {
+ if entry.Name == v || strings.HasPrefix(entry.Name, v+".") {
+ return fmt.Errorf("entry name %s is invalid as it conflicts with a pre-defined variable %s", entry.Name, v)
+ }
+ }
contextNames = append(contextNames, entry.Name)
var err error
- if entry.ConfigMap != nil {
+ if entry.ConfigMap != nil && entry.APICall == nil && entry.ImageRegistry == nil && entry.Variable == nil {
err = validateConfigMap(entry)
- } else if entry.APICall != nil {
+ } else if entry.ConfigMap == nil && entry.APICall != nil && entry.ImageRegistry == nil && entry.Variable == nil {
err = validateAPICall(entry)
- } else if entry.ImageRegistry != nil {
+ } else if entry.ConfigMap == nil && entry.APICall == nil && entry.ImageRegistry != nil && entry.Variable == nil {
err = validateImageRegistry(entry)
+ } else if entry.ConfigMap == nil && entry.APICall == nil && entry.ImageRegistry == nil && entry.Variable != nil {
+ err = validateVariable(entry)
} else {
- return fmt.Errorf("a configMap or apiCall or imageRegistry is required for context entries")
+ return fmt.Errorf("exactly one of configMap or apiCall or imageRegistry or variable is required for context entries")
}
if err != nil {
@@ -851,19 +858,26 @@ func validateRuleContext(rule kyverno.Rule) error {
return nil
}
+func validateVariable(entry kyverno.ContextEntry) error {
+ // If JMESPath contains variables, the validation will fail because it's not possible to infer which value
+ // will be inserted by the variable
+ // Skip validation if a variable is detected
+ jmesPath := variables.ReplaceAllVars(entry.Variable.JMESPath, func(s string) string { return "kyvernojmespathvariable" })
+ if !strings.Contains(jmesPath, "kyvernojmespathvariable") && entry.Variable.JMESPath != "" {
+ if _, err := jmespath.NewParser().Parse(entry.Variable.JMESPath); err != nil {
+ return fmt.Errorf("failed to parse JMESPath %s: %v", entry.Variable.JMESPath, err)
+ }
+ }
+ if entry.Variable.Value == nil && jmesPath == "" {
+ return fmt.Errorf("a variable must define a value or a jmesPath expression")
+ }
+ if entry.Variable.Default != nil && jmesPath == "" {
+ return fmt.Errorf("a variable must define a default value only when a jmesPath expression is defined")
+ }
+ return nil
+}
+
func validateConfigMap(entry kyverno.ContextEntry) error {
- if entry.ConfigMap == nil {
- return fmt.Errorf("configMap is empty")
- }
-
- if entry.APICall != nil {
- return fmt.Errorf("both configMap and apiCall are not allowed in a context entry")
- }
-
- if entry.ImageRegistry != nil {
- return fmt.Errorf("both imageRegistry and configMap are not allowed in a context entry")
- }
-
if entry.ConfigMap.Name == "" {
return fmt.Errorf("a name is required for configMap context entry")
}
@@ -876,18 +890,6 @@ func validateConfigMap(entry kyverno.ContextEntry) error {
}
func validateAPICall(entry kyverno.ContextEntry) error {
- if entry.APICall == nil {
- return fmt.Errorf("apiCall is empty")
- }
-
- if entry.ConfigMap != nil {
- return fmt.Errorf("both configMap and apiCall are not allowed in a context entry")
- }
-
- if entry.ImageRegistry != nil {
- return fmt.Errorf("both imageRegistry and apiCall are not allowed in a context entry")
- }
-
// Replace all variables to prevent validation failing on variable keys.
urlPath := variables.ReplaceAllVars(entry.APICall.URLPath, func(s string) string { return "kyvernoapicallvariable" })
@@ -911,18 +913,6 @@ func validateAPICall(entry kyverno.ContextEntry) error {
}
func validateImageRegistry(entry kyverno.ContextEntry) error {
- if entry.ImageRegistry == nil {
- return fmt.Errorf("imageRegistry is empty")
- }
-
- if entry.ConfigMap != nil {
- return fmt.Errorf("both configMap and imageRegistry are not allowed in a context entry")
- }
-
- if entry.APICall != nil {
- return fmt.Errorf("both configMap and apiCall are not allowed in a context entry")
- }
-
if entry.ImageRegistry.Reference == "" {
return fmt.Errorf("a ref is required for imageRegistry context entry")
}
diff --git a/test/cli/test/context-entries/kyverno-test.yaml b/test/cli/test/context-entries/kyverno-test.yaml
new file mode 100644
index 0000000000..1df2ecd642
--- /dev/null
+++ b/test/cli/test/context-entries/kyverno-test.yaml
@@ -0,0 +1,46 @@
+name: test-variables
+policies:
+ - policies.yaml
+resources:
+ - resources.yaml
+results:
+ - policy: example
+ rule: defined-value
+ resource: example
+ kind: Pod
+ result: pass
+ - policy: example
+ rule: defined-jmespath
+ resource: example
+ kind: Pod
+ result: pass
+ - policy: example
+ rule: defined-jmespath-with-default
+ resource: example
+ kind: Pod
+ result: pass
+ - policy: example
+ rule: defined-value-with-variable
+ resource: example
+ kind: Pod
+ result: pass
+ - policy: example
+ rule: defined-jmespath-with-default-variable
+ resource: example
+ kind: Pod
+ result: pass
+ - policy: example
+ rule: defined-value-jmespath
+ resource: example
+ kind: Pod
+ result: pass
+ - policy: example
+ rule: defined-value-jmespath-variable
+ resource: example
+ kind: Pod
+ result: pass
+ - policy: example
+ rule: value-override
+ resource: example
+ kind: Pod
+ result: pass
diff --git a/test/cli/test/context-entries/policies.yaml b/test/cli/test/context-entries/policies.yaml
new file mode 100644
index 0000000000..77062e3c85
--- /dev/null
+++ b/test/cli/test/context-entries/policies.yaml
@@ -0,0 +1,148 @@
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+ name: example
+spec:
+ rules:
+ - name: defined-value
+ context:
+ - name: example
+ variable:
+ value:
+ test:
+ nested:
+ value: 1
+ match:
+ resources:
+ kinds:
+ - Pod
+ validate:
+ deny:
+ conditions:
+ - key: "{{ example.test.nested.value }}"
+ operator: NotEquals
+ value: 1
+ - name: defined-jmespath
+ context:
+ - name: objName
+ variable:
+ jmesPath: request.object.metadata.name
+ match:
+ resources:
+ kinds:
+ - Pod
+ validate:
+ deny:
+ conditions:
+ - key: "{{ objName }}"
+ operator: NotEquals
+ value: "example"
+ - name: defined-jmespath-with-default
+ context:
+ - name: objName
+ variable:
+ jmesPath: request.object.metadata.generateName
+ default: example
+ match:
+ resources:
+ kinds:
+ - Pod
+ validate:
+ deny:
+ conditions:
+ - key: "{{ objName }}"
+ operator: NotEquals
+ value: "example"
+ - name: defined-value-with-variable
+ context:
+ - name: obj
+ variable:
+ value:
+ name: "{{ request.object.metadata.name }}"
+ match:
+ resources:
+ kinds:
+ - Pod
+ validate:
+ deny:
+ conditions:
+ - key: "{{ obj.name }}"
+ operator: NotEquals
+ value: "example"
+ - name: defined-jmespath-with-default-variable
+ context:
+ - name: objName
+ variable:
+ jmesPath: request.object.metadata.generateName
+ default: "{{ request.object.metadata.name }}"
+ match:
+ resources:
+ kinds:
+ - Pod
+ validate:
+ deny:
+ conditions:
+ - key: "{{ objName }}"
+ operator: NotEquals
+ value: "example"
+ - name: defined-value-jmespath
+ context:
+ - name: objName
+ variable:
+ value:
+ name: "{{ request.object.metadata.name }}"
+ jmesPath: name
+ match:
+ resources:
+ kinds:
+ - Pod
+ validate:
+ deny:
+ conditions:
+ - key: "{{ objName }}"
+ operator: NotEquals
+ value: "example"
+ - name: defined-value-jmespath-variable
+ context:
+ - name: jpExpression
+ variable:
+ value: name
+ - name: objName
+ variable:
+ value:
+ name: "{{ request.object.metadata.name }}"
+ jmesPath: "{{ jpExpression }}"
+ match:
+ resources:
+ kinds:
+ - Pod
+ validate:
+ deny:
+ conditions:
+ - key: "{{ objName }}"
+ operator: NotEquals
+ value: "example"
+ - name: value-override
+ context:
+ - name: obj
+ variable:
+ value:
+ notName: not-example
+ - name: obj
+ variable:
+ value:
+ name: example
+ match:
+ resources:
+ kinds:
+ - Pod
+ validate:
+ deny:
+ conditions:
+ any:
+ - key: "{{ obj.name }}"
+ operator: NotEquals
+ value: "example"
+ - key: "{{ to_string(obj.notName) }}"
+ operator: NotEquals
+ value: 'null'
diff --git a/test/cli/test/context-entries/resources.yaml b/test/cli/test/context-entries/resources.yaml
new file mode 100644
index 0000000000..d9e857eb21
--- /dev/null
+++ b/test/cli/test/context-entries/resources.yaml
@@ -0,0 +1,6 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: example
+spec:
+ containers: []
\ No newline at end of file