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
|
information (e.g. kind, name, namespace, labels) and admission
|
||||||
review request information like the name or role.
|
review request information like the name or role.
|
||||||
properties:
|
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:
|
clusterRoles:
|
||||||
description: ClusterRoles is the list of cluster-wide role
|
description: ClusterRoles is the list of cluster-wide role
|
||||||
names for the user.
|
names for the user.
|
||||||
|
@ -360,6 +790,436 @@ spec:
|
||||||
request information like the user name or role. At least one
|
request information like the user name or role. At least one
|
||||||
kind is required.
|
kind is required.
|
||||||
properties:
|
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:
|
clusterRoles:
|
||||||
description: ClusterRoles is the list of cluster-wide role
|
description: ClusterRoles is the list of cluster-wide role
|
||||||
names for the user.
|
names for the user.
|
||||||
|
@ -687,8 +1547,9 @@ spec:
|
||||||
ruleStatus:
|
ruleStatus:
|
||||||
description: Rules provides per rule statistics
|
description: Rules provides per rule statistics
|
||||||
items:
|
items:
|
||||||
description: RuleStats provides statistics for an individual rule
|
description: 'RuleStats provides statistics for an individual rule
|
||||||
within a policy.
|
within a policy. Deprecated. Policy metrics are now available
|
||||||
|
via the "/metrics" endpoint. See: https://kyverno.io/docs/monitoring-kyverno-with-prometheus-metrics/'
|
||||||
properties:
|
properties:
|
||||||
appliedCount:
|
appliedCount:
|
||||||
description: AppliedCount is the total number of times this
|
description: AppliedCount is the total number of times this
|
||||||
|
|
|
@ -118,6 +118,436 @@ spec:
|
||||||
information (e.g. kind, name, namespace, labels) and admission
|
information (e.g. kind, name, namespace, labels) and admission
|
||||||
review request information like the name or role.
|
review request information like the name or role.
|
||||||
properties:
|
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:
|
clusterRoles:
|
||||||
description: ClusterRoles is the list of cluster-wide role
|
description: ClusterRoles is the list of cluster-wide role
|
||||||
names for the user.
|
names for the user.
|
||||||
|
@ -361,6 +791,436 @@ spec:
|
||||||
request information like the user name or role. At least one
|
request information like the user name or role. At least one
|
||||||
kind is required.
|
kind is required.
|
||||||
properties:
|
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:
|
clusterRoles:
|
||||||
description: ClusterRoles is the list of cluster-wide role
|
description: ClusterRoles is the list of cluster-wide role
|
||||||
names for the user.
|
names for the user.
|
||||||
|
@ -667,7 +1527,8 @@ spec:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: Status contains policy runtime information.
|
description: Status contains policy runtime information. Deprecated. Policy
|
||||||
|
metrics are available via the metrics endpoint
|
||||||
properties:
|
properties:
|
||||||
averageExecutionTime:
|
averageExecutionTime:
|
||||||
description: AvgExecutionTime is the average time taken to process
|
description: AvgExecutionTime is the average time taken to process
|
||||||
|
@ -688,8 +1549,9 @@ spec:
|
||||||
ruleStatus:
|
ruleStatus:
|
||||||
description: Rules provides per rule statistics
|
description: Rules provides per rule statistics
|
||||||
items:
|
items:
|
||||||
description: RuleStats provides statistics for an individual rule
|
description: 'RuleStats provides statistics for an individual rule
|
||||||
within a policy.
|
within a policy. Deprecated. Policy metrics are now available
|
||||||
|
via the "/metrics" endpoint. See: https://kyverno.io/docs/monitoring-kyverno-with-prometheus-metrics/'
|
||||||
properties:
|
properties:
|
||||||
appliedCount:
|
appliedCount:
|
||||||
description: AppliedCount is the total number of times this
|
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
|
// MatchResources is used to specify resource and admission review request data for
|
||||||
// which a policy rule is applicable.
|
// which a policy rule is applicable.
|
||||||
type MatchResources struct {
|
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.
|
// UserInfo contains information about the user performing the operation.
|
||||||
// +optional
|
// +optional
|
||||||
UserInfo `json:",omitempty" yaml:",omitempty"`
|
UserInfo `json:",omitempty" yaml:",omitempty"`
|
||||||
|
|
||||||
// ResourceDescription contains information about the resource being created or modified.
|
// ResourceDescription contains information about the resource being created or modified.
|
||||||
// Requires at least one tag to be specified when under MatchResources.
|
// Requires at least one tag to be specified when under MatchResources.
|
||||||
|
// +optional
|
||||||
ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
|
ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExcludeResources specifies resource and admission review request data for
|
// ExcludeResources specifies resource and admission review request data for
|
||||||
// which a policy rule is not applicable.
|
// which a policy rule is not applicable.
|
||||||
type ExcludeResources struct {
|
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.
|
// UserInfo contains information about the user performing the operation.
|
||||||
// +optional
|
// +optional
|
||||||
UserInfo `json:",omitempty" yaml:",omitempty"`
|
UserInfo `json:",omitempty" yaml:",omitempty"`
|
||||||
|
@ -241,6 +258,18 @@ type ExcludeResources struct {
|
||||||
ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
|
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.
|
// UserInfo contains information about the user performing the operation.
|
||||||
type UserInfo struct {
|
type UserInfo struct {
|
||||||
// Roles is the list of namespaced role names for the user.
|
// 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()
|
admissionInfo := *admissionInfoRef.DeepCopy()
|
||||||
|
|
||||||
var reasonsForFailure []error
|
var reasonsForFailure []error
|
||||||
|
if len(rule.MatchResources.Any) > 0 {
|
||||||
if reflect.DeepEqual(admissionInfo, kyverno.RequestInfo{}) {
|
// inlcude object if ANY of the criterias match
|
||||||
rule.MatchResources.UserInfo = kyverno.UserInfo{}
|
// so if one matches then break from loop
|
||||||
}
|
oneMatched := false
|
||||||
|
for _, rmr := range rule.MatchResources.Any {
|
||||||
// checking if resource matches the rule
|
// if there are no errors it means it was a match
|
||||||
if !reflect.DeepEqual(rule.MatchResources.ResourceDescription, kyverno.ResourceDescription{}) ||
|
if len(matchesResourceDescriptionMatchHelper(rmr, admissionInfo, resource, dynamicConfig, namespaceLabels)) == 0 {
|
||||||
!reflect.DeepEqual(rule.MatchResources.UserInfo, kyverno.UserInfo{}) {
|
oneMatched = true
|
||||||
matchErrs := doesResourceMatchConditionBlock(rule.MatchResources.ResourceDescription, rule.MatchResources.UserInfo, admissionInfo, resource, dynamicConfig, namespaceLabels)
|
break
|
||||||
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 !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
|
// creating final error
|
||||||
|
@ -301,6 +326,39 @@ func MatchesResourceDescription(resourceRef unstructured.Unstructured, ruleRef k
|
||||||
return nil
|
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 {
|
func copyAnyAllConditions(original kyverno.AnyAllConditions) kyverno.AnyAllConditions {
|
||||||
if reflect.DeepEqual(original, kyverno.AnyAllConditions{}) {
|
if reflect.DeepEqual(original, kyverno.AnyAllConditions{}) {
|
||||||
return kyverno.AnyAllConditions{}
|
return kyverno.AnyAllConditions{}
|
||||||
|
|
|
@ -18,6 +18,746 @@ func TestMatchesResourceDescription(t *testing.T) {
|
||||||
Policy []byte
|
Policy []byte
|
||||||
areErrorsExpected bool
|
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",
|
Description: "Should match pod and not exclude it",
|
||||||
AdmissionInfo: kyverno.RequestInfo{
|
AdmissionInfo: kyverno.RequestInfo{
|
||||||
|
|
|
@ -109,14 +109,24 @@ func Validate(policy *kyverno.ClusterPolicy, client *dclient.Client, mock bool,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a rules match block does not match any kind,
|
// If a rule's match block does not match any kind,
|
||||||
// we should only allow such rules to have metadata in its overlay
|
// we should only allow it to have metadata in its overlay
|
||||||
if len(rule.MatchResources.Kinds) == 0 {
|
if len(rule.MatchResources.Any) > 0 {
|
||||||
if !ruleOnlyDealsWithResourceMetaData(rule) {
|
for _, rmr := range rule.MatchResources.Any {
|
||||||
return fmt.Errorf("policy can only deal with the metadata field of the resource if" +
|
if len(rmr.Kinds) == 0 {
|
||||||
" the rule does not match an kind")
|
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, "*") {
|
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
|
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
|
// doMatchAndExcludeConflict checks if the resultant
|
||||||
// of match and exclude block is not an empty set
|
// of match and exclude block is not an empty set
|
||||||
// returns true if it is an empty set
|
// returns true if it is an empty set
|
||||||
func doMatchAndExcludeConflict(rule kyverno.Rule) bool {
|
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{}) {
|
if reflect.DeepEqual(rule.ExcludeResources, kyverno.ExcludeResources{}) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -506,13 +540,62 @@ func validateResources(rule kyverno.Rule) (string, error) {
|
||||||
return fmt.Sprintf("resources.%s", path), err
|
return fmt.Sprintf("resources.%s", path), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// matched resources
|
if (len(rule.MatchResources.Any) > 0 || len(rule.MatchResources.All) > 0) && !reflect.DeepEqual(rule.MatchResources.ResourceDescription, kyverno.ResourceDescription{}) {
|
||||||
if path, err := validateMatchedResourceDescription(rule.MatchResources.ResourceDescription); err != nil {
|
return "match.", fmt.Errorf("Can't specify any/all together with match resources")
|
||||||
return fmt.Sprintf("match.resources.%s", path), err
|
|
||||||
}
|
}
|
||||||
// exclude resources
|
|
||||||
if path, err := validateExcludeResourceDescription(rule.ExcludeResources.ResourceDescription); err != nil {
|
if (len(rule.ExcludeResources.Any) > 0 || len(rule.ExcludeResources.All) > 0) && !reflect.DeepEqual(rule.ExcludeResources.ResourceDescription, kyverno.ResourceDescription{}) {
|
||||||
return fmt.Sprintf("exclude.resources.%s", path), err
|
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
|
//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)
|
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) {
|
func Test_checkAutoGenRules(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
@ -118,58 +118,17 @@ func (m *pMap) add(policy *kyverno.ClusterPolicy) {
|
||||||
|
|
||||||
for _, rule := range policy.Spec.Rules {
|
for _, rule := range policy.Spec.Rules {
|
||||||
|
|
||||||
for _, gvk := range rule.MatchResources.Kinds {
|
if len(rule.MatchResources.Any) > 0 {
|
||||||
_, kind := common.GetKindFromGVK(gvk)
|
for _, rmr := range rule.MatchResources.Any {
|
||||||
_, ok := m.kindDataMap[kind]
|
addCacheHelper(rmr, m, rule, mutateMap, pName, enforcePolicy, validateEnforceMap, validateAuditMap, generateMap, imageVerifyMap)
|
||||||
if !ok {
|
|
||||||
m.kindDataMap[kind] = make(map[PolicyType][]string)
|
|
||||||
}
|
}
|
||||||
|
} else if len(rule.MatchResources.All) > 0 {
|
||||||
if rule.HasMutate() {
|
for _, rmr := range rule.MatchResources.All {
|
||||||
if !mutateMap[kind+"/"+pName] {
|
addCacheHelper(rmr, m, rule, mutateMap, pName, enforcePolicy, validateEnforceMap, validateAuditMap, generateMap, imageVerifyMap)
|
||||||
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 {
|
||||||
|
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
|
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) {
|
func (pc *pMap) get(key PolicyType, gvk, namespace string) (names []string) {
|
||||||
pc.RLock()
|
pc.RLock()
|
||||||
defer pc.RUnlock()
|
defer pc.RUnlock()
|
||||||
|
@ -207,28 +222,44 @@ func (m *pMap) remove(policy *kyverno.ClusterPolicy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rule := range policy.Spec.Rules {
|
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) {
|
func (m *policyCache) getPolicyObject(key PolicyType, gvk string, nspace string) (policyObject []*kyverno.ClusterPolicy) {
|
||||||
_, kind := common.GetKindFromGVK(gvk)
|
_, kind := common.GetKindFromGVK(gvk)
|
||||||
policyNames := m.pMap.get(key, kind, nspace)
|
policyNames := m.pMap.get(key, kind, nspace)
|
||||||
|
|
|
@ -133,11 +133,50 @@ func Test_Add_Remove(t *testing.T) {
|
||||||
policy := newPolicy(t)
|
policy := newPolicy(t)
|
||||||
kind := "Pod"
|
kind := "Pod"
|
||||||
pCache.Add(policy)
|
pCache.Add(policy)
|
||||||
|
|
||||||
validateEnforce := pCache.get(ValidateEnforce, kind, "")
|
validateEnforce := pCache.get(ValidateEnforce, kind, "")
|
||||||
if len(validateEnforce) != 1 {
|
if len(validateEnforce) != 1 {
|
||||||
t.Errorf("expected 1 validate enforce policy, found %v", len(validateEnforce))
|
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)
|
pCache.Remove(policy)
|
||||||
deletedValidateEnforce := pCache.get(ValidateEnforce, kind, "")
|
deletedValidateEnforce := pCache.get(ValidateEnforce, kind, "")
|
||||||
if len(deletedValidateEnforce) != 0 {
|
if len(deletedValidateEnforce) != 0 {
|
||||||
|
@ -261,6 +300,179 @@ func newPolicy(t *testing.T) *kyverno.ClusterPolicy {
|
||||||
return policy
|
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 {
|
func newNsPolicy(t *testing.T) *kyverno.ClusterPolicy {
|
||||||
rawPolicy := []byte(`{
|
rawPolicy := []byte(`{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|
Loading…
Reference in a new issue