mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
adding any/all under match and exclude blocks (#2130)
* intial commit Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * update types Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * updated all type Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * extract to single struct Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * updated match resource description function Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * minor test working Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * match resources test is working Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * exclude resources test is working Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * changed double negetive in logic Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * yamls updated and added validation and cache loops Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * match exclude working but need to fix matchExcludeConflict function Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * restored doMatchAndExcludeConflict function Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * rewrote the matchExcludeConflictFunction Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * finalizing completed till utils_test.go Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * ready for review complete Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * update yamls Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * one more merge conflict solved Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * regenerates YAMLs Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * possible fix for failing tests Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * removed duplicate any/all logic and added a test, (rest refacotring is in progress) Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * cache test is working Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * improved cache test and it is working Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * added check for mutate and generate policies too Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * cleaned doesResourceMatchConditionBlock logic but validation still has code from attempt to combine the all block Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * reverted validate.go to older logic Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * removed commented code Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com> * removed extra comments Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com>
This commit is contained in:
parent
a3dfe3c647
commit
97eaa7e854
12 changed files with 11806 additions and 1123 deletions
File diff suppressed because it is too large
Load diff
|
@ -117,6 +117,436 @@ spec:
|
|||
information (e.g. kind, name, namespace, labels) and admission
|
||||
review request information like the name or role.
|
||||
properties:
|
||||
all:
|
||||
description: All allows specifying resources which will
|
||||
be ANDed
|
||||
items:
|
||||
description: ResourceFilters allow users to "AND" or "OR"
|
||||
between resources
|
||||
properties:
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide
|
||||
role names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: ResourceDescription contains information
|
||||
about the resource being created or modified.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Annotations is a map of annotations
|
||||
(key-value pairs of type string). Annotation
|
||||
keys and values support the wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(matches at least one character).
|
||||
type: object
|
||||
kinds:
|
||||
description: Kinds is a list of resource kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name is the name of the resource.
|
||||
The name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character).
|
||||
type: string
|
||||
names:
|
||||
description: 'Names are the names of the resources.
|
||||
Each name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character). NOTE: "Name" is being deprecated
|
||||
in favor of "Names".'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector
|
||||
for the resource namespace. Label keys and values
|
||||
in `matchLabels` support the wildcard characters
|
||||
`*` (matches zero or many characters) and `?`
|
||||
(matches one character).Wildcards allows writing
|
||||
label selectors like ["storage.k8s.io/*": "*"].
|
||||
Note that using ["*" : "*"] matches any key
|
||||
and value but does not match an empty label
|
||||
set.'
|
||||
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
|
||||
namespaces:
|
||||
description: Namespaces is a list of namespaces
|
||||
names. Each name supports wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(at least one character).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
selector:
|
||||
description: 'Selector is a label selector. Label
|
||||
keys and values in `matchLabels` support the
|
||||
wildcard characters `*` (matches zero or many
|
||||
characters) and `?` (matches one character).
|
||||
Wildcards allows writing label selectors like
|
||||
["storage.k8s.io/*": "*"]. Note that using ["*"
|
||||
: "*"] matches any key and value but does not
|
||||
match an empty label set.'
|
||||
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
|
||||
type: object
|
||||
roles:
|
||||
description: Roles is the list of namespaced role
|
||||
names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
description: Subjects is the list of subject names
|
||||
like users, user groups, and service accounts.
|
||||
items:
|
||||
description: Subject contains a reference to the
|
||||
object or user identities a role binding applies
|
||||
to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as
|
||||
user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of
|
||||
the referenced subject. Defaults to "" for
|
||||
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced.
|
||||
Values defined by this API group are "User",
|
||||
"Group", and "ServiceAccount". If the Authorizer
|
||||
does not recognized the kind value, the Authorizer
|
||||
should report an error.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If
|
||||
the object kind is non-namespace, such as
|
||||
"User" or "Group", and this value is not empty
|
||||
the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
any:
|
||||
description: Any allows specifying resources which will
|
||||
be ORed
|
||||
items:
|
||||
description: ResourceFilters allow users to "AND" or "OR"
|
||||
between resources
|
||||
properties:
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide
|
||||
role names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: ResourceDescription contains information
|
||||
about the resource being created or modified.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Annotations is a map of annotations
|
||||
(key-value pairs of type string). Annotation
|
||||
keys and values support the wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(matches at least one character).
|
||||
type: object
|
||||
kinds:
|
||||
description: Kinds is a list of resource kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name is the name of the resource.
|
||||
The name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character).
|
||||
type: string
|
||||
names:
|
||||
description: 'Names are the names of the resources.
|
||||
Each name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character). NOTE: "Name" is being deprecated
|
||||
in favor of "Names".'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector
|
||||
for the resource namespace. Label keys and values
|
||||
in `matchLabels` support the wildcard characters
|
||||
`*` (matches zero or many characters) and `?`
|
||||
(matches one character).Wildcards allows writing
|
||||
label selectors like ["storage.k8s.io/*": "*"].
|
||||
Note that using ["*" : "*"] matches any key
|
||||
and value but does not match an empty label
|
||||
set.'
|
||||
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
|
||||
namespaces:
|
||||
description: Namespaces is a list of namespaces
|
||||
names. Each name supports wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(at least one character).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
selector:
|
||||
description: 'Selector is a label selector. Label
|
||||
keys and values in `matchLabels` support the
|
||||
wildcard characters `*` (matches zero or many
|
||||
characters) and `?` (matches one character).
|
||||
Wildcards allows writing label selectors like
|
||||
["storage.k8s.io/*": "*"]. Note that using ["*"
|
||||
: "*"] matches any key and value but does not
|
||||
match an empty label set.'
|
||||
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
|
||||
type: object
|
||||
roles:
|
||||
description: Roles is the list of namespaced role
|
||||
names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
description: Subjects is the list of subject names
|
||||
like users, user groups, and service accounts.
|
||||
items:
|
||||
description: Subject contains a reference to the
|
||||
object or user identities a role binding applies
|
||||
to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as
|
||||
user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of
|
||||
the referenced subject. Defaults to "" for
|
||||
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced.
|
||||
Values defined by this API group are "User",
|
||||
"Group", and "ServiceAccount". If the Authorizer
|
||||
does not recognized the kind value, the Authorizer
|
||||
should report an error.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If
|
||||
the object kind is non-namespace, such as
|
||||
"User" or "Group", and this value is not empty
|
||||
the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide role
|
||||
names for the user.
|
||||
|
@ -360,6 +790,436 @@ spec:
|
|||
request information like the user name or role. At least one
|
||||
kind is required.
|
||||
properties:
|
||||
all:
|
||||
description: All allows specifying resources which will
|
||||
be ANDed
|
||||
items:
|
||||
description: ResourceFilters allow users to "AND" or "OR"
|
||||
between resources
|
||||
properties:
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide
|
||||
role names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: ResourceDescription contains information
|
||||
about the resource being created or modified.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Annotations is a map of annotations
|
||||
(key-value pairs of type string). Annotation
|
||||
keys and values support the wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(matches at least one character).
|
||||
type: object
|
||||
kinds:
|
||||
description: Kinds is a list of resource kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name is the name of the resource.
|
||||
The name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character).
|
||||
type: string
|
||||
names:
|
||||
description: 'Names are the names of the resources.
|
||||
Each name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character). NOTE: "Name" is being deprecated
|
||||
in favor of "Names".'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector
|
||||
for the resource namespace. Label keys and values
|
||||
in `matchLabels` support the wildcard characters
|
||||
`*` (matches zero or many characters) and `?`
|
||||
(matches one character).Wildcards allows writing
|
||||
label selectors like ["storage.k8s.io/*": "*"].
|
||||
Note that using ["*" : "*"] matches any key
|
||||
and value but does not match an empty label
|
||||
set.'
|
||||
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
|
||||
namespaces:
|
||||
description: Namespaces is a list of namespaces
|
||||
names. Each name supports wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(at least one character).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
selector:
|
||||
description: 'Selector is a label selector. Label
|
||||
keys and values in `matchLabels` support the
|
||||
wildcard characters `*` (matches zero or many
|
||||
characters) and `?` (matches one character).
|
||||
Wildcards allows writing label selectors like
|
||||
["storage.k8s.io/*": "*"]. Note that using ["*"
|
||||
: "*"] matches any key and value but does not
|
||||
match an empty label set.'
|
||||
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
|
||||
type: object
|
||||
roles:
|
||||
description: Roles is the list of namespaced role
|
||||
names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
description: Subjects is the list of subject names
|
||||
like users, user groups, and service accounts.
|
||||
items:
|
||||
description: Subject contains a reference to the
|
||||
object or user identities a role binding applies
|
||||
to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as
|
||||
user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of
|
||||
the referenced subject. Defaults to "" for
|
||||
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced.
|
||||
Values defined by this API group are "User",
|
||||
"Group", and "ServiceAccount". If the Authorizer
|
||||
does not recognized the kind value, the Authorizer
|
||||
should report an error.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If
|
||||
the object kind is non-namespace, such as
|
||||
"User" or "Group", and this value is not empty
|
||||
the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
any:
|
||||
description: Any allows specifying resources which will
|
||||
be ORed
|
||||
items:
|
||||
description: ResourceFilters allow users to "AND" or "OR"
|
||||
between resources
|
||||
properties:
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide
|
||||
role names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: ResourceDescription contains information
|
||||
about the resource being created or modified.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Annotations is a map of annotations
|
||||
(key-value pairs of type string). Annotation
|
||||
keys and values support the wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(matches at least one character).
|
||||
type: object
|
||||
kinds:
|
||||
description: Kinds is a list of resource kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name is the name of the resource.
|
||||
The name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character).
|
||||
type: string
|
||||
names:
|
||||
description: 'Names are the names of the resources.
|
||||
Each name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character). NOTE: "Name" is being deprecated
|
||||
in favor of "Names".'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector
|
||||
for the resource namespace. Label keys and values
|
||||
in `matchLabels` support the wildcard characters
|
||||
`*` (matches zero or many characters) and `?`
|
||||
(matches one character).Wildcards allows writing
|
||||
label selectors like ["storage.k8s.io/*": "*"].
|
||||
Note that using ["*" : "*"] matches any key
|
||||
and value but does not match an empty label
|
||||
set.'
|
||||
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
|
||||
namespaces:
|
||||
description: Namespaces is a list of namespaces
|
||||
names. Each name supports wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(at least one character).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
selector:
|
||||
description: 'Selector is a label selector. Label
|
||||
keys and values in `matchLabels` support the
|
||||
wildcard characters `*` (matches zero or many
|
||||
characters) and `?` (matches one character).
|
||||
Wildcards allows writing label selectors like
|
||||
["storage.k8s.io/*": "*"]. Note that using ["*"
|
||||
: "*"] matches any key and value but does not
|
||||
match an empty label set.'
|
||||
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
|
||||
type: object
|
||||
roles:
|
||||
description: Roles is the list of namespaced role
|
||||
names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
description: Subjects is the list of subject names
|
||||
like users, user groups, and service accounts.
|
||||
items:
|
||||
description: Subject contains a reference to the
|
||||
object or user identities a role binding applies
|
||||
to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as
|
||||
user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of
|
||||
the referenced subject. Defaults to "" for
|
||||
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced.
|
||||
Values defined by this API group are "User",
|
||||
"Group", and "ServiceAccount". If the Authorizer
|
||||
does not recognized the kind value, the Authorizer
|
||||
should report an error.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If
|
||||
the object kind is non-namespace, such as
|
||||
"User" or "Group", and this value is not empty
|
||||
the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide role
|
||||
names for the user.
|
||||
|
@ -687,8 +1547,9 @@ spec:
|
|||
ruleStatus:
|
||||
description: Rules provides per rule statistics
|
||||
items:
|
||||
description: RuleStats provides statistics for an individual rule
|
||||
within a policy.
|
||||
description: 'RuleStats provides statistics for an individual rule
|
||||
within a policy. Deprecated. Policy metrics are now available
|
||||
via the "/metrics" endpoint. See: https://kyverno.io/docs/monitoring-kyverno-with-prometheus-metrics/'
|
||||
properties:
|
||||
appliedCount:
|
||||
description: AppliedCount is the total number of times this
|
||||
|
|
|
@ -118,6 +118,436 @@ spec:
|
|||
information (e.g. kind, name, namespace, labels) and admission
|
||||
review request information like the name or role.
|
||||
properties:
|
||||
all:
|
||||
description: All allows specifying resources which will
|
||||
be ANDed
|
||||
items:
|
||||
description: ResourceFilters allow users to "AND" or "OR"
|
||||
between resources
|
||||
properties:
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide
|
||||
role names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: ResourceDescription contains information
|
||||
about the resource being created or modified.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Annotations is a map of annotations
|
||||
(key-value pairs of type string). Annotation
|
||||
keys and values support the wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(matches at least one character).
|
||||
type: object
|
||||
kinds:
|
||||
description: Kinds is a list of resource kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name is the name of the resource.
|
||||
The name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character).
|
||||
type: string
|
||||
names:
|
||||
description: 'Names are the names of the resources.
|
||||
Each name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character). NOTE: "Name" is being deprecated
|
||||
in favor of "Names".'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector
|
||||
for the resource namespace. Label keys and values
|
||||
in `matchLabels` support the wildcard characters
|
||||
`*` (matches zero or many characters) and `?`
|
||||
(matches one character).Wildcards allows writing
|
||||
label selectors like ["storage.k8s.io/*": "*"].
|
||||
Note that using ["*" : "*"] matches any key
|
||||
and value but does not match an empty label
|
||||
set.'
|
||||
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
|
||||
namespaces:
|
||||
description: Namespaces is a list of namespaces
|
||||
names. Each name supports wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(at least one character).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
selector:
|
||||
description: 'Selector is a label selector. Label
|
||||
keys and values in `matchLabels` support the
|
||||
wildcard characters `*` (matches zero or many
|
||||
characters) and `?` (matches one character).
|
||||
Wildcards allows writing label selectors like
|
||||
["storage.k8s.io/*": "*"]. Note that using ["*"
|
||||
: "*"] matches any key and value but does not
|
||||
match an empty label set.'
|
||||
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
|
||||
type: object
|
||||
roles:
|
||||
description: Roles is the list of namespaced role
|
||||
names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
description: Subjects is the list of subject names
|
||||
like users, user groups, and service accounts.
|
||||
items:
|
||||
description: Subject contains a reference to the
|
||||
object or user identities a role binding applies
|
||||
to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as
|
||||
user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of
|
||||
the referenced subject. Defaults to "" for
|
||||
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced.
|
||||
Values defined by this API group are "User",
|
||||
"Group", and "ServiceAccount". If the Authorizer
|
||||
does not recognized the kind value, the Authorizer
|
||||
should report an error.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If
|
||||
the object kind is non-namespace, such as
|
||||
"User" or "Group", and this value is not empty
|
||||
the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
any:
|
||||
description: Any allows specifying resources which will
|
||||
be ORed
|
||||
items:
|
||||
description: ResourceFilters allow users to "AND" or "OR"
|
||||
between resources
|
||||
properties:
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide
|
||||
role names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: ResourceDescription contains information
|
||||
about the resource being created or modified.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Annotations is a map of annotations
|
||||
(key-value pairs of type string). Annotation
|
||||
keys and values support the wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(matches at least one character).
|
||||
type: object
|
||||
kinds:
|
||||
description: Kinds is a list of resource kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name is the name of the resource.
|
||||
The name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character).
|
||||
type: string
|
||||
names:
|
||||
description: 'Names are the names of the resources.
|
||||
Each name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character). NOTE: "Name" is being deprecated
|
||||
in favor of "Names".'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector
|
||||
for the resource namespace. Label keys and values
|
||||
in `matchLabels` support the wildcard characters
|
||||
`*` (matches zero or many characters) and `?`
|
||||
(matches one character).Wildcards allows writing
|
||||
label selectors like ["storage.k8s.io/*": "*"].
|
||||
Note that using ["*" : "*"] matches any key
|
||||
and value but does not match an empty label
|
||||
set.'
|
||||
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
|
||||
namespaces:
|
||||
description: Namespaces is a list of namespaces
|
||||
names. Each name supports wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(at least one character).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
selector:
|
||||
description: 'Selector is a label selector. Label
|
||||
keys and values in `matchLabels` support the
|
||||
wildcard characters `*` (matches zero or many
|
||||
characters) and `?` (matches one character).
|
||||
Wildcards allows writing label selectors like
|
||||
["storage.k8s.io/*": "*"]. Note that using ["*"
|
||||
: "*"] matches any key and value but does not
|
||||
match an empty label set.'
|
||||
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
|
||||
type: object
|
||||
roles:
|
||||
description: Roles is the list of namespaced role
|
||||
names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
description: Subjects is the list of subject names
|
||||
like users, user groups, and service accounts.
|
||||
items:
|
||||
description: Subject contains a reference to the
|
||||
object or user identities a role binding applies
|
||||
to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as
|
||||
user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of
|
||||
the referenced subject. Defaults to "" for
|
||||
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced.
|
||||
Values defined by this API group are "User",
|
||||
"Group", and "ServiceAccount". If the Authorizer
|
||||
does not recognized the kind value, the Authorizer
|
||||
should report an error.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If
|
||||
the object kind is non-namespace, such as
|
||||
"User" or "Group", and this value is not empty
|
||||
the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide role
|
||||
names for the user.
|
||||
|
@ -361,6 +791,436 @@ spec:
|
|||
request information like the user name or role. At least one
|
||||
kind is required.
|
||||
properties:
|
||||
all:
|
||||
description: All allows specifying resources which will
|
||||
be ANDed
|
||||
items:
|
||||
description: ResourceFilters allow users to "AND" or "OR"
|
||||
between resources
|
||||
properties:
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide
|
||||
role names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: ResourceDescription contains information
|
||||
about the resource being created or modified.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Annotations is a map of annotations
|
||||
(key-value pairs of type string). Annotation
|
||||
keys and values support the wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(matches at least one character).
|
||||
type: object
|
||||
kinds:
|
||||
description: Kinds is a list of resource kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name is the name of the resource.
|
||||
The name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character).
|
||||
type: string
|
||||
names:
|
||||
description: 'Names are the names of the resources.
|
||||
Each name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character). NOTE: "Name" is being deprecated
|
||||
in favor of "Names".'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector
|
||||
for the resource namespace. Label keys and values
|
||||
in `matchLabels` support the wildcard characters
|
||||
`*` (matches zero or many characters) and `?`
|
||||
(matches one character).Wildcards allows writing
|
||||
label selectors like ["storage.k8s.io/*": "*"].
|
||||
Note that using ["*" : "*"] matches any key
|
||||
and value but does not match an empty label
|
||||
set.'
|
||||
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
|
||||
namespaces:
|
||||
description: Namespaces is a list of namespaces
|
||||
names. Each name supports wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(at least one character).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
selector:
|
||||
description: 'Selector is a label selector. Label
|
||||
keys and values in `matchLabels` support the
|
||||
wildcard characters `*` (matches zero or many
|
||||
characters) and `?` (matches one character).
|
||||
Wildcards allows writing label selectors like
|
||||
["storage.k8s.io/*": "*"]. Note that using ["*"
|
||||
: "*"] matches any key and value but does not
|
||||
match an empty label set.'
|
||||
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
|
||||
type: object
|
||||
roles:
|
||||
description: Roles is the list of namespaced role
|
||||
names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
description: Subjects is the list of subject names
|
||||
like users, user groups, and service accounts.
|
||||
items:
|
||||
description: Subject contains a reference to the
|
||||
object or user identities a role binding applies
|
||||
to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as
|
||||
user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of
|
||||
the referenced subject. Defaults to "" for
|
||||
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced.
|
||||
Values defined by this API group are "User",
|
||||
"Group", and "ServiceAccount". If the Authorizer
|
||||
does not recognized the kind value, the Authorizer
|
||||
should report an error.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If
|
||||
the object kind is non-namespace, such as
|
||||
"User" or "Group", and this value is not empty
|
||||
the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
any:
|
||||
description: Any allows specifying resources which will
|
||||
be ORed
|
||||
items:
|
||||
description: ResourceFilters allow users to "AND" or "OR"
|
||||
between resources
|
||||
properties:
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide
|
||||
role names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: ResourceDescription contains information
|
||||
about the resource being created or modified.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Annotations is a map of annotations
|
||||
(key-value pairs of type string). Annotation
|
||||
keys and values support the wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(matches at least one character).
|
||||
type: object
|
||||
kinds:
|
||||
description: Kinds is a list of resource kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name is the name of the resource.
|
||||
The name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character).
|
||||
type: string
|
||||
names:
|
||||
description: 'Names are the names of the resources.
|
||||
Each name supports wildcard characters "*" (matches
|
||||
zero or many characters) and "?" (at least one
|
||||
character). NOTE: "Name" is being deprecated
|
||||
in favor of "Names".'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector
|
||||
for the resource namespace. Label keys and values
|
||||
in `matchLabels` support the wildcard characters
|
||||
`*` (matches zero or many characters) and `?`
|
||||
(matches one character).Wildcards allows writing
|
||||
label selectors like ["storage.k8s.io/*": "*"].
|
||||
Note that using ["*" : "*"] matches any key
|
||||
and value but does not match an empty label
|
||||
set.'
|
||||
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
|
||||
namespaces:
|
||||
description: Namespaces is a list of namespaces
|
||||
names. Each name supports wildcard characters
|
||||
"*" (matches zero or many characters) and "?"
|
||||
(at least one character).
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
selector:
|
||||
description: 'Selector is a label selector. Label
|
||||
keys and values in `matchLabels` support the
|
||||
wildcard characters `*` (matches zero or many
|
||||
characters) and `?` (matches one character).
|
||||
Wildcards allows writing label selectors like
|
||||
["storage.k8s.io/*": "*"]. Note that using ["*"
|
||||
: "*"] matches any key and value but does not
|
||||
match an empty label set.'
|
||||
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
|
||||
type: object
|
||||
roles:
|
||||
description: Roles is the list of namespaced role
|
||||
names for the user.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
description: Subjects is the list of subject names
|
||||
like users, user groups, and service accounts.
|
||||
items:
|
||||
description: Subject contains a reference to the
|
||||
object or user identities a role binding applies
|
||||
to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as
|
||||
user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of
|
||||
the referenced subject. Defaults to "" for
|
||||
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced.
|
||||
Values defined by this API group are "User",
|
||||
"Group", and "ServiceAccount". If the Authorizer
|
||||
does not recognized the kind value, the Authorizer
|
||||
should report an error.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If
|
||||
the object kind is non-namespace, such as
|
||||
"User" or "Group", and this value is not empty
|
||||
the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
clusterRoles:
|
||||
description: ClusterRoles is the list of cluster-wide role
|
||||
names for the user.
|
||||
|
@ -667,7 +1527,8 @@ spec:
|
|||
type: string
|
||||
type: object
|
||||
status:
|
||||
description: Status contains policy runtime information.
|
||||
description: Status contains policy runtime information. Deprecated. Policy
|
||||
metrics are available via the metrics endpoint
|
||||
properties:
|
||||
averageExecutionTime:
|
||||
description: AvgExecutionTime is the average time taken to process
|
||||
|
@ -688,8 +1549,9 @@ spec:
|
|||
ruleStatus:
|
||||
description: Rules provides per rule statistics
|
||||
items:
|
||||
description: RuleStats provides statistics for an individual rule
|
||||
within a policy.
|
||||
description: 'RuleStats provides statistics for an individual rule
|
||||
within a policy. Deprecated. Policy metrics are now available
|
||||
via the "/metrics" endpoint. See: https://kyverno.io/docs/monitoring-kyverno-with-prometheus-metrics/'
|
||||
properties:
|
||||
appliedCount:
|
||||
description: AppliedCount is the total number of times this
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -220,18 +220,35 @@ const (
|
|||
// MatchResources is used to specify resource and admission review request data for
|
||||
// which a policy rule is applicable.
|
||||
type MatchResources struct {
|
||||
// Any allows specifying resources which will be ORed
|
||||
// +optional
|
||||
Any ResourceFilters `json:"any,omitempty" yaml:"any,omitempty"`
|
||||
|
||||
// All allows specifying resources which will be ANDed
|
||||
// +optional
|
||||
All ResourceFilters `json:"all,omitempty" yaml:"all,omitempty"`
|
||||
|
||||
// UserInfo contains information about the user performing the operation.
|
||||
// +optional
|
||||
UserInfo `json:",omitempty" yaml:",omitempty"`
|
||||
|
||||
// ResourceDescription contains information about the resource being created or modified.
|
||||
// Requires at least one tag to be specified when under MatchResources.
|
||||
// +optional
|
||||
ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
|
||||
}
|
||||
|
||||
// ExcludeResources specifies resource and admission review request data for
|
||||
// which a policy rule is not applicable.
|
||||
type ExcludeResources struct {
|
||||
// Any allows specifying resources which will be ORed
|
||||
// +optional
|
||||
Any ResourceFilters `json:"any,omitempty" yaml:"any,omitempty"`
|
||||
|
||||
// All allows specifying resources which will be ANDed
|
||||
// +optional
|
||||
All ResourceFilters `json:"all,omitempty" yaml:"all,omitempty"`
|
||||
|
||||
// UserInfo contains information about the user performing the operation.
|
||||
// +optional
|
||||
UserInfo `json:",omitempty" yaml:",omitempty"`
|
||||
|
@ -241,6 +258,18 @@ type ExcludeResources struct {
|
|||
ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
|
||||
}
|
||||
|
||||
type ResourceFilters []ResourceFilter
|
||||
|
||||
// ResourceFilters allow users to "AND" or "OR" between resources
|
||||
type ResourceFilter struct {
|
||||
// UserInfo contains information about the user performing the operation.
|
||||
// +optional
|
||||
UserInfo `json:",omitempty" yaml:",omitempty"`
|
||||
|
||||
// ResourceDescription contains information about the resource being created or modified.
|
||||
ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
|
||||
}
|
||||
|
||||
// UserInfo contains information about the user performing the operation.
|
||||
type UserInfo struct {
|
||||
// Roles is the list of namespaced role names for the user.
|
||||
|
|
|
@ -263,27 +263,52 @@ func MatchesResourceDescription(resourceRef unstructured.Unstructured, ruleRef k
|
|||
admissionInfo := *admissionInfoRef.DeepCopy()
|
||||
|
||||
var reasonsForFailure []error
|
||||
|
||||
if reflect.DeepEqual(admissionInfo, kyverno.RequestInfo{}) {
|
||||
rule.MatchResources.UserInfo = kyverno.UserInfo{}
|
||||
}
|
||||
|
||||
// checking if resource matches the rule
|
||||
if !reflect.DeepEqual(rule.MatchResources.ResourceDescription, kyverno.ResourceDescription{}) ||
|
||||
!reflect.DeepEqual(rule.MatchResources.UserInfo, kyverno.UserInfo{}) {
|
||||
matchErrs := doesResourceMatchConditionBlock(rule.MatchResources.ResourceDescription, rule.MatchResources.UserInfo, admissionInfo, resource, dynamicConfig, namespaceLabels)
|
||||
reasonsForFailure = append(reasonsForFailure, matchErrs...)
|
||||
} else {
|
||||
reasonsForFailure = append(reasonsForFailure, fmt.Errorf("match cannot be empty"))
|
||||
}
|
||||
|
||||
// checking if resource has been excluded
|
||||
if !reflect.DeepEqual(rule.ExcludeResources.ResourceDescription, kyverno.ResourceDescription{}) ||
|
||||
!reflect.DeepEqual(rule.ExcludeResources.UserInfo, kyverno.UserInfo{}) {
|
||||
excludeErrs := doesResourceMatchConditionBlock(rule.ExcludeResources.ResourceDescription, rule.ExcludeResources.UserInfo, admissionInfo, resource, dynamicConfig, namespaceLabels)
|
||||
if excludeErrs == nil {
|
||||
reasonsForFailure = append(reasonsForFailure, fmt.Errorf("resource excluded"))
|
||||
if len(rule.MatchResources.Any) > 0 {
|
||||
// inlcude object if ANY of the criterias match
|
||||
// so if one matches then break from loop
|
||||
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, dynamicConfig, namespaceLabels)) == 0 {
|
||||
oneMatched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !oneMatched {
|
||||
reasonsForFailure = append(reasonsForFailure, fmt.Errorf("no resource matched"))
|
||||
}
|
||||
} else if len(rule.MatchResources.All) > 0 {
|
||||
// include object if ALL of the criterias match
|
||||
for _, rmr := range rule.MatchResources.All {
|
||||
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionMatchHelper(rmr, admissionInfo, resource, dynamicConfig, namespaceLabels)...)
|
||||
}
|
||||
} else {
|
||||
rmr := kyverno.ResourceFilter{UserInfo: rule.MatchResources.UserInfo, ResourceDescription: rule.MatchResources.ResourceDescription}
|
||||
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionMatchHelper(rmr, admissionInfo, resource, dynamicConfig, namespaceLabels)...)
|
||||
}
|
||||
|
||||
if len(rule.ExcludeResources.Any) > 0 {
|
||||
// exclude the object if ANY of the criterias match
|
||||
for _, rer := range rule.ExcludeResources.Any {
|
||||
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionExcludeHelper(rer, admissionInfo, resource, dynamicConfig, namespaceLabels)...)
|
||||
}
|
||||
} else if len(rule.ExcludeResources.All) > 0 {
|
||||
// exlcude the object if ALL the criterias match
|
||||
excludedByAll := true
|
||||
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, dynamicConfig, namespaceLabels)) == 0 {
|
||||
excludedByAll = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if excludedByAll {
|
||||
reasonsForFailure = append(reasonsForFailure, fmt.Errorf("resource excluded since the combination of all criterias exclude it"))
|
||||
}
|
||||
} else {
|
||||
rer := kyverno.ResourceFilter{UserInfo: rule.ExcludeResources.UserInfo, ResourceDescription: rule.ExcludeResources.ResourceDescription}
|
||||
reasonsForFailure = append(reasonsForFailure, matchesResourceDescriptionExcludeHelper(rer, admissionInfo, resource, dynamicConfig, namespaceLabels)...)
|
||||
}
|
||||
|
||||
// creating final error
|
||||
|
@ -301,6 +326,39 @@ func MatchesResourceDescription(resourceRef unstructured.Unstructured, ruleRef k
|
|||
return nil
|
||||
}
|
||||
|
||||
func matchesResourceDescriptionMatchHelper(rmr kyverno.ResourceFilter, admissionInfo kyverno.RequestInfo, resource unstructured.Unstructured, dynamicConfig []string, namespaceLabels map[string]string) []error {
|
||||
var errs []error
|
||||
if reflect.DeepEqual(admissionInfo, kyverno.RequestInfo{}) {
|
||||
rmr.UserInfo = kyverno.UserInfo{}
|
||||
}
|
||||
|
||||
// checking if resource matches the rule
|
||||
if !reflect.DeepEqual(rmr.ResourceDescription, kyverno.ResourceDescription{}) ||
|
||||
!reflect.DeepEqual(rmr.UserInfo, kyverno.UserInfo{}) {
|
||||
matchErrs := doesResourceMatchConditionBlock(rmr.ResourceDescription, rmr.UserInfo, admissionInfo, resource, dynamicConfig, namespaceLabels)
|
||||
errs = append(errs, matchErrs...)
|
||||
} else {
|
||||
errs = append(errs, fmt.Errorf("match cannot be empty"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func matchesResourceDescriptionExcludeHelper(rer kyverno.ResourceFilter, admissionInfo kyverno.RequestInfo, resource unstructured.Unstructured, dynamicConfig []string, namespaceLabels map[string]string) []error {
|
||||
var errs []error
|
||||
// checking if resource matches the rule
|
||||
if !reflect.DeepEqual(rer.ResourceDescription, kyverno.ResourceDescription{}) ||
|
||||
!reflect.DeepEqual(rer.UserInfo, kyverno.UserInfo{}) {
|
||||
excludeErrs := doesResourceMatchConditionBlock(rer.ResourceDescription, rer.UserInfo, admissionInfo, resource, dynamicConfig, namespaceLabels)
|
||||
// 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 criterias excluded it"))
|
||||
errs = append(errs, excludeErrs...)
|
||||
}
|
||||
}
|
||||
// len(errs) != 0 if the filter excluded the resource
|
||||
return errs
|
||||
}
|
||||
|
||||
func copyAnyAllConditions(original kyverno.AnyAllConditions) kyverno.AnyAllConditions {
|
||||
if reflect.DeepEqual(original, kyverno.AnyAllConditions{}) {
|
||||
return kyverno.AnyAllConditions{}
|
||||
|
|
|
@ -18,6 +18,746 @@ func TestMatchesResourceDescription(t *testing.T) {
|
|||
Policy []byte
|
||||
areErrorsExpected bool
|
||||
}{
|
||||
{
|
||||
Description: "Match Any matches the Pod",
|
||||
AdmissionInfo: kyverno.RequestInfo{
|
||||
ClusterRoles: []string{"admin"},
|
||||
},
|
||||
Resource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "abc",
|
||||
"namespace" : "prod"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "cont-name",
|
||||
"image": "cont-img",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 81
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "30Mi",
|
||||
"cpu": "0.2"
|
||||
},
|
||||
"requests": {
|
||||
"memory": "20Mi",
|
||||
"cpu": "0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
Policy: []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "test-policy"
|
||||
},
|
||||
"spec": {
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
"name": "any-match-rule",
|
||||
"match": {
|
||||
"any": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names" : ["dev"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces" : ["prod"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "*",
|
||||
"imagePullPolicy": "IfNotPresent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
areErrorsExpected: false,
|
||||
},
|
||||
{
|
||||
Description: "Match Any does not match the Pod",
|
||||
AdmissionInfo: kyverno.RequestInfo{
|
||||
ClusterRoles: []string{"admin"},
|
||||
},
|
||||
Resource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "abc",
|
||||
"namespace" : "default"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "cont-name",
|
||||
"image": "cont-img",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 81
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "30Mi",
|
||||
"cpu": "0.2"
|
||||
},
|
||||
"requests": {
|
||||
"memory": "20Mi",
|
||||
"cpu": "0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
Policy: []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "test-policy"
|
||||
},
|
||||
"spec": {
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
"name": "test-rule",
|
||||
"match": {
|
||||
"any": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names" : ["dev"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces" : ["prod"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "*",
|
||||
"imagePullPolicy": "IfNotPresent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
areErrorsExpected: true,
|
||||
},
|
||||
{
|
||||
Description: "Match All matches the Pod",
|
||||
AdmissionInfo: kyverno.RequestInfo{
|
||||
ClusterRoles: []string{"admin"},
|
||||
},
|
||||
Resource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "abc",
|
||||
"namespace" : "prod"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "cont-name",
|
||||
"image": "cont-img",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 81
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "30Mi",
|
||||
"cpu": "0.2"
|
||||
},
|
||||
"requests": {
|
||||
"memory": "20Mi",
|
||||
"cpu": "0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
Policy: []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "test-policy"
|
||||
},
|
||||
"spec": {
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
"name": "test-rule",
|
||||
"match": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names" : ["abc"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces" : ["prod"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "*",
|
||||
"imagePullPolicy": "IfNotPresent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
areErrorsExpected: false,
|
||||
},
|
||||
{
|
||||
Description: "Match All does not match the Pod",
|
||||
AdmissionInfo: kyverno.RequestInfo{
|
||||
ClusterRoles: []string{"admin"},
|
||||
},
|
||||
Resource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "abc",
|
||||
"namespace" : "prod"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "cont-name",
|
||||
"image": "cont-img",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 81
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "30Mi",
|
||||
"cpu": "0.2"
|
||||
},
|
||||
"requests": {
|
||||
"memory": "20Mi",
|
||||
"cpu": "0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
Policy: []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "test-policy"
|
||||
},
|
||||
"spec": {
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
"name": "test-rule",
|
||||
"match": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names" : ["xyz"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces" : ["prod"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "*",
|
||||
"imagePullPolicy": "IfNotPresent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
areErrorsExpected: true,
|
||||
},
|
||||
{
|
||||
Description: "Exclude Any excludes the Pod",
|
||||
AdmissionInfo: kyverno.RequestInfo{
|
||||
ClusterRoles: []string{"admin"},
|
||||
},
|
||||
Resource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "dev",
|
||||
"namespace" : "prod"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "cont-name",
|
||||
"image": "cont-img",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 81
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "30Mi",
|
||||
"cpu": "0.2"
|
||||
},
|
||||
"requests": {
|
||||
"memory": "20Mi",
|
||||
"cpu": "0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
Policy: []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "test-policy"
|
||||
},
|
||||
"spec": {
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
"name": "test-rule",
|
||||
"match": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"exclude": {
|
||||
"any": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names": [
|
||||
"dev"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces": [
|
||||
"default"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "*",
|
||||
"imagePullPolicy": "IfNotPresent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
areErrorsExpected: true,
|
||||
},
|
||||
{
|
||||
Description: "Exclude Any does not exclude the Pod",
|
||||
AdmissionInfo: kyverno.RequestInfo{
|
||||
ClusterRoles: []string{"admin"},
|
||||
},
|
||||
Resource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "abc",
|
||||
"namespace" : "prod"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "cont-name",
|
||||
"image": "cont-img",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 81
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "30Mi",
|
||||
"cpu": "0.2"
|
||||
},
|
||||
"requests": {
|
||||
"memory": "20Mi",
|
||||
"cpu": "0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
Policy: []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "test-policy"
|
||||
},
|
||||
"spec": {
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
"name": "test-rule",
|
||||
"match": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"exclude": {
|
||||
"any": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names": [
|
||||
"dev"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces": [
|
||||
"default"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "*",
|
||||
"imagePullPolicy": "IfNotPresent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
areErrorsExpected: false,
|
||||
},
|
||||
{
|
||||
Description: "Exclude All excludes the Pod",
|
||||
AdmissionInfo: kyverno.RequestInfo{
|
||||
ClusterRoles: []string{"admin"},
|
||||
},
|
||||
Resource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "dev",
|
||||
"namespace" : "prod"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "cont-name",
|
||||
"image": "cont-img",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 81
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "30Mi",
|
||||
"cpu": "0.2"
|
||||
},
|
||||
"requests": {
|
||||
"memory": "20Mi",
|
||||
"cpu": "0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
Policy: []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "test-policy"
|
||||
},
|
||||
"spec": {
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
"name": "test-rule",
|
||||
"match": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"exclude": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names": [
|
||||
"dev"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces": [
|
||||
"prod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "*",
|
||||
"imagePullPolicy": "IfNotPresent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
areErrorsExpected: true,
|
||||
},
|
||||
{
|
||||
Description: "Exclude All does not exclude the Pod",
|
||||
AdmissionInfo: kyverno.RequestInfo{
|
||||
ClusterRoles: []string{"admin"},
|
||||
},
|
||||
Resource: []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "abc",
|
||||
"namespace" : "prod"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "cont-name",
|
||||
"image": "cont-img",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 81
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "30Mi",
|
||||
"cpu": "0.2"
|
||||
},
|
||||
"requests": {
|
||||
"memory": "20Mi",
|
||||
"cpu": "0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
Policy: []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "test-policy"
|
||||
},
|
||||
"spec": {
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
"name": "test-rule",
|
||||
"match": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"exclude": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names": [
|
||||
"abc"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces": [
|
||||
"default"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(image)": "*",
|
||||
"imagePullPolicy": "IfNotPresent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
areErrorsExpected: false,
|
||||
},
|
||||
{
|
||||
Description: "Should match pod and not exclude it",
|
||||
AdmissionInfo: kyverno.RequestInfo{
|
||||
|
|
|
@ -109,14 +109,24 @@ func Validate(policy *kyverno.ClusterPolicy, client *dclient.Client, mock bool,
|
|||
return err
|
||||
}
|
||||
|
||||
// If a rules match block does not match any kind,
|
||||
// we should only allow such rules to have metadata in its overlay
|
||||
if len(rule.MatchResources.Kinds) == 0 {
|
||||
if !ruleOnlyDealsWithResourceMetaData(rule) {
|
||||
return fmt.Errorf("policy can only deal with the metadata field of the resource if" +
|
||||
" the rule does not match an kind")
|
||||
// If a rule's match block does not match any kind,
|
||||
// we should only allow it to have metadata in its overlay
|
||||
if len(rule.MatchResources.Any) > 0 {
|
||||
for _, rmr := range rule.MatchResources.Any {
|
||||
if len(rmr.Kinds) == 0 {
|
||||
return validateMatchKindHelper(rule)
|
||||
}
|
||||
}
|
||||
} else if len(rule.MatchResources.All) > 0 {
|
||||
for _, rmr := range rule.MatchResources.All {
|
||||
if len(rmr.Kinds) == 0 {
|
||||
return validateMatchKindHelper(rule)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if len(rule.MatchResources.Kinds) == 0 {
|
||||
return validateMatchKindHelper(rule)
|
||||
}
|
||||
return fmt.Errorf("at least one element must be specified in a kind block. the kind attribute is mandatory when working with the resources element")
|
||||
}
|
||||
|
||||
if utils.ContainsString(rule.MatchResources.Kinds, "*") || utils.ContainsString(rule.ExcludeResources.Kinds, "*") {
|
||||
|
@ -182,11 +192,35 @@ func Validate(policy *kyverno.ClusterPolicy, client *dclient.Client, mock bool,
|
|||
return nil
|
||||
}
|
||||
|
||||
func validateMatchKindHelper(rule kyverno.Rule) error {
|
||||
if !ruleOnlyDealsWithResourceMetaData(rule) {
|
||||
return fmt.Errorf("policy can only deal with the metadata field of the resource if" +
|
||||
" the rule does not match an kind")
|
||||
}
|
||||
return fmt.Errorf("At least one element must be specified in a kind block. The kind attribute is mandatory when working with the resources element")
|
||||
}
|
||||
|
||||
// doMatchAndExcludeConflict checks if the resultant
|
||||
// of match and exclude block is not an empty set
|
||||
// returns true if it is an empty set
|
||||
func doMatchAndExcludeConflict(rule kyverno.Rule) bool {
|
||||
|
||||
if len(rule.ExcludeResources.All) > 0 || len(rule.MatchResources.All) > 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
// if both have any then no resource should be common
|
||||
if len(rule.MatchResources.Any) > 0 && len(rule.ExcludeResources.Any) > 0 {
|
||||
for _, rmr := range rule.MatchResources.Any {
|
||||
for _, rer := range rule.ExcludeResources.Any {
|
||||
if reflect.DeepEqual(rmr, rer) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(rule.ExcludeResources, kyverno.ExcludeResources{}) {
|
||||
return false
|
||||
}
|
||||
|
@ -506,13 +540,62 @@ func validateResources(rule kyverno.Rule) (string, error) {
|
|||
return fmt.Sprintf("resources.%s", path), err
|
||||
}
|
||||
|
||||
// matched resources
|
||||
if path, err := validateMatchedResourceDescription(rule.MatchResources.ResourceDescription); err != nil {
|
||||
return fmt.Sprintf("match.resources.%s", path), err
|
||||
if (len(rule.MatchResources.Any) > 0 || len(rule.MatchResources.All) > 0) && !reflect.DeepEqual(rule.MatchResources.ResourceDescription, kyverno.ResourceDescription{}) {
|
||||
return "match.", fmt.Errorf("Can't specify any/all together with match resources")
|
||||
}
|
||||
// exclude resources
|
||||
if path, err := validateExcludeResourceDescription(rule.ExcludeResources.ResourceDescription); err != nil {
|
||||
return fmt.Sprintf("exclude.resources.%s", path), err
|
||||
|
||||
if (len(rule.ExcludeResources.Any) > 0 || len(rule.ExcludeResources.All) > 0) && !reflect.DeepEqual(rule.ExcludeResources.ResourceDescription, kyverno.ResourceDescription{}) {
|
||||
return "exclude.", fmt.Errorf("Can't specify any/all together with exclude resources")
|
||||
}
|
||||
|
||||
if len(rule.MatchResources.Any) > 0 && len(rule.MatchResources.All) > 0 {
|
||||
return "match.", fmt.Errorf("Can't specify any and all together.")
|
||||
}
|
||||
|
||||
if len(rule.ExcludeResources.Any) > 0 && len(rule.ExcludeResources.All) > 0 {
|
||||
return "match.", fmt.Errorf("Can't specify any and all together.")
|
||||
}
|
||||
|
||||
if len(rule.MatchResources.Any) > 0 {
|
||||
for _, rmr := range rule.MatchResources.Any {
|
||||
// matched resources
|
||||
if path, err := validateMatchedResourceDescription(rmr.ResourceDescription); err != nil {
|
||||
return fmt.Sprintf("match.resources.%s", path), err
|
||||
}
|
||||
}
|
||||
} else if len(rule.MatchResources.All) > 0 {
|
||||
for _, rmr := range rule.MatchResources.All {
|
||||
// matched resources
|
||||
if path, err := validateMatchedResourceDescription(rmr.ResourceDescription); err != nil {
|
||||
return fmt.Sprintf("match.resources.%s", path), err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// matched resources
|
||||
if path, err := validateMatchedResourceDescription(rule.MatchResources.ResourceDescription); err != nil {
|
||||
return fmt.Sprintf("match.resources.%s", path), err
|
||||
}
|
||||
}
|
||||
|
||||
if len(rule.ExcludeResources.Any) > 0 {
|
||||
for _, rmr := range rule.ExcludeResources.Any {
|
||||
// exclude resources
|
||||
if path, err := validateExcludeResourceDescription(rmr.ResourceDescription); err != nil {
|
||||
return fmt.Sprintf("exclude.resources.%s", path), err
|
||||
}
|
||||
}
|
||||
} else if len(rule.ExcludeResources.All) > 0 {
|
||||
for _, rmr := range rule.ExcludeResources.All {
|
||||
// exclude resources
|
||||
if path, err := validateExcludeResourceDescription(rmr.ResourceDescription); err != nil {
|
||||
return fmt.Sprintf("exclude.resources.%s", path), err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// exclude resources
|
||||
if path, err := validateExcludeResourceDescription(rule.ExcludeResources.ResourceDescription); err != nil {
|
||||
return fmt.Sprintf("exclude.resources.%s", path), err
|
||||
}
|
||||
}
|
||||
|
||||
//validating the values present under validate.preconditions, if they exist
|
||||
|
|
|
@ -1287,6 +1287,55 @@ func Test_Validate_Kind(t *testing.T) {
|
|||
assert.Assert(t, err != nil)
|
||||
}
|
||||
|
||||
func Test_Validate_Any_Kind(t *testing.T) {
|
||||
rawPolicy := []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "policy-to-monitor-root-user-access"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "audit",
|
||||
"rules": [
|
||||
{
|
||||
"name": "monitor-annotation-for-root-user-access",
|
||||
"match": {
|
||||
"any": [
|
||||
{
|
||||
"resources": {
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"AllowRootUserAccess": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"validate": {
|
||||
"message": "Label provisioner.wg.net/cloudprovider is required",
|
||||
"pattern": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"provisioner.wg.net/cloudprovider": "*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
|
||||
var policy *kyverno.ClusterPolicy
|
||||
err := json.Unmarshal(rawPolicy, &policy)
|
||||
assert.NilError(t, err)
|
||||
|
||||
openAPIController, _ := openapi.NewOpenAPIController()
|
||||
err = Validate(policy, nil, true, openAPIController)
|
||||
assert.Assert(t, err != nil)
|
||||
}
|
||||
|
||||
func Test_checkAutoGenRules(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
|
|
@ -118,58 +118,17 @@ func (m *pMap) add(policy *kyverno.ClusterPolicy) {
|
|||
|
||||
for _, rule := range policy.Spec.Rules {
|
||||
|
||||
for _, gvk := range rule.MatchResources.Kinds {
|
||||
_, kind := common.GetKindFromGVK(gvk)
|
||||
_, ok := m.kindDataMap[kind]
|
||||
if !ok {
|
||||
m.kindDataMap[kind] = make(map[PolicyType][]string)
|
||||
if len(rule.MatchResources.Any) > 0 {
|
||||
for _, rmr := range rule.MatchResources.Any {
|
||||
addCacheHelper(rmr, m, rule, mutateMap, pName, enforcePolicy, validateEnforceMap, validateAuditMap, generateMap, imageVerifyMap)
|
||||
}
|
||||
|
||||
if rule.HasMutate() {
|
||||
if !mutateMap[kind+"/"+pName] {
|
||||
mutateMap[kind+"/"+pName] = true
|
||||
mutatePolicy := m.kindDataMap[kind][Mutate]
|
||||
m.kindDataMap[kind][Mutate] = append(mutatePolicy, pName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if rule.HasValidate() {
|
||||
if enforcePolicy {
|
||||
if !validateEnforceMap[kind+"/"+pName] {
|
||||
validateEnforceMap[kind+"/"+pName] = true
|
||||
validatePolicy := m.kindDataMap[kind][ValidateEnforce]
|
||||
m.kindDataMap[kind][ValidateEnforce] = append(validatePolicy, pName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// ValidateAudit
|
||||
if !validateAuditMap[kind+"/"+pName] {
|
||||
validateAuditMap[kind+"/"+pName] = true
|
||||
validatePolicy := m.kindDataMap[kind][ValidateAudit]
|
||||
m.kindDataMap[kind][ValidateAudit] = append(validatePolicy, pName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if rule.HasGenerate() {
|
||||
if !generateMap[kind+"/"+pName] {
|
||||
generateMap[kind+"/"+pName] = true
|
||||
generatePolicy := m.kindDataMap[kind][Generate]
|
||||
m.kindDataMap[kind][Generate] = append(generatePolicy, pName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if rule.HasVerifyImages() {
|
||||
if !imageVerifyMap[kind+"/"+pName] {
|
||||
imageVerifyMap[kind+"/"+pName] = true
|
||||
imageVerifyMapPolicy := m.kindDataMap[kind][VerifyImages]
|
||||
m.kindDataMap[kind][VerifyImages] = append(imageVerifyMapPolicy, pName)
|
||||
}
|
||||
continue
|
||||
} else if len(rule.MatchResources.All) > 0 {
|
||||
for _, rmr := range rule.MatchResources.All {
|
||||
addCacheHelper(rmr, m, rule, mutateMap, pName, enforcePolicy, validateEnforceMap, validateAuditMap, generateMap, imageVerifyMap)
|
||||
}
|
||||
} else {
|
||||
r := kyverno.ResourceFilter{UserInfo: rule.MatchResources.UserInfo, ResourceDescription: rule.MatchResources.ResourceDescription}
|
||||
addCacheHelper(r, m, rule, mutateMap, pName, enforcePolicy, validateEnforceMap, validateAuditMap, generateMap, imageVerifyMap)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +139,62 @@ func (m *pMap) add(policy *kyverno.ClusterPolicy) {
|
|||
m.nameCacheMap[VerifyImages] = imageVerifyMap
|
||||
}
|
||||
|
||||
func addCacheHelper(rmr kyverno.ResourceFilter, m *pMap, rule kyverno.Rule, mutateMap map[string]bool, pName string, enforcePolicy bool, validateEnforceMap map[string]bool, validateAuditMap map[string]bool, generateMap map[string]bool, imageVerifyMap map[string]bool) {
|
||||
for _, gvk := range rmr.Kinds {
|
||||
_, kind := common.GetKindFromGVK(gvk)
|
||||
_, ok := m.kindDataMap[kind]
|
||||
if !ok {
|
||||
m.kindDataMap[kind] = make(map[PolicyType][]string)
|
||||
}
|
||||
|
||||
if rule.HasMutate() {
|
||||
if !mutateMap[kind+"/"+pName] {
|
||||
mutateMap[kind+"/"+pName] = true
|
||||
mutatePolicy := m.kindDataMap[kind][Mutate]
|
||||
m.kindDataMap[kind][Mutate] = append(mutatePolicy, pName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if rule.HasValidate() {
|
||||
if enforcePolicy {
|
||||
if !validateEnforceMap[kind+"/"+pName] {
|
||||
validateEnforceMap[kind+"/"+pName] = true
|
||||
validatePolicy := m.kindDataMap[kind][ValidateEnforce]
|
||||
m.kindDataMap[kind][ValidateEnforce] = append(validatePolicy, pName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// ValidateAudit
|
||||
if !validateAuditMap[kind+"/"+pName] {
|
||||
validateAuditMap[kind+"/"+pName] = true
|
||||
validatePolicy := m.kindDataMap[kind][ValidateAudit]
|
||||
m.kindDataMap[kind][ValidateAudit] = append(validatePolicy, pName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if rule.HasGenerate() {
|
||||
if !generateMap[kind+"/"+pName] {
|
||||
generateMap[kind+"/"+pName] = true
|
||||
generatePolicy := m.kindDataMap[kind][Generate]
|
||||
m.kindDataMap[kind][Generate] = append(generatePolicy, pName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if rule.HasVerifyImages() {
|
||||
if !imageVerifyMap[kind+"/"+pName] {
|
||||
imageVerifyMap[kind+"/"+pName] = true
|
||||
imageVerifyMapPolicy := m.kindDataMap[kind][VerifyImages]
|
||||
m.kindDataMap[kind][VerifyImages] = append(imageVerifyMapPolicy, pName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (pc *pMap) get(key PolicyType, gvk, namespace string) (names []string) {
|
||||
pc.RLock()
|
||||
defer pc.RUnlock()
|
||||
|
@ -207,28 +222,44 @@ func (m *pMap) remove(policy *kyverno.ClusterPolicy) {
|
|||
}
|
||||
|
||||
for _, rule := range policy.Spec.Rules {
|
||||
for _, gvk := range rule.MatchResources.Kinds {
|
||||
_, kind := common.GetKindFromGVK(gvk)
|
||||
dataMap := m.kindDataMap[kind]
|
||||
for policyType, policies := range dataMap {
|
||||
var newPolicies []string
|
||||
for _, p := range policies {
|
||||
if p == pName {
|
||||
continue
|
||||
}
|
||||
newPolicies = append(newPolicies, p)
|
||||
}
|
||||
m.kindDataMap[kind][policyType] = newPolicies
|
||||
}
|
||||
for _, nameCache := range m.nameCacheMap {
|
||||
if ok := nameCache[kind+"/"+pName]; ok {
|
||||
delete(nameCache, kind+"/"+pName)
|
||||
}
|
||||
}
|
||||
|
||||
if len(rule.MatchResources.Any) > 0 {
|
||||
for _, rmr := range rule.MatchResources.Any {
|
||||
removeCacheHelper(rmr, m, pName)
|
||||
}
|
||||
} else if len(rule.MatchResources.All) > 0 {
|
||||
for _, rmr := range rule.MatchResources.All {
|
||||
removeCacheHelper(rmr, m, pName)
|
||||
}
|
||||
} else {
|
||||
r := kyverno.ResourceFilter{UserInfo: rule.MatchResources.UserInfo, ResourceDescription: rule.MatchResources.ResourceDescription}
|
||||
removeCacheHelper(r, m, pName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeCacheHelper(rmr kyverno.ResourceFilter, m *pMap, pName string) {
|
||||
for _, gvk := range rmr.Kinds {
|
||||
_, kind := common.GetKindFromGVK(gvk)
|
||||
dataMap := m.kindDataMap[kind]
|
||||
for policyType, policies := range dataMap {
|
||||
var newPolicies []string
|
||||
for _, p := range policies {
|
||||
if p == pName {
|
||||
continue
|
||||
}
|
||||
newPolicies = append(newPolicies, p)
|
||||
}
|
||||
m.kindDataMap[kind][policyType] = newPolicies
|
||||
}
|
||||
for _, nameCache := range m.nameCacheMap {
|
||||
if ok := nameCache[kind+"/"+pName]; ok {
|
||||
delete(nameCache, kind+"/"+pName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *policyCache) getPolicyObject(key PolicyType, gvk string, nspace string) (policyObject []*kyverno.ClusterPolicy) {
|
||||
_, kind := common.GetKindFromGVK(gvk)
|
||||
policyNames := m.pMap.get(key, kind, nspace)
|
||||
|
|
|
@ -133,11 +133,50 @@ func Test_Add_Remove(t *testing.T) {
|
|||
policy := newPolicy(t)
|
||||
kind := "Pod"
|
||||
pCache.Add(policy)
|
||||
|
||||
validateEnforce := pCache.get(ValidateEnforce, kind, "")
|
||||
if len(validateEnforce) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(validateEnforce))
|
||||
}
|
||||
|
||||
mutate := pCache.get(Mutate, kind, "")
|
||||
if len(mutate) != 1 {
|
||||
t.Errorf("expected 1 mutate policy, found %v", len(mutate))
|
||||
}
|
||||
|
||||
generate := pCache.get(Generate, kind, "")
|
||||
if len(mutate) != 1 {
|
||||
t.Errorf("expected 1 generate policy, found %v", len(generate))
|
||||
}
|
||||
|
||||
pCache.Remove(policy)
|
||||
deletedValidateEnforce := pCache.get(ValidateEnforce, kind, "")
|
||||
if len(deletedValidateEnforce) != 0 {
|
||||
t.Errorf("expected 0 validate enforce policy, found %v", len(deletedValidateEnforce))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Add_Remove_Any(t *testing.T) {
|
||||
pCache := newPolicyCache(log.Log, dummyLister{}, dummyNsLister{})
|
||||
policy := newAnyPolicy(t)
|
||||
kind := "Pod"
|
||||
pCache.Add(policy)
|
||||
|
||||
validateEnforce := pCache.get(ValidateEnforce, kind, "")
|
||||
if len(validateEnforce) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(validateEnforce))
|
||||
}
|
||||
|
||||
mutate := pCache.get(Mutate, kind, "")
|
||||
if len(mutate) != 1 {
|
||||
t.Errorf("expected 1 mutate policy, found %v", len(mutate))
|
||||
}
|
||||
|
||||
generate := pCache.get(Generate, kind, "")
|
||||
if len(mutate) != 1 {
|
||||
t.Errorf("expected 1 generate policy, found %v", len(generate))
|
||||
}
|
||||
|
||||
pCache.Remove(policy)
|
||||
deletedValidateEnforce := pCache.get(ValidateEnforce, kind, "")
|
||||
if len(deletedValidateEnforce) != 0 {
|
||||
|
@ -261,6 +300,179 @@ func newPolicy(t *testing.T) *kyverno.ClusterPolicy {
|
|||
return policy
|
||||
}
|
||||
|
||||
func newAnyPolicy(t *testing.T) *kyverno.ClusterPolicy {
|
||||
rawPolicy := []byte(`{
|
||||
"metadata": {
|
||||
"name": "test-policy"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"rules": [
|
||||
{
|
||||
"name": "deny-privileged-disallowpriviligedescalation",
|
||||
"match": {
|
||||
"any": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names": [
|
||||
"dev"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces": [
|
||||
"prod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"validate": {
|
||||
"deny": {
|
||||
"conditions": {
|
||||
"all": [
|
||||
{
|
||||
"key": "a",
|
||||
"operator": "Equals",
|
||||
"value": "a"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "deny-privileged-disallowpriviligedescalation",
|
||||
"match": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names": [
|
||||
"dev"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces": [
|
||||
"prod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"validate": {
|
||||
"pattern": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"image": "!*:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "annotate-host-path",
|
||||
"match": {
|
||||
"any": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names": [
|
||||
"dev"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces": [
|
||||
"prod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"+(cluster-autoscaler.kubernetes.io/safe-to-evict)": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "default-deny-ingress",
|
||||
"match": {
|
||||
"any": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"names": [
|
||||
"dev"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
],
|
||||
"namespaces": [
|
||||
"prod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"generate": {
|
||||
"kind": "NetworkPolicy",
|
||||
"name": "default-deny-ingress",
|
||||
"namespace": "{{request.object.metadata.name}}",
|
||||
"data": {
|
||||
"spec": {
|
||||
"podSelector": {},
|
||||
"policyTypes": [
|
||||
"Ingress"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
|
||||
var policy *kyverno.ClusterPolicy
|
||||
err := json.Unmarshal(rawPolicy, &policy)
|
||||
assert.NilError(t, err)
|
||||
|
||||
return policy
|
||||
}
|
||||
|
||||
func newNsPolicy(t *testing.T) *kyverno.ClusterPolicy {
|
||||
rawPolicy := []byte(`{
|
||||
"metadata": {
|
||||
|
|
Loading…
Reference in a new issue