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

feat: add operations support in match/exclude (#6658)

* feat: add operations support in match/exclude

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* clean

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* matching

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* operation

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* make operation mandatory

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* kuttl

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-03-29 06:22:21 +02:00 committed by GitHub
parent 12294dc47b
commit dc8a60a43e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 2722 additions and 86 deletions

View file

@ -5,6 +5,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/variables/regex"
"github.com/sigstore/k8s-manifest-sigstore/pkg/k8smanifest"
admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@ -646,3 +647,14 @@ type DryRunOption struct {
type IgnoreFieldList []ObjectFieldBinding
type ObjectFieldBinding k8smanifest.ObjectFieldBinding
// AdmissionOperation can have one of the values CREATE, UPDATE, CONNECT, DELETE, which are used to match a specific action.
// +kubebuilder:validation:Enum=CREATE;CONNECT;UPDATE;DELETE
type AdmissionOperation admissionv1.Operation
const (
Create AdmissionOperation = AdmissionOperation(admissionv1.Create)
Update AdmissionOperation = AdmissionOperation(admissionv1.Update)
Delete AdmissionOperation = AdmissionOperation(admissionv1.Delete)
Connect AdmissionOperation = AdmissionOperation(admissionv1.Connect)
)

View file

@ -52,7 +52,7 @@ func Test_MatchResources(t *testing.T) {
}},
},
errors: []string{
`dummy: Invalid value: v1.MatchResources{Any:v1.ResourceFilters{v1.ResourceFilter{UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject{v1.Subject{Kind:"ServiceAccount", APIGroup:"", Name:"sa-1", Namespace:"ns"}}}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil)}}}, All:v1.ResourceFilters{v1.ResourceFilter{UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject{v1.Subject{Kind:"ServiceAccount", APIGroup:"", Name:"sa-1", Namespace:"ns"}}}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil)}}}, UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject(nil)}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil)}}: Can't specify any and all together`,
`dummy: Invalid value: v1.MatchResources{Any:v1.ResourceFilters{v1.ResourceFilter{UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject{v1.Subject{Kind:"ServiceAccount", APIGroup:"", Name:"sa-1", Namespace:"ns"}}}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil), Operations:[]v1.AdmissionOperation(nil)}}}, All:v1.ResourceFilters{v1.ResourceFilter{UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject{v1.Subject{Kind:"ServiceAccount", APIGroup:"", Name:"sa-1", Namespace:"ns"}}}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil), Operations:[]v1.AdmissionOperation(nil)}}}, UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject(nil)}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil), Operations:[]v1.AdmissionOperation(nil)}}: Can't specify any and all together`,
},
}}

View file

@ -26,7 +26,7 @@ func Test_ResourceDescription(t *testing.T) {
Names: []string{"bar", "baz"},
},
errors: []string{
`dummy: Invalid value: v1.ResourceDescription{Kinds:[]string(nil), Name:"foo", Names:[]string{"bar", "baz"}, Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil)}: Both name and names can not be specified together`,
`dummy: Invalid value: v1.ResourceDescription{Kinds:[]string(nil), Name:"foo", Names:[]string{"bar", "baz"}, Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil), Operations:[]v1.AdmissionOperation(nil)}: Both name and names can not be specified together`,
},
}, {
name: "selector",

View file

@ -51,6 +51,10 @@ type ResourceDescription struct {
// does not match an empty label set.
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" yaml:"namespaceSelector,omitempty"`
// Operations can contain values ["CREATE, "UPDATE", "CONNECT", "DELETE"], which are used to match a specific action.
// +optional
Operations []AdmissionOperation `json:"operations,omitempty" yaml:"operations,omitempty"`
}
func (r ResourceDescription) IsEmpty() bool {

View file

@ -1007,6 +1007,11 @@ func (in *ResourceDescription) DeepCopyInto(out *ResourceDescription) {
*out = new(metav1.LabelSelector)
(*in).DeepCopyInto(*out)
}
if in.Operations != nil {
in, out := &in.Operations, &out.Operations
*out = make([]AdmissionOperation, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceDescription.

View file

@ -53,7 +53,7 @@ func Test_MatchResources(t *testing.T) {
}},
},
errors: []string{
`dummy: Invalid value: v2beta1.MatchResources{Any:v1.ResourceFilters{v1.ResourceFilter{UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject{v1.Subject{Kind:"ServiceAccount", APIGroup:"", Name:"sa-1", Namespace:"ns"}}}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil)}}}, All:v1.ResourceFilters{v1.ResourceFilter{UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject{v1.Subject{Kind:"ServiceAccount", APIGroup:"", Name:"sa-1", Namespace:"ns"}}}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil)}}}}: Can't specify any and all together`,
`dummy: Invalid value: v2beta1.MatchResources{Any:v1.ResourceFilters{v1.ResourceFilter{UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject{v1.Subject{Kind:"ServiceAccount", APIGroup:"", Name:"sa-1", Namespace:"ns"}}}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil), Operations:[]v1.AdmissionOperation(nil)}}}, All:v1.ResourceFilters{v1.ResourceFilter{UserInfo:v1.UserInfo{Roles:[]string(nil), ClusterRoles:[]string(nil), Subjects:[]v1.Subject{v1.Subject{Kind:"ServiceAccount", APIGroup:"", Name:"sa-1", Namespace:"ns"}}}, ResourceDescription:v1.ResourceDescription{Kinds:[]string(nil), Name:"", Names:[]string(nil), Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil), Operations:[]v1.AdmissionOperation(nil)}}}}: Can't specify any and all together`,
},
}}

View file

@ -25,7 +25,7 @@ func Test_ResourceDescription(t *testing.T) {
Names: []string{"bar", "baz"},
},
errors: []string{
`dummy: Invalid value: v2beta1.ResourceDescription{Kinds:[]string(nil), Names:[]string{"bar", "baz"}, Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil)}: Both name and names can not be specified together`,
`dummy: Invalid value: v2beta1.ResourceDescription{Kinds:[]string(nil), Names:[]string{"bar", "baz"}, Namespaces:[]string(nil), Annotations:map[string]string(nil), Selector:(*v1.LabelSelector)(nil), NamespaceSelector:(*v1.LabelSelector)(nil), Operations:[]v1.AdmissionOperation(nil)}: Both name and names can not be specified together`,
},
}, {
name: "selector",

View file

@ -3,6 +3,7 @@ package v2beta1
import (
"fmt"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
@ -45,6 +46,10 @@ type ResourceDescription struct {
// does not match an empty label set.
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" yaml:"namespaceSelector,omitempty"`
// Operations can contain values ["CREATE, "UPDATE", "CONNECT", "DELETE"], which are used to match a specific action.
// +optional
Operations []kyvernov1.AdmissionOperation `json:"operations,omitempty" yaml:"operations,omitempty"`
}
// Validate implements programmatic validation

View file

@ -318,6 +318,11 @@ func (in *ResourceDescription) DeepCopyInto(out *ResourceDescription) {
*out = new(metav1.LabelSelector)
(*in).DeepCopyInto(*out)
}
if in.Operations != nil {
in, out := &in.Operations, &out.Operations
*out = make([]v1.AdmissionOperation, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceDescription.

File diff suppressed because it is too large Load diff

View file

@ -483,7 +483,7 @@ OuterLoop:
store.ContextLoaderFactory(nil),
nil,
)
policyContext := engine.NewPolicyContextWithJsonContext(ctx).
policyContext := engine.NewPolicyContextWithJsonContext(kyvernov1.Create, ctx).
WithPolicy(c.Policy).
WithNewResource(*updatedResource).
WithNamespaceLabels(namespaceLabels).

View file

@ -241,6 +241,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -444,6 +459,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -654,6 +684,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -857,6 +902,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters

View file

@ -241,6 +241,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -444,6 +459,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -654,6 +684,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -857,6 +902,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters

View file

@ -370,6 +370,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -588,6 +603,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -794,6 +824,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -1160,6 +1205,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -1378,6 +1438,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -1584,6 +1659,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -3615,6 +3705,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -3840,6 +3946,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -4059,6 +4181,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one of
the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the wildcard
@ -4441,6 +4578,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -4666,6 +4819,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -4885,6 +5054,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one of
the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the wildcard
@ -7086,6 +7270,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -7304,6 +7503,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -7678,6 +7892,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -7896,6 +8125,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -10063,6 +10307,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -10288,6 +10548,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -10507,6 +10783,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one of
the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the wildcard
@ -10889,6 +11180,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -11114,6 +11421,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -11333,6 +11656,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one of
the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the wildcard

View file

@ -371,6 +371,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -589,6 +604,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -795,6 +825,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -1161,6 +1206,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -1379,6 +1439,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -1585,6 +1660,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -3617,6 +3707,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -3842,6 +3948,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -4061,6 +4183,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one of
the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the wildcard
@ -4443,6 +4580,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -4668,6 +4821,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -4887,6 +5056,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one of
the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the wildcard
@ -7089,6 +7273,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -7307,6 +7506,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -7681,6 +7895,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -7899,6 +8128,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one
of the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the
@ -10066,6 +10310,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -10291,6 +10551,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -10510,6 +10786,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one of
the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the wildcard
@ -10892,6 +11183,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -11117,6 +11424,22 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values
["CREATE, "UPDATE", "CONNECT", "DELETE"],
which are used to match a specific action.
items:
description: AdmissionOperation can have
one of the values CREATE, UPDATE, CONNECT,
DELETE, which are used to match a specific
action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector.
Label keys and values in `matchLabels` support
@ -11336,6 +11659,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used
to match a specific action.
items:
description: AdmissionOperation can have one of
the values CREATE, UPDATE, CONNECT, DELETE,
which are used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label
keys and values in `matchLabels` support the wildcard

View file

@ -176,6 +176,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters
@ -379,6 +394,21 @@ spec:
items:
type: string
type: array
operations:
description: Operations can contain values ["CREATE,
"UPDATE", "CONNECT", "DELETE"], which are used to
match a specific action.
items:
description: AdmissionOperation can have one of the
values CREATE, UPDATE, CONNECT, DELETE, which are
used to match a specific action.
enum:
- CREATE
- CONNECT
- UPDATE
- DELETE
type: string
type: array
selector:
description: 'Selector is a label selector. Label keys
and values in `matchLabels` support the wildcard characters

File diff suppressed because it is too large Load diff

View file

@ -581,6 +581,16 @@ of deployments across all namespaces.</p>
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v1.AdmissionOperation">AdmissionOperation
(<code>string</code> alias)</p></h3>
<p>
(<em>Appears on:</em>
<a href="#kyverno.io/v1.ResourceDescription">ResourceDescription</a>,
<a href="#kyverno.io/v2beta1.ResourceDescription">ResourceDescription</a>)
</p>
<p>
<p>AdmissionOperation can have one of the values CREATE, UPDATE, CONNECT, DELETE, which are used to match a specific action.</p>
</p>
<h3 id="kyverno.io/v1.AnyAllConditions">AnyAllConditions
</h3>
<p>
@ -2734,6 +2744,20 @@ and <code>?</code> (matches one character).Wildcards allows writing label select
does not match an empty label set.</p>
</td>
</tr>
<tr>
<td>
<code>operations</code><br/>
<em>
<a href="#kyverno.io/v1.AdmissionOperation">
[]AdmissionOperation
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Operations can contain values [&ldquo;CREATE, &ldquo;UPDATE&rdquo;, &ldquo;CONNECT&rdquo;, &ldquo;DELETE&rdquo;], which are used to match a specific action.</p>
</td>
</tr>
</tbody>
</table>
<hr />
@ -6406,6 +6430,20 @@ and <code>?</code> (matches one character).Wildcards allows writing label select
does not match an empty label set.</p>
</td>
</tr>
<tr>
<td>
<code>operations</code><br/>
<em>
<a href="#kyverno.io/v1.AdmissionOperation">
[]AdmissionOperation
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Operations can contain values [&ldquo;CREATE, &ldquo;UPDATE&rdquo;, &ldquo;CONNECT&rdquo;, &ldquo;DELETE&rdquo;], which are used to match a specific action.</p>
</td>
</tr>
</tbody>
</table>
<hr />

View file

@ -75,7 +75,7 @@ func NewBackgroundContext(dclient dclient.Interface, ur *kyvernov1beta1.UpdateRe
logger.Error(err, "unable to add image info to variables context")
}
policyContext := engine.NewPolicyContextWithJsonContext(ctx).
policyContext := engine.NewPolicyContextWithJsonContext(kyvernov1.AdmissionOperation(ur.Spec.Context.AdmissionRequestInfo.Operation), ctx).
WithPolicy(policy).
WithNewResource(*trigger).
WithOldResource(old).

View file

@ -81,7 +81,7 @@ func (s *scanner) validateResource(ctx context.Context, resource unstructured.Un
if err := enginectx.AddOperation("CREATE"); err != nil {
return nil, err
}
policyCtx := engine.NewPolicyContextWithJsonContext(enginectx).
policyCtx := engine.NewPolicyContextWithJsonContext(kyvernov1.Create, enginectx).
WithNewResource(resource).
WithPolicy(policy).
WithNamespaceLabels(nsLabels)
@ -103,7 +103,7 @@ func (s *scanner) validateImages(ctx context.Context, resource unstructured.Unst
if err := enginectx.AddOperation("CREATE"); err != nil {
return nil, err
}
policyCtx := engine.NewPolicyContextWithJsonContext(enginectx).
policyCtx := engine.NewPolicyContextWithJsonContext(kyvernov1.Create, enginectx).
WithNewResource(resource).
WithPolicy(policy).
WithNamespaceLabels(nsLabels)

View file

@ -17,6 +17,7 @@ type PolicyContext interface {
NewResource() unstructured.Unstructured
OldResource() unstructured.Unstructured
AdmissionInfo() kyvernov1beta1.RequestInfo
Operation() kyvernov1.AdmissionOperation
NamespaceLabels() map[string]string
RequestResource() metav1.GroupVersionResource
ResourceKind() (schema.GroupVersionKind, string)

View file

@ -84,10 +84,10 @@ func (e *engine) filterRule(
policy := policyContext.Policy()
gvk, subresource := policyContext.ResourceKind()
if err := engineutils.MatchesResourceDescription(newResource, rule, admissionInfo, namespaceLabels, policy.GetNamespace(), gvk, subresource); err != nil {
if err := engineutils.MatchesResourceDescription(newResource, rule, admissionInfo, namespaceLabels, policy.GetNamespace(), gvk, subresource, policyContext.Operation()); err != nil {
if ruleType == engineapi.Generation {
// if the oldResource matched, return "false" to delete GR for it
if err = engineutils.MatchesResourceDescription(oldResource, rule, admissionInfo, namespaceLabels, policy.GetNamespace(), gvk, subresource); err == nil {
if err = engineutils.MatchesResourceDescription(oldResource, rule, admissionInfo, namespaceLabels, policy.GetNamespace(), gvk, subresource, policyContext.Operation()); err == nil {
return &engineapi.RuleResponse{
Name: rule.Name,
Type: ruleType,

View file

@ -148,6 +148,7 @@ func matches(
policyContext.Policy().GetNamespace(),
gvk,
subresource,
policyContext.Operation(),
)
if err == nil {
return nil
@ -162,6 +163,7 @@ func matches(
policyContext.Policy().GetNamespace(),
gvk,
subresource,
policyContext.Operation(),
)
if err == nil {
return nil

View file

@ -789,7 +789,7 @@ func buildContext(t *testing.T, policy, resource string, oldResource string) eng
err = enginecontext.AddResource(ctx, []byte(resource))
assert.NilError(t, err)
policyContext := policycontext.NewPolicyContextWithJsonContext(ctx).
policyContext := policycontext.NewPolicyContextWithJsonContext(kyvernov1.Create, ctx).
WithPolicy(&cpol).
WithNewResource(*resourceUnstructured)

View file

@ -219,7 +219,7 @@ func buildContext(t *testing.T, policy, resource string, oldResource string) *Po
err = enginecontext.AddResource(ctx, []byte(resource))
assert.NilError(t, err)
policyContext := policycontext.NewPolicyContextWithJsonContext(ctx).
policyContext := policycontext.NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&cpol).
WithNewResource(*resourceUnstructured)

View file

@ -114,7 +114,7 @@ func Test_VariableSubstitutionPatchStrategicMerge(t *testing.T) {
t.Error(err)
}
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured)
@ -187,7 +187,7 @@ func Test_variableSubstitutionPathNotExist(t *testing.T) {
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured)
@ -264,7 +264,7 @@ func Test_variableSubstitutionCLI(t *testing.T) {
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured)
@ -384,7 +384,7 @@ func Test_chained_rules(t *testing.T) {
err = ctx.AddResource(resource.Object)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resource)
@ -472,7 +472,7 @@ func Test_precondition(t *testing.T) {
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured)
@ -566,7 +566,7 @@ func Test_nonZeroIndexNumberPatchesJson6902(t *testing.T) {
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured)
@ -652,7 +652,7 @@ func Test_foreach(t *testing.T) {
err = ctx.AddResource(resource.Object)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resource)
@ -754,7 +754,7 @@ func Test_foreach_element_mutation(t *testing.T) {
err = ctx.AddResource(resource.Object)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resource)
@ -875,7 +875,7 @@ func Test_Container_InitContainer_foreach(t *testing.T) {
err = ctx.AddResource(resource.Object)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resource)
@ -1020,7 +1020,7 @@ func testApplyPolicyToResource(t *testing.T, policyRaw, resourceRaw []byte) engi
err = ctx.AddResource(resource.Object)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resource)
@ -1571,7 +1571,7 @@ func Test_mutate_existing_resources(t *testing.T) {
_, err = dclient.GetResource(context.TODO(), target.GetAPIVersion(), target.GetKind(), target.GetNamespace(), target.GetName())
assert.NilError(t, err)
policyContext = NewPolicyContextWithJsonContext(ctx).
policyContext = NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*trigger)
@ -1678,7 +1678,7 @@ func Test_RuleSelectorMutate(t *testing.T) {
_, err = ctx.Query("request.object.metadata.name")
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured)
@ -2057,7 +2057,7 @@ func Test_SpecialCharacters(t *testing.T) {
}
// Create policy context.
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resource)

View file

@ -33,6 +33,9 @@ type PolicyContext struct {
// admissionInfo contains the admission request information
admissionInfo kyvernov1beta1.RequestInfo
// operation contains the admission operatipn
operation kyvernov1.AdmissionOperation
// requestResource is GVR of the admission request
requestResource metav1.GroupVersionResource
@ -86,6 +89,10 @@ func (c *PolicyContext) AdmissionInfo() kyvernov1beta1.RequestInfo {
return c.admissionInfo
}
func (c *PolicyContext) Operation() kyvernov1.AdmissionOperation {
return c.operation
}
func (c *PolicyContext) NamespaceLabels() map[string]string {
return c.namespaceLabels
}
@ -171,14 +178,15 @@ func (c PolicyContext) copy() *PolicyContext {
// Constructors
func NewPolicyContextWithJsonContext(jsonContext enginectx.Interface) *PolicyContext {
func NewPolicyContextWithJsonContext(operation kyvernov1.AdmissionOperation, jsonContext enginectx.Interface) *PolicyContext {
return &PolicyContext{
operation: operation,
jsonContext: jsonContext,
}
}
func NewPolicyContext() *PolicyContext {
return NewPolicyContextWithJsonContext(enginectx.NewContext())
func NewPolicyContext(operation kyvernov1.AdmissionOperation) *PolicyContext {
return NewPolicyContextWithJsonContext(operation, enginectx.NewContext())
}
func NewPolicyContextFromAdmissionRequest(
@ -202,7 +210,7 @@ func NewPolicyContextFromAdmissionRequest(
if err != nil {
return nil, err
}
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyvernov1.AdmissionOperation(request.Operation), ctx).
WithNewResource(newResource).
WithOldResource(oldResource).
WithAdmissionInfo(admissionInfo).

View file

@ -57,6 +57,7 @@ func doesResourceMatchConditionBlock(
namespaceLabels map[string]string,
gvk schema.GroupVersionKind,
subresource string,
operation kyvernov1.AdmissionOperation,
) []error {
var errs []error
@ -126,6 +127,12 @@ func doesResourceMatchConditionBlock(
}
}
if len(conditionBlock.Operations) > 0 {
if !slices.Contains(conditionBlock.Operations, operation) {
errs = append(errs, fmt.Errorf("operation does not match"))
}
}
var userInfoErrors []error
if len(userInfo.Roles) > 0 {
if !datautils.SliceContains(userInfo.Roles, admissionInfo.Roles...) {
@ -144,6 +151,7 @@ func doesResourceMatchConditionBlock(
userInfoErrors = append(userInfoErrors, fmt.Errorf("user info does not match subject for the given conditionBlock"))
}
}
return append(errs, userInfoErrors...)
}
@ -161,6 +169,7 @@ func MatchesResourceDescription(
policyNamespace string,
gvk schema.GroupVersionKind,
subresource string,
operation kyvernov1.AdmissionOperation,
) error {
if resourceRef.Object == nil {
return fmt.Errorf("resource is empty")
@ -168,7 +177,6 @@ func MatchesResourceDescription(
rule := ruleRef.DeepCopy()
resource := *resourceRef.DeepCopy()
admissionInfo := *admissionInfoRef.DeepCopy()
empty := []string{}
var reasonsForFailure []error
if policyNamespace != "" && policyNamespace != resourceRef.GetNamespace() {
@ -181,7 +189,7 @@ func MatchesResourceDescription(
oneMatched := false
for _, rmr := range rule.MatchResources.Any {
// if there are no errors it means it was a match
if len(matchesResourceDescriptionMatchHelper(rmr, admissionInfo, resource, empty, namespaceLabels, gvk, subresource)) == 0 {
if len(matchesResourceDescriptionMatchHelper(rmr, admissionInfo, resource, namespaceLabels, gvk, subresource, operation)) == 0 {
oneMatched = true
break
}
@ -192,17 +200,17 @@ func MatchesResourceDescription(
} else if len(rule.MatchResources.All) > 0 {
// include object if ALL of the criteria match
for _, rmr := range rule.MatchResources.All {
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionMatchHelper(rmr, admissionInfo, resource, empty, namespaceLabels, gvk, subresource)...)
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionMatchHelper(rmr, admissionInfo, resource, namespaceLabels, gvk, subresource, operation)...)
}
} else {
rmr := kyvernov1.ResourceFilter{UserInfo: rule.MatchResources.UserInfo, ResourceDescription: rule.MatchResources.ResourceDescription}
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionMatchHelper(rmr, admissionInfo, resource, empty, namespaceLabels, gvk, subresource)...)
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionMatchHelper(rmr, admissionInfo, resource, namespaceLabels, gvk, subresource, operation)...)
}
if len(rule.ExcludeResources.Any) > 0 {
// exclude the object if ANY of the criteria match
for _, rer := range rule.ExcludeResources.Any {
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionExcludeHelper(rer, admissionInfo, resource, namespaceLabels, gvk, subresource)...)
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionExcludeHelper(rer, admissionInfo, resource, namespaceLabels, gvk, subresource, operation)...)
}
} else if len(rule.ExcludeResources.All) > 0 {
// exclude the object if ALL the criteria match
@ -210,7 +218,7 @@ func MatchesResourceDescription(
for _, rer := range rule.ExcludeResources.All {
// we got no errors inplying a resource did NOT exclude it
// "matchesResourceDescriptionExcludeHelper" returns errors if resource is excluded by a filter
if len(matchesResourceDescriptionExcludeHelper(rer, admissionInfo, resource, namespaceLabels, gvk, subresource)) == 0 {
if len(matchesResourceDescriptionExcludeHelper(rer, admissionInfo, resource, namespaceLabels, gvk, subresource, operation)) == 0 {
excludedByAll = false
break
}
@ -220,7 +228,7 @@ func MatchesResourceDescription(
}
} else {
rer := kyvernov1.ResourceFilter{UserInfo: rule.ExcludeResources.UserInfo, ResourceDescription: rule.ExcludeResources.ResourceDescription}
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionExcludeHelper(rer, admissionInfo, resource, namespaceLabels, gvk, subresource)...)
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionExcludeHelper(rer, admissionInfo, resource, namespaceLabels, gvk, subresource, operation)...)
}
// creating final error
@ -242,10 +250,10 @@ func matchesResourceDescriptionMatchHelper(
rmr kyvernov1.ResourceFilter,
admissionInfo kyvernov1beta1.RequestInfo,
resource unstructured.Unstructured,
dynamicConfig []string,
namespaceLabels map[string]string,
gvk schema.GroupVersionKind,
subresource string,
operation kyvernov1.AdmissionOperation,
) []error {
var errs []error
if datautils.DeepEqual(admissionInfo, kyvernov1beta1.RequestInfo{}) {
@ -255,7 +263,7 @@ func matchesResourceDescriptionMatchHelper(
// checking if resource matches the rule
if !datautils.DeepEqual(rmr.ResourceDescription, kyvernov1.ResourceDescription{}) ||
!datautils.DeepEqual(rmr.UserInfo, kyvernov1.UserInfo{}) {
matchErrs := doesResourceMatchConditionBlock(rmr.ResourceDescription, rmr.UserInfo, admissionInfo, resource, namespaceLabels, gvk, subresource)
matchErrs := doesResourceMatchConditionBlock(rmr.ResourceDescription, rmr.UserInfo, admissionInfo, resource, namespaceLabels, gvk, subresource, operation)
errs = append(errs, matchErrs...)
} else {
errs = append(errs, fmt.Errorf("match cannot be empty"))
@ -270,12 +278,13 @@ func matchesResourceDescriptionExcludeHelper(
namespaceLabels map[string]string,
gvk schema.GroupVersionKind,
subresource string,
operation kyvernov1.AdmissionOperation,
) []error {
var errs []error
// checking if resource matches the rule
if !datautils.DeepEqual(rer.ResourceDescription, kyvernov1.ResourceDescription{}) ||
!datautils.DeepEqual(rer.UserInfo, kyvernov1.UserInfo{}) {
excludeErrs := doesResourceMatchConditionBlock(rer.ResourceDescription, rer.UserInfo, admissionInfo, resource, namespaceLabels, gvk, subresource)
excludeErrs := doesResourceMatchConditionBlock(rer.ResourceDescription, rer.UserInfo, admissionInfo, resource, namespaceLabels, gvk, subresource, operation)
// it was a match so we want to exclude it
if len(excludeErrs) == 0 {
errs = append(errs, fmt.Errorf("resource excluded since one of the criteria excluded it"))

View file

@ -905,7 +905,7 @@ func TestMatchesResourceDescription(t *testing.T) {
resource, _ := kubeutils.BytesToUnstructured(tc.Resource)
for _, rule := range autogen.ComputeRules(&policy) {
err := MatchesResourceDescription(*resource, rule, tc.AdmissionInfo, nil, "", resource.GroupVersionKind(), "")
err := MatchesResourceDescription(*resource, rule, tc.AdmissionInfo, nil, "", resource.GroupVersionKind(), "", "CREATE")
if err != nil {
if !tc.areErrorsExpected {
t.Errorf("Testcase %d Unexpected error: %v\nmsg: %s", i+1, err, tc.Description)
@ -1810,7 +1810,7 @@ func TestMatchesResourceDescription_GenerateName(t *testing.T) {
resource, _ := kubeutils.BytesToUnstructured(tc.Resource)
for _, rule := range autogen.ComputeRules(&policy) {
err := MatchesResourceDescription(*resource, rule, tc.AdmissionInfo, nil, "", resource.GroupVersionKind(), "")
err := MatchesResourceDescription(*resource, rule, tc.AdmissionInfo, nil, "", resource.GroupVersionKind(), "", "CREATE")
if err != nil {
if !tc.areErrorsExpected {
t.Errorf("Testcase %d Unexpected error: %v\nmsg: %s", i+1, err, tc.Description)
@ -1877,7 +1877,7 @@ func TestResourceDescriptionMatch_MultipleKind(t *testing.T) {
}
rule := v1.Rule{MatchResources: v1.MatchResources{ResourceDescription: resourceDescription}}
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), ""); err != nil {
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err != nil {
t.Errorf("Testcase has failed due to the following:%v", err)
}
}
@ -1980,7 +1980,7 @@ func TestResourceDescriptionMatch_ExcludeDefaultGroups(t *testing.T) {
}
// First test: confirm that this above rule produces errors (and raise an error if err == nil)
if err := MatchesResourceDescription(*resource, rule, requestInfo, nil, "", resource.GroupVersionKind(), ""); err == nil {
if err := MatchesResourceDescription(*resource, rule, requestInfo, nil, "", resource.GroupVersionKind(), "", "CREATE"); err == nil {
t.Error("Testcase was expected to fail, but err was nil")
}
@ -2000,7 +2000,7 @@ func TestResourceDescriptionMatch_ExcludeDefaultGroups(t *testing.T) {
}
// Second test: confirm that matching this rule does not create any errors (and raise if err != nil)
if err := MatchesResourceDescription(*resource, rule2, requestInfo, nil, "", resource.GroupVersionKind(), ""); err != nil {
if err := MatchesResourceDescription(*resource, rule2, requestInfo, nil, "", resource.GroupVersionKind(), "", "CREATE"); err != nil {
t.Errorf("Testcase was expected to not fail, but err was %s", err)
}
@ -2014,7 +2014,7 @@ func TestResourceDescriptionMatch_ExcludeDefaultGroups(t *testing.T) {
}}
// Third test: confirm that now the custom exclude-snippet should run in CheckSubjects() and that should result in this rule failing (raise if err == nil for that reason)
if err := MatchesResourceDescription(*resource, rule2, requestInfo, nil, "", resource.GroupVersionKind(), ""); err == nil {
if err := MatchesResourceDescription(*resource, rule2, requestInfo, nil, "", resource.GroupVersionKind(), "", "CREATE"); err == nil {
t.Error("Testcase was expected to fail, but err was nil #1!")
}
}
@ -2073,7 +2073,7 @@ func TestResourceDescriptionMatch_Name(t *testing.T) {
}
rule := v1.Rule{MatchResources: v1.MatchResources{ResourceDescription: resourceDescription}}
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), ""); err != nil {
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err != nil {
t.Errorf("Testcase has failed due to the following:%v", err)
}
}
@ -2131,7 +2131,7 @@ func TestResourceDescriptionMatch_GenerateName(t *testing.T) {
}
rule := v1.Rule{MatchResources: v1.MatchResources{ResourceDescription: resourceDescription}}
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), ""); err != nil {
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err != nil {
t.Errorf("Testcase has failed due to the following:%v", err)
}
}
@ -2190,7 +2190,7 @@ func TestResourceDescriptionMatch_Name_Regex(t *testing.T) {
}
rule := v1.Rule{MatchResources: v1.MatchResources{ResourceDescription: resourceDescription}}
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), ""); err != nil {
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err != nil {
t.Errorf("Testcase has failed due to the following:%v", err)
}
}
@ -2248,7 +2248,7 @@ func TestResourceDescriptionMatch_GenerateName_Regex(t *testing.T) {
}
rule := v1.Rule{MatchResources: v1.MatchResources{ResourceDescription: resourceDescription}}
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), ""); err != nil {
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err != nil {
t.Errorf("Testcase has failed due to the following:%v", err)
}
}
@ -2315,7 +2315,7 @@ func TestResourceDescriptionMatch_Label_Expression_NotMatch(t *testing.T) {
}
rule := v1.Rule{MatchResources: v1.MatchResources{ResourceDescription: resourceDescription}}
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), ""); err != nil {
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err != nil {
t.Errorf("Testcase has failed due to the following:%v", err)
}
}
@ -2383,7 +2383,7 @@ func TestResourceDescriptionMatch_Label_Expression_Match(t *testing.T) {
}
rule := v1.Rule{MatchResources: v1.MatchResources{ResourceDescription: resourceDescription}}
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), ""); err != nil {
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err != nil {
t.Errorf("Testcase has failed due to the following:%v", err)
}
}
@ -2464,7 +2464,7 @@ func TestResourceDescriptionExclude_Label_Expression_Match(t *testing.T) {
ExcludeResources: v1.MatchResources{ResourceDescription: resourceDescriptionExclude},
}
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), ""); err == nil {
if err := MatchesResourceDescription(*resource, rule, v1beta1.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err == nil {
t.Errorf("Testcase has failed due to the following:\n Function has returned no error, even though it was supposed to fail")
}
}

View file

@ -135,7 +135,7 @@ func TestValidate_image_tag_fail(t *testing.T) {
"validation error: imagePullPolicy 'Always' required with tag 'latest'. rule validate-latest failed at path /spec/containers/0/imagePullPolicy/",
}
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
for index, r := range er.PolicyResponse.Rules {
assert.Equal(t, r.Message, msgs[index])
}
@ -235,7 +235,7 @@ func TestValidate_image_tag_pass(t *testing.T) {
"validation rule 'validate-tag' passed.",
"validation rule 'validate-latest' passed.",
}
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
for index, r := range er.PolicyResponse.Rules {
assert.Equal(t, r.Message, msgs[index])
}
@ -309,7 +309,7 @@ func TestValidate_Fail_anyPattern(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
assert.Assert(t, !er.IsSuccessful())
msgs := []string{"validation error: A namespace is required. rule check-default-namespace[0] failed at path /metadata/namespace/ rule check-default-namespace[1] failed at path /metadata/namespace/"}
@ -392,7 +392,7 @@ func TestValidate_host_network_port(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation error: Host network and port are not allowed. rule validate-host-network-port failed at path /spec/containers/0/ports/0/hostPort/"}
for index, r := range er.PolicyResponse.Rules {
@ -482,7 +482,7 @@ func TestValidate_anchor_arraymap_pass(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation rule 'validate-host-path' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -570,7 +570,7 @@ func TestValidate_anchor_arraymap_fail(t *testing.T) {
assert.NilError(t, err)
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation error: Host path '/var/lib/' is not allowed. rule validate-host-path failed at path /spec/volumes/0/hostPath/path/"}
for index, r := range er.PolicyResponse.Rules {
@ -640,7 +640,7 @@ func TestValidate_anchor_map_notfound(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation rule 'pod rule 2' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -713,7 +713,7 @@ func TestValidate_anchor_map_found_valid(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation rule 'pod rule 2' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -787,7 +787,7 @@ func TestValidate_inequality_List_Processing(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation rule 'pod rule 2' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -867,7 +867,7 @@ func TestValidate_inequality_List_ProcessingBrackets(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation rule 'pod rule 2' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -941,7 +941,7 @@ func TestValidate_anchor_map_found_invalid(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation error: pod: validate run as non root user. rule pod rule 2 failed at path /spec/securityContext/runAsNonRoot/"}
for index, r := range er.PolicyResponse.Rules {
@ -1016,7 +1016,7 @@ func TestValidate_AnchorList_pass(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation rule 'pod image rule' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -1091,7 +1091,7 @@ func TestValidate_AnchorList_fail(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
assert.Assert(t, !er.IsSuccessful())
}
@ -1161,7 +1161,7 @@ func TestValidate_existenceAnchor_fail(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
assert.Assert(t, !er.IsSuccessful())
}
@ -1231,7 +1231,7 @@ func TestValidate_existenceAnchor_pass(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation rule 'pod image rule' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -1319,7 +1319,7 @@ func TestValidate_negationAnchor_deny(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation error: Host path is not allowed. rule validate-host-path failed at path /spec/volumes/0/hostPath/"}
for index, r := range er.PolicyResponse.Rules {
@ -1406,7 +1406,7 @@ func TestValidate_negationAnchor_pass(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
msgs := []string{"validation rule 'validate-host-path' passed."}
for index, r := range er.PolicyResponse.Rules {
@ -1478,7 +1478,7 @@ func Test_VariableSubstitutionPathNotExistInPattern(t *testing.T) {
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
@ -1568,7 +1568,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_OnePatternStatisfiesButSu
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
@ -1626,7 +1626,7 @@ func Test_VariableSubstitution_NotOperatorWithStringVariable(t *testing.T) {
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "validation error: rule not-operator-with-variable-should-alway-fail-validation failed at path /spec/content/")
@ -1714,7 +1714,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathNotPresent(t *test
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
@ -1804,7 +1804,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathPresent_NonePatter
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
@ -1906,7 +1906,7 @@ func Test_VariableSubstitutionValidate_VariablesInMessageAreResolved(t *testing.
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "The animal cow is not in the allowed list of animals.")
@ -1956,7 +1956,7 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
err = enginecontext.AddResource(ctx, test.resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, nil)
for i, rule := range er.PolicyResponse.Rules {
@ -2115,7 +2115,7 @@ func executeTest(t *testing.T, test testCase) {
t.Fatal(err)
}
pc := NewPolicyContextWithJsonContext(ctx).
pc := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(newR).
WithOldResource(oldR).
@ -2204,7 +2204,7 @@ func TestValidate_context_variable_substitution_CLI(t *testing.T) {
er := testValidate(
context.TODO(),
registryclient.NewOrDie(),
NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured),
NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured),
cfg,
enginetest.ContextLoaderFactory(
nil,
@ -2310,7 +2310,7 @@ func Test_EmptyStringInDenyCondition(t *testing.T) {
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(),
NewPolicyContextWithJsonContext(ctx).
NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured),
cfg, nil)
@ -2403,7 +2403,7 @@ func Test_StringInDenyCondition(t *testing.T) {
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(),
NewPolicyContextWithJsonContext(ctx).
NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured),
cfg, nil)
@ -3082,7 +3082,7 @@ func testForEach(t *testing.T, policyraw []byte, resourceRaw []byte, msg string,
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContext := NewPolicyContextWithJsonContext(ctx).
policyContext := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured)
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg, contextLoader)
@ -3144,7 +3144,7 @@ func Test_delete_ignore_pattern(t *testing.T) {
err = enginecontext.AddResource(ctx, resourceRaw)
assert.NilError(t, err)
policyContextCreate := NewPolicyContextWithJsonContext(ctx).
policyContextCreate := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithNewResource(*resourceUnstructured)
@ -3152,7 +3152,7 @@ func Test_delete_ignore_pattern(t *testing.T) {
assert.Equal(t, len(engineResponseCreate.PolicyResponse.Rules), 1)
assert.Equal(t, engineResponseCreate.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
policyContextDelete := NewPolicyContextWithJsonContext(ctx).
policyContextDelete := NewPolicyContextWithJsonContext(kyverno.Create, ctx).
WithPolicy(&policy).
WithOldResource(*resourceUnstructured)
@ -3215,7 +3215,7 @@ func Test_ValidatePattern_anyPattern(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(tc.rawResource)
assert.NilError(t, err)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
if tc.expectedFailed {
assert.Assert(t, er.IsFailed())
} else if tc.expectedSkipped {

View file

@ -1064,7 +1064,7 @@ func TestValidate_failure_action_overrides(t *testing.T) {
resourceUnstructured, err := kubeutils.BytesToUnstructured(tc.rawResource)
assert.NilError(t, err)
ctx := engine.NewPolicyContext().WithPolicy(&policy).WithNewResource(*resourceUnstructured).WithNamespaceLabels(tc.rawResourceNamespaceLabels)
ctx := engine.NewPolicyContext(kyvernov1.Create).WithPolicy(&policy).WithNewResource(*resourceUnstructured).WithNamespaceLabels(tc.rawResourceNamespaceLabels)
er := eng.Validate(
context.TODO(),
ctx,
@ -1126,7 +1126,7 @@ func Test_RuleSelector(t *testing.T) {
assert.NilError(t, err)
assert.Assert(t, resourceUnstructured != nil)
ctx := engine.NewPolicyContext().WithPolicy(&policy).WithNewResource(*resourceUnstructured)
ctx := engine.NewPolicyContext(kyvernov1.Create).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
eng := engine.NewEngine(
config.NewDefaultConfiguration(),

View file

@ -0,0 +1,6 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- policy.yaml
assert:
- policy-assert.yaml

View file

@ -0,0 +1,6 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- file: pod-create.yaml
- file: pod-update.yaml
shouldFail: true

View file

@ -0,0 +1,8 @@
## Description
This test creates a policy to deny pod updates.
It then creates a pod and updates it.
## Expected Behavior
The pod should create fine but the update should be rejected.

View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

View file

@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: foo
labels:
xxx: yyy
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: test
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,18 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: test
spec:
validationFailureAction: Enforce
background: false
rules:
- name: test
match:
any:
- resources:
kinds:
- Pod
operations:
- UPDATE
validate:
deny: {}