mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-29 02:45:06 +00:00
feat: [preconditions, conditions] added backwards-compatible support for logical operators (#1604)
Signed-off-by: Yashvardhan Kukreja <yash.kukreja.98@gmail.com>
This commit is contained in:
parent
6f15432a21
commit
10c714d5ba
21 changed files with 449 additions and 525 deletions
|
@ -385,26 +385,8 @@ spec:
|
|||
maxLength: 63
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. This too can be made to happen in a logical-manner where in some situation all the conditions need to pass and in some other situation, atleast one condition is enough to pass. For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -415,26 +397,8 @@ spec:
|
|||
description: Deny defines conditions to fail the validation rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny in a logical manner For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed on failure.
|
||||
|
@ -1565,26 +1529,8 @@ spec:
|
|||
maxLength: 63
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. This too can be made to happen in a logical-manner where in some situation all the conditions need to pass and in some other situation, atleast one condition is enough to pass. For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -1595,26 +1541,8 @@ spec:
|
|||
description: Deny defines conditions to fail the validation rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny in a logical manner For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed on failure.
|
||||
|
|
|
@ -583,34 +583,15 @@ spec:
|
|||
maxLength: 63
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule
|
||||
execution. This is useful for finer control of when an rule
|
||||
is applied. A condition can reference object data using JMESPath
|
||||
notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional
|
||||
criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath)
|
||||
for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid
|
||||
operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of
|
||||
values. The values can be fixed set or can be variables
|
||||
declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional
|
||||
rule execution. This is useful for finer control of when an
|
||||
rule is applied. A condition can reference object data using
|
||||
JMESPath notation. This too can be made to happen in a logical-manner
|
||||
where in some situation all the conditions need to pass and
|
||||
in some other situation, atleast one condition is enough to
|
||||
pass. For the sake of backwards compatibility, it can be populated
|
||||
with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -624,32 +605,10 @@ spec:
|
|||
rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional
|
||||
criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath)
|
||||
for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform.
|
||||
Valid operators are Equals, NotEquals, In and
|
||||
NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or
|
||||
set of values. The values can be fixed set or
|
||||
can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny
|
||||
in a logical manner For the sake of backwards compatibility,
|
||||
it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed
|
||||
|
|
|
@ -584,34 +584,15 @@ spec:
|
|||
maxLength: 63
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule
|
||||
execution. This is useful for finer control of when an rule
|
||||
is applied. A condition can reference object data using JMESPath
|
||||
notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional
|
||||
criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath)
|
||||
for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid
|
||||
operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of
|
||||
values. The values can be fixed set or can be variables
|
||||
declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional
|
||||
rule execution. This is useful for finer control of when an
|
||||
rule is applied. A condition can reference object data using
|
||||
JMESPath notation. This too can be made to happen in a logical-manner
|
||||
where in some situation all the conditions need to pass and
|
||||
in some other situation, atleast one condition is enough to
|
||||
pass. For the sake of backwards compatibility, it can be populated
|
||||
with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -625,32 +606,10 @@ spec:
|
|||
rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional
|
||||
criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath)
|
||||
for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform.
|
||||
Valid operators are Equals, NotEquals, In and
|
||||
NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or
|
||||
set of values. The values can be fixed set or
|
||||
can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny
|
||||
in a logical manner For the sake of backwards compatibility,
|
||||
it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed
|
||||
|
|
|
@ -390,26 +390,8 @@ spec:
|
|||
maxLength: 63
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. This too can be made to happen in a logical-manner where in some situation all the conditions need to pass and in some other situation, atleast one condition is enough to pass. For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -420,26 +402,8 @@ spec:
|
|||
description: Deny defines conditions to fail the validation rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny in a logical manner For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed on failure.
|
||||
|
@ -1570,26 +1534,8 @@ spec:
|
|||
maxLength: 63
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. This too can be made to happen in a logical-manner where in some situation all the conditions need to pass and in some other situation, atleast one condition is enough to pass. For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -1600,26 +1546,8 @@ spec:
|
|||
description: Deny defines conditions to fail the validation rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny in a logical manner For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed on failure.
|
||||
|
|
|
@ -390,26 +390,8 @@ spec:
|
|||
maxLength: 63
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. This too can be made to happen in a logical-manner where in some situation all the conditions need to pass and in some other situation, atleast one condition is enough to pass. For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -420,26 +402,8 @@ spec:
|
|||
description: Deny defines conditions to fail the validation rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny in a logical manner For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed on failure.
|
||||
|
@ -1570,26 +1534,8 @@ spec:
|
|||
maxLength: 63
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. This too can be made to happen in a logical-manner where in some situation all the conditions need to pass and in some other situation, atleast one condition is enough to pass. For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -1600,26 +1546,8 @@ spec:
|
|||
description: Deny defines conditions to fail the validation rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform. Valid operators are Equals, NotEquals, In and NotIn.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny in a logical manner For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed on failure.
|
||||
|
|
|
@ -111,7 +111,7 @@ spec:
|
|||
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
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector for 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.'
|
||||
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.
|
||||
|
@ -261,7 +261,7 @@ spec:
|
|||
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
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector for 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.'
|
||||
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.
|
||||
|
@ -389,26 +389,8 @@ spec:
|
|||
description: Name is a label to identify the rule, It must be unique within the policy.
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. This too can be made to happen in a logical-manner where in some situation all the conditions need to pass and in some other situation, atleast one condition is enough to pass. For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -419,26 +401,8 @@ spec:
|
|||
description: Deny defines conditions to fail the validation rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny in a logical manner For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed on failure.
|
||||
|
@ -1290,7 +1254,7 @@ spec:
|
|||
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
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector for 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.'
|
||||
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.
|
||||
|
@ -1440,7 +1404,7 @@ spec:
|
|||
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
|
||||
namespaceSelector:
|
||||
description: 'NamespaceSelector is a label selector for 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.'
|
||||
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.
|
||||
|
@ -1568,26 +1532,8 @@ spec:
|
|||
description: Name is a label to identify the rule, It must be unique within the policy.
|
||||
type: string
|
||||
preconditions:
|
||||
description: Conditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: AnyAllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. This too can be made to happen in a logical-manner where in some situation all the conditions need to pass and in some other situation, atleast one condition is enough to pass. For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
validate:
|
||||
description: Validation is used to validate matching resources.
|
||||
properties:
|
||||
|
@ -1598,26 +1544,8 @@ spec:
|
|||
description: Deny defines conditions to fail the validation rule.
|
||||
properties:
|
||||
conditions:
|
||||
description: Specifies set of condition to deny.
|
||||
items:
|
||||
description: Condition defines variable-based conditional criteria for rule execution.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the context entry (using JMESPath) for conditional rule evaluation.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
operator:
|
||||
description: Operator is the operation to perform.
|
||||
enum:
|
||||
- Equals
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using using JMESPath.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
type: array
|
||||
description: specifies the set of conditions to deny in a logical manner For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
message:
|
||||
description: Message specifies a custom message to be displayed on failure.
|
||||
|
|
|
@ -80,11 +80,15 @@ type Rule struct {
|
|||
// +optional
|
||||
ExcludeResources ExcludeResources `json:"exclude,omitempty" yaml:"exclude,omitempty"`
|
||||
|
||||
// Conditions enable variable-based conditional rule execution. This is useful for
|
||||
// AnyAllConditions enable variable-based conditional rule execution. This is useful for
|
||||
// finer control of when an rule is applied. A condition can reference object data
|
||||
// using JMESPath notation.
|
||||
// This too can be made to happen in a logical-manner where in some situation all the conditions need to pass
|
||||
// and in some other situation, atleast one condition is enough to pass.
|
||||
// For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
// +optional
|
||||
Conditions []Condition `json:"preconditions,omitempty" yaml:"preconditions,omitempty"`
|
||||
AnyAllConditions apiextensions.JSON `json:"preconditions,omitempty" yaml:"preconditions,omitempty"`
|
||||
|
||||
// Mutation is used to modify matching resources.
|
||||
// +optional
|
||||
|
@ -99,6 +103,25 @@ type Rule struct {
|
|||
Generation Generation `json:"generate,omitempty" yaml:"generate,omitempty"`
|
||||
}
|
||||
|
||||
// AnyAllCondition consists of conditions wrapped denoting a logical criteria to be fulfilled.
|
||||
// AnyConditions get fulfilled when at least one of its sub-conditions passes.
|
||||
// AllConditions get fulfilled only when all of its sub-conditions pass.
|
||||
type AnyAllConditions struct {
|
||||
// AnyConditions enable variable-based conditional rule execution. This is useful for
|
||||
// finer control of when an rule is applied. A condition can reference object data
|
||||
// using JMESPath notation.
|
||||
// Here, atleast one of the conditions need to pass
|
||||
// +optional
|
||||
AnyConditions []Condition `json:"any,omitempty" yaml:"any,omitempty"`
|
||||
|
||||
// AllConditions enable variable-based conditional rule execution. This is useful for
|
||||
// finer control of when an rule is applied. A condition can reference object data
|
||||
// using JMESPath notation.
|
||||
// Here, all of the conditions need to pass
|
||||
// +optional
|
||||
AllConditions []Condition `json:"all,omitempty" yaml:"all,omitempty"`
|
||||
}
|
||||
|
||||
// ContextEntry adds variables and data sources to a rule Context. Either a
|
||||
// ConfigMap reference or a APILookup must be provided.
|
||||
type ContextEntry struct {
|
||||
|
@ -341,8 +364,10 @@ type Validation struct {
|
|||
// Deny specifies a list of conditions. The validation rule fails, if any Condition
|
||||
// evaluates to "false".
|
||||
type Deny struct {
|
||||
// Specifies set of condition to deny.
|
||||
Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"`
|
||||
// specifies the set of conditions to deny in a logical manner
|
||||
// For the sake of backwards compatibility, it can be populated with []kyverno.Condition.
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
AnyAllConditions apiextensions.JSON `json:"conditions,omitempty" yaml:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// Generation defines how new resources should be created and managed.
|
||||
|
|
|
@ -39,6 +39,35 @@ func (in *APICall) DeepCopy() *APICall {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AnyAllConditions) DeepCopyInto(out *AnyAllConditions) {
|
||||
*out = *in
|
||||
if in.AnyConditions != nil {
|
||||
in, out := &in.AnyConditions, &out.AnyConditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.AllConditions != nil {
|
||||
in, out := &in.AllConditions, &out.AllConditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnyAllConditions.
|
||||
func (in *AnyAllConditions) DeepCopy() *AnyAllConditions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AnyAllConditions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CloneFrom) DeepCopyInto(out *CloneFrom) {
|
||||
*out = *in
|
||||
|
@ -166,13 +195,6 @@ func (in *ContextEntry) DeepCopy() *ContextEntry {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Deny) DeepCopyInto(out *Deny) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Deny.
|
||||
|
@ -525,16 +547,6 @@ func (in *Rule) DeepCopyInto(out *Rule) {
|
|||
}
|
||||
in.MatchResources.DeepCopyInto(&out.MatchResources)
|
||||
in.ExcludeResources.DeepCopyInto(&out.ExcludeResources)
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
in.Mutation.DeepCopyInto(&out.Mutation)
|
||||
in.Validation.DeepCopyInto(&out.Validation)
|
||||
in.Generation.DeepCopyInto(&out.Generation)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule.
|
||||
|
|
|
@ -92,7 +92,11 @@ func filterRule(rule kyverno.Rule, policyContext *PolicyContext) *response.RuleR
|
|||
}
|
||||
|
||||
// operate on the copy of the conditions, as we perform variable substitution
|
||||
copyConditions := copyConditions(rule.Conditions)
|
||||
copyConditions, err := copyConditions(rule.AnyAllConditions)
|
||||
if err != nil {
|
||||
logger.V(4).Info("cannot copy AnyAllConditions", "reason", err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
// evaluate pre-conditions
|
||||
if !variables.EvaluateConditions(logger, ctx, copyConditions) {
|
||||
|
|
|
@ -76,7 +76,11 @@ func Mutate(policyContext *PolicyContext) (resp *response.EngineResponse) {
|
|||
}
|
||||
|
||||
// operate on the copy of the conditions, as we perform variable substitution
|
||||
copyConditions := copyConditions(rule.Conditions)
|
||||
copyConditions, err := copyConditions(rule.AnyAllConditions)
|
||||
if err != nil {
|
||||
logger.V(2).Info("failed to load context", "reason", err.Error())
|
||||
continue
|
||||
}
|
||||
// evaluate pre-conditions
|
||||
// - handle variable substitutions
|
||||
if !variables.EvaluateConditions(logger, ctx, copyConditions) {
|
||||
|
|
|
@ -2,13 +2,13 @@ package engine
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
"gotest.tools/assert"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_VariableSubstitutionOverlay(t *testing.T) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/minio/minio/pkg/wildcard"
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
@ -276,7 +277,15 @@ func MatchesResourceDescription(resourceRef unstructured.Unstructured, ruleRef k
|
|||
return nil
|
||||
}
|
||||
|
||||
func copyConditions(original []kyverno.Condition) []kyverno.Condition {
|
||||
func copyAnyAllConditions(original kyverno.AnyAllConditions) kyverno.AnyAllConditions {
|
||||
if reflect.DeepEqual(original, kyverno.AnyAllConditions{}) {
|
||||
return kyverno.AnyAllConditions{}
|
||||
}
|
||||
return *original.DeepCopy()
|
||||
}
|
||||
|
||||
// backwards compatibility
|
||||
func copyOldConditions(original []kyverno.Condition) []kyverno.Condition {
|
||||
if original == nil || len(original) == 0 {
|
||||
return []kyverno.Condition{}
|
||||
}
|
||||
|
@ -289,6 +298,21 @@ func copyConditions(original []kyverno.Condition) []kyverno.Condition {
|
|||
return copies
|
||||
}
|
||||
|
||||
func copyConditions(original apiextensions.JSON) (interface{}, error) {
|
||||
// conditions are currently in the form of []interface{}
|
||||
kyvernoOriginalConditions, err := utils.ApiextensionsJsonToKyvernoConditions(original)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch typedValue := kyvernoOriginalConditions.(type) {
|
||||
case kyverno.AnyAllConditions:
|
||||
return copyAnyAllConditions(typedValue), nil
|
||||
case []kyverno.Condition: // backwards compatibility
|
||||
return copyOldConditions(typedValue), nil
|
||||
}
|
||||
return nil, fmt.Errorf("wrongfully configured data")
|
||||
}
|
||||
|
||||
// excludeResource checks if the resource has ownerRef set
|
||||
func excludeResource(resource unstructured.Unstructured) bool {
|
||||
kind := resource.GetKind()
|
||||
|
|
|
@ -113,8 +113,11 @@ func validateResource(log logr.Logger, ctx *PolicyContext) *response.EngineRespo
|
|||
log.V(3).Info("matched validate rule")
|
||||
|
||||
// operate on the copy of the conditions, as we perform variable substitution
|
||||
preconditionsCopy := copyConditions(rule.Conditions)
|
||||
|
||||
preconditionsCopy, err := copyConditions(rule.AnyAllConditions)
|
||||
if err != nil {
|
||||
log.V(2).Info("wrongfully configured data", "reason", err.Error())
|
||||
continue
|
||||
}
|
||||
// evaluate pre-conditions
|
||||
// - handle variable substitutions
|
||||
if !variables.EvaluateConditions(log, ctx.JSONContext, preconditionsCopy) {
|
||||
|
@ -131,7 +134,11 @@ func validateResource(log logr.Logger, ctx *PolicyContext) *response.EngineRespo
|
|||
}
|
||||
}
|
||||
} else if rule.Validation.Deny != nil {
|
||||
denyConditionsCopy := copyConditions(rule.Validation.Deny.Conditions)
|
||||
denyConditionsCopy, err := copyConditions(rule.Validation.Deny.AnyAllConditions)
|
||||
if err != nil {
|
||||
log.V(2).Info("wrongfully configured data", "reason", err.Error())
|
||||
continue
|
||||
}
|
||||
deny := variables.EvaluateConditions(log, ctx.JSONContext, denyConditionsCopy)
|
||||
ruleResp := response.RuleResponse{
|
||||
Name: rule.Name,
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -17,8 +17,49 @@ func Evaluate(log logr.Logger, ctx context.EvalInterface, condition kyverno.Cond
|
|||
return handle.Evaluate(condition.Key, condition.Value)
|
||||
}
|
||||
|
||||
//EvaluateConditions evaluates multiple conditions as a logical AND operation
|
||||
func EvaluateConditions(log logr.Logger, ctx context.EvalInterface, conditions []kyverno.Condition) bool {
|
||||
//EvaluateConditions evalues all the conditions present in a slice, in a backwards compatible way
|
||||
func EvaluateConditions(log logr.Logger, ctx context.EvalInterface, conditions interface{}) bool {
|
||||
switch typedConditions := conditions.(type) {
|
||||
case kyverno.AnyAllConditions:
|
||||
return evaluateAnyAllConditions(log, ctx, typedConditions)
|
||||
case []kyverno.Condition: // backwards compatibility
|
||||
return evaluateOldConditions(log, ctx, typedConditions)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//evaluateAnyAllConditions evaluates multiple conditions as a logical AND (all) or OR (any) operation depending on the conditions
|
||||
func evaluateAnyAllConditions(log logr.Logger, ctx context.EvalInterface, conditions kyverno.AnyAllConditions) bool {
|
||||
anyConditions, allConditions := conditions.AnyConditions, conditions.AllConditions
|
||||
anyConditionsResult, allConditionsResult := true, true
|
||||
|
||||
// update the anyConditionsResult if they are present
|
||||
if anyConditions != nil {
|
||||
anyConditionsResult = false
|
||||
for _, condition := range anyConditions {
|
||||
if Evaluate(log, ctx, condition) {
|
||||
anyConditionsResult = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update the allConditionsResult if they are present
|
||||
if allConditions != nil {
|
||||
for _, condition := range allConditions {
|
||||
if !Evaluate(log, ctx, condition) {
|
||||
allConditionsResult = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finalResult := anyConditionsResult && allConditionsResult
|
||||
return finalResult
|
||||
}
|
||||
|
||||
//evaluateOldConditions evaluates multiple conditions when those conditions are provided in the old manner i.e. without 'any' or 'all'
|
||||
func evaluateOldConditions(log logr.Logger, ctx context.EvalInterface, conditions []kyverno.Condition) bool {
|
||||
for _, condition := range conditions {
|
||||
if !Evaluate(log, ctx, condition) {
|
||||
return false
|
||||
|
|
|
@ -2,10 +2,13 @@ package policy
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/variables"
|
||||
"github.com/kyverno/kyverno/pkg/utils"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
|
@ -50,13 +53,9 @@ func ContainsVariablesOtherThanObject(policy kyverno.ClusterPolicy) error {
|
|||
}
|
||||
}
|
||||
|
||||
for condIdx, condition := range rule.Conditions {
|
||||
if condition.Key, err = variables.SubstituteVars(log.Log, ctx, condition.Key); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %v used at spec/rules[%d]/condition[%d]/key: %s", condition.Key, idx, condIdx, err.Error())
|
||||
}
|
||||
|
||||
if condition.Value, err = variables.SubstituteVars(log.Log, ctx, condition.Value); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid %v variable used at spec/rules[%d]/condition[%d]/value: %s", condition.Value, idx, condIdx, err.Error())
|
||||
if rule.AnyAllConditions != nil {
|
||||
if err = validatePreConditions(idx, ctx, rule.AnyAllConditions); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,15 +93,8 @@ func ContainsVariablesOtherThanObject(policy kyverno.ClusterPolicy) error {
|
|||
}
|
||||
|
||||
if rule.Validation.Deny != nil {
|
||||
for i := range rule.Validation.Deny.Conditions {
|
||||
if _, err = variables.SubstituteVars(log.Log, ctx, rule.Validation.Deny.Conditions[i].Key); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/validate/deny/conditions[%d]/key: %v",
|
||||
rule.Validation.Deny.Conditions[i].Key, idx, i, err)
|
||||
}
|
||||
if _, err = variables.SubstituteVars(log.Log, ctx, rule.Validation.Deny.Conditions[i].Value); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/validate/deny/conditions[%d]/value: %v",
|
||||
rule.Validation.Deny.Conditions[i].Value, idx, i, err)
|
||||
}
|
||||
if err = validateDenyConditions(idx, ctx, rule.Validation.Deny.AnyAllConditions); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,6 +122,103 @@ func ContainsVariablesOtherThanObject(policy kyverno.ClusterPolicy) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func validatePreConditions(idx int, ctx context.EvalInterface, anyAllConditions apiextensions.JSON) error {
|
||||
var err error
|
||||
// conditions are currently in the form of []interface{}
|
||||
kyvernoAnyAllConditions, err := utils.ApiextensionsJsonToKyvernoConditions(anyAllConditions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch typedPreConditions := kyvernoAnyAllConditions.(type) {
|
||||
case kyverno.AnyAllConditions:
|
||||
if !reflect.DeepEqual(typedPreConditions, kyverno.AnyAllConditions{}) && typedPreConditions.AnyConditions != nil {
|
||||
for condIdx, condition := range typedPreConditions.AnyConditions {
|
||||
if condition.Key, err = variables.SubstituteVars(log.Log, ctx, condition.Key); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/any/condition[%d]/key", condition.Key, idx, condIdx)
|
||||
}
|
||||
|
||||
if condition.Value, err = variables.SubstituteVars(log.Log, ctx, condition.Value); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid %s variable used at spec/rules[%d]/any/condition[%d]/value", condition.Value, idx, condIdx)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(typedPreConditions, kyverno.AnyAllConditions{}) && typedPreConditions.AllConditions != nil {
|
||||
for condIdx, condition := range typedPreConditions.AllConditions {
|
||||
if condition.Key, err = variables.SubstituteVars(log.Log, ctx, condition.Key); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/all/condition[%d]/key", condition.Key, idx, condIdx)
|
||||
}
|
||||
|
||||
if condition.Value, err = variables.SubstituteVars(log.Log, ctx, condition.Value); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid %s variable used at spec/rules[%d]/all/condition[%d]/value", condition.Value, idx, condIdx)
|
||||
}
|
||||
}
|
||||
}
|
||||
case []kyverno.Condition: //backwards compatibility
|
||||
for condIdx, condition := range typedPreConditions {
|
||||
if condition.Key, err = variables.SubstituteVars(log.Log, ctx, condition.Key); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/condition[%d]/key", condition.Key, idx, condIdx)
|
||||
}
|
||||
|
||||
if condition.Value, err = variables.SubstituteVars(log.Log, ctx, condition.Value); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid %s variable used at spec/rules[%d]/condition[%d]/value", condition.Value, idx, condIdx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDenyConditions(idx int, ctx context.EvalInterface, denyConditions apiextensions.JSON) error {
|
||||
// conditions are currently in the form of []interface{}
|
||||
kyvernoDenyConditions, err := utils.ApiextensionsJsonToKyvernoConditions(denyConditions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch typedDenyConditions := kyvernoDenyConditions.(type) {
|
||||
case kyverno.AnyAllConditions:
|
||||
// validating validate.deny.any.conditions
|
||||
if !reflect.DeepEqual(typedDenyConditions, kyverno.AnyAllConditions{}) && typedDenyConditions.AnyConditions != nil {
|
||||
for i := range typedDenyConditions.AnyConditions {
|
||||
if _, err := variables.SubstituteVars(log.Log, ctx, typedDenyConditions.AnyConditions[i].Key); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/validate/deny/any/conditions[%d]/key: %v",
|
||||
typedDenyConditions.AnyConditions[i].Key, idx, i, err)
|
||||
}
|
||||
if _, err := variables.SubstituteVars(log.Log, ctx, typedDenyConditions.AnyConditions[i].Value); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/validate/deny/any/conditions[%d]/value: %v",
|
||||
typedDenyConditions.AnyConditions[i].Value, idx, i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// validating validate.deny.all.conditions
|
||||
if !reflect.DeepEqual(typedDenyConditions, kyverno.AnyAllConditions{}) && typedDenyConditions.AllConditions != nil {
|
||||
for i := range typedDenyConditions.AllConditions {
|
||||
if _, err := variables.SubstituteVars(log.Log, ctx, typedDenyConditions.AllConditions[i].Key); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/validate/deny/all/conditions[%d]/key: %v",
|
||||
typedDenyConditions.AllConditions[i].Key, idx, i, err)
|
||||
}
|
||||
if _, err := variables.SubstituteVars(log.Log, ctx, typedDenyConditions.AllConditions[i].Value); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/validate/deny/all/conditions[%d]/value: %v",
|
||||
typedDenyConditions.AllConditions[i].Value, idx, i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
case []kyverno.Condition: // backwards compatibility
|
||||
// validating validate.deny.conditions
|
||||
for i := range typedDenyConditions {
|
||||
if _, err := variables.SubstituteVars(log.Log, ctx, typedDenyConditions[i].Key); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/validate/deny/conditions[%d]/key: %v",
|
||||
typedDenyConditions[i].Key, idx, i, err)
|
||||
}
|
||||
if _, err := variables.SubstituteVars(log.Log, ctx, typedDenyConditions[i].Value); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable %s used at spec/rules[%d]/validate/deny/conditions[%d]/value: %v",
|
||||
typedDenyConditions[i].Value, idx, i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkNotFoundErr(err error) bool {
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/utils"
|
||||
"github.com/minio/minio/pkg/wildcard"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
log "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
@ -482,32 +483,63 @@ func validateResources(rule kyverno.Rule) (string, error) {
|
|||
return fmt.Sprintf("exclude.resources.%s", path), err
|
||||
}
|
||||
|
||||
//validating the values present under validation.preconditions, if they exist
|
||||
if rule.Conditions != nil {
|
||||
if path, err := validateConditions(rule.Conditions, "preconditions"); err != nil {
|
||||
//validating the values present under validate.preconditions, if they exist
|
||||
if rule.AnyAllConditions != nil {
|
||||
if path, err := validateConditions(rule.AnyAllConditions, "preconditions"); err != nil {
|
||||
return fmt.Sprintf("validate.%s", path), err
|
||||
}
|
||||
}
|
||||
// validating the values present under validation.deny.conditions, if they exist
|
||||
if rule.Validation.Deny != nil {
|
||||
if path, err := validateConditions(rule.Validation.Deny.Conditions, "conditions"); err != nil {
|
||||
//validating the values present under validate.conditions, if they exist
|
||||
if rule.Validation.Deny != nil && rule.Validation.Deny.AnyAllConditions != nil {
|
||||
if path, err := validateConditions(rule.Validation.Deny.AnyAllConditions, "conditions"); err != nil {
|
||||
return fmt.Sprintf("validate.deny.%s", path), err
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// validateConditions validates all the 'conditions' or 'preconditions' of a rule depending on the corresponding 'condition.key'.
|
||||
// As of now, it is validating the 'value' field whether it contains the only allowed set of values or not when 'condition.key' is {{request.operation}}
|
||||
func validateConditions(conditions []kyverno.Condition, schemaKey string) (string, error) {
|
||||
// []kyverno.Condition can only exist under either 'conditions' or 'preconditions' key of the policy schema
|
||||
if schemaKey != "conditions" && schemaKey != "preconditions" {
|
||||
return fmt.Sprintf(schemaKey), fmt.Errorf("wrong schema key found for validating the conditions. Conditions can only occur under 'preconditions' or 'conditions' key in the policy schema")
|
||||
// this is backwards compatible i.e. conditions can be provided in the old manner as well i.e. without 'any' or 'all'
|
||||
func validateConditions(conditions apiextensions.JSON, schemaKey string) (string, error) {
|
||||
// Conditions can only exist under some specific keys of the policy schema
|
||||
allowedSchemaKeys := map[string]bool{
|
||||
"preconditions": true,
|
||||
"conditions": true,
|
||||
}
|
||||
for i, condition := range conditions {
|
||||
if path, err := validateConditionValues(condition); err != nil {
|
||||
return fmt.Sprintf("%s[%d].%s", schemaKey, i, path), err
|
||||
if !allowedSchemaKeys[schemaKey] {
|
||||
return fmt.Sprintf(schemaKey), fmt.Errorf("wrong schema key found for validating the conditions. Conditions can only occur under one of ['preconditions', 'conditions'] keys in the policy schema")
|
||||
}
|
||||
|
||||
// conditions are currently in the form of []interface{}
|
||||
kyvernoConditions, err := utils.ApiextensionsJsonToKyvernoConditions(conditions)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("%s", schemaKey), err
|
||||
}
|
||||
switch typedConditions := kyvernoConditions.(type) {
|
||||
case kyverno.AnyAllConditions:
|
||||
// validating the conditions under 'any', if there are any
|
||||
if !reflect.DeepEqual(typedConditions, kyverno.AnyAllConditions{}) && typedConditions.AnyConditions != nil {
|
||||
for i, condition := range typedConditions.AnyConditions {
|
||||
if path, err := validateConditionValues(condition); err != nil {
|
||||
return fmt.Sprintf("%s.any[%d].%s", schemaKey, i, path), err
|
||||
}
|
||||
}
|
||||
}
|
||||
// validating the conditions under 'all', if there are any
|
||||
if !reflect.DeepEqual(typedConditions, kyverno.AnyAllConditions{}) && typedConditions.AllConditions != nil {
|
||||
for i, condition := range typedConditions.AllConditions {
|
||||
if path, err := validateConditionValues(condition); err != nil {
|
||||
return fmt.Sprintf("%s.all[%d].%s", schemaKey, i, path), err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case []kyverno.Condition: // backwards compatibility
|
||||
for i, condition := range typedConditions {
|
||||
if path, err := validateConditionValues(condition); err != nil {
|
||||
return fmt.Sprintf("%s[%d].%s", schemaKey, i, path), err
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
|
|
|
@ -4,8 +4,10 @@ import (
|
|||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/openapi"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
|
@ -253,23 +255,29 @@ func Test_Validate_ResourceDescription_MatchedValid(t *testing.T) {
|
|||
func Test_Validate_DenyConditions_KeyRequestOperation_Empty(t *testing.T) {
|
||||
denyConditions := []byte(`[]`)
|
||||
|
||||
var dcs []kyverno.Condition
|
||||
var dcs apiextensions.JSON
|
||||
err := json.Unmarshal(denyConditions, &dcs)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(dcs, "conditions")
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(dcs, "conditions")
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
func Test_Validate_Preconditions_KeyRequestOperation_Empty(t *testing.T) {
|
||||
preConditions := []byte(`[]`)
|
||||
|
||||
var pcs []kyverno.Condition
|
||||
var pcs apiextensions.JSON
|
||||
err := json.Unmarshal(preConditions, &pcs)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(pcs, "preconditions")
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(pcs, "preconditions")
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
func Test_Validate_DenyConditionsValuesString_KeyRequestOperation_ExpectedValue(t *testing.T) {
|
||||
|
@ -303,12 +311,15 @@ func Test_Validate_DenyConditionsValuesString_KeyRequestOperation_ExpectedValue(
|
|||
]
|
||||
`)
|
||||
|
||||
var dcs []kyverno.Condition
|
||||
var dcs apiextensions.JSON
|
||||
err := json.Unmarshal(denyConditions, &dcs)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(dcs, "conditions")
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(dcs, "conditions")
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
func Test_Validate_DenyConditionsValuesString_KeyRequestOperation_RightfullyTemplatizedValue(t *testing.T) {
|
||||
|
@ -327,12 +338,15 @@ func Test_Validate_DenyConditionsValuesString_KeyRequestOperation_RightfullyTemp
|
|||
]
|
||||
`)
|
||||
|
||||
var dcs []kyverno.Condition
|
||||
var dcs apiextensions.JSON
|
||||
err := json.Unmarshal(denyConditions, &dcs)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(dcs, "conditions")
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(dcs, "conditions")
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
func Test_Validate_DenyConditionsValuesString_KeyRequestOperation_WrongfullyTemplatizedValue(t *testing.T) {
|
||||
|
@ -375,12 +389,15 @@ func Test_Validate_PreconditionsValuesString_KeyRequestOperation_UnknownValue(t
|
|||
]
|
||||
`)
|
||||
|
||||
var pcs []kyverno.Condition
|
||||
var pcs apiextensions.JSON
|
||||
err := json.Unmarshal(preConditions, &pcs)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(pcs, "preconditions")
|
||||
assert.Assert(t, err != nil)
|
||||
|
||||
_, err = validateConditions(pcs, "preconditions")
|
||||
assert.Assert(t, err != nil)
|
||||
}
|
||||
|
||||
func Test_Validate_DenyConditionsValuesList_KeyRequestOperation_ExpectedItem(t *testing.T) {
|
||||
|
@ -439,12 +456,15 @@ func Test_Validate_PreconditionsValuesList_KeyRequestOperation_UnknownItem(t *te
|
|||
]
|
||||
`)
|
||||
|
||||
var pcs []kyverno.Condition
|
||||
var pcs apiextensions.JSON
|
||||
err := json.Unmarshal(preConditions, &pcs)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = validateConditions(pcs, "preconditions")
|
||||
assert.Assert(t, err != nil)
|
||||
|
||||
_, err = validateConditions(pcs, "preconditions")
|
||||
assert.Assert(t, err != nil)
|
||||
}
|
||||
|
||||
func Test_Validate_ResourceDescription_MissingKindsOnExclude(t *testing.T) {
|
||||
|
@ -1203,7 +1223,7 @@ func Test_doesMatchExcludeConflict(t *testing.T) {
|
|||
},
|
||||
{
|
||||
description: "empty case",
|
||||
rule: []byte(`{"name":"check-allow-deletes","match":{"resources":{"selector":{"matchLabels":{"allow-deletes":"false"}}}},"exclude":{"clusterRoles":["random"]},"validate":{"message":"Deleting {{request.object.kind}}/{{request.object.metadata.name}} is not allowed","deny":{"conditions":[{"key":"{{request.operation}}","operator":"Equal","value":"DELETE"}]}}}`),
|
||||
rule: []byte(`{"name":"check-allow-deletes","match":{"resources":{"selector":{"matchLabels":{"allow-deletes":"false"}}}},"exclude":{"clusterRoles":["random"]},"validate":{"message":"Deleting {{request.object.kind}}/{{request.object.metadata.name}} is not allowed","deny":{"conditions":{"all":[{"key":"{{request.operation}}","operator":"Equal","value":"DELETE"}]}}}}`),
|
||||
expectedOutput: false,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -121,13 +121,15 @@ func newPolicy(t *testing.T) *kyverno.ClusterPolicy {
|
|||
},
|
||||
"validate": {
|
||||
"deny": {
|
||||
"conditions": [
|
||||
{
|
||||
"key": "a",
|
||||
"operator": "Equals",
|
||||
"value": "a"
|
||||
}
|
||||
]
|
||||
"conditions": {
|
||||
"all": [
|
||||
{
|
||||
"key": "a",
|
||||
"operator": "Equals",
|
||||
"value": "a"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -226,13 +228,15 @@ func newNsPolicy(t *testing.T) *kyverno.ClusterPolicy {
|
|||
},
|
||||
"validate": {
|
||||
"deny": {
|
||||
"conditions": [
|
||||
{
|
||||
"key": "a",
|
||||
"operator": "Equals",
|
||||
"value": "a"
|
||||
}
|
||||
]
|
||||
"conditions": {
|
||||
"all": [
|
||||
{
|
||||
"key": "a",
|
||||
"operator": "Equals",
|
||||
"value": "a"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/common"
|
||||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
"github.com/kyverno/kyverno/pkg/utils"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
)
|
||||
|
||||
// GenerateJSONPatchesForDefaults generates default JSON patches for
|
||||
|
@ -360,7 +361,7 @@ type kyvernoRule struct {
|
|||
MatchResources *kyverno.MatchResources `json:"match"`
|
||||
ExcludeResources *kyverno.ExcludeResources `json:"exclude,omitempty"`
|
||||
Context *[]kyverno.ContextEntry `json:"context,omitempty"`
|
||||
Conditions *[]kyverno.Condition `json:"preconditions,omitempty"`
|
||||
AnyAllConditions *apiextensions.JSON `json:"preconditions,omitempty"`
|
||||
Mutation *kyverno.Mutation `json:"mutate,omitempty"`
|
||||
Validation *kyverno.Validation `json:"validate,omitempty"`
|
||||
}
|
||||
|
@ -429,8 +430,16 @@ func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr.
|
|||
controllerRule.Context = &rule.DeepCopy().Context
|
||||
}
|
||||
|
||||
if len(rule.Conditions) > 0 {
|
||||
controllerRule.Conditions = &rule.DeepCopy().Conditions
|
||||
kyvernoAnyAllConditions, _ := utils.ApiextensionsJsonToKyvernoConditions(rule.AnyAllConditions)
|
||||
switch typedAnyAllConditions := kyvernoAnyAllConditions.(type) {
|
||||
case kyverno.AnyAllConditions:
|
||||
if !reflect.DeepEqual(typedAnyAllConditions, kyverno.AnyAllConditions{}) {
|
||||
controllerRule.AnyAllConditions = &rule.DeepCopy().AnyAllConditions
|
||||
}
|
||||
case []kyverno.Condition:
|
||||
if len(typedAnyAllConditions) > 0 {
|
||||
controllerRule.AnyAllConditions = &rule.DeepCopy().AnyAllConditions
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(exclude, kyverno.ExcludeResources{}) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
@ -8,10 +9,12 @@ import (
|
|||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
client "github.com/kyverno/kyverno/pkg/dclient"
|
||||
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
"github.com/minio/minio/pkg/wildcard"
|
||||
"k8s.io/api/admission/v1beta1"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
@ -193,3 +196,23 @@ func SliceContains(slice []string, values ...string) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
// ApiextensionsJsonTOKyvernoConditions takes in user-provided conditions in abstract apiextensions.JSON form
|
||||
// and converts it into []kyverno.Condition or kyverno.AnyAllConditions according to its content.
|
||||
// it also helps in validating the condtions as it returns an error when the conditions are provided wrongfully by the user.
|
||||
func ApiextensionsJsonToKyvernoConditions(original apiextensions.JSON) (interface{}, error) {
|
||||
// marshalling the abstract apiextensions.JSON back to JSON form
|
||||
jsonByte, err := json.Marshal(original)
|
||||
|
||||
var kyvernoOldConditions []kyverno.Condition
|
||||
if err = json.Unmarshal(jsonByte, &kyvernoOldConditions); err == nil {
|
||||
return kyvernoOldConditions, nil
|
||||
}
|
||||
|
||||
var kyvernoAnyAllConditions kyverno.AnyAllConditions
|
||||
if err = json.Unmarshal(jsonByte, &kyvernoAnyAllConditions); err == nil {
|
||||
return kyvernoAnyAllConditions, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("conditions filled wrongfully")
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue