mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 02:18:15 +00:00
fix: mutation code (#7095)
* fix: mutation code Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * kuttl tests Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
9cac3698ec
commit
b9afce90ad
152 changed files with 3570 additions and 8 deletions
|
@ -37,6 +37,17 @@ const (
|
|||
ApplyOne ApplyRulesType = "One"
|
||||
)
|
||||
|
||||
// ForeachOrder specifies the iteration order in foreach statements.
|
||||
// +kubebuilder:validation:Enum=Ascending;Descending
|
||||
type ForeachOrder string
|
||||
|
||||
const (
|
||||
// Ascending means iterating from first to last element.
|
||||
Ascending ForeachOrder = "Ascending"
|
||||
// Descending means iterating from last to first element.
|
||||
Descending ForeachOrder = "Descending"
|
||||
)
|
||||
|
||||
// AnyAllConditions consists of conditions wrapped denoting a logical criteria to be fulfilled.
|
||||
// AnyConditions get fulfilled when at least one of its sub-conditions passes.
|
||||
// AllConditions get fulfilled only when all of its sub-conditions pass.
|
||||
|
@ -302,6 +313,11 @@ type ForEachMutation struct {
|
|||
// to which the validation logic is applied.
|
||||
List string `json:"list,omitempty" yaml:"list,omitempty"`
|
||||
|
||||
// Order defines the iteration order on the list.
|
||||
// Can be Ascending to iterate from first to last element or Descending to iterate in from last to first element.
|
||||
// +optional
|
||||
Order *ForeachOrder `json:"order,omitempty" yaml:"order,omitempty"`
|
||||
|
||||
// Context defines variables and data sources that can be used during rule execution.
|
||||
// +optional
|
||||
Context []ContextEntry `json:"context,omitempty" yaml:"context,omitempty"`
|
||||
|
|
|
@ -452,6 +452,11 @@ func (in *DryRunOption) DeepCopy() *DryRunOption {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ForEachMutation) DeepCopyInto(out *ForEachMutation) {
|
||||
*out = *in
|
||||
if in.Order != nil {
|
||||
in, out := &in.Order, &out.Order
|
||||
*out = new(ForeachOrder)
|
||||
**out = **in
|
||||
}
|
||||
if in.Context != nil {
|
||||
in, out := &in.Context, &out.Context
|
||||
*out = make([]ContextEntry, len(*in))
|
||||
|
|
|
@ -5670,6 +5670,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -9227,6 +9236,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -12447,6 +12465,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -16132,6 +16159,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -19805,6 +19841,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -23363,6 +23408,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -26584,6 +26638,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -30269,6 +30332,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
|
|
@ -1928,6 +1928,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -5485,6 +5494,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -8705,6 +8723,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -12390,6 +12417,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
|
|
@ -1929,6 +1929,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -5487,6 +5496,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -8708,6 +8726,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -12393,6 +12420,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
|
|
@ -5874,6 +5874,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -9431,6 +9440,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -12651,6 +12669,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -16336,6 +16363,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -20009,6 +20045,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -23567,6 +23612,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -26788,6 +26842,15 @@ spec:
|
|||
that results in one or more elements to which the
|
||||
validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order on
|
||||
the list. Can be Ascending to iterate from first
|
||||
to last element or Descending to iterate in from
|
||||
last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic merge
|
||||
patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
@ -30473,6 +30536,15 @@ spec:
|
|||
that results in one or more elements to which
|
||||
the validation logic is applied.
|
||||
type: string
|
||||
order:
|
||||
description: Order defines the iteration order
|
||||
on the list. Can be Ascending to iterate from
|
||||
first to last element or Descending to iterate
|
||||
in from last to first element.
|
||||
enum:
|
||||
- Ascending
|
||||
- Descending
|
||||
type: string
|
||||
patchStrategicMerge:
|
||||
description: PatchStrategicMerge is a strategic
|
||||
merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
|
||||
|
|
|
@ -1386,6 +1386,21 @@ to which the validation logic is applied.</p>
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>order</code><br/>
|
||||
<em>
|
||||
<a href="#kyverno.io/v1.ForeachOrder">
|
||||
ForeachOrder
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Order defines the iteration order on the list.
|
||||
Can be Ascending to iterate from first to last element or Descending to iterate in from last to first element.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>context</code><br/>
|
||||
<em>
|
||||
<a href="#kyverno.io/v1.ContextEntry">
|
||||
|
@ -1594,6 +1609,15 @@ Kubernetes apiextensions/v1.JSON
|
|||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<h3 id="kyverno.io/v1.ForeachOrder">ForeachOrder
|
||||
(<code>string</code> alias)</p></h3>
|
||||
<p>
|
||||
(<em>Appears on:</em>
|
||||
<a href="#kyverno.io/v1.ForEachMutation">ForEachMutation</a>)
|
||||
</p>
|
||||
<p>
|
||||
<p>ForeachOrder specifies the iteration order in foreach statements.</p>
|
||||
</p>
|
||||
<h3 id="kyverno.io/v1.GenerateType">GenerateType
|
||||
(<code>string</code> alias)</p></h3>
|
||||
<p>
|
||||
|
|
|
@ -69,15 +69,22 @@ func (f *forEachMutator) mutateElements(ctx context.Context, foreach kyvernov1.F
|
|||
|
||||
patchedResource := f.resource
|
||||
var allPatches []jsonpatch.JsonPatchOperation
|
||||
reverse := false
|
||||
if foreach.RawPatchStrategicMerge != nil {
|
||||
reverse = true
|
||||
} else if foreach.Order != nil && *foreach.Order == kyvernov1.Descending {
|
||||
reverse = true
|
||||
}
|
||||
if reverse {
|
||||
engineutils.InvertedElement(elements)
|
||||
}
|
||||
|
||||
for index, element := range elements {
|
||||
if element == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if reverse {
|
||||
index = len(elements) - 1 - index
|
||||
}
|
||||
f.policyContext.JSONContext().Reset()
|
||||
policyContext := f.policyContext.Copy()
|
||||
|
||||
|
@ -131,8 +138,7 @@ func (f *forEachMutator) mutateElements(ctx context.Context, foreach kyvernov1.F
|
|||
allPatches = append(allPatches, mutateResp.Patches...)
|
||||
}
|
||||
}
|
||||
sortedPatches := patch.FilterAndSortPatches(allPatches)
|
||||
return mutate.NewResponse(engineapi.RuleStatusPass, patchedResource.unstructured, sortedPatches, "")
|
||||
return mutate.NewResponse(engineapi.RuleStatusPass, patchedResource.unstructured, allPatches, "")
|
||||
}
|
||||
|
||||
func buildRuleResponse(rule *kyvernov1.Rule, mutateResp *mutate.Response, info resourceInfo) *engineapi.RuleResponse {
|
||||
|
|
|
@ -23,17 +23,17 @@ func generatePatches(src, dst []byte) ([]jsonpatch.JsonPatchOperation, error) {
|
|||
if pp, err := jsonpatch.CreatePatch(src, dst); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return FilterAndSortPatches(pp), err
|
||||
return filterAndSortPatches(pp), err
|
||||
}
|
||||
}
|
||||
|
||||
// FilterAndSortPatches
|
||||
// filterAndSortPatches
|
||||
// 1. filters out patches with the certain paths
|
||||
// 2. sorts the removal patches(with same path) by the key of index
|
||||
// in descending order. The sort is required as when removing multiple
|
||||
// elements from an array, the elements must be removed in descending
|
||||
// order to preserve each index value.
|
||||
func FilterAndSortPatches(originalPatches []jsonpatch.JsonPatchOperation) []jsonpatch.JsonPatchOperation {
|
||||
func filterAndSortPatches(originalPatches []jsonpatch.JsonPatchOperation) []jsonpatch.JsonPatchOperation {
|
||||
patches := filterInvalidPatches(originalPatches)
|
||||
|
||||
result := make([]jsonpatch.JsonPatchOperation, len(patches))
|
||||
|
|
|
@ -320,7 +320,7 @@ func Test_sortRemovalPatches(t *testing.T) {
|
|||
}
|
||||
|
||||
for i, test := range tests {
|
||||
sortedPatches := FilterAndSortPatches(test.patches)
|
||||
sortedPatches := filterAndSortPatches(test.patches)
|
||||
assertnew.Equal(t, test.expected, sortedPatches, fmt.Sprintf("%dth test fails", i))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ spec:
|
|||
mutate:
|
||||
foreach:
|
||||
- list: request.object.spec.volumes[]
|
||||
order: Descending
|
||||
preconditions:
|
||||
all:
|
||||
- key: hostPath
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- resource.yaml
|
||||
assert:
|
||||
- resource-mutated.yaml
|
|
@ -0,0 +1,13 @@
|
|||
## Description
|
||||
|
||||
This is a test of the policy in this folder.
|
||||
|
||||
Note: In order for this test to work on Pods emitted from Pod controllers, the Kyverno ConfigMap excludeGroups value may need to be modified to remove the entry for system:serviceaccounts:kube-system or else mutation may not occur.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The resource is expected to be mutated so it resembles the specified asserted resources. If it does, the test passes. If it does not, it fails.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-emptydir-sizelimit
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,46 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: add-emptydir-sizelimit
|
||||
---
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-emptydir-sizelimit
|
||||
annotations:
|
||||
pod-policies.kyverno.io/autogen-controllers: none
|
||||
policies.kyverno.io/title: Add emptyDir sizeLimit
|
||||
policies.kyverno.io/category: Other
|
||||
policies.kyverno.io/subject: Pod
|
||||
policies.kyverno.io/minversion: 1.6.0
|
||||
kyverno.io/kyverno-version: 1.7.3,1.8.0-rc2
|
||||
kyverno.io/kubernetes-version: "1.24"
|
||||
policies.kyverno.io/description: >-
|
||||
When a Pod requests an emptyDir, by default it does not have a size limit which
|
||||
may allow it to consume excess or all of the space in the medium backing the volume.
|
||||
This can quickly overrun a Node and may result in a denial of service for other
|
||||
workloads. This policy adds a sizeLimit field to all Pods mounting emptyDir
|
||||
volumes, if not present, and sets it to 100Mi.
|
||||
spec:
|
||||
rules:
|
||||
- name: mutate-emptydir
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
mutate:
|
||||
foreach:
|
||||
- list: "request.object.spec.volumes[]"
|
||||
preconditions:
|
||||
all:
|
||||
- key: "{{element.keys(@)}}"
|
||||
operator: AnyIn
|
||||
value: emptyDir
|
||||
- key: "{{element.emptyDir.sizeLimit || ''}}"
|
||||
operator: Equals
|
||||
value: ''
|
||||
patchesJson6902: |-
|
||||
- path: "/spec/volumes/{{elementIndex}}/emptyDir/sizeLimit"
|
||||
op: add
|
||||
value: 100Mi
|
|
@ -0,0 +1,86 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod01
|
||||
namespace: add-emptydir-sizelimit
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- image: aiboelckajdow:1.35
|
||||
name: busybox
|
||||
volumeMounts:
|
||||
- mountPath: /foo
|
||||
name: foo
|
||||
volumes:
|
||||
- emptyDir:
|
||||
sizeLimit: 100Mi
|
||||
name: foo
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod02
|
||||
namespace: add-emptydir-sizelimit
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- name: busybox
|
||||
image: iopybmeyffhjq:1.35
|
||||
volumeMounts:
|
||||
- mountPath: /foo
|
||||
name: foo
|
||||
volumes:
|
||||
- name: foo
|
||||
emptyDir:
|
||||
sizeLimit: 50Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod03
|
||||
namespace: add-emptydir-sizelimit
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- name: busybox
|
||||
image: flfmfioapzhdts:1.35
|
||||
volumeMounts:
|
||||
- mountPath: /foo
|
||||
name: foo
|
||||
- mountPath: /bar
|
||||
name: bar
|
||||
volumes:
|
||||
- name: foo
|
||||
emptyDir:
|
||||
sizeLimit: 50Mi
|
||||
- name: bar
|
||||
emptyDir:
|
||||
sizeLimit: 100Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod04
|
||||
namespace: add-emptydir-sizelimit
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- image: imvplaiskduqnf:1.35
|
||||
name: busybox
|
||||
volumeMounts:
|
||||
- mountPath: /foo
|
||||
name: foo
|
||||
- mountPath: /bar
|
||||
name: bar
|
||||
- mountPath: /baz
|
||||
name: baz
|
||||
volumes:
|
||||
- emptyDir:
|
||||
sizeLimit: 50Mi
|
||||
name: foo
|
||||
- hostPath:
|
||||
path: /opt/baz
|
||||
name: baz
|
||||
- emptyDir:
|
||||
sizeLimit: 100Mi
|
||||
name: bar
|
|
@ -0,0 +1,83 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod01
|
||||
namespace: add-emptydir-sizelimit
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- name: busybox
|
||||
image: aiboelckajdow:1.35
|
||||
volumeMounts:
|
||||
- mountPath: /foo
|
||||
name: foo
|
||||
volumes:
|
||||
- name: foo
|
||||
emptyDir: {}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod02
|
||||
namespace: add-emptydir-sizelimit
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- name: busybox
|
||||
image: iopybmeyffhjq:1.35
|
||||
volumeMounts:
|
||||
- mountPath: /foo
|
||||
name: foo
|
||||
volumes:
|
||||
- name: foo
|
||||
emptyDir:
|
||||
sizeLimit: 50Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod03
|
||||
namespace: add-emptydir-sizelimit
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- name: busybox
|
||||
image: flfmfioapzhdts:1.35
|
||||
volumeMounts:
|
||||
- mountPath: /foo
|
||||
name: foo
|
||||
- mountPath: /bar
|
||||
name: bar
|
||||
volumes:
|
||||
- name: foo
|
||||
emptyDir:
|
||||
sizeLimit: 50Mi
|
||||
- name: bar
|
||||
emptyDir: {}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod04
|
||||
namespace: add-emptydir-sizelimit
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- name: busybox
|
||||
image: imvplaiskduqnf:1.35
|
||||
volumeMounts:
|
||||
- mountPath: /foo
|
||||
name: foo
|
||||
- mountPath: /bar
|
||||
name: bar
|
||||
- mountPath: /baz
|
||||
name: baz
|
||||
volumes:
|
||||
- name: foo
|
||||
emptyDir:
|
||||
sizeLimit: 50Mi
|
||||
- name: baz
|
||||
hostPath:
|
||||
path: /opt/baz
|
||||
- name: bar
|
||||
emptyDir: {}
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- crd.yaml
|
||||
assert:
|
||||
- crd-assert.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- resource.yaml
|
||||
assert:
|
||||
- resource-mutated.yaml
|
|
@ -0,0 +1,12 @@
|
|||
## Description
|
||||
|
||||
This is a description of what my test does and why it needs to do it.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
This is the expected behavior of my test. Although it's assumed the test, overall, should pass/succeed, be specific about what the internal behavior is which leads to that result.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
1234
|
||||
test
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: externalsecrets.external-secrets.io
|
||||
spec: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ExternalSecret
|
||||
listKind: ExternalSecretList
|
||||
plural: externalsecrets
|
||||
singular: externalsecret
|
||||
storedVersions:
|
||||
- v1beta1
|
|
@ -0,0 +1,694 @@
|
|||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.3
|
||||
name: externalsecrets.external-secrets.io
|
||||
spec:
|
||||
group: external-secrets.io
|
||||
names:
|
||||
categories:
|
||||
- externalsecrets
|
||||
kind: ExternalSecret
|
||||
listKind: ExternalSecretList
|
||||
plural: externalsecrets
|
||||
shortNames:
|
||||
- es
|
||||
singular: externalsecret
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.secretStoreRef.name
|
||||
name: Store
|
||||
type: string
|
||||
- jsonPath: .spec.refreshInterval
|
||||
name: Refresh Interval
|
||||
type: string
|
||||
- jsonPath: .status.conditions[?(@.type=="Ready")].reason
|
||||
name: Status
|
||||
type: string
|
||||
deprecated: true
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ExternalSecret is the Schema for the external-secrets API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ExternalSecretSpec defines the desired state of ExternalSecret.
|
||||
properties:
|
||||
data:
|
||||
description: Data defines the connection between the Kubernetes Secret
|
||||
keys and the Provider data
|
||||
items:
|
||||
description: ExternalSecretData defines the connection between the
|
||||
Kubernetes Secret key (spec.data.<key>) and the Provider data.
|
||||
properties:
|
||||
remoteRef:
|
||||
description: ExternalSecretDataRemoteRef defines Provider data
|
||||
location.
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
property:
|
||||
description: Used to select a specific property of the Provider
|
||||
value (if a map), if supported
|
||||
type: string
|
||||
version:
|
||||
description: Used to select a specific version of the Provider
|
||||
value, if supported
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
secretKey:
|
||||
type: string
|
||||
required:
|
||||
- remoteRef
|
||||
- secretKey
|
||||
type: object
|
||||
type: array
|
||||
dataFrom:
|
||||
description: DataFrom is used to fetch all properties from a specific
|
||||
Provider data If multiple entries are specified, the Secret keys
|
||||
are merged in the specified order
|
||||
items:
|
||||
description: ExternalSecretDataRemoteRef defines Provider data location.
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
property:
|
||||
description: Used to select a specific property of the Provider
|
||||
value (if a map), if supported
|
||||
type: string
|
||||
version:
|
||||
description: Used to select a specific version of the Provider
|
||||
value, if supported
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
type: array
|
||||
refreshInterval:
|
||||
default: 1h
|
||||
description: RefreshInterval is the amount of time before the values
|
||||
are read again from the SecretStore provider Valid time units are
|
||||
"ns", "us" (or "µs"), "ms", "s", "m", "h" May be set to zero to
|
||||
fetch and create it once. Defaults to 1h.
|
||||
type: string
|
||||
secretStoreRef:
|
||||
description: SecretStoreRef defines which SecretStore to fetch the
|
||||
ExternalSecret data.
|
||||
properties:
|
||||
kind:
|
||||
description: Kind of the SecretStore resource (SecretStore or
|
||||
ClusterSecretStore) Defaults to `SecretStore`
|
||||
type: string
|
||||
name:
|
||||
description: Name of the SecretStore resource
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
target:
|
||||
description: ExternalSecretTarget defines the Kubernetes Secret to
|
||||
be created There can be only one target per ExternalSecret.
|
||||
properties:
|
||||
creationPolicy:
|
||||
default: Owner
|
||||
description: CreationPolicy defines rules on how to create the
|
||||
resulting Secret Defaults to 'Owner'
|
||||
type: string
|
||||
immutable:
|
||||
description: Immutable defines if the final secret will be immutable
|
||||
type: boolean
|
||||
name:
|
||||
description: Name defines the name of the Secret resource to be
|
||||
managed This field is immutable Defaults to the .metadata.name
|
||||
of the ExternalSecret resource
|
||||
type: string
|
||||
template:
|
||||
description: Template defines a blueprint for the created Secret
|
||||
resource.
|
||||
properties:
|
||||
data:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
engineVersion:
|
||||
default: v1
|
||||
description: EngineVersion specifies the template engine version
|
||||
that should be used to compile/execute the template specified
|
||||
in .data and .templateFrom[].
|
||||
type: string
|
||||
metadata:
|
||||
description: ExternalSecretTemplateMetadata defines metadata
|
||||
fields for the Secret blueprint.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
templateFrom:
|
||||
items:
|
||||
maxProperties: 1
|
||||
minProperties: 1
|
||||
properties:
|
||||
configMap:
|
||||
properties:
|
||||
items:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- items
|
||||
- name
|
||||
type: object
|
||||
secret:
|
||||
properties:
|
||||
items:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- items
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- secretStoreRef
|
||||
- target
|
||||
type: object
|
||||
status:
|
||||
properties:
|
||||
conditions:
|
||||
items:
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
refreshTime:
|
||||
description: refreshTime is the time and date the external secret
|
||||
was fetched and the target secret updated
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
syncedResourceVersion:
|
||||
description: SyncedResourceVersion keeps track of the last synced
|
||||
version
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.secretStoreRef.name
|
||||
name: Store
|
||||
type: string
|
||||
- jsonPath: .spec.refreshInterval
|
||||
name: Refresh Interval
|
||||
type: string
|
||||
- jsonPath: .status.conditions[?(@.type=="Ready")].reason
|
||||
name: Status
|
||||
type: string
|
||||
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
||||
name: Ready
|
||||
type: string
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ExternalSecret is the Schema for the external-secrets API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ExternalSecretSpec defines the desired state of ExternalSecret.
|
||||
properties:
|
||||
data:
|
||||
description: Data defines the connection between the Kubernetes Secret
|
||||
keys and the Provider data
|
||||
items:
|
||||
description: ExternalSecretData defines the connection between the
|
||||
Kubernetes Secret key (spec.data.<key>) and the Provider data.
|
||||
properties:
|
||||
remoteRef:
|
||||
description: RemoteRef points to the remote secret and defines
|
||||
which secret (version/property/..) to fetch.
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
decodingStrategy:
|
||||
default: None
|
||||
description: Used to define a decoding Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
metadataPolicy:
|
||||
description: Policy for fetching tags/labels from provider
|
||||
secrets, possible options are Fetch, None. Defaults to
|
||||
None
|
||||
type: string
|
||||
property:
|
||||
description: Used to select a specific property of the Provider
|
||||
value (if a map), if supported
|
||||
type: string
|
||||
version:
|
||||
description: Used to select a specific version of the Provider
|
||||
value, if supported
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
secretKey:
|
||||
description: SecretKey defines the key in which the controller
|
||||
stores the value. This is the key in the Kind=Secret
|
||||
type: string
|
||||
sourceRef:
|
||||
description: SourceRef allows you to override the source from
|
||||
which the value will pulled from.
|
||||
maxProperties: 1
|
||||
properties:
|
||||
generatorRef:
|
||||
description: GeneratorRef points to a generator custom resource
|
||||
in
|
||||
properties:
|
||||
apiVersion:
|
||||
default: generators.external-secrets.io/v1alpha1
|
||||
description: Specify the apiVersion of the generator
|
||||
resource
|
||||
type: string
|
||||
kind:
|
||||
description: Specify the Kind of the resource, e.g.
|
||||
Password, ACRAccessToken etc.
|
||||
type: string
|
||||
name:
|
||||
description: Specify the name of the generator resource
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
storeRef:
|
||||
description: SecretStoreRef defines which SecretStore to
|
||||
fetch the ExternalSecret data.
|
||||
properties:
|
||||
kind:
|
||||
description: Kind of the SecretStore resource (SecretStore
|
||||
or ClusterSecretStore) Defaults to `SecretStore`
|
||||
type: string
|
||||
name:
|
||||
description: Name of the SecretStore resource
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- remoteRef
|
||||
- secretKey
|
||||
type: object
|
||||
type: array
|
||||
dataFrom:
|
||||
description: DataFrom is used to fetch all properties from a specific
|
||||
Provider data If multiple entries are specified, the Secret keys
|
||||
are merged in the specified order
|
||||
items:
|
||||
properties:
|
||||
extract:
|
||||
description: 'Used to extract multiple key/value pairs from
|
||||
one secret Note: Extract does not support sourceRef.Generator
|
||||
or sourceRef.GeneratorRef.'
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
decodingStrategy:
|
||||
default: None
|
||||
description: Used to define a decoding Strategy
|
||||
type: string
|
||||
key:
|
||||
description: Key is the key used in the Provider, mandatory
|
||||
type: string
|
||||
metadataPolicy:
|
||||
description: Policy for fetching tags/labels from provider
|
||||
secrets, possible options are Fetch, None. Defaults to
|
||||
None
|
||||
type: string
|
||||
property:
|
||||
description: Used to select a specific property of the Provider
|
||||
value (if a map), if supported
|
||||
type: string
|
||||
version:
|
||||
description: Used to select a specific version of the Provider
|
||||
value, if supported
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
find:
|
||||
description: 'Used to find secrets based on tags or regular
|
||||
expressions Note: Find does not support sourceRef.Generator
|
||||
or sourceRef.GeneratorRef.'
|
||||
properties:
|
||||
conversionStrategy:
|
||||
default: Default
|
||||
description: Used to define a conversion Strategy
|
||||
type: string
|
||||
decodingStrategy:
|
||||
default: None
|
||||
description: Used to define a decoding Strategy
|
||||
type: string
|
||||
name:
|
||||
description: Finds secrets based on the name.
|
||||
properties:
|
||||
regexp:
|
||||
description: Finds secrets base
|
||||
type: string
|
||||
type: object
|
||||
path:
|
||||
description: A root path to start the find operations.
|
||||
type: string
|
||||
tags:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Find secrets based on tags.
|
||||
type: object
|
||||
type: object
|
||||
rewrite:
|
||||
description: Used to rewrite secret Keys after getting them
|
||||
from the secret Provider Multiple Rewrite operations can be
|
||||
provided. They are applied in a layered order (first to last)
|
||||
items:
|
||||
properties:
|
||||
regexp:
|
||||
description: Used to rewrite with regular expressions.
|
||||
The resulting key will be the output of a regexp.ReplaceAll
|
||||
operation.
|
||||
properties:
|
||||
source:
|
||||
description: Used to define the regular expression
|
||||
of a re.Compiler.
|
||||
type: string
|
||||
target:
|
||||
description: Used to define the target pattern of
|
||||
a ReplaceAll operation.
|
||||
type: string
|
||||
required:
|
||||
- source
|
||||
- target
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
sourceRef:
|
||||
description: SourceRef points to a store or generator which
|
||||
contains secret values ready to use. Use this in combination
|
||||
with Extract or Find pull values out of a specific SecretStore.
|
||||
When sourceRef points to a generator Extract or Find is not
|
||||
supported. The generator returns a static map of values
|
||||
maxProperties: 1
|
||||
properties:
|
||||
generatorRef:
|
||||
description: GeneratorRef points to a generator custom resource
|
||||
in
|
||||
properties:
|
||||
apiVersion:
|
||||
default: generators.external-secrets.io/v1alpha1
|
||||
description: Specify the apiVersion of the generator
|
||||
resource
|
||||
type: string
|
||||
kind:
|
||||
description: Specify the Kind of the resource, e.g.
|
||||
Password, ACRAccessToken etc.
|
||||
type: string
|
||||
name:
|
||||
description: Specify the name of the generator resource
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
storeRef:
|
||||
description: SecretStoreRef defines which SecretStore to
|
||||
fetch the ExternalSecret data.
|
||||
properties:
|
||||
kind:
|
||||
description: Kind of the SecretStore resource (SecretStore
|
||||
or ClusterSecretStore) Defaults to `SecretStore`
|
||||
type: string
|
||||
name:
|
||||
description: Name of the SecretStore resource
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
refreshInterval:
|
||||
default: 1h
|
||||
description: RefreshInterval is the amount of time before the values
|
||||
are read again from the SecretStore provider Valid time units are
|
||||
"ns", "us" (or "µs"), "ms", "s", "m", "h" May be set to zero to
|
||||
fetch and create it once. Defaults to 1h.
|
||||
type: string
|
||||
secretStoreRef:
|
||||
description: SecretStoreRef defines which SecretStore to fetch the
|
||||
ExternalSecret data.
|
||||
properties:
|
||||
kind:
|
||||
description: Kind of the SecretStore resource (SecretStore or
|
||||
ClusterSecretStore) Defaults to `SecretStore`
|
||||
type: string
|
||||
name:
|
||||
description: Name of the SecretStore resource
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
target:
|
||||
default:
|
||||
creationPolicy: Owner
|
||||
deletionPolicy: Retain
|
||||
description: ExternalSecretTarget defines the Kubernetes Secret to
|
||||
be created There can be only one target per ExternalSecret.
|
||||
properties:
|
||||
creationPolicy:
|
||||
default: Owner
|
||||
description: CreationPolicy defines rules on how to create the
|
||||
resulting Secret Defaults to 'Owner'
|
||||
enum:
|
||||
- Owner
|
||||
- Orphan
|
||||
- Merge
|
||||
- None
|
||||
type: string
|
||||
deletionPolicy:
|
||||
default: Retain
|
||||
description: DeletionPolicy defines rules on how to delete the
|
||||
resulting Secret Defaults to 'Retain'
|
||||
enum:
|
||||
- Delete
|
||||
- Merge
|
||||
- Retain
|
||||
type: string
|
||||
immutable:
|
||||
description: Immutable defines if the final secret will be immutable
|
||||
type: boolean
|
||||
name:
|
||||
description: Name defines the name of the Secret resource to be
|
||||
managed This field is immutable Defaults to the .metadata.name
|
||||
of the ExternalSecret resource
|
||||
type: string
|
||||
template:
|
||||
description: Template defines a blueprint for the created Secret
|
||||
resource.
|
||||
properties:
|
||||
data:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
engineVersion:
|
||||
default: v2
|
||||
type: string
|
||||
mergePolicy:
|
||||
default: Replace
|
||||
type: string
|
||||
metadata:
|
||||
description: ExternalSecretTemplateMetadata defines metadata
|
||||
fields for the Secret blueprint.
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
templateFrom:
|
||||
items:
|
||||
properties:
|
||||
configMap:
|
||||
properties:
|
||||
items:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
templateAs:
|
||||
default: Values
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- items
|
||||
- name
|
||||
type: object
|
||||
literal:
|
||||
type: string
|
||||
secret:
|
||||
properties:
|
||||
items:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
templateAs:
|
||||
default: Values
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- items
|
||||
- name
|
||||
type: object
|
||||
target:
|
||||
default: Data
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
properties:
|
||||
conditions:
|
||||
items:
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
refreshTime:
|
||||
description: refreshTime is the time and date the external secret
|
||||
was fetched and the target secret updated
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
syncedResourceVersion:
|
||||
description: SyncedResourceVersion keeps track of the last synced
|
||||
version
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-external-secret-prefix
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,44 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: add-external-secret-prefix
|
||||
---
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-external-secret-prefix
|
||||
annotations:
|
||||
policies.kyverno.io/title: Add prefix to external secret
|
||||
policies.kyverno.io/category: ExternalSecretOperator
|
||||
policies.kyverno.io/severity: medium
|
||||
policies.kyverno.io/subject: ExternalSecret
|
||||
kyverno.io/kyverno-version: 1.7.1
|
||||
policies.kyverno.io/minversion: 1.6.0
|
||||
kyverno.io/kubernetes-version: "1.23"
|
||||
policies.kyverno.io/description: >-
|
||||
This Policy mutates secretRef key to add a prefix.
|
||||
External Secret Operator proposes to use kyverno to force ExternalSecrets
|
||||
to have namespace prefix so that kubernetes administrators do not need to
|
||||
define permissions and users per namespace.
|
||||
Doing this developers are abstracted by administrators naming convention and will not
|
||||
be able to access secrets from other namespaces.
|
||||
In this example, in the JSON patch change "prefix-" to your preferred prefix. For example: {{ request.namespace }}
|
||||
spec:
|
||||
rules:
|
||||
- name: add-external-secret-prefix
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- ExternalSecret
|
||||
mutate:
|
||||
foreach:
|
||||
- list: "request.object.spec.data"
|
||||
patchesJson6902: |-
|
||||
- path: /spec/data/{{elementIndex}}/remoteRef
|
||||
op: add
|
||||
value:
|
||||
key: "prefix-{{element.remoteRef.key}}"
|
||||
property: "{{element.remoteRef.property}}"
|
||||
conversionStrategy: "{{element.remoteRef.conversionStrategy}}"
|
||||
decodingStrategy: "{{element.remoteRef.decodingStrategy}}"
|
|
@ -0,0 +1,27 @@
|
|||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
namespace: add-external-secret-prefix
|
||||
spec:
|
||||
data:
|
||||
- remoteRef:
|
||||
conversionStrategy: Default
|
||||
decodingStrategy: None
|
||||
key: prefix-remote-secret
|
||||
property: name.first
|
||||
secretKey: firstname
|
||||
- remoteRef:
|
||||
conversionStrategy: Default
|
||||
decodingStrategy: None
|
||||
key: prefix-friend-secret
|
||||
property: friends.1.first
|
||||
secretKey: first_friend
|
||||
refreshInterval: 1m
|
||||
secretStoreRef:
|
||||
kind: SecretStore
|
||||
name: aws
|
||||
target:
|
||||
creationPolicy: Owner
|
||||
deletionPolicy: Retain
|
||||
name: secret-to-be-created
|
|
@ -0,0 +1,26 @@
|
|||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
namespace: add-external-secret-prefix
|
||||
spec:
|
||||
refreshInterval: 1m
|
||||
secretStoreRef:
|
||||
name: aws
|
||||
kind: SecretStore
|
||||
target:
|
||||
name: secret-to-be-created
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: firstname
|
||||
remoteRef:
|
||||
key: remote-secret
|
||||
property: "name.first"
|
||||
conversionStrategy: Default
|
||||
decodingStrategy: None
|
||||
- secretKey: first_friend
|
||||
remoteRef:
|
||||
key: friend-secret
|
||||
property: "friends.1.first"
|
||||
conversionStrategy: Default
|
||||
decodingStrategy: None
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- resource.yaml
|
||||
assert:
|
||||
- resource-mutated.yaml
|
|
@ -0,0 +1,13 @@
|
|||
## Description
|
||||
|
||||
This is a test of the policy in this folder.
|
||||
|
||||
Note: In order for this test to work on Pods emitted from Pod controllers, the Kyverno ConfigMap excludeGroups value may need to be modified to remove the entry for system:serviceaccounts:kube-system or else mutation may not occur.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The resource is expected to be mutated so it resembles the specified asserted resources. If it does, the test passes. If it does not, it fails.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-image-as-env-var
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,40 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: add-image-as-env-var
|
||||
---
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-image-as-env-var
|
||||
annotations:
|
||||
pod-policies.kyverno.io/autogen-controllers: none
|
||||
policies.kyverno.io/title: Add Image as Environment Variable
|
||||
policies.kyverno.io/category: Other
|
||||
policies.kyverno.io/severity: medium
|
||||
kyverno.io/kyverno-version: 1.10.0-alpha.2
|
||||
kyverno.io/kubernetes-version: "1.26"
|
||||
policies.kyverno.io/subject: Pod
|
||||
policies.kyverno.io/description: >-
|
||||
The Kubernetes downward API only has the ability to express so many
|
||||
options as environment variables. The image consumed in a Pod is commonly
|
||||
needed to make the application aware of some logic it must take. This policy
|
||||
takes the value of the `image` field and adds it as an environment variable
|
||||
to Pods.
|
||||
spec:
|
||||
rules:
|
||||
- name: pod-containers-inject-image
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
mutate:
|
||||
foreach:
|
||||
- list: request.object.spec.containers[]
|
||||
patchesJson6902: |-
|
||||
- op: add
|
||||
path: /spec/containers/{{elementIndex}}/env/-
|
||||
value:
|
||||
name: K8S_IMAGE
|
||||
value: "{{ element.image }}"
|
|
@ -0,0 +1,47 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod01
|
||||
namespace: add-image-as-env-var
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: FOO
|
||||
value: bar
|
||||
- name: K8S_IMAGE
|
||||
value: aiboelckajdow:1.35
|
||||
image: aiboelckajdow:1.35
|
||||
name: busybox
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod02
|
||||
namespace: add-image-as-env-var
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: K8S_IMAGE
|
||||
value: bicoapeibsjasjdhb:1.35
|
||||
image: bicoapeibsjasjdhb:1.35
|
||||
name: busybox
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod03
|
||||
namespace: add-image-as-env-var
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: COLOR
|
||||
value: red
|
||||
- name: K8S_IMAGE
|
||||
value: pqmbjduzivyyaiv:1.35
|
||||
image: pqmbjduzivyyaiv:1.35
|
||||
name: busybox
|
||||
- env:
|
||||
- name: K8S_IMAGE
|
||||
value: yqkbmzydleyds:1.1.0
|
||||
image: yqkbmzydleyds:1.1.0
|
||||
name: nginx
|
|
@ -0,0 +1,37 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod01
|
||||
namespace: add-image-as-env-var
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: aiboelckajdow:1.35
|
||||
env:
|
||||
- name: FOO
|
||||
value: bar
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod02
|
||||
namespace: add-image-as-env-var
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: bicoapeibsjasjdhb:1.35
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod03
|
||||
namespace: add-image-as-env-var
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: pqmbjduzivyyaiv:1.35
|
||||
env:
|
||||
- name: COLOR
|
||||
value: red
|
||||
- name: nginx
|
||||
image: yqkbmzydleyds:1.1.0
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- resource.yaml
|
||||
assert:
|
||||
- resource-mutated.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This is a test of the policy in this folder.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The resource is expected to be mutated so it resembles the specified asserted resources. If it does, the test passes. If it does not, it fails.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-node-affinity
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,38 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: add-node-affinity
|
||||
---
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-node-affinity
|
||||
annotations:
|
||||
policies.kyverno.io/title: Add Node Affinity
|
||||
policies.kyverno.io/category: Other
|
||||
policies.kyverno.io/severity: medium
|
||||
policies.kyverno.io/subject: Deployment
|
||||
kyverno.io/kyverno-version: 1.6.0
|
||||
kyverno.io/kubernetes-version: "1.21"
|
||||
policies.kyverno.io/description: >-
|
||||
Node affinity, similar to node selection, is a way to specify which node(s) on which Pods will be scheduled
|
||||
but based on more complex conditions. This policy will add node affinity to a Deployment and if one already
|
||||
exists an expression will be added to it.
|
||||
spec:
|
||||
background: false
|
||||
rules:
|
||||
- name: add-node-affinity-deployment
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Deployment
|
||||
mutate:
|
||||
patchesJson6902: |-
|
||||
- path: "/spec/template/spec/affinity/nodeAffinity/requiredDuringSchedulingIgnoredDuringExecution/nodeSelectorTerms/-1/matchExpressions/-1"
|
||||
op: add
|
||||
value:
|
||||
key: zone_weight
|
||||
operator: Lt
|
||||
values:
|
||||
- "400"
|
|
@ -0,0 +1,107 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: tomcat
|
||||
name: tomcat-deployment
|
||||
namespace: add-node-affinity
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: tomcat
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: tomcat
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: zone_weight
|
||||
operator: Lt
|
||||
values:
|
||||
- "400"
|
||||
containers:
|
||||
- image: thisisdefinitelynottomcat:9.0
|
||||
name: tomcat
|
||||
ports:
|
||||
- containerPort: 80
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
name: nginx-deployment
|
||||
namespace: add-node-affinity
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: fookey
|
||||
operator: In
|
||||
values:
|
||||
- bar
|
||||
- key: zone_weight
|
||||
operator: Lt
|
||||
values:
|
||||
- "400"
|
||||
containers:
|
||||
- image: thisisdefinitelynotnginx:1.0.1
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
name: redis-deployment
|
||||
namespace: add-node-affinity
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: zone_weight
|
||||
operator: Lt
|
||||
values:
|
||||
- "400"
|
||||
matchFields:
|
||||
- key: metadata.name
|
||||
operator: In
|
||||
values:
|
||||
- red
|
||||
containers:
|
||||
- image: thisisdefinitelynotredis:latest
|
||||
name: redis
|
||||
ports:
|
||||
- containerPort: 80
|
||||
protocol: TCP
|
|
@ -0,0 +1,86 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: tomcat-deployment
|
||||
namespace: add-node-affinity
|
||||
labels:
|
||||
app: tomcat
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: tomcat
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: tomcat
|
||||
spec:
|
||||
containers:
|
||||
- name: tomcat
|
||||
image: thisisdefinitelynottomcat:9.0
|
||||
ports:
|
||||
- containerPort: 80
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
namespace: add-node-affinity
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: fookey
|
||||
operator: In
|
||||
values:
|
||||
- bar
|
||||
containers:
|
||||
- name: nginx
|
||||
image: thisisdefinitelynotnginx:1.0.1
|
||||
ports:
|
||||
- containerPort: 80
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-deployment
|
||||
namespace: add-node-affinity
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchFields:
|
||||
- key: metadata.name
|
||||
operator: In
|
||||
values:
|
||||
- red
|
||||
containers:
|
||||
- name: redis
|
||||
image: thisisdefinitelynotredis:latest
|
||||
ports:
|
||||
- containerPort: 80
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- pod.yaml
|
||||
assert:
|
||||
- pod-mutated.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- deployment.yaml
|
||||
assert:
|
||||
- deployment-mutated.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- cronjob.yaml
|
||||
assert:
|
||||
- cronjob-mutated.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This is a test of the policy in this folder.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The resource is expected to be mutated so it resembles the specified asserted resources. If it does, the test passes. If it does not, it fails.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,20 @@
|
|||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: hello
|
||||
namespace: add-pod-priorityclassname
|
||||
spec:
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- date; echo Hello from the Kubernetes cluster
|
||||
image: somejunkimagegoeshere
|
||||
name: hello
|
||||
priorityClassName: non-production
|
||||
restartPolicy: OnFailure
|
||||
schedule: '*/1 * * * *'
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: hello
|
||||
namespace: add-pod-priorityclassname
|
||||
spec:
|
||||
schedule: "*/1 * * * *"
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: hello
|
||||
image: somejunkimagegoeshere
|
||||
args:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- date; echo Hello from the Kubernetes cluster
|
||||
restartPolicy: OnFailure
|
|
@ -0,0 +1,24 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: busybox
|
||||
name: busybox
|
||||
namespace: add-pod-priorityclassname
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: busybox
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: busybox
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- sleep
|
||||
- "9999"
|
||||
image: somejunkbusyboximage:1.28
|
||||
name: busybox
|
||||
priorityClassName: non-production
|
|
@ -0,0 +1,21 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: busybox
|
||||
namespace: add-pod-priorityclassname
|
||||
labels:
|
||||
app: busybox
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: busybox
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: busybox
|
||||
spec:
|
||||
containers:
|
||||
- image: somejunkbusyboximage:1.28
|
||||
name: busybox
|
||||
command: ["sleep", "9999"]
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: blank
|
||||
namespace: add-pod-priorityclassname
|
||||
spec:
|
||||
containers:
|
||||
- image: sfsdafasdfsadfsadf
|
||||
name: busybox
|
||||
priorityClassName: non-production
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: blank
|
||||
namespace: add-pod-priorityclassname
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: sfsdafasdfsadfsadf
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-pod-priorityclassname
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,93 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: add-pod-priorityclassname
|
||||
---
|
||||
apiVersion: scheduling.k8s.io/v1
|
||||
kind: PriorityClass
|
||||
metadata:
|
||||
name: non-production
|
||||
value: 1234
|
||||
globalDefault: false
|
||||
description: "This priority class should be used for XYZ service pods only."
|
||||
---
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-pod-priorityclassname
|
||||
annotations:
|
||||
policies.kyverno.io/title: Add Pod priorityClassName
|
||||
policies.kyverno.io/category: Other
|
||||
policies.kyverno.io/severity: medium
|
||||
policies.kyverno.io/subject: Pod
|
||||
pod-policies.kyverno.io/autogen-controllers: none
|
||||
kyverno.io/kyverno-version: 1.7.1
|
||||
policies.kyverno.io/minversion: 1.6.0
|
||||
kyverno.io/kubernetes-version: "1.23"
|
||||
policies.kyverno.io/description: >-
|
||||
A Pod PriorityClass is used to provide a guarantee on the scheduling of a Pod relative to others.
|
||||
This policy adds the priorityClassName of `non-production` to any Pod deployed
|
||||
into a Namespace that does not have the label env=production.
|
||||
spec:
|
||||
background: false
|
||||
rules:
|
||||
- name: add-priorityclass-pods
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: env
|
||||
operator: NotIn
|
||||
values:
|
||||
- production
|
||||
mutate:
|
||||
patchesJson6902: |-
|
||||
- op: remove
|
||||
path: '/spec/priority'
|
||||
- op: add
|
||||
path: /spec/priorityClassName
|
||||
value: 'non-production'
|
||||
- name: add-priorityclass-controllers
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Deployment
|
||||
- DaemonSet
|
||||
- StatefulSet
|
||||
- Job
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: env
|
||||
operator: NotIn
|
||||
values:
|
||||
- production
|
||||
mutate:
|
||||
patchesJson6902: |-
|
||||
- op: remove
|
||||
path: '/spec/template/spec/priority'
|
||||
- op: add
|
||||
path: /spec/template/spec/priorityClassName
|
||||
value: 'non-production'
|
||||
- name: add-priorityclass-cronjobs
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- CronJob
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: env
|
||||
operator: NotIn
|
||||
values:
|
||||
- production
|
||||
mutate:
|
||||
patchesJson6902: |-
|
||||
- op: remove
|
||||
path: '/spec/jobTemplate/spec/template/spec/priority'
|
||||
- op: add
|
||||
path: /spec/jobTemplate/spec/template/spec/priorityClassName
|
||||
value: 'non-production'
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- resource.yaml
|
||||
assert:
|
||||
- resource-mutated.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This is a test of the policy in this folder.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The resource is expected to be mutated so it resembles the specified asserted resource. If it does, the test passes. If it does not, it fails.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-tolerations
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,43 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: add-tolerations
|
||||
---
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-tolerations
|
||||
annotations:
|
||||
policies.kyverno.io/title: Add Tolerations
|
||||
policies.kyverno.io/category: Other
|
||||
policies.kyverno.io/severity: medium
|
||||
policies.kyverno.io/subject: Pod
|
||||
kyverno.io/kyverno-version: 1.7.1
|
||||
policies.kyverno.io/minversion: 1.6.0
|
||||
kyverno.io/kubernetes-version: "1.23"
|
||||
policies.kyverno.io/description: >-
|
||||
Pod tolerations are used to schedule on Nodes which have
|
||||
a matching taint. This policy adds the toleration `org.com/role=service:NoSchedule`
|
||||
if existing tolerations do not contain the key `org.com/role`.
|
||||
spec:
|
||||
rules:
|
||||
- name: service-toleration
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
preconditions:
|
||||
any:
|
||||
- key: "org.com/role"
|
||||
operator: AnyNotIn
|
||||
value: "{{ request.object.spec.tolerations[].key || `[]` }}"
|
||||
mutate:
|
||||
patchesJson6902: |-
|
||||
- op: add
|
||||
path: "/spec/tolerations/-"
|
||||
value:
|
||||
key: org.com/role
|
||||
operator: Equal
|
||||
value: service
|
||||
effect: NoSchedule
|
|
@ -0,0 +1,25 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: addpod02
|
||||
namespace: add-tolerations
|
||||
spec:
|
||||
containers:
|
||||
- image: containerimage01
|
||||
name: container01
|
||||
tolerations:
|
||||
- effect: NoSchedule
|
||||
key: org.com/test
|
||||
operator: Exists
|
||||
- effect: NoExecute
|
||||
key: node.kubernetes.io/not-ready
|
||||
operator: Exists
|
||||
tolerationSeconds: 300
|
||||
- effect: NoExecute
|
||||
key: node.kubernetes.io/unreachable
|
||||
operator: Exists
|
||||
tolerationSeconds: 300
|
||||
- effect: NoSchedule
|
||||
key: org.com/role
|
||||
operator: Equal
|
||||
value: service
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: addpod02
|
||||
namespace: add-tolerations
|
||||
spec:
|
||||
containers:
|
||||
- name: container01
|
||||
image: containerimage01
|
||||
tolerations:
|
||||
- key: org.com/test
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- resource.yaml
|
||||
assert:
|
||||
- resource-mutated.yaml
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: sleep 10
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This is a test of the policy in this folder.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The resource is expected to be mutated so it resembles the specified asserted resource. If it does, the test passes. If it does not, it fails.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-volume
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,41 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: add-volume
|
||||
annotations:
|
||||
policies.kyverno.io/title: Add Volume to Deployment
|
||||
policies.kyverno.io/category: Sample
|
||||
policies.kyverno.io/subject: Deployment, Volume
|
||||
policies.kyverno.io/minversion: 1.6.0
|
||||
policies.kyverno.io/description: >-
|
||||
Some Kubernetes applications like HashiCorp Vault must perform some modifications
|
||||
to resources in order to invoke their specific functionality. Often times, that functionality
|
||||
is controlled by the presence of a label or specific annotation. This policy, based on HashiCorp
|
||||
Vault, adds a volume and volumeMount to a Deployment if there is an annotation called
|
||||
"vault.k8s.corp.net/inject=enabled" present.
|
||||
spec:
|
||||
rules:
|
||||
- name: add-volume
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Deployment
|
||||
preconditions:
|
||||
any:
|
||||
- key: "{{request.object.spec.template.metadata.annotations.\"vault.k8s.corp.net/inject\"}}"
|
||||
operator: Equals
|
||||
value: enabled
|
||||
mutate:
|
||||
patchesJson6902: |-
|
||||
- op: add
|
||||
path: /spec/template/spec/volumes/-
|
||||
value:
|
||||
name: vault-secret
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
- op: add
|
||||
path: /spec/template/spec/containers/0/volumeMounts/-
|
||||
value:
|
||||
mountPath: /secret
|
||||
name: vault-secret
|
|
@ -0,0 +1,37 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: myapp
|
||||
name: mydeploy
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: myapp
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
vault.k8s.corp.net/inject: enabled
|
||||
labels:
|
||||
app: myapp
|
||||
spec:
|
||||
containers:
|
||||
- image: somedummyimagehere:latest
|
||||
name: container01
|
||||
volumeMounts:
|
||||
- mountPath: /secret
|
||||
name: vault-secret
|
||||
- image: anotherdummyimagehere:1.2.3
|
||||
name: container02
|
||||
volumeMounts:
|
||||
- mountPath: /extra
|
||||
name: foobar
|
||||
volumes:
|
||||
- hostPath:
|
||||
path: /foo/bar
|
||||
type: ""
|
||||
name: foobar
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: vault-secret
|
|
@ -0,0 +1,30 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: myapp
|
||||
name: mydeploy
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: myapp
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: myapp
|
||||
annotations:
|
||||
vault.k8s.corp.net/inject: enabled
|
||||
spec:
|
||||
containers:
|
||||
- image: somedummyimagehere:latest
|
||||
name: container01
|
||||
- image: anotherdummyimagehere:1.2.3
|
||||
name: container02
|
||||
volumeMounts:
|
||||
- mountPath: /extra
|
||||
name: foobar
|
||||
volumes:
|
||||
- hostPath:
|
||||
path: /foo/bar
|
||||
name: foobar
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- resource.yaml
|
||||
assert:
|
||||
- resource-mutated.yaml
|
|
@ -0,0 +1,13 @@
|
|||
## Description
|
||||
|
||||
This is a test of the policy in this folder.
|
||||
|
||||
Note: In order for this test to work on Pods emitted from Pod controllers, the Kyverno ConfigMap excludeGroups value may need to be modified to remove the entry for system:serviceaccounts:kube-system or else mutation may not occur.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The resource is expected to be mutated so it resembles the specified asserted resource. If it does, the test passes. If it does not, it fails.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: annotate-base-images
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,53 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: annotate-base-images
|
||||
---
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: annotate-base-images
|
||||
annotations:
|
||||
policies.kyverno.io/title: Annotate Base Images
|
||||
policies.kyverno.io/category: Other
|
||||
policies.kyverno.io/severity: medium
|
||||
pod-policies.kyverno.io/autogen-controllers: none
|
||||
kyverno.io/kyverno-version: 1.7.0
|
||||
policies.kyverno.io/minversion: 1.7.0
|
||||
kyverno.io/kubernetes-version: "1.23"
|
||||
policies.kyverno.io/subject: Pod
|
||||
policies.kyverno.io/description: >-
|
||||
A base image used to construct a container image is not accessible
|
||||
by any Kubernetes component and not a field in a Pod spec as it must
|
||||
be fetched from a registry. Having this information available in the resource
|
||||
referencing the containers helps to provide a clearer understanding of
|
||||
its contents. This policy adds an annotation to a Pod or its controllers
|
||||
with the base image used for each container if present in an OCI annotation.
|
||||
spec:
|
||||
rules:
|
||||
- name: mutate-base-image
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
preconditions:
|
||||
all:
|
||||
- key: "{{request.operation || 'BACKGROUND'}}"
|
||||
operator: NotEquals
|
||||
value: DELETE
|
||||
mutate:
|
||||
foreach:
|
||||
- list: "request.object.spec.containers"
|
||||
context:
|
||||
- name: imageData
|
||||
imageRegistry:
|
||||
reference: "{{ element.image }}"
|
||||
- name: basename
|
||||
variable:
|
||||
jmesPath: imageData.manifest.annotations."org.opencontainers.image.base.name"
|
||||
default: ''
|
||||
patchesJson6902: |-
|
||||
- path: "/metadata/annotations/kyverno.io~1baseimages{{elementIndex}}"
|
||||
op: add
|
||||
value: "{{basename}}"
|
|
@ -0,0 +1,14 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
annotations:
|
||||
kyverno.io/baseimages0: distroless.dev/static:latest
|
||||
kyverno.io/baseimages1: cgr.dev/chainguard/static:latest
|
||||
name: testpodannotate
|
||||
namespace: annotate-base-images
|
||||
spec:
|
||||
containers:
|
||||
- image: ghcr.io/kyverno/kyverno:v1.8.0
|
||||
name: kyverno180
|
||||
- image: ghcr.io/kyverno/kyverno:v1.9.0
|
||||
name: kyverno190
|
|
@ -0,0 +1,11 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: testpodannotate
|
||||
namespace: annotate-base-images
|
||||
spec:
|
||||
containers:
|
||||
- name: kyverno180
|
||||
image: ghcr.io/kyverno/kyverno:v1.8.0
|
||||
- name: kyverno190
|
||||
image: ghcr.io/kyverno/kyverno:v1.9.0
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-assert.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- pod.yaml
|
||||
assert:
|
||||
- pod-assert.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test adds an element to an array and removes it.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
After mutation, the array is expected to be the same as the original array.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
5661
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox:1.35
|
||||
env:
|
||||
- name: ENV_ONE
|
||||
value: "one"
|
||||
- name: ENV_TWO
|
||||
value: "two"
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox:1.35
|
||||
env:
|
||||
- name: ENV_ONE
|
||||
value: "one"
|
||||
- name: ENV_TWO
|
||||
value: "two"
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: foreach-remove-elements
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,44 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: foreach-remove-elements
|
||||
spec:
|
||||
background: false
|
||||
schemaValidation: false
|
||||
rules:
|
||||
- name: dummy-1
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
mutate:
|
||||
foreach:
|
||||
- list: request.object.spec.containers[0].env
|
||||
order: Ascending
|
||||
patchesJson6902: |-
|
||||
- path: /spec/containers/0/env/{{elementIndex}}
|
||||
op: add
|
||||
value:
|
||||
name: DUMMY
|
||||
value: "dummy"
|
||||
- path: /spec/containers/0/env/{{elementIndex}}
|
||||
op: remove
|
||||
- name: dummy-2
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
mutate:
|
||||
foreach:
|
||||
- list: request.object.spec.containers[0].env
|
||||
order: Descending
|
||||
patchesJson6902: |-
|
||||
- path: /spec/containers/0/env/{{elementIndex}}
|
||||
op: add
|
||||
value:
|
||||
name: DUMMY
|
||||
value: "dummy"
|
||||
- path: /spec/containers/0/env/{{elementIndex}}
|
||||
op: remove
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-assert.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- pod.yaml
|
||||
assert:
|
||||
- pod-assert.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test removes an element from an array and adds one, effectively replacing it.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
After mutation, the array is expected to contained only replaced elements.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
5661
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox:1.35
|
||||
env:
|
||||
- name: DUMMY_2
|
||||
value: "dummy-2"
|
||||
- name: DUMMY_2
|
||||
value: "dummy-2"
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox:1.35
|
||||
env:
|
||||
- name: ENV_ONE
|
||||
value: "one"
|
||||
- name: ENV_TWO
|
||||
value: "two"
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: foreach-remove-elements
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,44 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: foreach-remove-elements
|
||||
spec:
|
||||
background: false
|
||||
schemaValidation: false
|
||||
rules:
|
||||
- name: dummy-1
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
mutate:
|
||||
foreach:
|
||||
- list: request.object.spec.containers[0].env
|
||||
order: Ascending
|
||||
patchesJson6902: |-
|
||||
- path: /spec/containers/0/env/{{elementIndex}}
|
||||
op: remove
|
||||
- path: /spec/containers/0/env/{{elementIndex}}
|
||||
op: add
|
||||
value:
|
||||
name: DUMMY
|
||||
value: "dummy"
|
||||
- name: dummy-2
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
mutate:
|
||||
foreach:
|
||||
- list: request.object.spec.containers[0].env
|
||||
order: Descending
|
||||
patchesJson6902: |-
|
||||
- path: /spec/containers/0/env/{{elementIndex}}
|
||||
op: remove
|
||||
- path: /spec/containers/0/env/{{elementIndex}}
|
||||
op: add
|
||||
value:
|
||||
name: DUMMY_2
|
||||
value: "dummy-2"
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-assert.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- pod.yaml
|
||||
assert:
|
||||
- pod-assert.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test removes multiple elements from an array iterating in ascending order.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
Element at index 0 is removed but element at index 1 is not (because when we removed element at index 0, the element at index 1 moved to index 0 and there's nothing to remove at index 1 anymore).
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
5661
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox:1.35
|
||||
env:
|
||||
# first element was removed, second env var became index 0
|
||||
# next patch is supposed to remove element at index 1 but it doesn't exist anymore
|
||||
- name: ENV_TWO
|
||||
value: "two"
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox:1.35
|
||||
env:
|
||||
- name: ENV_ONE
|
||||
value: "one"
|
||||
- name: ENV_TWO
|
||||
value: "two"
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: foreach-remove-elements
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,20 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: foreach-remove-elements
|
||||
spec:
|
||||
background: false
|
||||
schemaValidation: false
|
||||
rules:
|
||||
- name: remove-elements
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
mutate:
|
||||
foreach:
|
||||
- list: request.object.spec.containers[0].env
|
||||
patchesJson6902: |-
|
||||
- path: /spec/containers/0/env/{{elementIndex}}
|
||||
op: remove
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-assert.yaml
|
|
@ -0,0 +1,8 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- pod.yaml
|
||||
assert:
|
||||
- pod-assert.yaml
|
||||
error:
|
||||
- pod-error.yaml
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue