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:
parent
a32bdf1ac1
commit
c796bb765c
513 changed files with 4473 additions and 718 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -32,4 +32,4 @@ spec:
|
|||
required: true
|
||||
useCache: true
|
||||
verifyDigest: true
|
||||
validationFailureAction: Audit
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -20,4 +20,4 @@ spec:
|
|||
podSecurity:
|
||||
level: restricted
|
||||
version: latest
|
||||
validationFailureAction: Audit
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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...)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>)
|
||||
|
|
|
@ -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 "false" 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>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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": [
|
||||
{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -35,7 +35,6 @@ var policy = `
|
|||
"name": "disallow-unsigned-images"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -180,7 +180,6 @@ func Test_PolicyDeserilize(t *testing.T) {
|
|||
"name": "set-image-pull-policy"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"rules": [
|
||||
{
|
||||
"name": "set-image-pull-policy",
|
||||
|
|
|
@ -655,7 +655,6 @@ func Test_foreach_element_mutation(t *testing.T) {
|
|||
"name": "mutate-privileged"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "audit",
|
||||
"background": false,
|
||||
"webhookTimeoutSeconds": 10,
|
||||
"failurePolicy": "Fail",
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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" : {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*
|
|
@ -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
|
23
test/cli/test-exceptions/exceptions-deprecated/policy.yaml
Normal file
23
test/cli/test-exceptions/exceptions-deprecated/policy.yaml
Normal 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"
|
|
@ -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"]
|
15
test/cli/test-fail/invalid-ns-deprecated/kyverno-test.yaml
Normal file
15
test/cli/test-fail/invalid-ns-deprecated/kyverno-test.yaml
Normal 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
|
39
test/cli/test-fail/invalid-ns-deprecated/policy.yaml
Normal file
39
test/cli/test-fail/invalid-ns-deprecated/policy.yaml
Normal 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'
|
8
test/cli/test-fail/invalid-ns-deprecated/resources.yaml
Normal file
8
test/cli/test-fail/invalid-ns-deprecated/resources.yaml
Normal 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
|
|
@ -36,4 +36,4 @@ spec:
|
|||
labels:
|
||||
=(schiff.telekom.de/owner): '!schiff'
|
||||
platform.das-schiff.telekom.de/owner: '!das-schiff'
|
||||
validationFailureAction: Enforce
|
||||
validationFailureAction: Enforce
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -38,4 +38,3 @@ spec:
|
|||
kinds:
|
||||
- Namespace
|
||||
name: default-deny
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -57,4 +57,3 @@ spec:
|
|||
kinds:
|
||||
- Namespace
|
||||
name: generate-limitrange
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -34,4 +34,3 @@ spec:
|
|||
kinds:
|
||||
- Namespace
|
||||
name: clone-list-labelled-secrets
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -32,4 +32,3 @@ spec:
|
|||
kinds:
|
||||
- Namespace
|
||||
name: sync-image-pull-secret
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -80,4 +80,3 @@ spec:
|
|||
to_string(@)
|
||||
}}
|
||||
name: mutate1
|
||||
validationFailureAction: Enforce
|
||||
|
|
|
@ -77,4 +77,3 @@ spec:
|
|||
- key: '{{ tg_attributes }}'
|
||||
operator: Equals
|
||||
value: "false"
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -24,4 +24,3 @@ spec:
|
|||
+(sizeLimit): 20Mi
|
||||
name: '{{ element.name }}'
|
||||
name: setDefault
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -27,4 +27,3 @@ spec:
|
|||
op: add
|
||||
value: "100m"
|
||||
name: add-default-requests
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -29,4 +29,3 @@ spec:
|
|||
value:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
validationFailureAction: Audit
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
|
@ -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
|
34
test/cli/test/admission_user_info_deprecated/resource.yaml
Normal file
34
test/cli/test/admission_user_info_deprecated/resource.yaml
Normal 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
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
clusterRoles:
|
||||
- cluster-admin
|
||||
kind: UserInfo
|
||||
userInfo:
|
||||
username: molybdenum@somecorp.com
|
16
test/cli/test/any-all-wildcard-deprecated/kyverno-test.yaml
Normal file
16
test/cli/test/any-all-wildcard-deprecated/kyverno-test.yaml
Normal 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
|
22
test/cli/test/any-all-wildcard-deprecated/policy.yaml
Normal file
22
test/cli/test/any-all-wildcard-deprecated/policy.yaml
Normal 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.
|
31
test/cli/test/any-all-wildcard-deprecated/resource.yaml
Normal file
31
test/cli/test/any-all-wildcard-deprecated/resource.yaml
Normal 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
|
|
@ -17,6 +17,6 @@ spec:
|
|||
- namespace2
|
||||
name: disallow
|
||||
validate:
|
||||
validationFailureAction: Enforce
|
||||
deny: {}
|
||||
message: This resource is protected and changes are not allowed.
|
||||
validationFailureAction: Enforce
|
||||
|
|
|
@ -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
|
27
test/cli/test/any-namespaceSelector-deprecated/policy.yaml
Normal file
27
test/cli/test/any-namespaceSelector-deprecated/policy.yaml
Normal 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'
|
|
@ -0,0 +1,9 @@
|
|||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: test-nginx
|
||||
namespace: test1
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Values
|
||||
namespaceSelector:
|
||||
- labels:
|
||||
foo.com/managed-state: managed
|
||||
name: test1
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue