1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: return policies with either audit or enforce rules from the cache (#10667)

* fix: return policies with either audit or enforce rules from the cache

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>

* feat: introduce validationFailureAction under verifyImage rules

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>

* feat: add chainsaw tests

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>

* fix

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>

---------

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
Mariam Fahmy 2024-08-06 21:24:28 +03:00 committed by GitHub
parent a32bdf1ac1
commit c796bb765c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
513 changed files with 4473 additions and 718 deletions

View file

@ -17,7 +17,6 @@ import (
// +kubebuilder:resource:path=clusterpolicies,scope="Cluster",shortName=cpol,categories=kyverno
// +kubebuilder:printcolumn:name="ADMISSION",type=boolean,JSONPath=".spec.admission"
// +kubebuilder:printcolumn:name="BACKGROUND",type=boolean,JSONPath=".spec.background"
// +kubebuilder:printcolumn:name="VALIDATE ACTION",type=string,JSONPath=".spec.validationFailureAction"
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="FAILURE POLICY",type=string,JSONPath=".spec.failurePolicy",priority=1

View file

@ -454,11 +454,11 @@ func (m *ForEachMutation) SetPatchStrategicMerge(in apiextensions.JSON) {
// Validation defines checks to be performed on matching resources.
type Validation struct {
// ValidationFailureAction defines if a validation policy rule violation should block
// the admission review request (enforce), or allow (audit) the admission review request
// the admission review request (Enforce), or allow (Audit) the admission review request
// and report an error in a policy report. Optional.
// Allowed values are audit or enforce.
// Allowed values are Audit or Enforce.
// +optional
// +kubebuilder:validation:Enum=audit;enforce;Audit;Enforce
// +kubebuilder:validation:Enum=Audit;Enforce
ValidationFailureAction *ValidationFailureAction `json:"validationFailureAction,omitempty" yaml:"validationFailureAction,omitempty"`
// ValidationFailureActionOverrides is a Cluster Policy attribute that specifies ValidationFailureAction

View file

@ -40,6 +40,11 @@ var signatureAlgorithmMap = map[string]bool{
// are signed with the supplied public key. Once the image is verified it is
// mutated to include the SHA digest retrieved during the registration.
type ImageVerification struct {
// Allowed values are Audit or Enforce.
// +optional
// +kubebuilder:validation:Enum=Audit;Enforce
ValidationFailureAction *ValidationFailureAction `json:"validationFailureAction,omitempty" yaml:"validationFailureAction,omitempty"`
// Type specifies the method of signature validation. The allowed options
// are Cosign and Notary. By default Cosign is used if a type is not specified.
// +kubebuilder:validation:Optional

View file

@ -15,7 +15,6 @@ import (
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ADMISSION",type=boolean,JSONPath=".spec.admission"
// +kubebuilder:printcolumn:name="BACKGROUND",type=boolean,JSONPath=".spec.background"
// +kubebuilder:printcolumn:name="VALIDATE ACTION",type=string,JSONPath=".spec.validationFailureAction"
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="FAILURE POLICY",type=string,JSONPath=".spec.failurePolicy",priority=1

View file

@ -171,6 +171,19 @@ func (s *Spec) HasValidate() bool {
return false
}
// HasValidateEnforce checks if the policy has any validate rules with enforce action
func (s *Spec) HasValidateEnforce() bool {
for _, rule := range s.Rules {
if rule.HasValidate() {
action := rule.Validation.ValidationFailureAction
if action != nil && action.Enforce() {
return true
}
}
}
return s.ValidationFailureAction.Enforce()
}
// HasGenerate checks for generate rule types
func (s *Spec) HasGenerate() bool {
for _, rule := range s.Rules {
@ -228,32 +241,6 @@ func (s *Spec) BackgroundProcessingEnabled() bool {
return *s.Background
}
// GetValidationFailureAction returns the value of the validationFailureAction
func (s *Spec) GetValidationFailureAction() ValidationFailureAction {
for _, rule := range s.Rules {
if rule.HasValidate() {
validationFailureAction := rule.Validation.ValidationFailureAction
if validationFailureAction != nil {
return *validationFailureAction
}
}
}
return s.ValidationFailureAction
}
// GetValidationFailureActionOverrides returns the value of the validationFailureActionOverrides
func (s *Spec) GetValidationFailureActionOverrides() []ValidationFailureActionOverride {
for _, rule := range s.Rules {
if rule.HasValidate() {
validationFailureActionOverrides := rule.Validation.ValidationFailureActionOverrides
if len(validationFailureActionOverrides) != 0 {
return validationFailureActionOverrides
}
}
}
return s.ValidationFailureActionOverrides
}
// GetMutateExistingOnPolicyUpdate return MutateExistingOnPolicyUpdate set value
func (s *Spec) GetMutateExistingOnPolicyUpdate() bool {
for _, rule := range s.Rules {

View file

@ -794,6 +794,11 @@ func (in *ImageRegistryCredentials) DeepCopy() *ImageRegistryCredentials {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageVerification) DeepCopyInto(out *ImageVerification) {
*out = *in
if in.ValidationFailureAction != nil {
in, out := &in.ValidationFailureAction, &out.ValidationFailureAction
*out = new(ValidationFailureAction)
**out = **in
}
if in.ImageReferences != nil {
in, out := &in.ImageReferences, &out.ImageReferences
*out = make([]string, len(*in))

View file

@ -18,7 +18,6 @@ import (
// +kubebuilder:resource:path=clusterpolicies,scope="Cluster",shortName=cpol,categories=kyverno
// +kubebuilder:printcolumn:name="ADMISSION",type=boolean,JSONPath=".spec.admission"
// +kubebuilder:printcolumn:name="BACKGROUND",type=boolean,JSONPath=".spec.background"
// +kubebuilder:printcolumn:name="VALIDATE ACTION",type=string,JSONPath=".spec.validationFailureAction"
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="FAILURE POLICY",type=string,JSONPath=".spec.failurePolicy",priority=1

View file

@ -12,11 +12,11 @@ type AssertionTree = kjson.Any
// Validation defines checks to be performed on matching resources.
type Validation struct {
// ValidationFailureAction defines if a validation policy rule violation should block
// the admission review request (enforce), or allow (audit) the admission review request
// the admission review request (Enforce), or allow (Audit) the admission review request
// and report an error in a policy report. Optional.
// Allowed values are audit or enforce.
// Allowed values are Audit or Enforce.
// +optional
// +kubebuilder:validation:Enum=audit;enforce;Audit;Enforce
// +kubebuilder:validation:Enum=Audit;Enforce
ValidationFailureAction *kyvernov1.ValidationFailureAction `json:"validationFailureAction,omitempty" yaml:"validationFailureAction,omitempty"`
// ValidationFailureActionOverrides is a Cluster Policy attribute that specifies ValidationFailureAction

View file

@ -9,6 +9,11 @@ import (
// are signed with the supplied public key. Once the image is verified it is
// mutated to include the SHA digest retrieved during the registration.
type ImageVerification struct {
// Allowed values are Audit or Enforce.
// +optional
// +kubebuilder:validation:Enum=Audit;Enforce
ValidationFailureAction *kyvernov1.ValidationFailureAction `json:"validationFailureAction,omitempty" yaml:"validationFailureAction,omitempty"`
// Type specifies the method of signature validation. The allowed options
// are Cosign and Notary. By default Cosign is used if a type is not specified.
// +kubebuilder:validation:Optional

View file

@ -16,7 +16,6 @@ import (
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ADMISSION",type=boolean,JSONPath=".spec.admission"
// +kubebuilder:printcolumn:name="BACKGROUND",type=boolean,JSONPath=".spec.background"
// +kubebuilder:printcolumn:name="VALIDATE ACTION",type=string,JSONPath=".spec.validationFailureAction"
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status`
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="FAILURE POLICY",type=string,JSONPath=".spec.failurePolicy",priority=1

View file

@ -135,6 +135,19 @@ func (s *Spec) HasValidate() bool {
return false
}
// HasValidateEnforce checks if the policy has any validate rules with enforce action
func (s *Spec) HasValidateEnforce() bool {
for _, rule := range s.Rules {
if rule.HasValidate() {
action := rule.Validation.ValidationFailureAction
if action != nil && action.Enforce() {
return true
}
}
}
return s.ValidationFailureAction.Enforce()
}
// HasGenerate checks for generate rule types
func (s *Spec) HasGenerate() bool {
for _, rule := range s.Rules {
@ -197,32 +210,6 @@ func (s *Spec) BackgroundProcessingEnabled() bool {
return *s.Background
}
// GetValidationFailureAction returns the value of the validationFailureAction
func (s *Spec) GetValidationFailureAction() kyvernov1.ValidationFailureAction {
for _, rule := range s.Rules {
if rule.HasValidate() {
validationFailureAction := rule.Validation.ValidationFailureAction
if validationFailureAction != nil {
return *validationFailureAction
}
}
}
return s.ValidationFailureAction
}
// GetValidationFailureActionOverrides returns the value of the validationFailureActionOverrides
func (s *Spec) GetValidationFailureActionOverrides() []kyvernov1.ValidationFailureActionOverride {
for _, rule := range s.Rules {
if rule.HasValidate() {
validationFailureActionOverrides := rule.Validation.ValidationFailureActionOverrides
if len(validationFailureActionOverrides) != 0 {
return validationFailureActionOverrides
}
}
}
return s.ValidationFailureActionOverrides
}
// GetMutateExistingOnPolicyUpdate return MutateExistingOnPolicyUpdate set value
func (s *Spec) GetMutateExistingOnPolicyUpdate() bool {
for _, rule := range s.Rules {

View file

@ -368,6 +368,11 @@ func (in *Exception) DeepCopy() *Exception {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageVerification) DeepCopyInto(out *ImageVerification) {
*out = *in
if in.ValidationFailureAction != nil {
in, out := &in.ValidationFailureAction, &out.ValidationFailureAction
*out = new(v1.ValidationFailureAction)
**out = **in
}
if in.ImageReferences != nil {
in, out := &in.ImageReferences, &out.ImageReferences
*out = make([]string, len(*in))

View file

@ -31,9 +31,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -3436,12 +3433,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -4277,6 +4272,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -7804,12 +7805,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -8658,6 +8657,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -8798,9 +8803,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -11975,12 +11977,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -12785,6 +12785,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -16312,12 +16318,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -17166,6 +17170,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have

View file

@ -31,9 +31,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -3437,12 +3434,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -4278,6 +4273,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -7806,12 +7807,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -8660,6 +8659,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -8800,9 +8805,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -11978,12 +11980,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -12788,6 +12788,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -16315,12 +16321,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -17169,6 +17173,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have

View file

@ -26,7 +26,6 @@ metadata:
name: require-ns-purpose-label
namespace: test
spec:
validationFailureAction: Enforce
rules:
- name: require-ns-purpose-label
match:
@ -35,6 +34,7 @@ spec:
kinds:
- Namespace
validate:
validationFailureAction: Enforce
message: "You must have label 'purpose' with value 'production' set on all new namespaces."
pattern:
metadata:

View file

@ -18,6 +18,7 @@ spec:
- Pod
name: pods-require-account
validate:
validationFailureAction: Audit
message: User pods must include an account for charging
pattern:
metadata:
@ -30,6 +31,7 @@ spec:
- Pod
name: pods-require-limits
validate:
validationFailureAction: Audit
message: CPU and memory resource requests and limits are required for user pods
pattern:
spec:
@ -41,4 +43,3 @@ spec:
requests:
cpu: ?*
memory: ?*
validationFailureAction: Audit

View file

@ -18,6 +18,7 @@ spec:
- Pod
name: pods-require-account
validate:
validationFailureAction: Audit
message: User pods must include an account for charging
pattern:
metadata:
@ -30,6 +31,7 @@ spec:
- Pod
name: pods-require-limits
validate:
validationFailureAction: Audit
message: CPU and memory resource requests and limits are required for user pods
pattern:
spec:
@ -41,4 +43,3 @@ spec:
requests:
cpu: ?*
memory: ?*
validationFailureAction: Audit

View file

@ -32,4 +32,4 @@ spec:
required: true
useCache: true
verifyDigest: true
validationFailureAction: Audit
validationFailureAction: Audit

View file

@ -56,4 +56,4 @@ spec:
- CREATE
message: '{{request.object.metadata.namespace}}/{{request.object.kind}}/{{request.object.metadata.name}}
resource is protected. Admin or allowed users can change the resource'
validationFailureAction: Audit
validationFailureAction: Audit

View file

@ -18,6 +18,7 @@ spec:
- Pod
name: pods-require-account
validate:
validationFailureAction: Audit
message: User pods must include an account for charging
pattern:
metadata:
@ -41,4 +42,4 @@ spec:
requests:
cpu: ?*
memory: ?*
validationFailureAction: Audit
validationFailureAction: Audit

View file

@ -8,7 +8,6 @@ metadata:
policies.kyverno.io/category: Pod Security Standards (Restricted)
spec:
background: false
validationFailureAction: audit
rules:
- name: pods-require-account
match:
@ -19,6 +18,7 @@ spec:
matchLabels:
istio/rev: "default"
validate:
validationFailureAction: audit
message: User pods must include an account for charging
pattern:
metadata:
@ -30,6 +30,7 @@ spec:
kinds:
- Pod
validate:
validationFailureAction: audit
message: CPU and memory resource requests and limits are required for user pods
pattern:
spec:

View file

@ -19,6 +19,7 @@ spec:
- Pod
name: pods-require-account
validate:
validationFailureAction: Audit
message: User pods must include an account for charging
pattern:
metadata:
@ -31,6 +32,7 @@ spec:
- Pod
name: pods-require-limits
validate:
validationFailureAction: Audit
message: CPU and memory resource requests and limits are required for user pods
pattern:
spec:
@ -42,4 +44,3 @@ spec:
requests:
cpu: ?*
memory: ?*
validationFailureAction: Audit

View file

@ -20,4 +20,4 @@ spec:
podSecurity:
level: restricted
version: latest
validationFailureAction: Audit
validationFailureAction: Audit

View file

@ -25,9 +25,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -3430,12 +3427,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -4271,6 +4266,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -7798,12 +7799,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -8652,6 +8651,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -8792,9 +8797,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -11969,12 +11971,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -12779,6 +12779,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -16306,12 +16312,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -17160,6 +17164,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have

View file

@ -25,9 +25,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -3431,12 +3428,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -4272,6 +4267,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -7800,12 +7801,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -8654,6 +8653,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -8794,9 +8799,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -11972,12 +11974,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -12782,6 +12782,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -16309,12 +16315,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -17163,6 +17167,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have

View file

@ -110,7 +110,7 @@ func TestLoadWithKubectlValidate(t *testing.T) {
assert.NotNil(t, policy)
spec := policy.GetSpec()
assert.NotNil(t, spec)
assert.True(t, spec.GetValidationFailureAction().Audit())
assert.True(t, spec.ValidationFailureAction.Audit())
assert.NotNil(t, spec.Background)
assert.True(t, *spec.Background)
assert.NotNil(t, spec.Admission)

View file

@ -205,7 +205,7 @@ func (p *PolicyProcessor) ApplyPoliciesOnResource() ([]engineapi.EngineResponse,
}
responses = append(responses, generateResponse)
}
p.Rc.addGenerateResponse(p.AuditWarn, generateResponse)
p.Rc.addGenerateResponse(generateResponse)
}
}
p.Rc.addEngineResponses(p.AuditWarn, responses...)

View file

@ -63,7 +63,7 @@ func (rc *ResultCounts) addEngineResponse(auditWarn bool, response engineapi.Eng
}
}
func (rc *ResultCounts) addGenerateResponse(auditWarn bool, response engineapi.EngineResponse) {
func (rc *ResultCounts) addGenerateResponse(response engineapi.EngineResponse) {
genericPolicy := response.Policy()
if polType := genericPolicy.GetType(); polType == engineapi.ValidatingAdmissionPolicyType {
return
@ -75,11 +75,7 @@ func (rc *ResultCounts) addGenerateResponse(auditWarn bool, response engineapi.E
if ruleResponse.Status() == engineapi.RuleStatusPass {
rc.Pass++
} else {
if auditWarn && response.GetValidationFailureAction().Audit() {
rc.Warn++
} else {
rc.Fail++
}
rc.Fail++
}
continue
}

View file

@ -25,9 +25,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -3430,12 +3427,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -4271,6 +4266,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -7798,12 +7799,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -8652,6 +8651,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -8792,9 +8797,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -11969,12 +11971,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -12779,6 +12779,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -16306,12 +16312,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -17160,6 +17164,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have

View file

@ -25,9 +25,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -3431,12 +3428,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -4272,6 +4267,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -7800,12 +7801,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -8654,6 +8653,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -8794,9 +8799,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -11972,12 +11974,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -12782,6 +12782,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -16309,12 +16315,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -17163,6 +17167,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have

View file

@ -5222,9 +5222,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -8627,12 +8624,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -9468,6 +9463,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -12995,12 +12996,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -13849,6 +13848,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -13989,9 +13994,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -17166,12 +17168,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -17976,6 +17976,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -21503,12 +21509,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -22357,6 +22361,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -22778,9 +22788,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -26184,12 +26191,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -27025,6 +27030,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -30553,12 +30564,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -31407,6 +31416,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -31547,9 +31562,6 @@ spec:
- jsonPath: .spec.background
name: BACKGROUND
type: boolean
- jsonPath: .spec.validationFailureAction
name: VALIDATE ACTION
type: string
- jsonPath: .status.conditions[?(@.type == "Ready")].status
name: READY
type: string
@ -34725,12 +34737,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -35535,6 +35545,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -39062,12 +39078,10 @@ spec:
validationFailureAction:
description: |-
ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.
Allowed values are Audit or Enforce.
enum:
- audit
- enforce
- Audit
- Enforce
type: string
@ -39916,6 +39930,12 @@ spec:
description: UseCache enables caching of image verify
responses for this rule.
type: boolean
validationFailureAction:
description: Allowed values are Audit or Enforce.
enum:
- Audit
- Enforce
type: string
verifyDigest:
default: true
description: VerifyDigest validates that images have

View file

@ -2389,6 +2389,20 @@ mutated to include the SHA digest retrieved during the registration.</p>
<tbody>
<tr>
<td>
<code>validationFailureAction</code><br/>
<em>
<a href="#kyverno.io/v1.ValidationFailureAction">
ValidationFailureAction
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Allowed values are Audit or Enforce.</p>
</td>
</tr>
<tr>
<td>
<code>type</code><br/>
<em>
<a href="#kyverno.io/v1.ImageVerificationType">
@ -4472,9 +4486,9 @@ ValidationFailureAction
<td>
<em>(Optional)</em>
<p>ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.</p>
Allowed values are Audit or Enforce.</p>
</td>
</tr>
<tr>
@ -4623,9 +4637,11 @@ github.com/kyverno/kyverno-json/pkg/apis/policy/v1alpha1.Any
(<code>string</code> alias)</p></h3>
<p>
(<em>Appears on:</em>
<a href="#kyverno.io/v1.ImageVerification">ImageVerification</a>,
<a href="#kyverno.io/v1.Spec">Spec</a>,
<a href="#kyverno.io/v1.Validation">Validation</a>,
<a href="#kyverno.io/v1.ValidationFailureActionOverride">ValidationFailureActionOverride</a>,
<a href="#kyverno.io/v2beta1.ImageVerification">ImageVerification</a>,
<a href="#kyverno.io/v2beta1.Spec">Spec</a>,
<a href="#kyverno.io/v2beta1.Validation">Validation</a>)
</p>
@ -8369,6 +8385,20 @@ mutated to include the SHA digest retrieved during the registration.</p>
<tbody>
<tr>
<td>
<code>validationFailureAction</code><br/>
<em>
<a href="#kyverno.io/v1.ValidationFailureAction">
ValidationFailureAction
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Allowed values are Audit or Enforce.</p>
</td>
</tr>
<tr>
<td>
<code>type</code><br/>
<em>
<a href="#kyverno.io/v1.ImageVerificationType">
@ -9248,9 +9278,9 @@ ValidationFailureAction
<td>
<em>(Optional)</em>
<p>ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.</p>
Allowed values are Audit or Enforce.</p>
</td>
</tr>
<tr>

View file

@ -4694,6 +4694,35 @@ mutated to include the SHA digest retrieved during the registration.</p>
<tr>
<td><code>validationFailureAction</code>
</br>
<a href="#kyverno-io-v1-ValidationFailureAction">
<span style="font-family: monospace">ValidationFailureAction</span>
</a>
</td>
<td>
<p>Allowed values are Audit or Enforce.</p>
</td>
</tr>
<tr>
<td><code>type</code>
@ -8965,9 +8994,9 @@ It is an empty string when validating admission policy is successfully generated
<p>ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.</p>
Allowed values are Audit or Enforce.</p>
@ -9274,6 +9303,7 @@ by specifying exclusions for Pod Security Standards controls.</p>
<p>
(<em>Appears in:</em>
<a href="#kyverno-io-v1-ImageVerification">ImageVerification</a>,
<a href="#kyverno-io-v1-Spec">Spec</a>,
<a href="#kyverno-io-v1-Validation">Validation</a>,
<a href="#kyverno-io-v1-ValidationFailureActionOverride">ValidationFailureActionOverride</a>)

View file

@ -2773,6 +2773,35 @@ mutated to include the SHA digest retrieved during the registration.</p>
<tr>
<td><code>validationFailureAction</code>
</br>
<a href="#kyverno-io-v1-ValidationFailureAction">
<span style="font-family: monospace">ValidationFailureAction</span>
</a>
</td>
<td>
<p>Allowed values are Audit or Enforce.</p>
</td>
</tr>
<tr>
<td><code>type</code>
@ -4536,9 +4565,9 @@ Defaults to &quot;false&quot; if not specified.</p>
<p>ValidationFailureAction defines if a validation policy rule violation should block
the admission review request (enforce), or allow (audit) the admission review request
the admission review request (Enforce), or allow (Audit) the admission review request
and report an error in a policy report. Optional.
Allowed values are audit or enforce.</p>
Allowed values are Audit or Enforce.</p>

View file

@ -242,7 +242,7 @@ func Test_GetSupportedControllers(t *testing.T) {
},
{
name: "rule-with-validate-podsecurity",
policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"pod-security"},"spec":{"validationFailureAction":"enforce","rules":[{"name":"restricted","match":{"all":[{"resources":{"kinds":["Pod"]}}]},"validate":{"podSecurity":{"level":"restricted","version":"v1.24"}}}]}}`),
policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"pod-security"},"spec":{"rules":[{"name":"restricted","match":{"all":[{"resources":{"kinds":["Pod"]}}]},"validate":{"validationFailureAction":"enforce","podSecurity":{"level":"restricted","version":"v1.24"}}}]}}`),
expectedControllers: PodControllers,
},
}
@ -406,7 +406,6 @@ kind: ClusterPolicy
metadata:
name: check-image
spec:
validationFailureAction: enforce
background: false
webhookTimeoutSeconds: 30
failurePolicy: Fail
@ -540,7 +539,7 @@ kA==
}
func Test_PodSecurityWithNoExceptions(t *testing.T) {
policy := []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"pod-security"},"spec":{"validationFailureAction":"enforce","rules":[{"name":"restricted","match":{"all":[{"resources":{"kinds":["Pod"]}}]},"validate":{"podSecurity":{"level":"restricted","version":"v1.24"}}}]}}`)
policy := []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"pod-security"},"spec":{"rules":[{"name":"restricted","match":{"all":[{"resources":{"kinds":["Pod"]}}]},"validate":{"validationFailureAction":"enforce","podSecurity":{"level":"restricted","version":"v1.24"}}}]}}`)
policies, _, _, err := yamlutils.GetPolicy([]byte(policy))
assert.NilError(t, err)
assert.Equal(t, 1, len(policies))
@ -558,7 +557,6 @@ func Test_ValidateWithCELExpressions(t *testing.T) {
"name": "disallow-host-path"
},
"spec": {
"validationFailureAction": "Enforce",
"background": false,
"rules": [
{
@ -575,6 +573,7 @@ func Test_ValidateWithCELExpressions(t *testing.T) {
]
},
"validate": {
"validationFailureAction": "Enforce",
"cel": {
"expressions": [
{

View file

@ -129,7 +129,9 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
}
if target := rule.Validation.GetPattern(); target != nil {
newValidate := kyvernov1.Validation{
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
ValidationFailureAction: rule.Validation.ValidationFailureAction,
ValidationFailureActionOverrides: rule.Validation.ValidationFailureActionOverrides,
}
newValidate.SetPattern(
map[string]interface{}{
@ -143,8 +145,10 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
}
if rule.Validation.Deny != nil {
deny := kyvernov1.Validation{
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "deny"),
Deny: rule.Validation.Deny,
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "deny"),
Deny: rule.Validation.Deny,
ValidationFailureAction: rule.Validation.ValidationFailureAction,
ValidationFailureActionOverrides: rule.Validation.ValidationFailureActionOverrides,
}
rule.Validation = deny
return rule
@ -159,6 +163,8 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
Version: rule.Validation.PodSecurity.Version,
Exclude: newExclude,
},
ValidationFailureAction: rule.Validation.ValidationFailureAction,
ValidationFailureActionOverrides: rule.Validation.ValidationFailureActionOverrides,
}
rule.Validation = podSecurity
return rule
@ -177,8 +183,12 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
}
patterns = append(patterns, newPattern)
}
validationFailureAction := rule.Validation.ValidationFailureAction
validationFailureActionOverrides := rule.Validation.ValidationFailureActionOverrides
rule.Validation = kyvernov1.Validation{
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "anyPattern"),
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "anyPattern"),
ValidationFailureAction: validationFailureAction,
ValidationFailureActionOverrides: validationFailureActionOverrides,
}
rule.Validation.SetAnyPattern(patterns)
return rule
@ -186,9 +196,13 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
if len(rule.Validation.ForEachValidation) > 0 && rule.Validation.ForEachValidation != nil {
newForeachValidate := make([]kyvernov1.ForEachValidation, len(rule.Validation.ForEachValidation))
copy(newForeachValidate, rule.Validation.ForEachValidation)
validationFailureAction := rule.Validation.ValidationFailureAction
validationFailureActionOverrides := rule.Validation.ValidationFailureActionOverrides
rule.Validation = kyvernov1.Validation{
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
ForEachValidation: newForeachValidate,
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
ForEachValidation: newForeachValidate,
ValidationFailureAction: validationFailureAction,
ValidationFailureActionOverrides: validationFailureActionOverrides,
}
return rule
}

View file

@ -25,6 +25,7 @@ import (
// ImageVerificationApplyConfiguration represents an declarative configuration of the ImageVerification type for use
// with apply.
type ImageVerificationApplyConfiguration struct {
ValidationFailureAction *v1.ValidationFailureAction `json:"validationFailureAction,omitempty"`
Type *v1.ImageVerificationType `json:"type,omitempty"`
Image *string `json:"image,omitempty"`
ImageReferences []string `json:"imageReferences,omitempty"`
@ -52,6 +53,14 @@ func ImageVerification() *ImageVerificationApplyConfiguration {
return &ImageVerificationApplyConfiguration{}
}
// WithValidationFailureAction sets the ValidationFailureAction field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the ValidationFailureAction field is set to the value of the last call.
func (b *ImageVerificationApplyConfiguration) WithValidationFailureAction(value v1.ValidationFailureAction) *ImageVerificationApplyConfiguration {
b.ValidationFailureAction = &value
return b
}
// WithType sets the Type field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Type field is set to the value of the last call.

View file

@ -26,6 +26,7 @@ import (
// ImageVerificationApplyConfiguration represents an declarative configuration of the ImageVerification type for use
// with apply.
type ImageVerificationApplyConfiguration struct {
ValidationFailureAction *v1.ValidationFailureAction `json:"validationFailureAction,omitempty"`
Type *v1.ImageVerificationType `json:"type,omitempty"`
ImageReferences []string `json:"imageReferences,omitempty"`
SkipImageReferences []string `json:"skipImageReferences,omitempty"`
@ -45,6 +46,14 @@ func ImageVerification() *ImageVerificationApplyConfiguration {
return &ImageVerificationApplyConfiguration{}
}
// WithValidationFailureAction sets the ValidationFailureAction field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the ValidationFailureAction field is set to the value of the last call.
func (b *ImageVerificationApplyConfiguration) WithValidationFailureAction(value v1.ValidationFailureAction) *ImageVerificationApplyConfiguration {
b.ValidationFailureAction = &value
return b
}
// WithType sets the Type field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Type field is set to the value of the last call.

View file

@ -27,7 +27,7 @@ func (pc *controller) registerPolicyChangesMetricUpdatePolicy(ctx context.Contex
logger.Error(err, "error occurred while registering kyverno_policy_changes_total metrics for the above policy's updation", "name", oldP.GetName())
}
// curP will require a new kyverno_policy_changes_total metric if the above update involved change in the following fields:
if curSpec.BackgroundProcessingEnabled() != oldSpec.BackgroundProcessingEnabled() || curSpec.GetValidationFailureAction().Enforce() != oldSpec.GetValidationFailureAction().Enforce() {
if curSpec.BackgroundProcessingEnabled() != oldSpec.BackgroundProcessingEnabled() || curSpec.ValidationFailureAction.Enforce() != oldSpec.ValidationFailureAction.Enforce() {
err = policyChangesMetric.RegisterPolicy(ctx, pc.metricsConfig, curP, policyChangesMetric.PolicyUpdated)
if err != nil {
logger.Error(err, "error occurred while registering kyverno_policy_changes_total metrics for the above policy's updation", "name", curP.GetName())

View file

@ -35,7 +35,6 @@ var policy = `
"name": "disallow-unsigned-images"
},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"rules": [
{

View file

@ -199,7 +199,41 @@ func (er EngineResponse) GetValidationFailureAction() kyvernov1.ValidationFailur
return ""
}
spec := pol.AsKyvernoPolicy().GetSpec()
for _, v := range spec.GetValidationFailureActionOverrides() {
for _, r := range spec.Rules {
if r.HasValidate() {
for _, v := range r.Validation.ValidationFailureActionOverrides {
if !v.Action.IsValid() {
continue
}
if v.Namespaces == nil {
hasPass, err := utils.CheckSelector(v.NamespaceSelector, er.namespaceLabels)
if err == nil && hasPass {
return v.Action
}
}
for _, ns := range v.Namespaces {
if wildcard.Match(ns, er.PatchedResource.GetNamespace()) {
if v.NamespaceSelector == nil {
return v.Action
}
hasPass, err := utils.CheckSelector(v.NamespaceSelector, er.namespaceLabels)
if err == nil && hasPass {
return v.Action
}
}
}
}
if r.Validation.ValidationFailureAction != nil {
return *r.Validation.ValidationFailureAction
}
} else if r.HasVerifyImages() {
if r.VerifyImages[0].ValidationFailureAction != nil {
return *r.VerifyImages[0].ValidationFailureAction
}
}
}
for _, v := range spec.ValidationFailureActionOverrides {
if !v.Action.IsValid() {
continue
}
@ -221,5 +255,5 @@ func (er EngineResponse) GetValidationFailureAction() kyvernov1.ValidationFailur
}
}
}
return spec.GetValidationFailureAction()
return spec.ValidationFailureAction
}

View file

@ -40,7 +40,6 @@ func buildTestNamespaceLabelsContext(t *testing.T) api.PolicyContext {
"name": "block-label-changes"
},
"spec": {
"validationFailureAction": "Enforce",
"background": false,
"rules": [
{
@ -61,6 +60,7 @@ func buildTestNamespaceLabelsContext(t *testing.T) api.PolicyContext {
]
},
"validate": {
"validationFailureAction": "Enforce",
"message": "The label size is required",
"pattern": {
"metadata": {
@ -88,6 +88,7 @@ func buildTestNamespaceLabelsContext(t *testing.T) api.PolicyContext {
]
},
"validate": {
"validationFailureAction": "Enforce",
"message": "The label size cannot be changed for a namespace",
"deny": {
"conditions": {

View file

@ -180,7 +180,6 @@ func Test_PolicyDeserilize(t *testing.T) {
"name": "set-image-pull-policy"
},
"spec": {
"validationFailureAction": "enforce",
"rules": [
{
"name": "set-image-pull-policy",

View file

@ -655,7 +655,6 @@ func Test_foreach_element_mutation(t *testing.T) {
"name": "mutate-privileged"
},
"spec": {
"validationFailureAction": "audit",
"background": false,
"webhookTimeoutSeconds": 10,
"failurePolicy": "Fail",

View file

@ -837,7 +837,7 @@ func TestMatchesResourceDescription(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "name": "qos-demo", "labels": { "test": "qos" } }, "spec": { "replicas": 1, "selector": { "matchLabels": { "app": "nginx" } }, "template": { "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "labels": { "app": "nginx" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx:latest", "resources": { "limits": { "cpu": "50m" } } } ]}}}}`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } }, { "name": "check-cpu-memory-limits", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "validate": { "message": "Resource limits are required for CPU and memory", "pattern": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "memory": "?*", "cpu": "?*" } } } ] } } } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } }, { "name": "check-cpu-memory-limits", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "validate": { "message": "Resource limits are required for CPU and memory", "pattern": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "memory": "?*", "cpu": "?*" } } } ] } } } } } } ] } }`),
areErrorsExpected: false,
},
{
@ -846,7 +846,7 @@ func TestMatchesResourceDescription(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "myapp-pod2", "labels": { "app": "myapp2" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx" } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "disallow-latest-tag", "annotations": { "policies.kyverno.io/category": "Workload Isolation", "policies.kyverno.io/description": "The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod." } }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "require-image-tag", "match": { "resources": { "kinds": [ "v1/Pod" ] } }, "validate": { "message": "An image tag is required", "pattern": { "spec": { "containers": [ { "image": "*:*" } ] } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "disallow-latest-tag", "annotations": { "policies.kyverno.io/category": "Workload Isolation", "policies.kyverno.io/description": "The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod." } }, "spec": {"rules": [ { "name": "require-image-tag", "match": { "resources": { "kinds": [ "v1/Pod" ] } }, "validate": { "validationFailureAction": "enforce", "message": "An image tag is required", "pattern": { "spec": { "containers": [ { "image": "*:*" } ] } } } } ] } }`),
areErrorsExpected: false,
},
{
@ -864,7 +864,7 @@ func TestMatchesResourceDescription(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "apps/v1beta1", "kind": "Deployment", "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "name": "qos-demo", "labels": { "test": "qos" } }, "spec": { "replicas": 1, "selector": { "matchLabels": { "app": "nginx" } }, "template": { "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "labels": { "app": "nginx" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx:latest", "resources": { "limits": { "cpu": "50m" } } } ]}}}}`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } }, { "name": "check-cpu-memory-limits", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "validate": { "message": "Resource limits are required for CPU and memory", "pattern": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "memory": "?*", "cpu": "?*" } } } ] } } } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } }, { "name": "check-cpu-memory-limits", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "validate": { "message": "Resource limits are required for CPU and memory", "pattern": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "memory": "?*", "cpu": "?*" } } } ] } } } } } } ] } }`),
areErrorsExpected: true,
},
{
@ -873,7 +873,7 @@ func TestMatchesResourceDescription(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "kind": "ClusterRole", "apiVersion": "rbac.authorization.k8s.io/v1", "metadata": { "name": "secret-reader-demo", "namespace": "default" }, "rules": [ { "apiGroups": [ "" ], "resources": [ "secrets" ], "verbs": [ "get", "watch", "list" ] } ] }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "check-host-path" }, "spec": { "validationFailureAction": "enforce", "background": true, "rules": [ { "name": "check-host-path", "match": { "resources": { "kinds": [ "rbac.authorization.k8s.io/v1beta1/ClusterRole" ] } }, "validate": { "message": "Host path is not allowed", "pattern": { "spec": { "volumes": [ { "name": "*", "hostPath": { "path": "" } } ] } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "check-host-path" }, "spec": { "background": true, "rules": [ { "name": "check-host-path", "match": { "resources": { "kinds": [ "rbac.authorization.k8s.io/v1beta1/ClusterRole" ] } }, "validate": { "validationFailureAction": "enforce", "message": "Host path is not allowed", "pattern": { "spec": { "volumes": [ { "name": "*", "hostPath": { "path": "" } } ] } } } } ] } }`),
areErrorsExpected: true,
},
{
@ -882,7 +882,7 @@ func TestMatchesResourceDescription(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "myapp-pod2", "labels": { "app": "myapp2" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx" } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "disallow-latest-tag", "annotations": { "policies.kyverno.io/category": "Workload Isolation", "policies.kyverno.io/description": "The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod." } }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "require-image-tag", "match": { "resources": { "kinds": [ "pod" ] } }, "validate": { "message": "An image tag is required", "pattern": { "spec": { "containers": [ { "image": "*:*" } ] } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "disallow-latest-tag", "annotations": { "policies.kyverno.io/category": "Workload Isolation", "policies.kyverno.io/description": "The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod." } }, "spec": { "rules": [ { "name": "require-image-tag", "match": { "resources": { "kinds": [ "pod" ] } }, "validate": { "validationFailureAction": "enforce", "message": "An image tag is required", "pattern": { "spec": { "containers": [ { "image": "*:*" } ] } } } } ] } }`),
areErrorsExpected: true,
},
{
@ -891,7 +891,7 @@ func TestMatchesResourceDescription(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "name": "qos-demo", "labels": { "test": "qos" } }, "spec": { "replicas": 1, "selector": { "matchLabels": { "app": "nginx" } }, "template": { "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "labels": { "app": "nginx" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx:latest", "resources": { "limits": { "cpu": "50m" } } } ]}}}}`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } } ] } }`),
areErrorsExpected: true,
},
}
@ -1742,7 +1742,7 @@ func TestMatchesResourceDescription_GenerateName(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "generateName": "qos-demo", "labels": { "test": "qos" } }, "spec": { "replicas": 1, "selector": { "matchLabels": { "app": "nginx" } }, "template": { "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "labels": { "app": "nginx" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx:latest", "resources": { "limits": { "cpu": "50m" } } } ]}}}}`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } }, { "name": "check-cpu-memory-limits", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "validate": { "message": "Resource limits are required for CPU and memory", "pattern": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "memory": "?*", "cpu": "?*" } } } ] } } } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } }, { "name": "check-cpu-memory-limits", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "validate": { "validationFailureAction": "enforce", "message": "Resource limits are required for CPU and memory", "pattern": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "memory": "?*", "cpu": "?*" } } } ] } } } } } } ] } }`),
areErrorsExpected: false,
},
{
@ -1751,7 +1751,7 @@ func TestMatchesResourceDescription_GenerateName(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "v1", "kind": "Pod", "metadata": { "generateName": "myapp-pod2", "labels": { "app": "myapp2" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx" } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "disallow-latest-tag", "annotations": { "policies.kyverno.io/category": "Workload Isolation", "policies.kyverno.io/description": "The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod." } }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "require-image-tag", "match": { "resources": { "kinds": [ "v1/Pod" ] } }, "validate": { "message": "An image tag is required", "pattern": { "spec": { "containers": [ { "image": "*:*" } ] } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "disallow-latest-tag", "annotations": { "policies.kyverno.io/category": "Workload Isolation", "policies.kyverno.io/description": "The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod." } }, "spec": { "rules": [ { "name": "require-image-tag", "match": { "resources": { "kinds": [ "v1/Pod" ] } }, "validate": { "validationFailureAction": "enforce", "message": "An image tag is required", "pattern": { "spec": { "containers": [ { "image": "*:*" } ] } } } } ] } }`),
areErrorsExpected: false,
},
{
@ -1769,7 +1769,7 @@ func TestMatchesResourceDescription_GenerateName(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "apps/v1beta1", "kind": "Deployment", "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "generateName": "qos-demo", "labels": { "test": "qos" } }, "spec": { "replicas": 1, "selector": { "matchLabels": { "app": "nginx" } }, "template": { "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "labels": { "app": "nginx" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx:latest", "resources": { "limits": { "cpu": "50m" } } } ]}}}}`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } }, { "name": "check-cpu-memory-limits", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "validate": { "message": "Resource limits are required for CPU and memory", "pattern": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "memory": "?*", "cpu": "?*" } } } ] } } } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } }, { "name": "check-cpu-memory-limits", "match": { "resources": { "kinds": [ "apps/v1/Deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "validate": { "validationFailureAction": "enforce", "message": "Resource limits are required for CPU and memory", "pattern": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "memory": "?*", "cpu": "?*" } } } ] } } } } } } ] } }`),
areErrorsExpected: true,
},
{
@ -1778,7 +1778,7 @@ func TestMatchesResourceDescription_GenerateName(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "kind": "ClusterRole", "apiVersion": "rbac.authorization.k8s.io/v1", "metadata": { "generateName": "secret-reader-demo", "namespace": "default" }, "rules": [ { "apiGroups": [ "" ], "resources": [ "secrets" ], "verbs": [ "get", "watch", "list" ] } ] }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "check-host-path" }, "spec": { "validationFailureAction": "enforce", "background": true, "rules": [ { "name": "check-host-path", "match": { "resources": { "kinds": [ "rbac.authorization.k8s.io/v1beta1/ClusterRole" ] } }, "validate": { "message": "Host path is not allowed", "pattern": { "spec": { "volumes": [ { "name": "*", "hostPath": { "path": "" } } ] } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "check-host-path" }, "spec": { "background": true, "rules": [ { "name": "check-host-path", "match": { "resources": { "kinds": [ "rbac.authorization.k8s.io/v1beta1/ClusterRole" ] } }, "validate": { "validationFailureAction": "enforce", "message": "Host path is not allowed", "pattern": { "spec": { "volumes": [ { "name": "*", "hostPath": { "path": "" } } ] } } } } ] } }`),
areErrorsExpected: true,
},
{
@ -1787,7 +1787,7 @@ func TestMatchesResourceDescription_GenerateName(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "v1", "kind": "Pod", "metadata": { "generateName": "myapp-pod2", "labels": { "app": "myapp2" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx" } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "disallow-latest-tag", "annotations": { "policies.kyverno.io/category": "Workload Isolation", "policies.kyverno.io/description": "The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod." } }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "require-image-tag", "match": { "resources": { "kinds": [ "pod" ] } }, "validate": { "message": "An image tag is required", "pattern": { "spec": { "containers": [ { "image": "*:*" } ] } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "disallow-latest-tag", "annotations": { "policies.kyverno.io/category": "Workload Isolation", "policies.kyverno.io/description": "The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod." } }, "spec": { "rules": [ { "name": "require-image-tag", "match": { "resources": { "kinds": [ "pod" ] } }, "validate": { "validationFailureAction": "enforce", "message": "An image tag is required", "pattern": { "spec": { "containers": [ { "image": "*:*" } ] } } } } ] } }`),
areErrorsExpected: true,
},
{
@ -1796,7 +1796,7 @@ func TestMatchesResourceDescription_GenerateName(t *testing.T) {
ClusterRoles: []string{"admin"},
},
Resource: []byte(`{ "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "generateName": "qos-demo", "labels": { "test": "qos" } }, "spec": { "replicas": 1, "selector": { "matchLabels": { "app": "nginx" } }, "template": { "metadata": { "creationTimestamp": "2020-09-21T12:56:35Z", "labels": { "app": "nginx" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx:latest", "resources": { "limits": { "cpu": "50m" } } } ]}}}}`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "validationFailureAction": "enforce", "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } } ] } }`),
Policy: []byte(`{ "apiVersion": "kyverno.io/v1", "kind": "ClusterPolicy", "metadata": { "name": "policy-qos" }, "spec": { "rules": [ { "name": "add-memory-limit", "match": { "resources": { "kinds": [ "apps/v1/deployment" ], "selector": { "matchLabels": { "test": "qos" } } } }, "mutate": { "overlay": { "spec": { "template": { "spec": { "containers": [ { "(name)": "*", "resources": { "limits": { "+(memory)": "300Mi", "+(cpu)": "100" } } } ] } } } } } } ] } }`),
areErrorsExpected: true,
},
}

View file

@ -679,7 +679,6 @@ func TestValidate_foreach_zero_reported_asskip(t *testing.T) {
}
},
"spec": {
"validationFailureAction": "Enforce",
"background": true,
"rules": [
{
@ -690,6 +689,7 @@ func TestValidate_foreach_zero_reported_asskip(t *testing.T) {
}
},
"validate": {
"validationFailureAction": "Enforce",
"foreach": [
{
"list": "request.object.spec.volumes[].projected.sources[].serviceAccountToken.expirationSeconds",
@ -1948,7 +1948,6 @@ func Test_VariableSubstitutionValidate_VariablesInMessageAreResolved(t *testing.
"name": "cm-array-example"
},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"rules": [
{
@ -1961,6 +1960,7 @@ func Test_VariableSubstitutionValidate_VariablesInMessageAreResolved(t *testing.
}
},
"validate": {
"validationFailureAction": "enforce",
"message": "The animal {{ request.object.metadata.labels.animal }} is not in the allowed list of animals.",
"deny": {
"conditions": [
@ -2125,7 +2125,6 @@ func Test_BlockLabelRemove(t *testing.T) {
"name": "prevent-label-remove"
},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"rules": [
{
@ -2152,6 +2151,7 @@ func Test_BlockLabelRemove(t *testing.T) {
]
},
"validate": {
"validationFailureAction": "enforce",
"message": "not allowed",
"deny": {
"conditions": {
@ -2248,7 +2248,6 @@ func TestValidate_context_variable_substitution_CLI(t *testing.T) {
"name": "restrict-pod-count"
},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"rules": [
{
@ -2270,6 +2269,7 @@ func TestValidate_context_variable_substitution_CLI(t *testing.T) {
}
],
"validate": {
"validationFailureAction": "enforce",
"message": "restrict pod counts to be no more than 10 on node minikube",
"deny": {
"conditions": [
@ -2372,6 +2372,7 @@ func Test_EmptyStringInDenyCondition(t *testing.T) {
}
],
"validate": {
"validationFailureAction": "enforce",
"deny": {
"conditions": [
{
@ -2383,8 +2384,7 @@ func Test_EmptyStringInDenyCondition(t *testing.T) {
}
}
}
],
"validationFailureAction": "enforce"
]
}
}`)
@ -2457,6 +2457,7 @@ func Test_StringInDenyCondition(t *testing.T) {
}
],
"validate": {
"validationFailureAction": "enforce",
"deny": {
"conditions": [
{
@ -2468,8 +2469,7 @@ func Test_StringInDenyCondition(t *testing.T) {
}
}
}
],
"validationFailureAction": "enforce"
]
}
}`)
@ -3000,13 +3000,13 @@ func Test_outof_foreach_element_validation(t *testing.T) {
"kind": "ClusterPolicy",
"metadata": {"name": "check-container-names"},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"rules": [
{
"name": "test",
"match": {"resources": { "kinds": [ "Pod" ] } },
"validate": {
"validationFailureAction": "enforce",
"message": "Invalid name",
"pattern": {
"name": "{{ element.name }}"
@ -3033,7 +3033,6 @@ func Test_foreach_skip_initContainer_pass(t *testing.T) {
"name": "check-images"
},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"rules": [
{
@ -3046,6 +3045,7 @@ func Test_foreach_skip_initContainer_pass(t *testing.T) {
}
},
"validate": {
"validationFailureAction": "enforce",
"message": "unknown registry",
"foreach": [
{
@ -3210,13 +3210,13 @@ func Test_delete_ignore_pattern(t *testing.T) {
"kind": "ClusterPolicy",
"metadata": {"name": "check-container-labels"},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"rules": [
{
"name": "test",
"match": {"resources": { "kinds": [ "Pod" ] } },
"validate": {
"validationFailureAction": "enforce",
"message": "Invalid label",
"pattern": {
"metadata" : {

View file

@ -77,6 +77,12 @@ func GetPolicyInfos(policy kyvernov1.PolicyInterface) (string, string, PolicyTyp
policyType = Namespaced
}
backgroundMode := ParsePolicyBackgroundMode(policy)
validationMode, err := ParsePolicyValidationMode(policy.GetSpec().GetValidationFailureAction())
return name, namespace, policyType, backgroundMode, validationMode, err
isEnforce := policy.GetSpec().HasValidateEnforce()
var validationMode PolicyValidationMode
if isEnforce {
validationMode = Enforce
} else {
validationMode = Audit
}
return name, namespace, policyType, backgroundMode, validationMode, nil
}

View file

@ -3,6 +3,7 @@ package policycache
import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/ext/wildcard"
"github.com/kyverno/kyverno/pkg/autogen"
"github.com/kyverno/kyverno/pkg/clients/dclient"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -62,31 +63,56 @@ func (c *cache) GetPolicies(pkey PolicyType, gvr schema.GroupVersionResource, su
func filterPolicies(pkey PolicyType, result []kyvernov1.PolicyInterface, nspace string) []kyvernov1.PolicyInterface {
var policies []kyvernov1.PolicyInterface
for _, policy := range result {
var filteredPolicy kyvernov1.PolicyInterface
keepPolicy := true
switch pkey {
case ValidateAudit:
keepPolicy = checkValidationFailureActionOverrides(false, nspace, policy)
keepPolicy, filteredPolicy = checkValidationFailureActionOverrides(false, nspace, policy)
case ValidateEnforce:
keepPolicy = checkValidationFailureActionOverrides(true, nspace, policy)
keepPolicy, filteredPolicy = checkValidationFailureActionOverrides(true, nspace, policy)
}
// add policy to result
if keepPolicy {
policies = append(policies, policy)
policies = append(policies, filteredPolicy)
}
}
return policies
}
func checkValidationFailureActionOverrides(enforce bool, ns string, policy kyvernov1.PolicyInterface) bool {
validationFailureAction := policy.GetSpec().GetValidationFailureAction()
validationFailureActionOverrides := policy.GetSpec().GetValidationFailureActionOverrides()
if validationFailureAction.Enforce() != enforce && (ns == "" || len(validationFailureActionOverrides) == 0) {
return false
}
for _, action := range validationFailureActionOverrides {
if action.Action.Enforce() != enforce && wildcard.CheckPatterns(action.Namespaces, ns) {
return false
func checkValidationFailureActionOverrides(enforce bool, ns string, policy kyvernov1.PolicyInterface) (bool, kyvernov1.PolicyInterface) {
var filteredRules []kyvernov1.Rule
for _, rule := range autogen.ComputeRules(policy, "") {
if !rule.HasValidate() {
continue
}
// if the field isn't set, use the higher level policy setting
validationFailureAction := rule.Validation.ValidationFailureAction
if validationFailureAction == nil {
validationFailureAction = &policy.GetSpec().ValidationFailureAction
}
validationFailureActionOverrides := rule.Validation.ValidationFailureActionOverrides
if len(validationFailureActionOverrides) == 0 {
validationFailureActionOverrides = policy.GetSpec().ValidationFailureActionOverrides
}
if (ns == "" || len(validationFailureActionOverrides) == 0) && validationFailureAction.Enforce() == enforce {
filteredRules = append(filteredRules, rule)
continue
}
for _, action := range validationFailureActionOverrides {
if action.Action.Enforce() == enforce && wildcard.CheckPatterns(action.Namespaces, ns) {
filteredRules = append(filteredRules, rule)
continue
}
}
}
return true
if len(filteredRules) > 0 {
filteredPolicy := policy.CreateDeepCopy()
filteredPolicy.GetSpec().Rules = filteredRules
return true, filteredPolicy
}
return false, nil
}

View file

@ -80,10 +80,10 @@ func newPolicyMap() *policyMap {
}
func computeEnforcePolicy(spec *kyvernov1.Spec) bool {
if spec.GetValidationFailureAction().Enforce() {
if spec.ValidationFailureAction.Enforce() {
return true
}
for _, k := range spec.GetValidationFailureActionOverrides() {
for _, k := range spec.ValidationFailureActionOverrides {
if k.Action.Enforce() {
return true
}
@ -108,6 +108,17 @@ func (m *policyMap) set(key string, policy kyvernov1.PolicyInterface, client Res
}
kindStates := map[policyKey]state{}
for _, rule := range autogen.ComputeRules(policy, "") {
if rule.HasValidate() {
action := rule.Validation.ValidationFailureAction
if action != nil && action.Enforce() {
enforcePolicy = true
}
for _, k := range rule.Validation.ValidationFailureActionOverrides {
if k.Action.Enforce() {
enforcePolicy = true
}
}
}
entries := sets.New[policyKey]()
for _, gvk := range rule.MatchResources.GetKinds() {
group, version, kind, subresource := kubeutils.ParseKindSelector(gvk)

View file

@ -105,12 +105,22 @@ func BuildValidatingAdmissionPolicyBinding(
// set validation action for vap binding
var validationActions []admissionregistrationv1alpha1.ValidationAction
action := cpol.GetSpec().GetValidationFailureAction()
if action.Enforce() {
validationActions = append(validationActions, admissionregistrationv1alpha1.Deny)
} else if action.Audit() {
validationActions = append(validationActions, admissionregistrationv1alpha1.Audit)
validationActions = append(validationActions, admissionregistrationv1alpha1.Warn)
validateAction := cpol.GetSpec().Rules[0].Validation.ValidationFailureAction
if validateAction != nil {
if validateAction.Enforce() {
validationActions = append(validationActions, admissionregistrationv1alpha1.Deny)
} else if validateAction.Audit() {
validationActions = append(validationActions, admissionregistrationv1alpha1.Audit)
validationActions = append(validationActions, admissionregistrationv1alpha1.Warn)
}
} else {
validateAction := cpol.GetSpec().ValidationFailureAction
if validateAction.Enforce() {
validationActions = append(validationActions, admissionregistrationv1alpha1.Deny)
} else if validateAction.Audit() {
validationActions = append(validationActions, admissionregistrationv1alpha1.Audit)
validationActions = append(validationActions, admissionregistrationv1alpha1.Warn)
}
}
// set validating admission policy binding spec

View file

@ -17,14 +17,11 @@ func CanGenerateVAP(spec *kyvernov1.Spec) (bool, string) {
return false, msg
}
validationFailureActionOverrides := spec.GetValidationFailureActionOverrides()
if len(validationFailureActionOverrides) > 1 {
msg = "skip generating ValidatingAdmissionPolicy: multiple validationFailureActionOverrides are not applicable."
if ok, msg := checkValidationFailureActionOverrides(spec.ValidationFailureActionOverrides); !ok {
return false, msg
}
if len(validationFailureActionOverrides) != 0 && len(validationFailureActionOverrides[0].Namespaces) != 0 {
msg = "skip generating ValidatingAdmissionPolicy: Namespaces in validationFailureActionOverrides is not applicable."
if ok, msg := checkValidationFailureActionOverrides(rule.Validation.ValidationFailureActionOverrides); !ok {
return false, msg
}
@ -164,3 +161,17 @@ func checkResourceFilter(resFilters kyvernov1.ResourceFilters, isMatch bool) (bo
return true, msg
}
func checkValidationFailureActionOverrides(validationFailureActionOverrides []kyvernov1.ValidationFailureActionOverride) (bool, string) {
var msg string
if len(validationFailureActionOverrides) > 1 {
msg = "skip generating ValidatingAdmissionPolicy: multiple validationFailureActionOverrides are not applicable."
return false, msg
}
if len(validationFailureActionOverrides) != 0 && len(validationFailureActionOverrides[0].Namespaces) != 0 {
msg = "skip generating ValidatingAdmissionPolicy: Namespaces in validationFailureActionOverrides is not applicable."
return false, msg
}
return true, msg
}

View file

@ -114,12 +114,12 @@ func validateJSONPatch(patch string, ruleIdx int) error {
return nil
}
func checkValidationFailureAction(spec *kyvernov1.Spec) []string {
func checkValidationFailureAction(validationFailureAction kyvernov1.ValidationFailureAction, validationFailureActionOverrides []kyvernov1.ValidationFailureActionOverride) []string {
msg := "Validation failure actions enforce/audit are deprecated, use Enforce/Audit instead."
if spec.GetValidationFailureAction() == "enforce" || spec.GetValidationFailureAction() == "audit" {
if validationFailureAction == "enforce" || validationFailureAction == "audit" {
return []string{msg}
}
for _, override := range spec.GetValidationFailureActionOverrides() {
for _, override := range validationFailureActionOverrides {
if override.Action == "enforce" || override.Action == "audit" {
return []string{msg}
}
@ -138,7 +138,14 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
return warnings, fmt.Errorf("custom webhook configurations are only supported in kubernetes version 1.27.0 and above")
}
warnings = append(warnings, checkValidationFailureAction(spec)...)
warnings = append(warnings, checkValidationFailureAction(spec.ValidationFailureAction, spec.ValidationFailureActionOverrides)...)
for _, rule := range spec.Rules {
if rule.HasValidate() {
if rule.Validation.ValidationFailureAction != nil {
warnings = append(warnings, checkValidationFailureAction(*rule.Validation.ValidationFailureAction, rule.Validation.ValidationFailureActionOverrides)...)
}
}
}
var errs field.ErrorList
specPath := field.NewPath("spec")
@ -206,7 +213,15 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
}
if !policy.IsNamespaced() {
err := validateNamespaces(spec, specPath.Child("validationFailureActionOverrides"))
for i, r := range spec.Rules {
if r.HasValidate() {
err := validateNamespaces(r.Validation.ValidationFailureActionOverrides, specPath.Child("rules").Index(i).Child("validate").Child("validationFailureActionOverrides"))
if err != nil {
return warnings, err
}
}
}
err := validateNamespaces(spec.ValidationFailureActionOverrides, specPath.Child("validationFailureActionOverrides"))
if err != nil {
return warnings, err
}
@ -326,12 +341,20 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
if rule.HasVerifyImages() {
isAuditFailureAction := false
if spec.GetValidationFailureAction() == kyvernov1.Audit {
if spec.ValidationFailureAction.Audit() {
isAuditFailureAction = true
}
verifyImagePath := rulePath.Child("verifyImages")
for index, i := range rule.VerifyImages {
action := i.ValidationFailureAction
if action != nil {
if action.Audit() {
isAuditFailureAction = true
} else {
isAuditFailureAction = false
}
}
errs = append(errs, i.Validate(isAuditFailureAction, verifyImagePath.Index(index))...)
}
if len(errs) != 0 {
@ -1538,7 +1561,7 @@ func validateWildcardsWithNamespaces(enforce, audit, enforceW, auditW []string)
return nil
}
func validateNamespaces(s *kyvernov1.Spec, path *field.Path) error {
func validateNamespaces(validationFailureActionOverrides []kyvernov1.ValidationFailureActionOverride, path *field.Path) error {
action := map[string]sets.Set[string]{
"enforce": sets.New[string](),
"audit": sets.New[string](),
@ -1546,7 +1569,7 @@ func validateNamespaces(s *kyvernov1.Spec, path *field.Path) error {
"auditW": sets.New[string](),
}
for i, vfa := range s.GetValidationFailureActionOverrides() {
for i, vfa := range validationFailureActionOverrides {
if !vfa.Action.IsValid() {
return fmt.Errorf("invalid action")
}

View file

@ -141,28 +141,40 @@ func (h *resourceHandlers) Validate(ctx context.Context, logger logr.Logger, req
var ok bool
var msg string
var warnings []string
var enforceResponses []engineapi.EngineResponse
wg.Add(1)
go func() {
defer wg.Done()
ok, msg, warnings = vh.HandleValidationEnforce(ctx, request, policies, startTime)
ok, msg, warnings, enforceResponses = vh.HandleValidationEnforce(ctx, request, policies, startTime)
}()
go h.auditPool.Submit(func() {
vh.HandleValidationAudit(ctx, request)
})
if !admissionutils.IsDryRun(request.AdmissionRequest) {
h.handleBackgroundApplies(ctx, logger, request, generatePolicies, mutatePolicies, startTime, nil)
}
if len(policies) == 0 {
return admissionutils.ResponseSuccess(request.UID)
}
wg.Wait()
if !ok {
logger.Info("admission request denied")
events := webhookutils.GenerateEvents(enforceResponses, true)
h.eventGen.Add(events...)
return admissionutils.Response(request.UID, errors.New(msg), warnings...)
}
go h.auditPool.Submit(func() {
auditResponses := vh.HandleValidationAudit(ctx, request)
var events []event.Info
switch {
case len(auditResponses) == 0:
events = webhookutils.GenerateEvents(enforceResponses, false)
case len(enforceResponses) == 0:
events = webhookutils.GenerateEvents(auditResponses, false)
default:
responses := mergeEngineResponses(auditResponses, enforceResponses)
events = webhookutils.GenerateEvents(responses, false)
}
h.eventGen.Add(events...)
})
return admissionutils.ResponseSuccess(request.UID, warnings...)
}
@ -310,3 +322,34 @@ func filterPolicies(ctx context.Context, failurePolicy string, policies ...kyver
}
return results
}
func mergeEngineResponses(auditResponses, enforceResponses []engineapi.EngineResponse) []engineapi.EngineResponse {
responseMap := make(map[string]engineapi.EngineResponse)
var responses []engineapi.EngineResponse
for _, enforceResponse := range enforceResponses {
responseMap[enforceResponse.Policy().GetName()] = enforceResponse
}
for _, auditResponse := range auditResponses {
policyName := auditResponse.Policy().GetName()
if enforceResponse, exists := responseMap[policyName]; exists {
response := auditResponse
for _, ruleResponse := range enforceResponse.PolicyResponse.Rules {
response.PolicyResponse.Add(ruleResponse.Stats(), ruleResponse)
}
responses = append(responses, response)
delete(responseMap, policyName)
} else {
responses = append(responses, auditResponse)
}
}
if len(responseMap) != 0 {
for _, enforceResponse := range responseMap {
responses = append(responses, enforceResponse)
}
}
return responses
}

View file

@ -31,8 +31,8 @@ type ValidationHandler interface {
// HandleValidation handles validating webhook admission request
// If there are no errors in validating rule we apply generation rules
// patchedResource is the (resource + patches) after applying mutation rules
HandleValidationEnforce(context.Context, handlers.AdmissionRequest, []kyvernov1.PolicyInterface, time.Time) (bool, string, []string)
HandleValidationAudit(context.Context, handlers.AdmissionRequest)
HandleValidationEnforce(context.Context, handlers.AdmissionRequest, []kyvernov1.PolicyInterface, time.Time) (bool, string, []string, []engineapi.EngineResponse)
HandleValidationAudit(context.Context, handlers.AdmissionRequest) []engineapi.EngineResponse
}
func NewValidationHandler(
@ -82,18 +82,18 @@ func (v *validationHandler) HandleValidationEnforce(
request handlers.AdmissionRequest,
policies []kyvernov1.PolicyInterface,
admissionRequestTimestamp time.Time,
) (bool, string, []string) {
) (bool, string, []string, []engineapi.EngineResponse) {
resourceName := admissionutils.GetResourceName(request.AdmissionRequest)
logger := v.log.WithValues("action", "validate", "resource", resourceName, "operation", request.Operation, "gvk", request.Kind)
if len(policies) == 0 {
return true, "", nil
return true, "", nil, nil
}
policyContext, err := v.buildPolicyContextFromAdmissionRequest(logger, request)
if err != nil {
msg := fmt.Sprintf("failed to create policy context: %v", err)
return false, msg, nil
return false, msg, nil, nil
}
var engineResponses []engineapi.EngineResponse
@ -118,7 +118,7 @@ func (v *validationHandler) HandleValidationEnforce(
engineResponses = append(engineResponses, engineResponse)
if !engineResponse.IsSuccessful() {
logger.V(2).Info("validation failed", "action", policy.GetSpec().GetValidationFailureAction(), "policy", policy.GetName(), "failed rules", engineResponse.GetFailedRules())
logger.V(2).Info("validation failed", "action", "Enforce", "policy", policy.GetName(), "failed rules", engineResponse.GetFailedRules())
return
}
@ -130,12 +130,10 @@ func (v *validationHandler) HandleValidationEnforce(
}
blocked := webhookutils.BlockRequest(engineResponses, failurePolicy, logger)
events := webhookutils.GenerateEvents(engineResponses, blocked)
v.eventGen.Add(events...)
if blocked {
logger.V(4).Info("admission request blocked")
return false, webhookutils.GetBlockedMessages(engineResponses), nil
return false, webhookutils.GetBlockedMessages(engineResponses), nil, engineResponses
}
go func() {
@ -147,37 +145,36 @@ func (v *validationHandler) HandleValidationEnforce(
}()
warnings := webhookutils.GetWarningMessages(engineResponses)
return true, "", warnings
return true, "", warnings, engineResponses
}
func (v *validationHandler) HandleValidationAudit(
ctx context.Context,
request handlers.AdmissionRequest,
) {
) []engineapi.EngineResponse {
gvr := schema.GroupVersionResource(request.Resource)
policies := v.pCache.GetPolicies(policycache.ValidateAudit, gvr, request.SubResource, request.Namespace)
if len(policies) == 0 {
return
return nil
}
policyContext, err := v.buildPolicyContextFromAdmissionRequest(v.log, request)
if err != nil {
v.log.Error(err, "failed to build policy context")
return
return nil
}
var responses []engineapi.EngineResponse
needsReport := needsReports(request, policyContext.NewResource(), v.admissionReports)
tracing.Span(
context.Background(),
"",
fmt.Sprintf("AUDIT %s %s", request.Operation, request.Kind),
func(ctx context.Context, span trace.Span) {
responses, err := v.buildAuditResponses(ctx, policyContext, policies)
responses, err = v.buildAuditResponses(ctx, policyContext, policies)
if err != nil {
v.log.Error(err, "failed to build audit responses")
}
events := webhookutils.GenerateEvents(responses, false)
v.eventGen.Add(events...)
if needsReport {
if err := v.createReports(ctx, policyContext.NewResource(), request, responses...); err != nil {
v.log.Error(err, "failed to create report")
@ -186,6 +183,7 @@ func (v *validationHandler) HandleValidationAudit(
},
trace.WithLinks(trace.LinkFromContext(ctx)),
)
return responses
}
func (v *validationHandler) buildAuditResponses(

View file

@ -3,7 +3,6 @@ kind: ClusterPolicy
metadata:
name: enforce-label
spec:
validationFailureAction: Audit
background: false
rules:
- name: enforce-label
@ -13,6 +12,7 @@ spec:
kinds:
- Pod
validate:
validationFailureAction: Audit
message: "The foo label must be set."
pattern:
metadata:

View file

@ -19,12 +19,12 @@ spec:
- Pod
name: validate-image-tag
validate:
validationFailureAction: Audit
message: Using a mutable image tag e.g. 'latest' is not allowed.
pattern:
spec:
containers:
- image: '!*:latest'
validationFailureAction: Audit
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
@ -48,6 +48,7 @@ spec:
operator: NotEquals
value: DELETE
validate:
validationFailureAction: Audit
foreach:
- deny:
conditions:
@ -57,4 +58,3 @@ spec:
value: '{{ element.securityContext.capabilities.drop || '''' }}'
list: request.object.spec.[ephemeralContainers, initContainers, containers][]
message: Containers must drop `ALL` capabilities.
validationFailureAction: Audit

View file

@ -19,6 +19,7 @@ spec:
operator: NotEquals
value: DELETE
validate:
validationFailureAction: Enforce
foreach:
- context:
- imageRegistry:
@ -35,7 +36,6 @@ spec:
value: ghcr.io
list: request.object.spec.containers
message: images with root user are not allowed
validationFailureAction: Enforce
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
@ -57,6 +57,7 @@ spec:
operator: NotEquals
value: DELETE
validate:
validationFailureAction: Enforce
foreach:
- context:
- imageRegistry:
@ -76,4 +77,3 @@ spec:
list: request.object.spec.containers
message: Images must specify a source/base image from which they are built to
be valid.
validationFailureAction: Enforce

View file

@ -14,10 +14,10 @@ spec:
- Pod
name: validate-default-proc-mount
validate:
validationFailureAction: Audit
message: Default proc mount should set to Unmasked
pattern:
spec:
containers:
- securityContext:
procMount: Unmasked
validationFailureAction: Audit

View file

@ -14,6 +14,7 @@ spec:
- Pod
name: validate-selinux-options
validate:
validationFailureAction: Audit
message: SELinux level is required
pattern:
spec:
@ -21,4 +22,3 @@ spec:
- securityContext:
seLinuxOptions:
level: ?*
validationFailureAction: Audit

View file

@ -14,6 +14,7 @@ spec:
- Pod
name: validate-volumes-whitelist
validate:
validationFailureAction: Audit
anyPattern:
- spec:
volumes:
@ -25,4 +26,3 @@ spec:
volumes:
- configMap: '*'
message: Volume type is not of type hostPath, emptyDir, or configMap.
validationFailureAction: Audit

View file

@ -3,7 +3,6 @@ kind: ClusterPolicy
metadata:
name: disallow-host-namespaces
spec:
validationFailureAction: Enforce
background: false
rules:
- name: host-namespaces
@ -13,6 +12,7 @@ spec:
kinds:
- Pod
validate:
validationFailureAction: Enforce
message: >-
Sharing the host namespaces is disallowed. The fields spec.hostNetwork,
spec.hostIPC, and spec.hostPID must be unset or set to `false`.

View file

@ -3,7 +3,6 @@ kind: ClusterPolicy
metadata:
name: max-containers
spec:
validationFailureAction: Enforce
background: false
rules:
- name: max-two-containers
@ -13,6 +12,7 @@ spec:
kinds:
- Pod
validate:
validationFailureAction: Enforce
message: "A maximum of 2 containers are allowed inside a Pod."
deny:
conditions:

View file

@ -4,7 +4,6 @@ metadata:
name: psa
spec:
background: true
validationFailureAction: Enforce
rules:
- name: baseline
match:
@ -13,6 +12,7 @@ spec:
kinds:
- Pod
validate:
validationFailureAction: Enforce
podSecurity:
level: baseline
version: latest

View file

@ -0,0 +1,21 @@
apiVersion: kyverno.io/v2
kind: PolicyException
metadata:
name: delta-exception
namespace: delta
spec:
exceptions:
- policyName: disallow-host-namespaces
ruleNames:
- host-namespaces
- autogen-host-namespaces
match:
any:
- resources:
kinds:
- Pod
- Deployment
namespaces:
- delta
names:
- important-tool*

View file

@ -0,0 +1,29 @@
apiVersion: cli.kyverno.io/v1alpha1
exceptions:
- exception.yaml
kind: Test
metadata:
name: kyverno-test
policies:
- policy.yaml
resources:
- resources.yaml
results:
- kind: Deployment
policy: disallow-host-namespaces
resources:
- bad-deployment
result: fail
rule: autogen-host-namespaces
- kind: Deployment
policy: disallow-host-namespaces
resources:
- good-deployment
result: pass
rule: autogen-host-namespaces
- kind: Deployment
policy: disallow-host-namespaces
resources:
- important-tool
result: skip
rule: autogen-host-namespaces

View file

@ -0,0 +1,23 @@
apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
name: disallow-host-namespaces
spec:
background: false
validationFailureAction: Enforce
rules:
- name: host-namespaces
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
Sharing the host namespaces is disallowed. The fields spec.hostNetwork,
spec.hostIPC, and spec.hostPID must be unset or set to `false`.
pattern:
spec:
=(hostPID): "false"
=(hostIPC): "false"
=(hostNetwork): "false"

View file

@ -0,0 +1,66 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: important-tool
namespace: delta
labels:
app: busybox
spec:
replicas: 1
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox
spec:
hostIPC: true
containers:
- image: busybox:1.35
name: busybox
command: ["sleep", "1d"]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: bad-deployment
labels:
app: busybox
spec:
replicas: 1
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox
spec:
hostIPC: true
containers:
- image: busybox:1.35
name: busybox
command: ["sleep", "1d"]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: good-deployment
labels:
app: busybox
spec:
replicas: 1
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox
spec:
hostIPC: false
containers:
- image: busybox:1.35
name: busybox
command: ["sleep", "1d"]

View file

@ -0,0 +1,15 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: kyverno-test.yaml
policies:
- policy.yaml
resources:
- resources.yaml
results:
- kind: Namespace
policy: restrict-labels
resources:
- kyverno-system-tst
result: fail
rule: restrict-labels

View file

@ -0,0 +1,39 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
annotations:
policies.kyverno.io/category: Labels
policies.kyverno.io/description: This policy prevents the use of an label beginning
with a common key name (in this case "platform.das-schiff.telekom.de/owner |
owner"). This can be useful to ensure users either don't set reserved labels
or to force them to use a newer version of an label.
policies.kyverno.io/minversion: 1.3.0
policies.kyverno.io/title: Restrict Labels on Namespaces
labels:
policy.schiff.telekom.de: enforced
name: restrict-labels
spec:
admission: true
background: false
validationFailureAction: Enforce
rules:
- exclude:
any:
- clusterRoles:
- cluster-admin
resources: {}
match:
any:
- resources:
kinds:
- Namespace
name: restrict-labels
validate:
message: Every namespace has to have `platform.das-schiff.telekom.de/owner`
label. It must not have value `das-schiff` which is reserved for system namespaces
pattern:
metadata:
labels:
=(schiff.telekom.de/owner): '!schiff'
platform.das-schiff.telekom.de/owner: '!das-schiff'

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: Namespace
metadata:
name: kyverno-system-tst
labels:
name: kyverno-system-tst
schiff.telekom.de/owner: schiff
platform.das-schiff.telekom.de/owner: das-schiff

View file

@ -36,4 +36,4 @@ spec:
labels:
=(schiff.telekom.de/owner): '!schiff'
platform.das-schiff.telekom.de/owner: '!das-schiff'
validationFailureAction: Enforce
validationFailureAction: Enforce

View file

@ -21,6 +21,7 @@ spec:
- test
name: require-image-tag
validate:
validationFailureAction: Audit
message: An image tag is required.
pattern:
spec:
@ -40,4 +41,4 @@ spec:
spec:
containers:
- image: '!*:latest'
validationFailureAction: Audit
validationFailureAction: Audit

View file

@ -21,6 +21,7 @@ spec:
- test
name: require-image-tag
validate:
validationFailureAction: Audit
message: An image tag is required.
pattern:
spec:
@ -40,4 +41,4 @@ spec:
spec:
containers:
- image: '!*:latest'
validationFailureAction: Audit
validationFailureAction: Audit

View file

@ -21,6 +21,7 @@ spec:
- test
name: require-image-tag
validate:
validationFailureAction: Audit
message: An image tag is required.
pattern:
spec:
@ -40,4 +41,4 @@ spec:
spec:
containers:
- image: '!*:latest'
validationFailureAction: Audit
validationFailureAction: Audit

View file

@ -38,4 +38,3 @@ spec:
kinds:
- Namespace
name: default-deny
validationFailureAction: Audit

View file

@ -57,4 +57,3 @@ spec:
kinds:
- Namespace
name: generate-limitrange
validationFailureAction: Audit

View file

@ -34,4 +34,3 @@ spec:
kinds:
- Namespace
name: clone-list-labelled-secrets
validationFailureAction: Audit

View file

@ -32,4 +32,3 @@ spec:
kinds:
- Namespace
name: sync-image-pull-secret
validationFailureAction: Audit

View file

@ -80,4 +80,3 @@ spec:
to_string(@)
}}
name: mutate1
validationFailureAction: Enforce

View file

@ -77,4 +77,3 @@ spec:
- key: '{{ tg_attributes }}'
operator: Equals
value: "false"
validationFailureAction: Audit

View file

@ -24,4 +24,3 @@ spec:
+(sizeLimit): 20Mi
name: '{{ element.name }}'
name: setDefault
validationFailureAction: Audit

View file

@ -27,4 +27,3 @@ spec:
op: add
value: "100m"
name: add-default-requests
validationFailureAction: Audit

View file

@ -27,7 +27,6 @@ spec:
- key: '{{ request.operation }}'
operator: Equals
value: CREATE
validationFailureAction: Audit
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
@ -53,4 +52,3 @@ spec:
- image: registry.digitalocean.com/runlevl4/{{ images.containers."{{element.name}}".name}}:{{images.containers."{{element.name}}".tag}}
name: '{{ element.name }}'
name: test
validationFailureAction: Audit

View file

@ -29,4 +29,3 @@ spec:
value:
- CREATE
- UPDATE
validationFailureAction: Audit

View file

@ -43,7 +43,6 @@ spec:
- key: not-the-name
operator: AllIn
value: '{{ request.object.metadata.labels | keys(@) }}'
validationFailureAction: Audit
---
apiVersion: kyverno.io/v1
kind: Policy
@ -75,7 +74,6 @@ spec:
- name: ndots
value: "1"
name: add-ndots
validationFailureAction: Audit
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
@ -104,4 +102,3 @@ spec:
op: replace
value: {{ annotations }}
name: object_from_lists
validationFailureAction: Audit

View file

@ -21,6 +21,7 @@ spec:
- Pod
name: require-image-tag
validate:
validationFailureAction: Audit
message: An image tag is required.
pattern:
spec:
@ -33,9 +34,9 @@ spec:
- Pod
name: validate-image-tag
validate:
validationFailureAction: Audit
message: Using a mutable image tag e.g. 'latest' is not allowed.
pattern:
spec:
containers:
- image: '!*:latest'
validationFailureAction: Audit

View file

@ -0,0 +1,41 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
annotations:
policies.kyverno.io/category: Best Practices
policies.kyverno.io/description: 'The '':latest'' tag is mutable and can lead
to unexpected errors if the image changes. A best practice is to use an immutable
tag that maps to a specific version of an application pod. '
name: disallow-latest-tag
spec:
validationFailureAction: Audit
admission: true
background: false
rules:
- match:
any:
- clusterRoles:
- cluster-admin
resources:
kinds:
- Pod
name: require-image-tag
validate:
message: An image tag is required.
pattern:
spec:
containers:
- image: '*:*'
- match:
any:
- resources:
kinds:
- Pod
name: validate-image-tag
validate:
message: Using a mutable image tag e.g. 'latest' is not allowed.
pattern:
spec:
containers:
- image: '!*:latest'

View file

@ -0,0 +1,26 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: kyverno-test.yaml
policies:
- disallow_latest_tag.yaml
resources:
- resource.yaml
results:
- kind: Pod
policy: disallow-latest-tag
resources:
- myapp-pod1
- myapp-pod2
- myapp-pod3
result: pass
rule: require-image-tag
- kind: Pod
policy: disallow-latest-tag
resources:
- myapp-pod1
- myapp-pod2
- myapp-pod3
result: pass
rule: validate-image-tag
userinfo: user_info.yaml

View file

@ -0,0 +1,34 @@
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod1
labels:
app: myapp1
spec:
containers:
- name: nginx
image: nginx:1.12
---
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod2
labels:
app: myapp2
spec:
containers:
- name: nginx
image: nginx:1.12
---
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod3
labels:
app: myapp3
spec:
containers:
- name: nginx
image: ngnix:1.12

View file

@ -0,0 +1,6 @@
apiVersion: cli.kyverno.io/v1alpha1
clusterRoles:
- cluster-admin
kind: UserInfo
userInfo:
username: molybdenum@somecorp.com

View file

@ -0,0 +1,16 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: kyverno-test.yaml
policies:
- policy.yaml
resources:
- resource.yaml
results:
- kind: Pod
policy: disallow-protected-namespaces
resources:
- namespace2/test2
- namespace1/test1
result: fail
rule: disallow

View file

@ -0,0 +1,22 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-protected-namespaces
spec:
validationFailureAction: Enforce
admission: true
background: false
rules:
- match:
all:
- resources:
kinds:
- '*'
namespaces:
- namespace1
- namespace2
name: disallow
validate:
deny: {}
message: This resource is protected and changes are not allowed.

View file

@ -0,0 +1,31 @@
apiVersion: v1
kind: Pod
metadata:
name: test1
namespace: namespace1
spec:
containers:
- name: nginx
image: nginx:latest
---
apiVersion: v1
kind: Pod
metadata:
name: test2
namespace: namespace2
spec:
containers:
- name: nginx
image: nginx
---
apiVersion: v1
kind: Pod
metadata:
name: test3
namespace: namespace3
spec:
containers:
- name: nginx
image: nginx

View file

@ -17,6 +17,6 @@ spec:
- namespace2
name: disallow
validate:
validationFailureAction: Enforce
deny: {}
message: This resource is protected and changes are not allowed.
validationFailureAction: Enforce

View file

@ -0,0 +1,16 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
name: kyverno-test.yaml
policies:
- policy.yaml
resources:
- resource.yaml
results:
- kind: Pod
policy: enforce-pod-name
resources:
- test1/test-nginx
result: pass
rule: validate-name
variables: value.yaml

View file

@ -0,0 +1,27 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: enforce-pod-name
spec:
validationFailureAction: Audit
admission: true
background: true
rules:
- match:
any:
- resources:
kinds:
- Pod
namespaceSelector:
matchExpressions:
- key: foo.com/managed-state
operator: In
values:
- managed
name: validate-name
validate:
message: The Pod must end with -nginx
pattern:
metadata:
name: '*-nginx'

View file

@ -0,0 +1,9 @@
kind: Pod
apiVersion: v1
metadata:
name: test-nginx
namespace: test1
spec:
containers:
- name: nginx
image: nginx:latest

View file

@ -0,0 +1,6 @@
apiVersion: cli.kyverno.io/v1alpha1
kind: Values
namespaceSelector:
- labels:
foo.com/managed-state: managed
name: test1

View file

@ -20,8 +20,8 @@ spec:
- managed
name: validate-name
validate:
validationFailureAction: Audit
message: The Pod must end with -nginx
pattern:
metadata:
name: '*-nginx'
validationFailureAction: Audit

View file

@ -14,6 +14,7 @@ spec:
- Service
name: check-loadbalancer-public
validate:
validationFailureAction: Enforce
anyPattern:
- metadata:
annotations:
@ -26,4 +27,3 @@ spec:
message: Service of type 'LoadBalancer' is public and does not explicitly define
network security. To use a public LB you must supply either spec[loadBalancerSourceRanges]
or the 'service.beta.kubernetes.io/aws-load-balancer-security-groups' annotation.
validationFailureAction: Enforce

Some files were not shown because too many files have changed in this diff Show more