mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-13 19:28:55 +00:00
feat: support select namespace by label (#4461)
Signed-off-by: Eileen <eileenylj@gmail.com> Reconstruct ValidationFailureActionOverrides - Add `NamespaceSelector` - Generate relative manifests - Rewrite namespace matching logic in engineResponse - Add test cases for validatetionFailureActionOverrides - (WIP) Set Enforce as default
This commit is contained in:
parent
b1a2a287e7
commit
0a19556a79
13 changed files with 38878 additions and 30086 deletions
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/toggle"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
@ -28,10 +29,16 @@ func (a ValidationFailureAction) Audit() bool {
|
|||
return !a.Enforce()
|
||||
}
|
||||
|
||||
func (a ValidationFailureAction) IsValid() bool {
|
||||
// ValidationFailureAction should either be enforce / audit
|
||||
return a.Enforce() || a.Audit()
|
||||
}
|
||||
|
||||
type ValidationFailureActionOverride struct {
|
||||
// +kubebuilder:validation:Enum=audit;enforce;Audit;Enforce
|
||||
Action ValidationFailureAction `json:"action,omitempty" yaml:"action,omitempty"`
|
||||
Namespaces []string `json:"namespaces,omitempty" yaml:"namespaces,omitempty"`
|
||||
Action ValidationFailureAction `json:"action,omitempty" yaml:"action,omitempty"`
|
||||
Namespaces []string `json:"namespaces,omitempty" yaml:"namespaces,omitempty"`
|
||||
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" yaml:"namespaceSelector,omitempty"`
|
||||
}
|
||||
|
||||
// Spec contains a list of Rule instances and other policy controls.
|
||||
|
|
|
@ -1496,6 +1496,11 @@ func (in *ValidationFailureActionOverride) DeepCopyInto(out *ValidationFailureAc
|
|||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.NamespaceSelector != nil {
|
||||
in, out := &in.NamespaceSelector, &out.NamespaceSelector
|
||||
*out = new(metav1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidationFailureActionOverride.
|
||||
|
|
|
@ -6665,6 +6665,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
@ -13025,6 +13073,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
@ -19868,6 +19964,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
@ -26230,6 +26374,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
|
|
@ -3263,6 +3263,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
@ -9623,6 +9671,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
|
|
@ -3264,6 +3264,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
@ -9626,6 +9674,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
|
|
@ -6738,6 +6738,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
@ -13098,6 +13146,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
@ -19943,6 +20039,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
@ -26305,6 +26449,54 @@ spec:
|
|||
- Audit
|
||||
- Enforce
|
||||
type: string
|
||||
namespaceSelector:
|
||||
description: A label selector is a label query over a set of
|
||||
resources. The result of matchLabels and matchExpressions
|
||||
are ANDed. An empty label selector matches all objects. A
|
||||
null label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
namespaces:
|
||||
items:
|
||||
type: string
|
||||
|
|
File diff suppressed because it is too large
Load diff
3782
docs/crd/v1/index.html
Normal file
3782
docs/crd/v1/index.html
Normal file
File diff suppressed because it is too large
Load diff
|
@ -4013,6 +4013,18 @@ ValidationFailureAction
|
|||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>namespaceSelector</code><br/>
|
||||
<em>
|
||||
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#labelselector-v1-meta">
|
||||
Kubernetes meta/v1.LabelSelector
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
pssutils "github.com/kyverno/kyverno/pkg/pss/utils"
|
||||
utils "github.com/kyverno/kyverno/pkg/utils/match"
|
||||
"github.com/kyverno/kyverno/pkg/utils/wildcard"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
@ -23,6 +24,9 @@ type EngineResponse struct {
|
|||
|
||||
// Policy Response
|
||||
PolicyResponse PolicyResponse
|
||||
|
||||
// NamespaceLabels given by policy context
|
||||
NamespaceLabels map[string]string
|
||||
}
|
||||
|
||||
// PolicyResponse policy application response
|
||||
|
@ -248,16 +252,36 @@ func (er EngineResponse) getRules(predicate func(RuleStatus) bool) []string {
|
|||
|
||||
func (er *EngineResponse) GetValidationFailureAction() kyvernov1.ValidationFailureAction {
|
||||
for _, v := range er.PolicyResponse.ValidationFailureActionOverrides {
|
||||
for _, ns := range v.Namespaces {
|
||||
if wildcard.Match(ns, er.PatchedResource.GetNamespace()) {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return er.PolicyResponse.ValidationFailureAction
|
||||
}
|
||||
|
||||
type ValidationFailureActionOverride struct {
|
||||
Action kyvernov1.ValidationFailureAction `json:"action"`
|
||||
Namespaces []string `json:"namespaces"`
|
||||
Action kyvernov1.ValidationFailureAction `json:"action"`
|
||||
Namespaces []string `json:"namespaces,omitempty"`
|
||||
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" yaml:"namespaceSelector,omitempty"`
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ func Validate(ctx context.Context, rclient registryclient.Client, policyContext
|
|||
}()
|
||||
|
||||
resp = validateResource(ctx, logger, rclient, policyContext, cfg)
|
||||
resp.NamespaceLabels = policyContext.namespaceLabels
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -89,7 +90,8 @@ func buildResponse(ctx *PolicyContext, resp *response.EngineResponse, startTime
|
|||
resp.PolicyResponse.ValidationFailureAction = ctx.policy.GetSpec().ValidationFailureAction
|
||||
|
||||
for _, v := range ctx.policy.GetSpec().ValidationFailureActionOverrides {
|
||||
resp.PolicyResponse.ValidationFailureActionOverrides = append(resp.PolicyResponse.ValidationFailureActionOverrides, response.ValidationFailureActionOverride{Action: v.Action, Namespaces: v.Namespaces})
|
||||
newOverrides := response.ValidationFailureActionOverride{Action: v.Action, Namespaces: v.Namespaces, NamespaceSelector: v.NamespaceSelector}
|
||||
resp.PolicyResponse.ValidationFailureActionOverrides = append(resp.PolicyResponse.ValidationFailureActionOverrides, newOverrides)
|
||||
}
|
||||
|
||||
resp.PolicyResponse.ProcessingTime = time.Since(startTime)
|
||||
|
|
|
@ -8,6 +8,10 @@ import (
|
|||
)
|
||||
|
||||
func CheckSelector(expected *metav1.LabelSelector, actual map[string]string) (bool, error) {
|
||||
if expected == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
wildcards.ReplaceInSelector(expected, actual)
|
||||
selector, err := metav1.LabelSelectorAsSelector(expected)
|
||||
if err != nil {
|
||||
|
|
|
@ -19,10 +19,11 @@ import (
|
|||
|
||||
func TestValidate_failure_action_overrides(t *testing.T) {
|
||||
testcases := []struct {
|
||||
rawPolicy []byte
|
||||
rawResource []byte
|
||||
blocked bool
|
||||
messages map[string]string
|
||||
rawPolicy []byte
|
||||
rawResource []byte
|
||||
blocked bool
|
||||
messages map[string]string
|
||||
rawResourceNamespaceLabels map[string]string
|
||||
}{
|
||||
{
|
||||
rawPolicy: []byte(`
|
||||
|
@ -521,6 +522,531 @@ func TestValidate_failure_action_overrides(t *testing.T) {
|
|||
"check-label-app": "validation error: The label 'app' is required. rule check-label-app failed at path /metadata/labels/",
|
||||
},
|
||||
},
|
||||
{
|
||||
rawPolicy: []byte(`
|
||||
{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "check-label-app"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"validationFailureActionOverrides":
|
||||
[
|
||||
{
|
||||
"action": "audit",
|
||||
"namespaces": [
|
||||
"dev"
|
||||
],
|
||||
"namespaceSelector": {
|
||||
"matchExpressions": [{
|
||||
"key" : "kubernetes.io/metadata.name",
|
||||
"operator": "In",
|
||||
"values": [
|
||||
"prod"
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"name": "check-label-app",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"message": "The label 'app' is required.",
|
||||
"pattern": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app": "?*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
rawResource: []byte(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "test-pod",
|
||||
"namespace": "default"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"image": "nginx:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
blocked: true,
|
||||
messages: map[string]string{
|
||||
"check-label-app": "validation error: The label 'app' is required. rule check-label-app failed at path /metadata/labels/",
|
||||
},
|
||||
},
|
||||
{
|
||||
rawPolicy: []byte(`
|
||||
{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "check-label-app"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"validationFailureActionOverrides":
|
||||
[
|
||||
{
|
||||
"action": "audit",
|
||||
"namespaceSelector": {
|
||||
"matchExpressions": [{
|
||||
"key" : "kubernetes.io/metadata.name",
|
||||
"operator": "In",
|
||||
"values": [
|
||||
"prod"
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"name": "check-label-app",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"message": "The label 'app' is required.",
|
||||
"pattern": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app": "?*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
rawResource: []byte(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "test-pod",
|
||||
"namespace": "prod"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"image": "nginx:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
blocked: false,
|
||||
rawResourceNamespaceLabels: map[string]string{
|
||||
"kubernetes.io/metadata.name": "prod",
|
||||
},
|
||||
},
|
||||
{
|
||||
rawPolicy: []byte(`
|
||||
{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "check-label-app"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"validationFailureActionOverrides":
|
||||
[
|
||||
{
|
||||
"action": "audit",
|
||||
"namespaceSelector": {
|
||||
"matchExpressions": [{
|
||||
"key" : "kubernetes.io/metadata.name",
|
||||
"operator": "In",
|
||||
"values": [
|
||||
"prod"
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"name": "check-label-app",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"message": "The label 'app' is required.",
|
||||
"pattern": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app": "?*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
rawResource: []byte(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "test-pod",
|
||||
"namespace": "default"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"image": "nginx:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
blocked: true,
|
||||
messages: map[string]string{
|
||||
"check-label-app": "validation error: The label 'app' is required. rule check-label-app failed at path /metadata/labels/",
|
||||
},
|
||||
},
|
||||
{
|
||||
rawPolicy: []byte(`
|
||||
{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "check-label-app"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"validationFailureActionOverrides":
|
||||
[
|
||||
{
|
||||
"action": "audit",
|
||||
"namespaces": [
|
||||
"dev"
|
||||
],
|
||||
"namespaceSelector": {
|
||||
"matchExpressions": [{
|
||||
"key" : "kubernetes.io/metadata.name",
|
||||
"operator": "In",
|
||||
"values": [
|
||||
"prod"
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"name": "check-label-app",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"message": "The label 'app' is required.",
|
||||
"pattern": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app": "?*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
rawResource: []byte(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "test-pod",
|
||||
"namespace": "dev"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"image": "nginx:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
blocked: true,
|
||||
rawResourceNamespaceLabels: map[string]string{
|
||||
"kubernetes.io/metadata.name": "dev",
|
||||
},
|
||||
},
|
||||
{
|
||||
rawPolicy: []byte(`
|
||||
{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "check-label-app"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"validationFailureActionOverrides":
|
||||
[
|
||||
{
|
||||
"action": "audit",
|
||||
"namespaces": [
|
||||
"dev"
|
||||
],
|
||||
"namespaceSelector": {
|
||||
"matchExpressions": [{
|
||||
"key" : "kubernetes.io/metadata.name",
|
||||
"operator": "In",
|
||||
"values": [
|
||||
"prod"
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"name": "check-label-app",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"message": "The label 'app' is required.",
|
||||
"pattern": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app": "?*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
rawResource: []byte(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "test-pod",
|
||||
"namespace": "prod"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"image": "nginx:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
blocked: true,
|
||||
rawResourceNamespaceLabels: map[string]string{
|
||||
"kubernetes.io/metadata.name": "prod",
|
||||
},
|
||||
},
|
||||
{
|
||||
rawPolicy: []byte(`
|
||||
{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "check-label-app"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "audit",
|
||||
"validationFailureActionOverrides":
|
||||
[
|
||||
{
|
||||
"action": "enforce",
|
||||
"namespaces": [
|
||||
"dev"
|
||||
],
|
||||
"namespaceSelector": {
|
||||
"matchExpressions": [{
|
||||
"key" : "kubernetes.io/metadata.name",
|
||||
"operator": "In",
|
||||
"values": [
|
||||
"prod"
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"name": "check-label-app",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"message": "The label 'app' is required.",
|
||||
"pattern": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app": "?*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
rawResource: []byte(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "test-pod",
|
||||
"namespace": "dev"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"image": "nginx:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
blocked: false,
|
||||
rawResourceNamespaceLabels: map[string]string{
|
||||
"kubernetes.io/metadata.name": "dev",
|
||||
},
|
||||
}, {
|
||||
rawPolicy: []byte(`
|
||||
{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "check-label-app"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "audit",
|
||||
"validationFailureActionOverrides":
|
||||
[
|
||||
{
|
||||
"action": "enforce",
|
||||
"namespaces": [
|
||||
"dev"
|
||||
],
|
||||
"namespaceSelector": {
|
||||
"matchExpressions": [{
|
||||
"key" : "kubernetes.io/metadata.name",
|
||||
"operator": "In",
|
||||
"values": [
|
||||
"dev"
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"name": "check-label-app",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"message": "The label 'app' is required.",
|
||||
"pattern": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app": "?*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
rawResource: []byte(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "test-pod",
|
||||
"namespace": "dev"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"image": "nginx:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`),
|
||||
blocked: true,
|
||||
rawResourceNamespaceLabels: map[string]string{
|
||||
"kubernetes.io/metadata.name": "dev",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cfg := config.NewDefaultConfiguration()
|
||||
|
@ -535,7 +1061,7 @@ func TestValidate_failure_action_overrides(t *testing.T) {
|
|||
er := engine.Validate(
|
||||
context.TODO(),
|
||||
registryclient.NewOrDie(),
|
||||
engine.NewPolicyContext().WithPolicy(&policy).WithNewResource(*resourceUnstructured),
|
||||
engine.NewPolicyContext().WithPolicy(&policy).WithNewResource(*resourceUnstructured).WithNamespaceLabels(tc.rawResourceNamespaceLabels),
|
||||
cfg,
|
||||
)
|
||||
if tc.blocked && tc.messages != nil {
|
||||
|
|
Loading…
Add table
Reference in a new issue