mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +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
|
||||
.manifest
|
||||
kyverno.tar.gz
|
||||
vendor/
|
||||
|
|
|
@ -429,6 +429,24 @@ type PodSecurityStandard struct {
|
|||
// Wildcards ('*' and '?') are allowed. See: https://kubernetes.io/docs/concepts/containers/images.
|
||||
// +optional
|
||||
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/).
|
||||
|
|
|
@ -992,6 +992,11 @@ func (in *PodSecurityStandard) DeepCopyInto(out *PodSecurityStandard) {
|
|||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -13424,6 +13424,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -17919,6 +17931,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -22180,6 +22204,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -26649,6 +26685,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -31184,6 +31232,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -35680,6 +35740,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -39942,6 +40014,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -44411,6 +44495,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
|
|
@ -3473,6 +3473,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -7968,6 +7980,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -12229,6 +12253,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -16698,6 +16734,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
|
|
@ -3474,6 +3474,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -7970,6 +7982,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -12232,6 +12256,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -16701,6 +16737,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
|
|
@ -3473,6 +3473,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -7968,6 +7980,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -12229,6 +12253,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -16698,6 +16734,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
|
|
@ -3474,6 +3474,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -7970,6 +7982,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -12232,6 +12256,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -16701,6 +16737,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
|
|
@ -13643,6 +13643,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -18138,6 +18150,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -22399,6 +22423,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -26868,6 +26904,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -31405,6 +31453,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -35901,6 +35961,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -40163,6 +40235,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
type: object
|
||||
|
@ -44632,6 +44716,18 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
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:
|
||||
- controlName
|
||||
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>
|
||||
</td>
|
||||
</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>
|
||||
</table>
|
||||
<hr />
|
||||
|
|
6
go.mod
6
go.mod
|
@ -381,4 +381,8 @@ require (
|
|||
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/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE=
|
||||
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/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||
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/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
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/go.mod h1:yzDHaKovQy16rjN4kFnjF+IdNoN4p1ndw+va6+B8zUU=
|
||||
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-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/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/go.mod h1:BQPWo7cfxmJwgaHlphUHUpFkp5+YxeJes82oo39m5og=
|
||||
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/kubectl v0.28.4 h1:gWpUXW/T7aFne+rchYeHkyB8eVDl5UZce8G4X//kjUQ=
|
||||
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-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
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 {
|
||||
return nil, err
|
||||
} else {
|
||||
if rule.Validation != nil && rule.Validation.PodSecurity != nil {
|
||||
bytes = updateRestrictedFields(bytes, kind)
|
||||
if err := json.Unmarshal(bytes, &rule); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
bytes = updateGenRuleByte(bytes, kind)
|
||||
if err := json.Unmarshal(bytes, &rule); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bytes = updateGenRuleByte(bytes, kind)
|
||||
if err := json.Unmarshal(bytes, &rule); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// CEL variables are object, oldObject, request, params and authorizer.
|
||||
|
|
|
@ -321,17 +321,6 @@ func updateGenRuleByte(pbyte []byte, kind string) (obj []byte) {
|
|||
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) {
|
||||
if kind == "Pod" {
|
||||
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
|
||||
// with apply.
|
||||
type PodSecurityStandardApplyConfiguration struct {
|
||||
ControlName *string `json:"controlName,omitempty"`
|
||||
Images []string `json:"images,omitempty"`
|
||||
ControlName *string `json:"controlName,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
|
||||
|
@ -48,3 +50,21 @@ func (b *PodSecurityStandardApplyConfiguration) WithImages(values ...string) *Po
|
|||
}
|
||||
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"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
||||
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
"github.com/kyverno/kyverno/pkg/pss"
|
||||
pssutils "github.com/kyverno/kyverno/pkg/pss/utils"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
@ -35,6 +37,11 @@ func (h validatePssHandler) Process(
|
|||
_ engineapi.EngineContextLoader,
|
||||
exceptions []kyvernov2beta1.PolicyException,
|
||||
) (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
|
||||
exception := engineutils.MatchesException(exceptions, policyContext, logger)
|
||||
if exception != nil {
|
||||
|
@ -67,6 +74,7 @@ func (h validatePssHandler) Process(
|
|||
if err != nil {
|
||||
return resource, handlers.WithError(rule, engineapi.Validation, "failed to parse pod security api version", err)
|
||||
}
|
||||
pssChecks = convertChecks(pssChecks, resource.GetKind())
|
||||
podSecurityChecks := engineapi.PodSecurityChecks{
|
||||
Level: podSecurity.Level,
|
||||
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) {
|
||||
kind := resource.GetKind()
|
||||
|
||||
|
|
|
@ -2,16 +2,24 @@ package pss
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/ext/wildcard"
|
||||
pssutils "github.com/kyverno/kyverno/pkg/pss/utils"
|
||||
corev1 "k8s.io/api/core/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/policy"
|
||||
)
|
||||
|
||||
var (
|
||||
regexIndex = regexp.MustCompile(`\d+`)
|
||||
regexStr = regexp.MustCompile(`[a-zA-Z]+`)
|
||||
)
|
||||
|
||||
// Evaluate Pod's specified containers only and get PSSCheckResults
|
||||
func evaluatePSS(level *api.LevelVersion, pod corev1.Pod) (results []pssutils.PSSCheckResult) {
|
||||
checks := policy.DefaultChecks()
|
||||
|
@ -30,7 +38,7 @@ func evaluatePSS(level *api.LevelVersion, pod corev1.Pod) (results []pssutils.PS
|
|||
}
|
||||
|
||||
if level.Version == api.LatestVersion() {
|
||||
checkResult := latestVersionCheck.CheckPod(&pod.ObjectMeta, &pod.Spec)
|
||||
checkResult := latestVersionCheck.CheckPod(&pod.ObjectMeta, &pod.Spec, policy.WithFieldErrors())
|
||||
if !checkResult.Allowed {
|
||||
results = append(results, pssutils.PSSCheckResult{
|
||||
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) {
|
||||
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
|
||||
if !checkResult.Allowed {
|
||||
results = append(results, pssutils.PSSCheckResult{
|
||||
|
@ -61,9 +69,14 @@ func evaluatePSS(level *api.LevelVersion, pod corev1.Pod) (results []pssutils.PS
|
|||
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))
|
||||
|
||||
if err := exclude.Validate(exclude); err != nil {
|
||||
fmt.Print(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, result := range defaultCheckResults {
|
||||
defaultCheckResultsMap[result.ID] = result
|
||||
}
|
||||
|
@ -71,7 +84,70 @@ func exemptKyvernoExclusion(defaultCheckResults, excludeCheckResults []pssutils.
|
|||
for _, excludeResult := range excludeCheckResults {
|
||||
for _, checkID := range pssutils.PSS_controls_to_check_id[exclude.ControlName] {
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -119,17 +253,19 @@ func EvaluatePod(rule *kyvernov1.PodSecurity, pod *corev1.Pod) (bool, []pssutils
|
|||
switch {
|
||||
// exclude pod level checks
|
||||
case spec != nil:
|
||||
isContainerLevelExclusion := false
|
||||
excludeCheckResults := evaluatePSS(levelVersion, *spec)
|
||||
defaultCheckResults = exemptKyvernoExclusion(defaultCheckResults, excludeCheckResults, exclude)
|
||||
defaultCheckResults, err = exemptExclusions(defaultCheckResults, excludeCheckResults, exclude, pod, matching, isContainerLevelExclusion)
|
||||
|
||||
// exclude container level checks
|
||||
default:
|
||||
isContainerLevelExclusion := true
|
||||
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
|
||||
|
@ -185,7 +321,32 @@ func GetRestrictedFields(check policy.Check) []pssutils.RestrictedField {
|
|||
func FormatChecksPrint(checks []pssutils.PSSCheckResult) string {
|
||||
var str string
|
||||
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
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,8 +13,9 @@ scope:
|
|||
namespace: default
|
||||
results:
|
||||
- category: Pod Security
|
||||
message: |
|
||||
Validation rule 'restricted' failed. It violates PodSecurity "restricted:latest": ({Allowed:false ForbiddenReason:unrestricted capabilities ForbiddenDetail:container "container01" must set securityContext.capabilities.drop=["ALL"]})
|
||||
message: "Validation rule 'restricted' failed. It violates PodSecurity \"restricted:latest\":
|
||||
\n(Forbidden reason: unrestricted capabilities, field error list: [spec.containers[0].securityContext.capabilities.drop:
|
||||
Required value])"
|
||||
policy: podsecurity-subrule-restricted
|
||||
properties:
|
||||
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…
Reference in a new issue