1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 07:57:07 +00:00

feat: add new field to control VAP generation per policy (#12242)

* feat: add new field to control VAP generation per policy

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>

* chore: remove 1.28 and 1.29 from tests

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>

---------

Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
Mariam Fahmy 2025-02-28 15:35:13 +02:00 committed by GitHub
parent 5dd6ebd04b
commit 2ea7e7ce76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
60 changed files with 490 additions and 13 deletions

View file

@ -592,6 +592,12 @@ func (pss *PodSecurityStandard) Validate(path *field.Path) (errs field.ErrorList
// CEL allows validation checks using the Common Expression Language (https://kubernetes.io/docs/reference/using-api/cel/).
type CEL struct {
// Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
// Optional. Defaults to "false" if not specified.
// +optional
// +kubebuilder:default=false
Generate *bool `json:"generate,omitempty"`
// Expressions is a list of CELExpression types.
Expressions []admissionregistrationv1.Validation `json:"expressions,omitempty"`
@ -614,6 +620,10 @@ type CEL struct {
Variables []admissionregistrationv1.Variable `json:"variables,omitempty"`
}
func (c *CEL) GenerateVAP() bool {
return c.Generate != nil && *c.Generate
}
func (c *CEL) HasParam() bool {
return c.ParamKind != nil && c.ParamRef != nil
}

View file

@ -215,6 +215,11 @@ func (in *AutogenStatus) DeepCopy() *AutogenStatus {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CEL) DeepCopyInto(out *CEL) {
*out = *in
if in.Generate != nil {
in, out := &in.Generate, &out.Generate
*out = new(bool)
**out = **in
}
if in.Expressions != nil {
in, out := &in.Expressions, &out.Expressions
*out = make([]admissionregistrationv1.Validation, len(*in))

View file

@ -80,6 +80,12 @@ type ValidatingPolicySpec struct {
// +optional
Variables []admissionregistrationv1.Variable `json:"variables,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
// Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy.
// Optional. Defaults to "false" if not specified.
// +optional
// +kubebuilder:default=false
Generate *bool `json:"generate,omitempty"`
// ValidationAction specifies the action to be taken when the matched resource violates the policy.
// Required.
// +listType=set

View file

@ -989,6 +989,11 @@ func (in *ValidatingPolicySpec) DeepCopyInto(out *ValidatingPolicySpec) {
*out = make([]v1.Variable, len(*in))
copy(*out, *in)
}
if in.Generate != nil {
in, out := &in.Generate, &out.Generate
*out = new(bool)
**out = **in
}
if in.ValidationAction != nil {
in, out := &in.ValidationAction, &out.ValidationAction
*out = make([]v1.ValidationAction, len(*in))

View file

@ -3183,6 +3183,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -8299,6 +8305,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -13119,6 +13131,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -18293,6 +18311,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.

View file

@ -3184,6 +3184,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -8301,6 +8307,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -13122,6 +13134,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -18296,6 +18314,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.

View file

@ -157,6 +157,12 @@ spec:
Allowed values are Ignore or Fail. Defaults to Fail.
type: string
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy.
Optional. Defaults to "false" if not specified.
type: boolean
matchConditions:
description: |-
MatchConditions is a list of conditions that must be met for a request to be validated.

View file

@ -3177,6 +3177,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -8293,6 +8299,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -13113,6 +13125,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -18287,6 +18305,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.

View file

@ -3178,6 +3178,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -8295,6 +8301,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -13116,6 +13128,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -18290,6 +18308,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.

View file

@ -151,6 +151,12 @@ spec:
Allowed values are Ignore or Fail. Defaults to Fail.
type: string
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy.
Optional. Defaults to "false" if not specified.
type: boolean
matchConditions:
description: |-
MatchConditions is a list of conditions that must be met for a request to be validated.

View file

@ -3177,6 +3177,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -8293,6 +8299,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -13113,6 +13125,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -18287,6 +18305,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.

View file

@ -3178,6 +3178,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -8295,6 +8301,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -13116,6 +13128,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -18290,6 +18308,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.

View file

@ -151,6 +151,12 @@ spec:
Allowed values are Ignore or Fail. Defaults to Fail.
type: string
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy.
Optional. Defaults to "false" if not specified.
type: boolean
matchConditions:
description: |-
MatchConditions is a list of conditions that must be met for a request to be validated.

View file

@ -8602,6 +8602,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -13718,6 +13724,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -18538,6 +18550,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -23712,6 +23730,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -29176,6 +29200,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -34293,6 +34323,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -39114,6 +39150,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind and
Version.
@ -44288,6 +44330,12 @@ spec:
- expression
type: object
type: array
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to "false" if not specified.
type: boolean
paramKind:
description: ParamKind is a tuple of Group Kind
and Version.
@ -48699,6 +48747,12 @@ spec:
Allowed values are Ignore or Fail. Defaults to Fail.
type: string
generate:
default: false
description: |-
Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy.
Optional. Defaults to "false" if not specified.
type: boolean
matchConditions:
description: |-
MatchConditions is a list of conditions that must be met for a request to be validated.

View file

@ -1050,6 +1050,19 @@ attributes for keyless verification, or a nested attestor declaration.</p>
<tbody>
<tr>
<td>
<code>generate</code><br/>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>expressions</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#validation-v1-admissionregistration">
@ -10813,6 +10826,19 @@ Thus, Variables must be sorted by the order of first appearance and acyclic.</p>
</tr>
<tr>
<td>
<code>generate</code><br/>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy.
Optional. Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>validationActions</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#validationaction-v1-admissionregistration">
@ -12705,6 +12731,19 @@ Thus, Variables must be sorted by the order of first appearance and acyclic.</p>
</tr>
<tr>
<td>
<code>generate</code><br/>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy.
Optional. Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>validationActions</code><br/>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#validationaction-v1-admissionregistration">

View file

@ -2151,6 +2151,34 @@ attributes for keyless verification, or a nested attestor declaration.</p>
<tr>
<td><code>generate</code>
</br>
<span style="font-family: monospace">bool</span>
</td>
<td>
<p>Generate specifies whether to generate a Kubernetes ValidatingAdmissionPolicy from the rule.
Optional. Defaults to &quot;false&quot; if not specified.</p>
</td>
</tr>
<tr>
<td><code>expressions</code>

View file

@ -7,9 +7,9 @@ import (
)
// CanGenerateVAP check if Kyverno policy and a PolicyException can be translated to a Kubernetes ValidatingAdmissionPolicy
func CanGenerateVAP(spec *kyvernov1.Spec, exceptions []kyvernov2.PolicyException) (bool, string) {
func CanGenerateVAP(spec *kyvernov1.Spec, exceptions []kyvernov2.PolicyException, validate bool) (bool, string) {
var msg string
if ok, msg := checkPolicy(spec); !ok {
if ok, msg := checkPolicy(spec, validate); !ok {
return false, msg
}
@ -52,14 +52,14 @@ func checkExceptions(exceptions []kyvernov2.PolicyException) (bool, string) {
return true, msg
}
func checkPolicy(spec *kyvernov1.Spec) (bool, string) {
func checkPolicy(spec *kyvernov1.Spec, validate bool) (bool, string) {
var msg string
if ok, msg := checkRuleCount(spec); !ok {
return false, msg
}
rule := spec.Rules[0]
if ok, msg := checkRuleType(rule); !ok {
if ok, msg := checkRuleType(rule, validate); !ok {
return false, msg
}
@ -125,11 +125,16 @@ func checkRuleCount(spec *kyvernov1.Spec) (bool, string) {
return true, msg
}
func checkRuleType(rule kyvernov1.Rule) (bool, string) {
func checkRuleType(rule kyvernov1.Rule, validate bool) (bool, string) {
var msg string
if !rule.HasValidateCEL() {
msg = "skip generating ValidatingAdmissionPolicy for non CEL rules."
return false, msg
} else if !validate {
if !rule.Validation.CEL.GenerateVAP() {
msg = "skip generating ValidatingAdmissionPolicy: validate.cel.generate is not set to true."
return false, msg
}
}
return true, msg
}

View file

@ -827,6 +827,7 @@ func Test_Can_Generate_ValidatingAdmissionPolicy(t *testing.T) {
},
"validate": {
"cel": {
"generate": true,
"expressions": [
{
"expression": "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath))"
@ -841,6 +842,66 @@ func Test_Can_Generate_ValidatingAdmissionPolicy(t *testing.T) {
`),
expected: true,
},
{
name: "policy-with-generate-set-to-false",
policy: []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "disallow-host-path"
},
"spec": {
"validationFailureAction": "Enforce",
"rules": [
{
"name": "host-path",
"match": {
"any": [
{
"resources": {
"kinds": [
"Deployment"
],
"operations": [
"CREATE",
"UPDATE"
],
"selector": {
"matchLabels": {
"app": "mongodb"
},
"matchExpressions": [
{
"key": "tier",
"operator": "In",
"values": [
"database"
]
}
]
}
}
}
]
},
"validate": {
"cel": {
"generate": false,
"expressions": [
{
"expression": "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath))"
}
]
}
}
}
]
}
}
`),
expected: false,
},
{
name: "policy-with-no-rules",
policy: []byte(`
@ -863,7 +924,7 @@ func Test_Can_Generate_ValidatingAdmissionPolicy(t *testing.T) {
policies, _, _, _, err := yamlutils.GetPolicy([]byte(test.policy))
assert.NilError(t, err)
assert.Equal(t, 1, len(policies))
out, _ := CanGenerateVAP(policies[0].GetSpec(), nil)
out, _ := CanGenerateVAP(policies[0].GetSpec(), nil, false)
assert.Equal(t, out, test.expected)
})
}

View file

@ -397,7 +397,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam
return err
}
if ok, msg := admissionpolicy.CanGenerateVAP(spec, exceptions); !ok {
if ok, msg := admissionpolicy.CanGenerateVAP(spec, exceptions, false); !ok {
// delete the ValidatingAdmissionPolicy if exist
if vapErr == nil {
err = c.client.AdmissionregistrationV1().ValidatingAdmissionPolicies().Delete(ctx, vapName, metav1.DeleteOptions{})

View file

@ -454,7 +454,7 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
}
// check for CEL expression warnings in case of CEL subrules
if ok, _ := admissionpolicy.CanGenerateVAP(spec, nil); ok && client != nil {
if ok, _ := admissionpolicy.CanGenerateVAP(spec, nil, true); ok && client != nil {
resolver := &resolver.ClientDiscoveryResolver{
Discovery: client.GetKubeClient().Discovery(),
}

View file

@ -17,6 +17,7 @@ spec:
validate:
failureAction: Enforce
cel:
generate: true
expressions:
- expression: "!has(object.spec.ephemeralContainers)"
message: "Ephemeral (debug) containers are not permitted."

View file

@ -17,6 +17,7 @@ spec:
expression: "request.operation == 'CONNECT'"
validate:
cel:
generate: true
expressions:
- expression: "request.namespace != 'pci'"
message: Pods in this namespace may not be exec'd into.

View file

@ -21,6 +21,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -26,6 +26,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -30,6 +30,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -30,6 +30,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -30,6 +30,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -35,6 +35,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -26,6 +26,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -19,5 +19,6 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "'app' in object.metadata.labels"

View file

@ -26,5 +26,6 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "'app' in object.metadata.labels"

View file

@ -17,5 +17,6 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "'app' in object.metadata.labels"

View file

@ -19,6 +19,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -17,6 +17,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -26,6 +26,7 @@ spec:
- connector
validate:
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -26,6 +26,7 @@ spec:
- connector
validate:
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -28,6 +28,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -25,6 +25,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -16,5 +16,6 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "'app' in object.metadata.labels"

View file

@ -16,5 +16,6 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "'app' in object.metadata.labels"

View file

@ -34,6 +34,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -28,6 +28,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -28,6 +28,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -31,6 +31,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -21,5 +21,6 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "'app' in object.metadata.labels"

View file

@ -21,5 +21,6 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "'app' in object.metadata.labels"

View file

@ -22,6 +22,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -18,6 +18,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -27,6 +27,7 @@ spec:
validate:
failureAction: Audit
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -12,6 +12,7 @@ spec:
- Pod
validate:
cel:
generate: true
expressions:
- expression: "object.spec.containers.all(container, !container.image.matches('^[a-zA-Z]+:[0-9]*$'))"
message: "An image tag is required."
@ -23,6 +24,7 @@ spec:
- Pod
validate:
cel:
generate: true
expressions:
- expression: "object.spec.containers.all(container, !container.image.contains('latest'))"
message: "Using a mutable image tag e.g. 'latest' is not allowed."

View file

@ -20,5 +20,6 @@ spec:
namespaces:
- test
cel:
generate: true
expressions:
- expression: "'app' in object.metadata.labels"

View file

@ -16,8 +16,7 @@ spec:
- action: Enforce
namespaces:
- default
message: "The label `app` is required."
pattern:
metadata:
labels:
app: "?*"
cel:
generate: true
expressions:
- expression: "'app' in object.metadata.labels"

View file

@ -26,6 +26,7 @@ spec:
- connector
validate:
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -17,6 +17,7 @@ spec:
- UPDATE
validate:
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -17,6 +17,7 @@ spec:
- UPDATE
validate:
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -17,6 +17,7 @@ spec:
- UPDATE
validate:
cel:
generate: true
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -0,0 +1,26 @@
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: disable-generate
spec:
steps:
- name: create policy
use:
template: ../../../../../_step-templates/create-policy.yaml
with:
bindings:
- name: file
value: policy.yaml
- name: wait policy ready
use:
template: ../../../../../_step-templates/cluster-policy-ready.yaml
with:
bindings:
- name: name
value: disable-generate
- name: step-02
try:
- error:
file: validatingadmissionpolicy.yaml
- error:
file: validatingadmissionpolicybinding.yaml

View file

@ -0,0 +1,27 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disable-generate
spec:
background: false
rules:
- name: host-path
match:
all:
- resources:
kinds:
- Deployment
- StatefulSet
operations:
- CREATE
- UPDATE
selector:
matchLabels:
app: critical
validate:
failureAction: Audit
cel:
generate: false
expressions:
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."

View file

@ -0,0 +1,7 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
labels:
app.kubernetes.io/managed-by: kyverno
name: cpol-disable-generate
spec: {}

View file

@ -0,0 +1,7 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
labels:
app.kubernetes.io/managed-by: kyverno
name: cpol-disable-generate-binding
spec: {}