mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-15 20:20:22 +00:00
Unit tests for Pod Security Admission Integrations (#8585)
* feat: enable field-restricted exclusions using the psa Signed-off-by: Liang Deng <283304489@qq.com> * fix ci error Signed-off-by: Liang Deng <283304489@qq.com> * fix ci error Signed-off-by: Liang Deng <283304489@qq.com> * initial unit tests * Add all remaining unit tests Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * fine grain unit tests by adding fields and values * add detailed pod level exclusion and related tests * add tests for init & ephemeral containers * add kuttl tests for the new advanced support * add kuttl tests for the new advanced support * add readme for kuttl tests * add replacement in go.mod * resolving CI errors Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * fix ci errors Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * fix ci errors Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * updating pod-security-admissio Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * resolving null pointer panic Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * resolved conformance error Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * chainsaw Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * chainsaw Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * remove duplication Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * fix linting Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * remove over computation Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * added field checks, pss skip condition Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * correcting chainsaw tests Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * merge branch 'main' into unit-tests Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> * fix builds Signed-off-by: ShutingZhao <shuting@nirmata.com> --------- Signed-off-by: Liang Deng <283304489@qq.com> Signed-off-by: Gurmannat Sohal <iamgurmannatsohal@gmail.com> Signed-off-by: shuting <shuting@nirmata.com> Signed-off-by: Gurmannat Sohal <95538438+itsgurmannatsohal@users.noreply.github.com> Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> Co-authored-by: Liang Deng <283304489@qq.com> Co-authored-by: shuting <shuting@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
4fff841cdc
commit
6902a2b092
239 changed files with 11233 additions and 48 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -19,3 +19,4 @@ cmd/background-controller/background-controller
|
||||||
.dist
|
.dist
|
||||||
.manifest
|
.manifest
|
||||||
kyverno.tar.gz
|
kyverno.tar.gz
|
||||||
|
vendor/
|
||||||
|
|
|
@ -429,6 +429,24 @@ type PodSecurityStandard struct {
|
||||||
// Wildcards ('*' and '?') are allowed. See: https://kubernetes.io/docs/concepts/containers/images.
|
// Wildcards ('*' and '?') are allowed. See: https://kubernetes.io/docs/concepts/containers/images.
|
||||||
// +optional
|
// +optional
|
||||||
Images []string `json:"images,omitempty" yaml:"images,omitempty"`
|
Images []string `json:"images,omitempty" yaml:"images,omitempty"`
|
||||||
|
|
||||||
|
// RestrictedField selects the field for the given Pod Security Standard control.
|
||||||
|
// When not set, all restricted fields for the control are selected.
|
||||||
|
// +optional
|
||||||
|
RestrictedField string `json:"restrictedField,omitempty" yaml:"restrictedField,omitempty"`
|
||||||
|
|
||||||
|
// Values defines the allowed values that can be excluded.
|
||||||
|
// +optional
|
||||||
|
Values []string `json:"values,omitempty" yaml:"values,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate checks if the values in the PodSecurityStandard struct are valid.
|
||||||
|
func (pss *PodSecurityStandard) Validate(exclude PodSecurityStandard) error {
|
||||||
|
if (exclude.RestrictedField != "" && len(exclude.Values) == 0) || (exclude.RestrictedField == "" && len(exclude.Values) != 0) {
|
||||||
|
return fmt.Errorf("Values[] and RestrictedField must be set together")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CEL allows validation checks using the Common Expression Language (https://kubernetes.io/docs/reference/using-api/cel/).
|
// CEL allows validation checks using the Common Expression Language (https://kubernetes.io/docs/reference/using-api/cel/).
|
||||||
|
|
|
@ -992,6 +992,11 @@ func (in *PodSecurityStandard) DeepCopyInto(out *PodSecurityStandard) {
|
||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
|
if in.Values != nil {
|
||||||
|
in, out := &in.Values, &out.Values
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13424,6 +13424,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -17919,6 +17931,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -22180,6 +22204,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -26649,6 +26685,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -31184,6 +31232,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -35680,6 +35740,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -39942,6 +40014,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -44411,6 +44495,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -3473,6 +3473,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -7968,6 +7980,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -12229,6 +12253,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -16698,6 +16734,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -3474,6 +3474,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -7970,6 +7982,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -12232,6 +12256,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -16701,6 +16737,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -3473,6 +3473,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -7968,6 +7980,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -12229,6 +12253,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -16698,6 +16734,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -3474,6 +3474,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -7970,6 +7982,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -12232,6 +12256,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -16701,6 +16737,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -13643,6 +13643,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -18138,6 +18150,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -22399,6 +22423,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -26868,6 +26904,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -31405,6 +31453,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -35901,6 +35961,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -40163,6 +40235,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the
|
||||||
|
control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
@ -44632,6 +44716,18 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
restrictedField:
|
||||||
|
description: RestrictedField selects the field
|
||||||
|
for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for
|
||||||
|
the control are selected.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: Values defines the allowed values
|
||||||
|
that can be excluded.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
required:
|
required:
|
||||||
- controlName
|
- controlName
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -2848,6 +2848,31 @@ Empty list matches no containers, PSS checks are applied at the pod level only.
|
||||||
Wildcards (‘*’ and ‘?’) are allowed. See: <a href="https://kubernetes.io/docs/concepts/containers/images">https://kubernetes.io/docs/concepts/containers/images</a>.</p>
|
Wildcards (‘*’ and ‘?’) are allowed. See: <a href="https://kubernetes.io/docs/concepts/containers/images">https://kubernetes.io/docs/concepts/containers/images</a>.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>restrictedField</code><br/>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>RestrictedField selects the field for the given Pod Security Standard control.
|
||||||
|
When not set, all restricted fields for the control are selected.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>values</code><br/>
|
||||||
|
<em>
|
||||||
|
[]string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>Values defines the allowed values that can be excluded.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -381,4 +381,8 @@ require (
|
||||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace sigs.k8s.io/kubectl-validate => github.com/kyverno/kubectl-validate v0.0.0-20231116142848-59e4e6124b70
|
replace (
|
||||||
|
github.com/sigstore/cosign/v2 => github.com/kyverno/cosign/v2 v2.0.0-20231109090756-51fd41540436
|
||||||
|
k8s.io/pod-security-admission v0.29.0 => github.com/YTGhost/pod-security-admission v0.0.0-20231116105308-8b1daa0177f2
|
||||||
|
sigs.k8s.io/kubectl-validate => github.com/kyverno/kubectl-validate v0.0.0-20231116142848-59e4e6124b70
|
||||||
|
)
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -149,6 +149,8 @@ github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrU
|
||||||
github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E=
|
github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E=
|
||||||
github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE=
|
github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE=
|
||||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
|
github.com/YTGhost/pod-security-admission v0.0.0-20231116105308-8b1daa0177f2 h1:fU6MSdWY9ny1k+lWzCav7bBp/Is/uK/PAuLSn8SrVrs=
|
||||||
|
github.com/YTGhost/pod-security-admission v0.0.0-20231116105308-8b1daa0177f2/go.mod h1:rBAI9Kn+bV1UGQqDqZSgFo/+fm8S/3fFOsU42Z8SVkc=
|
||||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||||
|
@ -945,6 +947,8 @@ github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2G
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
|
github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
|
||||||
|
github.com/kyverno/cosign/v2 v2.0.0-20231109090756-51fd41540436 h1:PvxtUeaEvHgnVwnksc2LDBjWM7wsyIzZhZzS+RW+BEE=
|
||||||
|
github.com/kyverno/cosign/v2 v2.0.0-20231109090756-51fd41540436/go.mod h1:QuAzDDmES0ROCdTPf97GzjidUmn5lpQq84ESET3NAi8=
|
||||||
github.com/kyverno/go-jmespath v0.4.1-0.20231124160150-95e59c162877 h1:XOLJNGX/q6MVpI8p8MKvk6jGBMvO4CrdwrizMMSsaRU=
|
github.com/kyverno/go-jmespath v0.4.1-0.20231124160150-95e59c162877 h1:XOLJNGX/q6MVpI8p8MKvk6jGBMvO4CrdwrizMMSsaRU=
|
||||||
github.com/kyverno/go-jmespath v0.4.1-0.20231124160150-95e59c162877/go.mod h1:yzDHaKovQy16rjN4kFnjF+IdNoN4p1ndw+va6+B8zUU=
|
github.com/kyverno/go-jmespath v0.4.1-0.20231124160150-95e59c162877/go.mod h1:yzDHaKovQy16rjN4kFnjF+IdNoN4p1ndw+va6+B8zUU=
|
||||||
github.com/kyverno/go-jmespath/internal/testify v1.5.2-0.20230630133209-945021c749d9 h1:lL311dF3a2aeNibJj8v+uhFU3XkvRHZmCtAdSPOrQYY=
|
github.com/kyverno/go-jmespath/internal/testify v1.5.2-0.20230630133209-945021c749d9 h1:lL311dF3a2aeNibJj8v+uhFU3XkvRHZmCtAdSPOrQYY=
|
||||||
|
@ -1311,8 +1315,6 @@ github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR
|
||||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sigstore/cosign/v2 v2.2.2 h1:V1uE1/QnKGfj77vuqlEGBg6O2ZJqOrWkLwjTC21Vxw0=
|
|
||||||
github.com/sigstore/cosign/v2 v2.2.2/go.mod h1:bNmX0qyby7sgcqY9oY/jy5m+XJ3N3LtpOsNfO+A1CGo=
|
|
||||||
github.com/sigstore/fulcio v1.4.3 h1:9JcUCZjjVhRF9fmhVuz6i1RyhCc/EGCD7MOl+iqCJLQ=
|
github.com/sigstore/fulcio v1.4.3 h1:9JcUCZjjVhRF9fmhVuz6i1RyhCc/EGCD7MOl+iqCJLQ=
|
||||||
github.com/sigstore/fulcio v1.4.3/go.mod h1:BQPWo7cfxmJwgaHlphUHUpFkp5+YxeJes82oo39m5og=
|
github.com/sigstore/fulcio v1.4.3/go.mod h1:BQPWo7cfxmJwgaHlphUHUpFkp5+YxeJes82oo39m5og=
|
||||||
github.com/sigstore/k8s-manifest-sigstore v0.5.1 h1:jGYuk6LXJm/GzZB/RR2RZ23T84BCP/j96jmhWRV2Q+g=
|
github.com/sigstore/k8s-manifest-sigstore v0.5.1 h1:jGYuk6LXJm/GzZB/RR2RZ23T84BCP/j96jmhWRV2Q+g=
|
||||||
|
@ -2226,8 +2228,6 @@ k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e h1:snPmy96t93RredGRjKfMFt
|
||||||
k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
|
k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
|
||||||
k8s.io/kubectl v0.28.4 h1:gWpUXW/T7aFne+rchYeHkyB8eVDl5UZce8G4X//kjUQ=
|
k8s.io/kubectl v0.28.4 h1:gWpUXW/T7aFne+rchYeHkyB8eVDl5UZce8G4X//kjUQ=
|
||||||
k8s.io/kubectl v0.28.4/go.mod h1:CKOccVx3l+3MmDbkXtIUtibq93nN2hkDR99XDCn7c/c=
|
k8s.io/kubectl v0.28.4/go.mod h1:CKOccVx3l+3MmDbkXtIUtibq93nN2hkDR99XDCn7c/c=
|
||||||
k8s.io/pod-security-admission v0.29.0 h1:tY/ldtkbBCulMYVSWg6ZDLlgDYDWy6rLj8e/AgmwSj4=
|
|
||||||
k8s.io/pod-security-admission v0.29.0/go.mod h1:bGIeKCzU0Q0Nl185NHmqcMCiOjTcqTrBfAQaeupwq0E=
|
|
||||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
|
k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
|
||||||
|
|
|
@ -193,16 +193,9 @@ func convertRule(rule kyvernoRule, kind string) (*kyvernov1.Rule, error) {
|
||||||
if bytes, err := json.Marshal(rule); err != nil {
|
if bytes, err := json.Marshal(rule); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
if rule.Validation != nil && rule.Validation.PodSecurity != nil {
|
bytes = updateGenRuleByte(bytes, kind)
|
||||||
bytes = updateRestrictedFields(bytes, kind)
|
if err := json.Unmarshal(bytes, &rule); err != nil {
|
||||||
if err := json.Unmarshal(bytes, &rule); err != nil {
|
return nil, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bytes = updateGenRuleByte(bytes, kind)
|
|
||||||
if err := json.Unmarshal(bytes, &rule); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CEL variables are object, oldObject, request, params and authorizer.
|
// CEL variables are object, oldObject, request, params and authorizer.
|
||||||
|
|
|
@ -321,17 +321,6 @@ func updateGenRuleByte(pbyte []byte, kind string) (obj []byte) {
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateRestrictedFields(pbyte []byte, kind string) (obj []byte) {
|
|
||||||
if kind == "Pod" {
|
|
||||||
obj = []byte(strings.ReplaceAll(string(pbyte), `"restrictedField":"spec`, `"restrictedField":"spec.template.spec`))
|
|
||||||
}
|
|
||||||
if kind == "Cronjob" {
|
|
||||||
obj = []byte(strings.ReplaceAll(string(pbyte), `"restrictedField":"spec`, `"restrictedField":"spec.jobTemplate.spec.template.spec`))
|
|
||||||
}
|
|
||||||
obj = []byte(strings.ReplaceAll(string(obj), "metadata", "spec.template.metadata"))
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateCELFields(pbyte []byte, kind string) (obj []byte) {
|
func updateCELFields(pbyte []byte, kind string) (obj []byte) {
|
||||||
if kind == "Pod" {
|
if kind == "Pod" {
|
||||||
obj = []byte(strings.ReplaceAll(string(pbyte), "object.spec", "object.spec.template.spec"))
|
obj = []byte(strings.ReplaceAll(string(pbyte), "object.spec", "object.spec.template.spec"))
|
||||||
|
|
|
@ -21,8 +21,10 @@ package v1
|
||||||
// PodSecurityStandardApplyConfiguration represents an declarative configuration of the PodSecurityStandard type for use
|
// PodSecurityStandardApplyConfiguration represents an declarative configuration of the PodSecurityStandard type for use
|
||||||
// with apply.
|
// with apply.
|
||||||
type PodSecurityStandardApplyConfiguration struct {
|
type PodSecurityStandardApplyConfiguration struct {
|
||||||
ControlName *string `json:"controlName,omitempty"`
|
ControlName *string `json:"controlName,omitempty"`
|
||||||
Images []string `json:"images,omitempty"`
|
Images []string `json:"images,omitempty"`
|
||||||
|
RestrictedField *string `json:"restrictedField,omitempty"`
|
||||||
|
Values []string `json:"values,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PodSecurityStandardApplyConfiguration constructs an declarative configuration of the PodSecurityStandard type for use with
|
// PodSecurityStandardApplyConfiguration constructs an declarative configuration of the PodSecurityStandard type for use with
|
||||||
|
@ -48,3 +50,21 @@ func (b *PodSecurityStandardApplyConfiguration) WithImages(values ...string) *Po
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithRestrictedField sets the RestrictedField field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the RestrictedField field is set to the value of the last call.
|
||||||
|
func (b *PodSecurityStandardApplyConfiguration) WithRestrictedField(value string) *PodSecurityStandardApplyConfiguration {
|
||||||
|
b.RestrictedField = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithValues adds the given value to the Values field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, values provided by each call will be appended to the Values field.
|
||||||
|
func (b *PodSecurityStandardApplyConfiguration) WithValues(values ...string) *PodSecurityStandardApplyConfiguration {
|
||||||
|
for i := range values {
|
||||||
|
b.Values = append(b.Values, values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
|
@ -12,6 +13,7 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
||||||
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||||
"github.com/kyverno/kyverno/pkg/pss"
|
"github.com/kyverno/kyverno/pkg/pss"
|
||||||
|
pssutils "github.com/kyverno/kyverno/pkg/pss/utils"
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
batchv1 "k8s.io/api/batch/v1"
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
@ -35,6 +37,11 @@ func (h validatePssHandler) Process(
|
||||||
_ engineapi.EngineContextLoader,
|
_ engineapi.EngineContextLoader,
|
||||||
exceptions []kyvernov2beta1.PolicyException,
|
exceptions []kyvernov2beta1.PolicyException,
|
||||||
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
||||||
|
if engineutils.IsDeleteRequest(policyContext) {
|
||||||
|
logger.V(3).Info("skipping PSS validation on deleted resource")
|
||||||
|
return resource, nil
|
||||||
|
}
|
||||||
|
|
||||||
// check if there is a policy exception matches the incoming resource
|
// check if there is a policy exception matches the incoming resource
|
||||||
exception := engineutils.MatchesException(exceptions, policyContext, logger)
|
exception := engineutils.MatchesException(exceptions, policyContext, logger)
|
||||||
if exception != nil {
|
if exception != nil {
|
||||||
|
@ -67,6 +74,7 @@ func (h validatePssHandler) Process(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resource, handlers.WithError(rule, engineapi.Validation, "failed to parse pod security api version", err)
|
return resource, handlers.WithError(rule, engineapi.Validation, "failed to parse pod security api version", err)
|
||||||
}
|
}
|
||||||
|
pssChecks = convertChecks(pssChecks, resource.GetKind())
|
||||||
podSecurityChecks := engineapi.PodSecurityChecks{
|
podSecurityChecks := engineapi.PodSecurityChecks{
|
||||||
Level: podSecurity.Level,
|
Level: podSecurity.Level,
|
||||||
Version: podSecurity.Version,
|
Version: podSecurity.Version,
|
||||||
|
@ -85,6 +93,29 @@ func (h validatePssHandler) Process(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convertChecks(checks []pssutils.PSSCheckResult, kind string) (newChecks []pssutils.PSSCheckResult) {
|
||||||
|
if kind == "DaemonSet" || kind == "Deployment" || kind == "Job" || kind == "StatefulSet" || kind == "ReplicaSet" || kind == "ReplicationController" {
|
||||||
|
for i := range checks {
|
||||||
|
for j := range *checks[i].CheckResult.ErrList {
|
||||||
|
(*checks[i].CheckResult.ErrList)[j].Field = strings.ReplaceAll((*checks[i].CheckResult.ErrList)[j].Field, "spec", "spec.template.spec")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if kind == "CronJob" {
|
||||||
|
for i := range checks {
|
||||||
|
for j := range *checks[i].CheckResult.ErrList {
|
||||||
|
(*checks[i].CheckResult.ErrList)[j].Field = strings.ReplaceAll((*checks[i].CheckResult.ErrList)[j].Field, "spec", "spec.jobTemplate.spec.template.spec")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := range checks {
|
||||||
|
for j := range *checks[i].CheckResult.ErrList {
|
||||||
|
(*checks[i].CheckResult.ErrList)[j].Field = strings.ReplaceAll((*checks[i].CheckResult.ErrList)[j].Field, "metadata", "spec.template.metadata")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return checks
|
||||||
|
}
|
||||||
|
|
||||||
func getSpec(resource unstructured.Unstructured) (podSpec *corev1.PodSpec, metadata *metav1.ObjectMeta, err error) {
|
func getSpec(resource unstructured.Unstructured) (podSpec *corev1.PodSpec, metadata *metav1.ObjectMeta, err error) {
|
||||||
kind := resource.GetKind()
|
kind := resource.GetKind()
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,24 @@ package pss
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
"github.com/kyverno/kyverno/ext/wildcard"
|
"github.com/kyverno/kyverno/ext/wildcard"
|
||||||
pssutils "github.com/kyverno/kyverno/pkg/pss/utils"
|
pssutils "github.com/kyverno/kyverno/pkg/pss/utils"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/pod-security-admission/api"
|
"k8s.io/pod-security-admission/api"
|
||||||
"k8s.io/pod-security-admission/policy"
|
"k8s.io/pod-security-admission/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
regexIndex = regexp.MustCompile(`\d+`)
|
||||||
|
regexStr = regexp.MustCompile(`[a-zA-Z]+`)
|
||||||
|
)
|
||||||
|
|
||||||
// Evaluate Pod's specified containers only and get PSSCheckResults
|
// Evaluate Pod's specified containers only and get PSSCheckResults
|
||||||
func evaluatePSS(level *api.LevelVersion, pod corev1.Pod) (results []pssutils.PSSCheckResult) {
|
func evaluatePSS(level *api.LevelVersion, pod corev1.Pod) (results []pssutils.PSSCheckResult) {
|
||||||
checks := policy.DefaultChecks()
|
checks := policy.DefaultChecks()
|
||||||
|
@ -30,7 +38,7 @@ func evaluatePSS(level *api.LevelVersion, pod corev1.Pod) (results []pssutils.PS
|
||||||
}
|
}
|
||||||
|
|
||||||
if level.Version == api.LatestVersion() {
|
if level.Version == api.LatestVersion() {
|
||||||
checkResult := latestVersionCheck.CheckPod(&pod.ObjectMeta, &pod.Spec)
|
checkResult := latestVersionCheck.CheckPod(&pod.ObjectMeta, &pod.Spec, policy.WithFieldErrors())
|
||||||
if !checkResult.Allowed {
|
if !checkResult.Allowed {
|
||||||
results = append(results, pssutils.PSSCheckResult{
|
results = append(results, pssutils.PSSCheckResult{
|
||||||
ID: string(check.ID),
|
ID: string(check.ID),
|
||||||
|
@ -47,7 +55,7 @@ func evaluatePSS(level *api.LevelVersion, pod corev1.Pod) (results []pssutils.PS
|
||||||
} else if level.Version != api.LatestVersion() && level.Version.Older(versionCheck.MinimumVersion) {
|
} else if level.Version != api.LatestVersion() && level.Version.Older(versionCheck.MinimumVersion) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
checkResult := versionCheck.CheckPod(&pod.ObjectMeta, &pod.Spec)
|
checkResult := versionCheck.CheckPod(&pod.ObjectMeta, &pod.Spec, policy.WithFieldErrors())
|
||||||
// Append only if the checkResult is not already in pssCheckResult
|
// Append only if the checkResult is not already in pssCheckResult
|
||||||
if !checkResult.Allowed {
|
if !checkResult.Allowed {
|
||||||
results = append(results, pssutils.PSSCheckResult{
|
results = append(results, pssutils.PSSCheckResult{
|
||||||
|
@ -61,9 +69,14 @@ func evaluatePSS(level *api.LevelVersion, pod corev1.Pod) (results []pssutils.PS
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
func exemptKyvernoExclusion(defaultCheckResults, excludeCheckResults []pssutils.PSSCheckResult, exclude kyvernov1.PodSecurityStandard) []pssutils.PSSCheckResult {
|
func exemptExclusions(defaultCheckResults, excludeCheckResults []pssutils.PSSCheckResult, exclude kyvernov1.PodSecurityStandard, pod *corev1.Pod, matching *corev1.Pod, isContainerLevelExclusion bool) ([]pssutils.PSSCheckResult, error) {
|
||||||
defaultCheckResultsMap := make(map[string]pssutils.PSSCheckResult, len(defaultCheckResults))
|
defaultCheckResultsMap := make(map[string]pssutils.PSSCheckResult, len(defaultCheckResults))
|
||||||
|
|
||||||
|
if err := exclude.Validate(exclude); err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
for _, result := range defaultCheckResults {
|
for _, result := range defaultCheckResults {
|
||||||
defaultCheckResultsMap[result.ID] = result
|
defaultCheckResultsMap[result.ID] = result
|
||||||
}
|
}
|
||||||
|
@ -71,7 +84,70 @@ func exemptKyvernoExclusion(defaultCheckResults, excludeCheckResults []pssutils.
|
||||||
for _, excludeResult := range excludeCheckResults {
|
for _, excludeResult := range excludeCheckResults {
|
||||||
for _, checkID := range pssutils.PSS_controls_to_check_id[exclude.ControlName] {
|
for _, checkID := range pssutils.PSS_controls_to_check_id[exclude.ControlName] {
|
||||||
if excludeResult.ID == checkID {
|
if excludeResult.ID == checkID {
|
||||||
delete(defaultCheckResultsMap, checkID)
|
for _, excludeFieldErr := range *excludeResult.CheckResult.ErrList {
|
||||||
|
var excludeField, excludeContainerType string
|
||||||
|
var excludeIndexes []int
|
||||||
|
var isContainerLevelField bool = false
|
||||||
|
var excludeContainer corev1.Container
|
||||||
|
|
||||||
|
if isContainerLevelExclusion {
|
||||||
|
excludeField, excludeIndexes, excludeContainerType, isContainerLevelField = parseField(excludeFieldErr.Field)
|
||||||
|
} else {
|
||||||
|
excludeField = regexIndex.ReplaceAllString(excludeFieldErr.Field, "*")
|
||||||
|
}
|
||||||
|
|
||||||
|
if isContainerLevelField {
|
||||||
|
excludeContainer = getContainerInfo(matching, excludeIndexes[0], excludeContainerType)
|
||||||
|
}
|
||||||
|
excludeBadValues := extractBadValues(excludeFieldErr)
|
||||||
|
|
||||||
|
if excludeField == exclude.RestrictedField || len(exclude.RestrictedField) == 0 {
|
||||||
|
flag := true
|
||||||
|
if len(exclude.Values) != 0 {
|
||||||
|
for _, badValue := range excludeBadValues {
|
||||||
|
if !wildcard.CheckPatterns(exclude.Values, badValue) {
|
||||||
|
flag = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if flag {
|
||||||
|
defaultCheckResult := defaultCheckResultsMap[checkID]
|
||||||
|
if defaultCheckResult.CheckResult.ErrList != nil {
|
||||||
|
for idx, defaultFieldErr := range *defaultCheckResult.CheckResult.ErrList {
|
||||||
|
var defaultField, defaultContainerType string
|
||||||
|
var defaultIndexes []int
|
||||||
|
var isContainerLevelField bool = false
|
||||||
|
var defaultContainer corev1.Container
|
||||||
|
|
||||||
|
if isContainerLevelExclusion {
|
||||||
|
defaultField, defaultIndexes, defaultContainerType, isContainerLevelField = parseField(defaultFieldErr.Field)
|
||||||
|
} else {
|
||||||
|
defaultField = regexIndex.ReplaceAllString(defaultFieldErr.Field, "*")
|
||||||
|
}
|
||||||
|
|
||||||
|
if isContainerLevelField {
|
||||||
|
defaultContainer = getContainerInfo(pod, defaultIndexes[0], defaultContainerType)
|
||||||
|
if excludeField == defaultField && excludeContainer.Name == defaultContainer.Name {
|
||||||
|
remove(defaultCheckResult.CheckResult.ErrList, idx)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if excludeField == defaultField {
|
||||||
|
remove(defaultCheckResult.CheckResult.ErrList, idx)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(*defaultCheckResult.CheckResult.ErrList) == 0 {
|
||||||
|
delete(defaultCheckResultsMap, checkID)
|
||||||
|
} else {
|
||||||
|
defaultCheckResultsMap[checkID] = defaultCheckResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +157,65 @@ func exemptKyvernoExclusion(defaultCheckResults, excludeCheckResults []pssutils.
|
||||||
newDefaultCheckResults = append(newDefaultCheckResults, result)
|
newDefaultCheckResults = append(newDefaultCheckResults, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newDefaultCheckResults
|
return newDefaultCheckResults, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractBadValues(excludeFieldErr *field.Error) []string {
|
||||||
|
var excludeBadValues []string
|
||||||
|
|
||||||
|
switch excludeFieldErr.BadValue.(type) {
|
||||||
|
case string:
|
||||||
|
badValue := excludeFieldErr.BadValue.(string)
|
||||||
|
if badValue == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
excludeBadValues = append(excludeBadValues, badValue)
|
||||||
|
case bool:
|
||||||
|
excludeBadValues = append(excludeBadValues, strconv.FormatBool(excludeFieldErr.BadValue.(bool)))
|
||||||
|
case int:
|
||||||
|
excludeBadValues = append(excludeBadValues, strconv.Itoa(excludeFieldErr.BadValue.(int)))
|
||||||
|
case []string:
|
||||||
|
excludeBadValues = append(excludeBadValues, excludeFieldErr.BadValue.([]string)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return excludeBadValues
|
||||||
|
}
|
||||||
|
|
||||||
|
func remove(s *field.ErrorList, i int) {
|
||||||
|
(*s)[i] = (*s)[len(*s)-1]
|
||||||
|
*s = (*s)[:len(*s)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func isContainerType(str string) bool {
|
||||||
|
return str == "containers" || str == "initContainers" || str == "ephemeralContainers"
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseField(field string) (string, []int, string, bool) {
|
||||||
|
matchesIdx := regexIndex.FindAllStringSubmatch(field, -1)
|
||||||
|
matchesStr := regexStr.FindAllString(field, -1)
|
||||||
|
field = regexIndex.ReplaceAllString(field, "*")
|
||||||
|
var indexes []int
|
||||||
|
for _, match := range matchesIdx {
|
||||||
|
index, _ := strconv.Atoi(match[0])
|
||||||
|
indexes = append(indexes, index)
|
||||||
|
}
|
||||||
|
return field, indexes, matchesStr[1], isContainerType(matchesStr[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
func getContainerInfo(pod *corev1.Pod, index int, containerType string) corev1.Container {
|
||||||
|
var container corev1.Container
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case containerType == "containers":
|
||||||
|
container = pod.Spec.Containers[index]
|
||||||
|
case containerType == "initContainers":
|
||||||
|
container = pod.Spec.InitContainers[index]
|
||||||
|
case containerType == "ephemeralContainers":
|
||||||
|
container = (corev1.Container)(pod.Spec.EphemeralContainers[index].EphemeralContainerCommon)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return container
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseVersion(rule *kyvernov1.PodSecurity) (*api.LevelVersion, error) {
|
func parseVersion(rule *kyvernov1.PodSecurity) (*api.LevelVersion, error) {
|
||||||
|
@ -119,17 +253,19 @@ func EvaluatePod(rule *kyvernov1.PodSecurity, pod *corev1.Pod) (bool, []pssutils
|
||||||
switch {
|
switch {
|
||||||
// exclude pod level checks
|
// exclude pod level checks
|
||||||
case spec != nil:
|
case spec != nil:
|
||||||
|
isContainerLevelExclusion := false
|
||||||
excludeCheckResults := evaluatePSS(levelVersion, *spec)
|
excludeCheckResults := evaluatePSS(levelVersion, *spec)
|
||||||
defaultCheckResults = exemptKyvernoExclusion(defaultCheckResults, excludeCheckResults, exclude)
|
defaultCheckResults, err = exemptExclusions(defaultCheckResults, excludeCheckResults, exclude, pod, matching, isContainerLevelExclusion)
|
||||||
|
|
||||||
// exclude container level checks
|
// exclude container level checks
|
||||||
default:
|
default:
|
||||||
|
isContainerLevelExclusion := true
|
||||||
excludeCheckResults := evaluatePSS(levelVersion, *matching)
|
excludeCheckResults := evaluatePSS(levelVersion, *matching)
|
||||||
defaultCheckResults = exemptKyvernoExclusion(defaultCheckResults, excludeCheckResults, exclude)
|
defaultCheckResults, err = exemptExclusions(defaultCheckResults, excludeCheckResults, exclude, pod, matching, isContainerLevelExclusion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len(defaultCheckResults) == 0, defaultCheckResults, nil
|
return (len(defaultCheckResults) == 0 && err == nil), defaultCheckResults, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPodWithMatchingContainers extracts matching container/pod info by the given exclude rule
|
// GetPodWithMatchingContainers extracts matching container/pod info by the given exclude rule
|
||||||
|
@ -185,7 +321,32 @@ func GetRestrictedFields(check policy.Check) []pssutils.RestrictedField {
|
||||||
func FormatChecksPrint(checks []pssutils.PSSCheckResult) string {
|
func FormatChecksPrint(checks []pssutils.PSSCheckResult) string {
|
||||||
var str string
|
var str string
|
||||||
for _, check := range checks {
|
for _, check := range checks {
|
||||||
str += fmt.Sprintf("(%+v)\n", check.CheckResult)
|
str += fmt.Sprintf("\n(Forbidden reason: %s, field error list: [", check.CheckResult.ForbiddenReason)
|
||||||
|
for idx, err := range *check.CheckResult.ErrList {
|
||||||
|
badValueExist := true
|
||||||
|
switch err.BadValue.(type) {
|
||||||
|
case string:
|
||||||
|
badValue := err.BadValue.(string)
|
||||||
|
if badValue == "" {
|
||||||
|
badValueExist = false
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
switch err.Type {
|
||||||
|
case field.ErrorTypeForbidden:
|
||||||
|
if badValueExist {
|
||||||
|
str += fmt.Sprintf("%s is forbidden, don't set the BadValue: %+v", err.Field, err.BadValue)
|
||||||
|
} else {
|
||||||
|
str += err.Error()
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
str += err.Error()
|
||||||
|
}
|
||||||
|
if idx != len(*check.CheckResult.ErrList)-1 {
|
||||||
|
str += ", "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str += "])"
|
||||||
}
|
}
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,8 +13,9 @@ scope:
|
||||||
namespace: default
|
namespace: default
|
||||||
results:
|
results:
|
||||||
- category: Pod Security
|
- category: Pod Security
|
||||||
message: |
|
message: "Validation rule 'restricted' failed. It violates PodSecurity \"restricted:latest\":
|
||||||
Validation rule 'restricted' failed. It violates PodSecurity "restricted:latest": ({Allowed:false ForbiddenReason:unrestricted capabilities ForbiddenDetail:container "container01" must set securityContext.capabilities.drop=["ALL"]})
|
\n(Forbidden reason: unrestricted capabilities, field error list: [spec.containers[0].securityContext.capabilities.drop:
|
||||||
|
Required value])"
|
||||||
policy: podsecurity-subrule-restricted
|
policy: podsecurity-subrule-restricted
|
||||||
properties:
|
properties:
|
||||||
controls: capabilities_restricted
|
controls: capabilities_restricted
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the baseline:latest `Capabilities` PSS check and one pod (`bad-pod`) should not be created as it violate the baseline:latest `Capabilities` PSS check.
|
|
@ -0,0 +1,36 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- bar
|
||||||
|
- baz
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- baz
|
||||||
|
ephemeralContainers:
|
||||||
|
- name: nginx3
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- foo
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-capabilities
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,26 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- foo
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- baz
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- CHOWN
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- FOWNER
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-capabilities
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,31 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-capabilities
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-capabilities
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: baseline
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "Capabilities"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.containers[*].securityContext.capabilities.add"
|
||||||
|
values:
|
||||||
|
- "foo"
|
||||||
|
- controlName: "Capabilities"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.initContainers[*].securityContext.capabilities.add"
|
||||||
|
values:
|
||||||
|
- "baz"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the baseline:latest `Host Namespaces` PSS check and one pod (`bad-pod`) should not be created as it violate the baseline:latest `Host Namespaces` PSS check.
|
|
@ -0,0 +1,12 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
hostPID: true
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-host-namespaces
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,12 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
hostNetwork: true
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
|
@ -0,0 +1,12 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
hostNetwork: false
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-host-namespaces
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,23 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-host-namespaces
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-host-namespaces
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: baseline
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "Host Namespaces"
|
||||||
|
restrictedField: "spec.hostNetwork"
|
||||||
|
values:
|
||||||
|
- "true"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the baseline:latest `Host Ports` PSS check and one pod (`bad-pod`) should not be created as it violate the baseline:latest `Host Ports` PSS check.
|
|
@ -0,0 +1,23 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
ports:
|
||||||
|
- hostPort: 20
|
||||||
|
containerPort: 80
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
ports:
|
||||||
|
- hostPort: 20
|
||||||
|
containerPort: 80
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-host-ports
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,23 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
ports:
|
||||||
|
- hostPort: 10
|
||||||
|
containerPort: 80
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
ports:
|
||||||
|
- hostPort: 20
|
||||||
|
containerPort: 80
|
|
@ -0,0 +1,23 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
ports:
|
||||||
|
- hostPort: 0
|
||||||
|
containerPort: 80
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
ports:
|
||||||
|
- hostPort: 0
|
||||||
|
containerPort: 80
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-host-ports
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,32 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-host-ports
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-host-ports
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: baseline
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "Host Ports"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.containers[*].ports[*].hostPort"
|
||||||
|
values:
|
||||||
|
- "10"
|
||||||
|
- controlName: "Host Ports"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.initContainers[*].ports[*].hostPort"
|
||||||
|
values:
|
||||||
|
- "20"
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the baseline:latest `HostPath Volumes` PSS check.
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-hostpath-volume
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- name: host
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib1
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
|
@ -0,0 +1,11 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-hostpath-volumes
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,23 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-hostpath-volumes
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-hostpath-volumes
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: baseline
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "HostPath Volumes"
|
||||||
|
restrictedField: "spec.volumes[*].hostPath"
|
||||||
|
values:
|
||||||
|
- "path"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the baseline:latest `HostProcesses` PSS check and one pod (`bad-pod`) should not be created as it violate the baseline:latest `HostProcesses` PSS check.
|
|
@ -0,0 +1,26 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: true
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: true
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: true
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-hostprocesses
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,27 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
hostNetwork: true
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: true
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: true
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: true
|
|
@ -0,0 +1,26 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: false
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: false
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: false
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-hostprocess
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,39 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-hostprocess
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-hostprocess
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: baseline
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "Host Namespaces"
|
||||||
|
restrictedField: "spec.hostNetwork"
|
||||||
|
values:
|
||||||
|
- "true"
|
||||||
|
- controlName: "HostProcess"
|
||||||
|
restrictedField: "spec.securityContext.windowsOptions.hostProcess"
|
||||||
|
values:
|
||||||
|
- "true"
|
||||||
|
- controlName: "HostProcess"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.containers[*].securityContext.windowsOptions.hostProcess"
|
||||||
|
values:
|
||||||
|
- "true"
|
||||||
|
- controlName: "HostProcess"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.initContainers[*].securityContext.windowsOptions.hostProcess"
|
||||||
|
values:
|
||||||
|
- "true"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the restricted:latest `Privilege Escalation` PSS check and one pod (`bad-pod`) should not be created as it violate the restricted:latest `Privilege Escalation` PSS check.
|
|
@ -0,0 +1,31 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-privilege-escalation
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,33 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: true
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: true
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,33 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-privilege-escalation
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,31 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-privilege-escalation
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-privilege-escalation
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: restricted
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "Privilege Escalation"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.containers[*].securityContext.allowPrivilegeEscalation"
|
||||||
|
values:
|
||||||
|
- "true"
|
||||||
|
- controlName: "Privilege Escalation"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.initContainers[*].securityContext.allowPrivilegeEscalation"
|
||||||
|
values:
|
||||||
|
- "true"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the baseline:latest `Privileged Containers` PSS check.
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-privileged-containers
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,21 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
privileged: true
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
privileged: true
|
|
@ -0,0 +1,22 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
privileged: false
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
windowsOptions:
|
||||||
|
hostProcess: false
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-privileged-containers
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,31 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-privileged-containers
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-privileged-containers
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: baseline
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "Privileged Containers"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.containers[*].securityContext.privileged"
|
||||||
|
values:
|
||||||
|
- "true"
|
||||||
|
- controlName: "Privileged Containers"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.initContainers[*].securityContext.privileged"
|
||||||
|
values:
|
||||||
|
- "true"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the baseline:latest `/proc MountType` PSS check and one pod (`bad-pod`) should not be created as it violate the baseline:latest `/proc MountType` PSS check.
|
|
@ -0,0 +1,21 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
procMount: unknown
|
||||||
|
initContainers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
procMount: other
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-procmount
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,21 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
procMount: foo
|
||||||
|
# initContainers:
|
||||||
|
# - name: nginx2
|
||||||
|
# image: nginx
|
||||||
|
# args:
|
||||||
|
# - sleep
|
||||||
|
# - 1d
|
||||||
|
# securityContext:
|
||||||
|
# procMount: bar
|
|
@ -0,0 +1,21 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
procMount: default
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
procMount: default
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-procmount
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,31 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-procmount
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-procmount
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: baseline
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "/proc Mount Type"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.containers[*].securityContext.procMount"
|
||||||
|
values:
|
||||||
|
- "foo"
|
||||||
|
- controlName: "/proc Mount Type"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.initContainers[*].securityContext.procMount"
|
||||||
|
values:
|
||||||
|
- "bar"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the restricted:latest `Capabilities` PSS check and one pod (`bad-pod`) should not be created as it violate the restricted:latest `Capabilities` PSS check.
|
|
@ -0,0 +1,37 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
add:
|
||||||
|
- bar
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
add:
|
||||||
|
- baz
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-restricted-capabilities
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,37 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
add:
|
||||||
|
- foo
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
add:
|
||||||
|
- baz
|
|
@ -0,0 +1,35 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
add:
|
||||||
|
- NET_BIND_SERVICE
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-restricted-capabilities
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,31 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-restricted-capabilities
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-restricted-capabilities
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: restricted
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "Capabilities"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.containers[*].securityContext.capabilities.add"
|
||||||
|
values:
|
||||||
|
- "foo"
|
||||||
|
- controlName: "Capabilities"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.initContainers[*].securityContext.capabilities.add"
|
||||||
|
values:
|
||||||
|
- "baz"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the restricted:latest `Seccomp` PSS check and one pod (`bad-pod`) should not be created as it violate the restricted:latest `Seccomp` PSS check.
|
|
@ -0,0 +1,36 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: foo
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: baz
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: Localhost
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-restricted-seccomp
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,36 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: Unconfined
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: Unconfined
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: Unconfined
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,36 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-restricted-seccomp
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,35 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-restricted-seccomp
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-restricted-seccomp
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: restricted
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "Seccomp"
|
||||||
|
restrictedField: "spec.securityContext.seccompProfile.type"
|
||||||
|
values:
|
||||||
|
- "Unconfined"
|
||||||
|
- controlName: "Seccomp"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.containers[*].securityContext.seccompProfile.type"
|
||||||
|
values:
|
||||||
|
- "Unconfined"
|
||||||
|
- controlName: "Seccomp"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.initContainers[*].securityContext.seccompProfile.type"
|
||||||
|
values:
|
||||||
|
- "Unconfined"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the restricted:latest `Running as Non-root User` PSS check and one pod (`bad-pod`) should not be created as it violate the restricted:latest `Running as Non-root User` PSS check.
|
|
@ -0,0 +1,35 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 0
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-running-as-nonroot-user
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,35 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 0
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 10
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,35 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-running-as-non-root-user
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
|
@ -0,0 +1,29 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-running-as-non-root-user
|
||||||
|
spec:
|
||||||
|
background: true
|
||||||
|
validationFailureAction: Enforce
|
||||||
|
rules:
|
||||||
|
- name: test-exclusion-running-as-non-root-user
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
validate:
|
||||||
|
podSecurity:
|
||||||
|
level: restricted
|
||||||
|
version: latest
|
||||||
|
exclude:
|
||||||
|
- controlName: "Running as Non-root user"
|
||||||
|
restrictedField: "spec.securityContext.runAsUser"
|
||||||
|
values:
|
||||||
|
- "0"
|
||||||
|
- controlName: "Running as Non-root user"
|
||||||
|
images:
|
||||||
|
- nginx
|
||||||
|
restrictedField: "spec.containers[*].securityContext.runAsUser"
|
||||||
|
values:
|
||||||
|
- "0"
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This test ensures the PSS checks with the new advanced support on exclusions are applied to the resources successfully.
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
Two pods (`good-pod` & `excluded-pod`) should be created as it follows the restricted:latest `Running as Non-root` PSS check and one pod (`bad-pod`) should not be created as it violate the restricted:latest `Running as Non-root` PSS check.
|
|
@ -0,0 +1,33 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: bad-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: false
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,24 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: test-exclusion-running-as-nonroot
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
expect:
|
||||||
|
- check:
|
||||||
|
($error != null): true
|
||||||
|
file: bad-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: excluded-pod.yaml
|
||||||
|
- apply:
|
||||||
|
file: good-pod.yaml
|
|
@ -0,0 +1,33 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: excluded-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: false
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,33 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: good-pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx1
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
initContainers:
|
||||||
|
- name: nginx2
|
||||||
|
image: nginx
|
||||||
|
args:
|
||||||
|
- sleep
|
||||||
|
- 1d
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
|
@ -0,0 +1,9 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: test-exclusion-running-as-non-root
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue