diff --git a/api/kyverno/v1/common_types.go b/api/kyverno/v1/common_types.go index d9cc22fd0c..103f674ee9 100644 --- a/api/kyverno/v1/common_types.go +++ b/api/kyverno/v1/common_types.go @@ -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"` diff --git a/api/kyverno/v1/zz_generated.deepcopy.go b/api/kyverno/v1/zz_generated.deepcopy.go index b6aeef0bd6..dd9ad92d94 100755 --- a/api/kyverno/v1/zz_generated.deepcopy.go +++ b/api/kyverno/v1/zz_generated.deepcopy.go @@ -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)) diff --git a/charts/kyverno/templates/crds/crds.yaml b/charts/kyverno/templates/crds/crds.yaml index 562316ce40..82c293ac24 100644 --- a/charts/kyverno/templates/crds/crds.yaml +++ b/charts/kyverno/templates/crds/crds.yaml @@ -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/ diff --git a/config/crds/kyverno.io_clusterpolicies.yaml b/config/crds/kyverno.io_clusterpolicies.yaml index e661fd1216..a78c662bdf 100644 --- a/config/crds/kyverno.io_clusterpolicies.yaml +++ b/config/crds/kyverno.io_clusterpolicies.yaml @@ -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/ diff --git a/config/crds/kyverno.io_policies.yaml b/config/crds/kyverno.io_policies.yaml index 43563d745d..73b4366bcd 100644 --- a/config/crds/kyverno.io_policies.yaml +++ b/config/crds/kyverno.io_policies.yaml @@ -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/ diff --git a/config/install-latest-testing.yaml b/config/install-latest-testing.yaml index 977b810559..7282293afe 100644 --- a/config/install-latest-testing.yaml +++ b/config/install-latest-testing.yaml @@ -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/ diff --git a/docs/user/crd/index.html b/docs/user/crd/index.html index 0cc256abb6..73ebc82e52 100644 --- a/docs/user/crd/index.html +++ b/docs/user/crd/index.html @@ -1386,6 +1386,21 @@ to which the validation logic is applied.

+order
+ + +ForeachOrder + + + + +(Optional) +

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.

+ + + + context
@@ -1594,6 +1609,15 @@ Kubernetes apiextensions/v1.JSON
+

ForeachOrder +(string alias)

+

+(Appears on: +ForEachMutation) +

+

+

ForeachOrder specifies the iteration order in foreach statements.

+

GenerateType (string alias)

diff --git a/pkg/engine/handlers/mutation/common.go b/pkg/engine/handlers/mutation/common.go index ab41825b77..f88a2772ac 100644 --- a/pkg/engine/handlers/mutation/common.go +++ b/pkg/engine/handlers/mutation/common.go @@ -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 { diff --git a/pkg/engine/mutate/patch/patchesUtils.go b/pkg/engine/mutate/patch/patchesUtils.go index 6e574e5a2c..cccdfde723 100644 --- a/pkg/engine/mutate/patch/patchesUtils.go +++ b/pkg/engine/mutate/patch/patchesUtils.go @@ -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)) diff --git a/pkg/engine/mutate/patch/patchesUtils_test.go b/pkg/engine/mutate/patch/patchesUtils_test.go index 249426e9cf..17103e6c67 100644 --- a/pkg/engine/mutate/patch/patchesUtils_test.go +++ b/pkg/engine/mutate/patch/patchesUtils_test.go @@ -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)) } } diff --git a/test/conformance/kuttl/mutate/policy/cornercases/foreach-remove-elements/policy.yaml b/test/conformance/kuttl/mutate/policy/cornercases/foreach-remove-elements/policy.yaml index f244db6de6..a2d91a776c 100644 --- a/test/conformance/kuttl/mutate/policy/cornercases/foreach-remove-elements/policy.yaml +++ b/test/conformance/kuttl/mutate/policy/cornercases/foreach-remove-elements/policy.yaml @@ -15,6 +15,7 @@ spec: mutate: foreach: - list: request.object.spec.volumes[] + order: Descending preconditions: all: - key: hostPath diff --git a/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/01-policy.yaml new file mode 100644 index 0000000000..f3857739b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/02-resource.yaml b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/02-resource.yaml new file mode 100644 index 0000000000..7e08de156a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/02-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/README.md b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/README.md new file mode 100644 index 0000000000..4763840548 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/policy-ready.yaml new file mode 100644 index 0000000000..6696bb1d2d --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-emptydir-sizelimit +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/policy.yaml b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/policy.yaml new file mode 100644 index 0000000000..2a7cf157b3 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/policy.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/resource-mutated.yaml new file mode 100644 index 0000000000..f1080792f5 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/resource-mutated.yaml @@ -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 diff --git a/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/resource.yaml b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/resource.yaml new file mode 100644 index 0000000000..878ced1811 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-emptydirsizelimit/resource.yaml @@ -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: {} diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/01-crd.yaml b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/01-crd.yaml new file mode 100644 index 0000000000..6db5372cb0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/01-crd.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- crd.yaml +assert: +- crd-assert.yaml diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/02-policy.yaml b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/02-policy.yaml new file mode 100644 index 0000000000..57ffd5631d --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/02-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/03-resource.yaml b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/03-resource.yaml new file mode 100644 index 0000000000..de14ac5c9c --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/03-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/README.md b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/README.md new file mode 100644 index 0000000000..6ec7030d63 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/crd-assert.yaml b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/crd-assert.yaml new file mode 100644 index 0000000000..a7aee3c477 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/crd-assert.yaml @@ -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 diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/crd.yaml b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/crd.yaml new file mode 100644 index 0000000000..8cf533cc60 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/crd.yaml @@ -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.) 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.) 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: {} diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/policy-ready.yaml new file mode 100644 index 0000000000..51234b6594 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-external-secret-prefix +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/policy.yaml b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/policy.yaml new file mode 100644 index 0000000000..ae3d6a0ecf --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/policy.yaml @@ -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}}" diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/resource-mutated.yaml new file mode 100644 index 0000000000..03eab8636c --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/resource-mutated.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/resource.yaml b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/resource.yaml new file mode 100644 index 0000000000..e89a9db993 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-external-secret-prefix/resource.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/01-policy.yaml new file mode 100644 index 0000000000..f3857739b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/02-resource.yaml b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/02-resource.yaml new file mode 100644 index 0000000000..7e08de156a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/02-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/README.md b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/README.md new file mode 100644 index 0000000000..4763840548 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/policy-ready.yaml new file mode 100644 index 0000000000..da767ab21e --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/policy-ready.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/policy.yaml b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/policy.yaml new file mode 100644 index 0000000000..fe52715a16 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/policy.yaml @@ -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 }}" \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/resource-mutated.yaml new file mode 100644 index 0000000000..02d10206c8 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/resource-mutated.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/resource.yaml b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/resource.yaml new file mode 100644 index 0000000000..9f670115a5 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-image-as-env-var/resource.yaml @@ -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 diff --git a/test/conformance/kuttl/mutate/refactor/add-node-affinity/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/add-node-affinity/01-policy.yaml new file mode 100644 index 0000000000..f3857739b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-node-affinity/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-node-affinity/02-resource.yaml b/test/conformance/kuttl/mutate/refactor/add-node-affinity/02-resource.yaml new file mode 100644 index 0000000000..7e08de156a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-node-affinity/02-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-node-affinity/README.md b/test/conformance/kuttl/mutate/refactor/add-node-affinity/README.md new file mode 100644 index 0000000000..04644f67f5 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-node-affinity/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-node-affinity/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/add-node-affinity/policy-ready.yaml new file mode 100644 index 0000000000..ba706ce75a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-node-affinity/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-node-affinity +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-node-affinity/policy.yaml b/test/conformance/kuttl/mutate/refactor/add-node-affinity/policy.yaml new file mode 100644 index 0000000000..315e4c5770 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-node-affinity/policy.yaml @@ -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" diff --git a/test/conformance/kuttl/mutate/refactor/add-node-affinity/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/add-node-affinity/resource-mutated.yaml new file mode 100644 index 0000000000..a7d826b9fa --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-node-affinity/resource-mutated.yaml @@ -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 diff --git a/test/conformance/kuttl/mutate/refactor/add-node-affinity/resource.yaml b/test/conformance/kuttl/mutate/refactor/add-node-affinity/resource.yaml new file mode 100644 index 0000000000..ea470494af --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-node-affinity/resource.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/01-policy.yaml new file mode 100644 index 0000000000..f3857739b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/02-pod.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/02-pod.yaml new file mode 100644 index 0000000000..79800b2516 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/02-pod.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- pod.yaml +assert: +- pod-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/03-deployment.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/03-deployment.yaml new file mode 100644 index 0000000000..61dea991e2 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/03-deployment.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- deployment.yaml +assert: +- deployment-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/04-cronjob.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/04-cronjob.yaml new file mode 100644 index 0000000000..d84c0963be --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/04-cronjob.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- cronjob.yaml +assert: +- cronjob-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/README.md b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/README.md new file mode 100644 index 0000000000..04644f67f5 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/cronjob-mutated.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/cronjob-mutated.yaml new file mode 100644 index 0000000000..f2c62f44dc --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/cronjob-mutated.yaml @@ -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 * * * *' diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/cronjob.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/cronjob.yaml new file mode 100644 index 0000000000..830a04e39f --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/cronjob.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/deployment-mutated.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/deployment-mutated.yaml new file mode 100644 index 0000000000..d005a048f5 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/deployment-mutated.yaml @@ -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 diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/deployment.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/deployment.yaml new file mode 100644 index 0000000000..516f8074cf --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/deployment.yaml @@ -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"] \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/pod-mutated.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/pod-mutated.yaml new file mode 100644 index 0000000000..b9c25ea733 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/pod-mutated.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: blank + namespace: add-pod-priorityclassname +spec: + containers: + - image: sfsdafasdfsadfsadf + name: busybox + priorityClassName: non-production diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/pod.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/pod.yaml new file mode 100644 index 0000000000..b5db2b7c27 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: blank + namespace: add-pod-priorityclassname +spec: + containers: + - name: busybox + image: sfsdafasdfsadfsadf \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/policy-ready.yaml new file mode 100644 index 0000000000..c95f7c6422 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-pod-priorityclassname +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/policy.yaml b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/policy.yaml new file mode 100644 index 0000000000..0a1dc98679 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-pod-priorityclassname/policy.yaml @@ -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' \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-tolerations/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/add-tolerations/01-policy.yaml new file mode 100644 index 0000000000..f3857739b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-tolerations/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-tolerations/02-resource.yaml b/test/conformance/kuttl/mutate/refactor/add-tolerations/02-resource.yaml new file mode 100644 index 0000000000..7e08de156a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-tolerations/02-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-tolerations/README.md b/test/conformance/kuttl/mutate/refactor/add-tolerations/README.md new file mode 100644 index 0000000000..1e9be3bf91 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-tolerations/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-tolerations/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/add-tolerations/policy-ready.yaml new file mode 100644 index 0000000000..f3ea2605c3 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-tolerations/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-tolerations +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-tolerations/policy.yaml b/test/conformance/kuttl/mutate/refactor/add-tolerations/policy.yaml new file mode 100644 index 0000000000..640622b412 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-tolerations/policy.yaml @@ -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 diff --git a/test/conformance/kuttl/mutate/refactor/add-tolerations/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/add-tolerations/resource-mutated.yaml new file mode 100644 index 0000000000..7f209bdd3c --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-tolerations/resource-mutated.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-tolerations/resource.yaml b/test/conformance/kuttl/mutate/refactor/add-tolerations/resource.yaml new file mode 100644 index 0000000000..ff625d5ef0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-tolerations/resource.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-volume-deployment/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/01-policy.yaml new file mode 100644 index 0000000000..f3857739b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-volume-deployment/02-resource.yaml b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/02-resource.yaml new file mode 100644 index 0000000000..7e08de156a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/02-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-volume-deployment/03-sleep.yaml b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/03-sleep.yaml new file mode 100644 index 0000000000..b2822f5976 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/03-sleep.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: sleep 10 diff --git a/test/conformance/kuttl/mutate/refactor/add-volume-deployment/README.md b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/README.md new file mode 100644 index 0000000000..1e9be3bf91 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-volume-deployment/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/policy-ready.yaml new file mode 100644 index 0000000000..d2a163ed95 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-volume +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-volume-deployment/policy.yaml b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/policy.yaml new file mode 100644 index 0000000000..3fa6a6903f --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/policy.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-volume-deployment/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/resource-mutated.yaml new file mode 100644 index 0000000000..0884c306f2 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/resource-mutated.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/add-volume-deployment/resource.yaml b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/resource.yaml new file mode 100644 index 0000000000..3cd01a542e --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/add-volume-deployment/resource.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/annotate-base-images/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/annotate-base-images/01-policy.yaml new file mode 100644 index 0000000000..f3857739b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/annotate-base-images/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/annotate-base-images/02-resource.yaml b/test/conformance/kuttl/mutate/refactor/annotate-base-images/02-resource.yaml new file mode 100644 index 0000000000..7e08de156a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/annotate-base-images/02-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/annotate-base-images/README.md b/test/conformance/kuttl/mutate/refactor/annotate-base-images/README.md new file mode 100644 index 0000000000..4760c95418 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/annotate-base-images/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/annotate-base-images/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/annotate-base-images/policy-ready.yaml new file mode 100644 index 0000000000..cbdcf062cd --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/annotate-base-images/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: annotate-base-images +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/annotate-base-images/policy.yaml b/test/conformance/kuttl/mutate/refactor/annotate-base-images/policy.yaml new file mode 100644 index 0000000000..f1034b75a5 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/annotate-base-images/policy.yaml @@ -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}}" \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/annotate-base-images/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/annotate-base-images/resource-mutated.yaml new file mode 100644 index 0000000000..3342035fd5 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/annotate-base-images/resource-mutated.yaml @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/annotate-base-images/resource.yaml b/test/conformance/kuttl/mutate/refactor/annotate-base-images/resource.yaml new file mode 100644 index 0000000000..c9b9b12b38 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/annotate-base-images/resource.yaml @@ -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 diff --git a/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/01-policy.yaml new file mode 100644 index 0000000000..404ce85387 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - policy.yaml +assert: + - policy-assert.yaml diff --git a/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/02-pod.yaml b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/02-pod.yaml new file mode 100644 index 0000000000..1c30edc8b6 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/02-pod.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - pod.yaml +assert: + - pod-assert.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/README.md b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/README.md new file mode 100644 index 0000000000..d4ce0de70e --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/pod-assert.yaml b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/pod-assert.yaml new file mode 100644 index 0000000000..13e4c5e395 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/pod-assert.yaml @@ -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" diff --git a/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/pod.yaml b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/pod.yaml new file mode 100644 index 0000000000..13e4c5e395 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/pod.yaml @@ -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" diff --git a/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/policy-assert.yaml b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/policy-assert.yaml new file mode 100644 index 0000000000..368e9a1688 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: foreach-remove-elements +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/policy.yaml b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/policy.yaml new file mode 100644 index 0000000000..b19e5cbe41 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/add-and-remove/policy.yaml @@ -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 diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/01-policy.yaml new file mode 100644 index 0000000000..404ce85387 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - policy.yaml +assert: + - policy-assert.yaml diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/02-pod.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/02-pod.yaml new file mode 100644 index 0000000000..1c30edc8b6 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/02-pod.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - pod.yaml +assert: + - pod-assert.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/README.md b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/README.md new file mode 100644 index 0000000000..660299b665 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/pod-assert.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/pod-assert.yaml new file mode 100644 index 0000000000..e512796fdd --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/pod-assert.yaml @@ -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" diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/pod.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/pod.yaml new file mode 100644 index 0000000000..13e4c5e395 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/pod.yaml @@ -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" diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/policy-assert.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/policy-assert.yaml new file mode 100644 index 0000000000..368e9a1688 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: foreach-remove-elements +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/policy.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/policy.yaml new file mode 100644 index 0000000000..04fe979c0d --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-and-add/policy.yaml @@ -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" diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/01-policy.yaml new file mode 100644 index 0000000000..404ce85387 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - policy.yaml +assert: + - policy-assert.yaml diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/02-pod.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/02-pod.yaml new file mode 100644 index 0000000000..1c30edc8b6 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/02-pod.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - pod.yaml +assert: + - pod-assert.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/README.md b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/README.md new file mode 100644 index 0000000000..cf047935e8 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/pod-assert.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/pod-assert.yaml new file mode 100644 index 0000000000..fe00900f58 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/pod-assert.yaml @@ -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" diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/pod.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/pod.yaml new file mode 100644 index 0000000000..13e4c5e395 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/pod.yaml @@ -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" diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/policy-assert.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/policy-assert.yaml new file mode 100644 index 0000000000..368e9a1688 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: foreach-remove-elements +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/policy.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/policy.yaml new file mode 100644 index 0000000000..022c29828c --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-ascending-order/policy.yaml @@ -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 diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/01-policy.yaml new file mode 100644 index 0000000000..404ce85387 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - policy.yaml +assert: + - policy-assert.yaml diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/02-pod.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/02-pod.yaml new file mode 100644 index 0000000000..d522d8a59d --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/02-pod.yaml @@ -0,0 +1,8 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - pod.yaml +assert: + - pod-assert.yaml +error: + - pod-error.yaml diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/README.md b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/README.md new file mode 100644 index 0000000000..197be5bbd8 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/README.md @@ -0,0 +1,11 @@ +## Description + +This test removes multiple elements from an array iterating in descending order. + +## Expected Behavior + +Element at index 1 is removed then element at index 0 is removed, the array becomes empty. + +## Reference Issue(s) + +5661 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/pod-assert.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/pod-assert.yaml new file mode 100644 index 0000000000..655c6a39d8 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/pod-assert.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox +spec: + containers: + - name: busybox + image: busybox:1.35 diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/pod-error.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/pod-error.yaml new file mode 100644 index 0000000000..07c7eaf5cc --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/pod-error.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox +spec: + containers: + - name: busybox + image: busybox:1.35 + env: null \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/pod.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/pod.yaml new file mode 100644 index 0000000000..13e4c5e395 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/pod.yaml @@ -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" diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/policy-assert.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/policy-assert.yaml new file mode 100644 index 0000000000..368e9a1688 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: foreach-remove-elements +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/policy.yaml b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/policy.yaml new file mode 100644 index 0000000000..0f926b313c --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/foreach/remove-multiple-elements-in-descending-order/policy.yaml @@ -0,0 +1,21 @@ +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 + order: Descending + patchesJson6902: |- + - path: /spec/containers/0/env/{{elementIndex}} + op: remove diff --git a/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/01-policy.yaml new file mode 100644 index 0000000000..f3857739b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/02-resource.yaml b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/02-resource.yaml new file mode 100644 index 0000000000..7e08de156a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/02-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/README.md b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/README.md new file mode 100644 index 0000000000..4760c95418 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/policy-ready.yaml new file mode 100644 index 0000000000..875489a78b --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: inject-env-var-from-image-label +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/policy.yaml b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/policy.yaml new file mode 100644 index 0000000000..109b28368a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/policy.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: inject-env-var-from-image-label +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: inject-env-var-from-image-label + annotations: + policies.kyverno.io/title: Inject Env Var from Image Label + policies.kyverno.io/category: Other + policies.kyverno.io/severity: medium + pod-policies.kyverno.io/autogen-controllers: none + kyverno.io/kyverno-version: 1.6.0 + policies.kyverno.io/minversion: 1.7.0 + kyverno.io/kubernetes-version: "1.23" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Container images which use metadata such as the LABEL directive in a Dockerfile + do not surface this information to apps running within. In some cases, running the image + as a container may need access to this information. This policy injects the value of a label + set in a Dockerfile named `maintainer` as an environment variable to the corresponding container + in the Pod. +spec: + rules: + - name: add-env-maintainer + match: + any: + - resources: + kinds: + - Pod + preconditions: + all: + - key: "{{request.operation || 'BACKGROUND'}}" + operator: NotEquals + value: DELETE + mutate: + foreach: + - list: "request.object.spec.containers" + context: + - name: maintainer + imageRegistry: + reference: "{{ element.image }}" + jmesPath: "configData.config.Labels.maintainer || ''" + preconditions: + all: + - key: "{{maintainer}}" + operator: NotEquals + value: "" + patchesJson6902: |- + - op: add + path: "/spec/containers/{{elementIndex}}/env/-" + value: + name: MAINTAINER + value: "{{maintainer}}" \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/resource-mutated.yaml new file mode 100644 index 0000000000..20e4404966 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/resource-mutated.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: testpodlabel + namespace: inject-env-var-from-image-label +spec: + containers: + - env: + - name: MAINTAINER + value: NGINX Docker Maintainers + image: docker.io/nginx@sha256:63b44e8ddb83d5dd8020327c1f40436e37a6fffd3ef2498a6204df23be6e7e94 + name: nginx \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/resource.yaml b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/resource.yaml new file mode 100644 index 0000000000..5fa437cba0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/inject-env-var-from-image-label/resource.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: testpodlabel + namespace: inject-env-var-from-image-label +spec: + containers: + - name: nginx + image: docker.io/nginx@sha256:63b44e8ddb83d5dd8020327c1f40436e37a6fffd3ef2498a6204df23be6e7e94 diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/01-crd.yaml b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/01-crd.yaml new file mode 100644 index 0000000000..6db5372cb0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/01-crd.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- crd.yaml +assert: +- crd-assert.yaml diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/02-policy.yaml b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/02-policy.yaml new file mode 100644 index 0000000000..57ffd5631d --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/02-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/03-resource.yaml b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/03-resource.yaml new file mode 100644 index 0000000000..de14ac5c9c --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/03-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/README.md b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/README.md new file mode 100644 index 0000000000..1e9be3bf91 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/crd-assert.yaml b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/crd-assert.yaml new file mode 100644 index 0000000000..7c5977cd96 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/crd-assert.yaml @@ -0,0 +1,12 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: policies.config.kio.kasten.io +status: + acceptedNames: + kind: Policy + listKind: PolicyList + plural: policies + singular: policy + storedVersions: + - v1alpha1 diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/crd.yaml b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/crd.yaml new file mode 100644 index 0000000000..8d66ccb902 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/crd.yaml @@ -0,0 +1,70 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + generation: 1 + name: policies.config.kio.kasten.io +spec: + conversion: + strategy: None + group: config.kio.kasten.io + names: + kind: Policy + listKind: PolicyList + plural: policies + singular: policy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.validation + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: Policy is the Schema for the policies 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: + type: object + x-kubernetes-preserve-unknown-fields: true + status: + description: PolicyStatus defines the observed state of Policy + properties: + error: + description: List of errors with the policy (for example, due to validation + failures) + items: + type: string + type: array + hash: + description: Hash of Spec + format: int32 + type: integer + specModifiedTime: + description: Timestamp when spec last changed + format: date-time + type: string + validation: + description: Validation status + type: string + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/policy-ready.yaml new file mode 100644 index 0000000000..99fd5a77ed --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: k10-minimum-retention +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/policy.yaml b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/policy.yaml new file mode 100644 index 0000000000..296f683049 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/policy.yaml @@ -0,0 +1,78 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: k10-minimum-retention +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: k10-minimum-retention + annotations: + policies.kyverno.io/title: Minimum Backup Retention + policies.kyverno.io/category: Kasten K10 by Veeam + kyverno.io/kyverno-version: 1.6.2 + policies.kyverno.io/minversion: 1.6.2 + kyverno.io/kubernetes-version: "1.21-1.22" + policies.kyverno.io/subject: Policy + policies.kyverno.io/description: >- + K10 Policy resources can be validated to adhere to common compliance retention standards. + Uncomment the regulation/compliance standards you want to enforce for according to GFS retention. + This policy deletes the retention value in the backup operation and replaces it with the specified retention. + Note: K10 Policy uses the GFS retention scheme and export operations default to use the retention of the backup operation. + To use different + This policy can also be used go reduce retentions lengths to enforce cost optimization. +spec: + schemaValidation: false + rules: + - name: k10-minimum-retention + match: + any: + - resources: + kinds: + - config.kio.kasten.io/v1alpha1/Policy + mutate: + # Federal Information Security Management Act (FISMA): 3 Years + #patchesJson6902: |- + # - path: "/spec/retention" + # op: replace + # value: {"hourly":24,"daily":30,"weekly":4,"monthly":12,"yearly":3} + + # Health Insurance Portability and Accountability Act (HIPAA): 6 Years + #patchesJson6902: |- + # - path: "/spec/retention" + # op: replace + # value: {"hourly":24,"daily":30,"weekly":4,"monthly":12,"yearly":6} + + # National Energy Commission (NERC): 3 to 6 Years + #patchesJson6902: |- + # - path: "/spec/retention" + # op: replace + # value: {"hourly":24,"daily":30,"weekly":4,"monthly":12,"yearly":3} + + # Basel II Capital Accord: 3 to 7 Years + #patchesJson6902: |- + # - path: "/spec/retention" + # op: replace + # value: {"hourly":24,"daily":30,"weekly":4,"monthly":12,"yearly":3} + + # Sarbanes-Oxley Act of 2002 (SOX): 7 Years + #patchesJson6902: |- + # - path: "/spec/retention" + # op: replace + # value: {"hourly":24,"daily":30,"weekly":4,"monthly":12,"yearly":7} + + # National Industrial Security Program Operating Manual (NISPOM): 6 to 12 Months + #patchesJson6902: |- + # - path: "/spec/retention" + # op: replace + # value: {"hourly":24,"daily":30,"weekly":4,"monthly":6} + + # Cost Optimization (Maximum Retention: 3 Months) + patchesJson6902: |- + - path: "/spec/retention" + op: replace + value: + hourly: 24 + daily: 30 + weekly: 4 + monthly: 3 diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/resource-mutated.yaml new file mode 100644 index 0000000000..1717549537 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/resource-mutated.yaml @@ -0,0 +1,42 @@ +apiVersion: config.kio.kasten.io/v1alpha1 +kind: Policy +metadata: + generation: 1 + labels: + appPriority: Mission-Critical + name: hourly-policy + namespace: k10-minimum-retention +spec: + actions: + - action: backup + - action: export + exportParameters: + exportData: + enabled: true + frequency: '@monthly' + profile: + name: my-profile + namespace: kasten-io + retention: + monthly: 12 + yearly: 5 + comment: My sample custom backup policy + frequency: '@hourly' + retention: + daily: 30 + hourly: 24 + monthly: 3 + weekly: 4 + selector: + matchLabels: + k10.kasten.io/appNamespace: sampleApp + subFrequency: + days: + - 15 + hours: + - 22 + - 7 + minutes: + - 30 + weekdays: + - 5 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/resource.yaml b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/resource.yaml new file mode 100644 index 0000000000..9f139aaba1 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/k10-minimum-retention/resource.yaml @@ -0,0 +1,35 @@ +apiVersion: config.kio.kasten.io/v1alpha1 +kind: Policy +metadata: + name: hourly-policy + namespace: k10-minimum-retention + labels: + appPriority: Mission-Critical +spec: + comment: My sample custom backup policy + frequency: '@hourly' # change this to @daily to test the 'audit_mission_critical_RPO' policy + subFrequency: + minutes: [30] + hours: [22,7] + weekdays: [5] + days: [15] + retention: + daily: 14 + weekly: 4 + monthly: 6 + actions: + - action: backup + - action: export # comment this line out to test 'enforce_3-2-1' policy + exportParameters: + frequency: '@monthly' + profile: + name: my-profile + namespace: kasten-io + exportData: + enabled: true + retention: + monthly: 12 + yearly: 5 + selector: + matchLabels: + k10.kasten.io/appNamespace: sampleApp \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/01-policy.yaml new file mode 100644 index 0000000000..404ce85387 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - policy.yaml +assert: + - policy-assert.yaml diff --git a/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/02-pod.yaml b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/02-pod.yaml new file mode 100644 index 0000000000..d522d8a59d --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/02-pod.yaml @@ -0,0 +1,8 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - pod.yaml +assert: + - pod-assert.yaml +error: + - pod-error.yaml diff --git a/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/README.md b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/README.md new file mode 100644 index 0000000000..ecdbc082d3 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/README.md @@ -0,0 +1,11 @@ +## Description + +This test uses a nested foreach to remove all env variables from all containers. + +## Expected Behavior + +The created pod contains the same containers as the original pod but all env variables in all containers have been removed. + +## Reference Issue(s) + +5661 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/pod-assert.yaml b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/pod-assert.yaml new file mode 100644 index 0000000000..de5a1bd6fb --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/pod-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox +spec: + containers: + - name: busybox-1 + image: busybox:1.35 + - name: busybox-2 + image: busybox:1.35 diff --git a/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/pod-error.yaml b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/pod-error.yaml new file mode 100644 index 0000000000..24bc3167b7 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/pod-error.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox +spec: + containers: + - name: busybox-1 + image: busybox:1.35 + env: null + - name: busybox-2 + image: busybox:1.35 + env: null diff --git a/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/pod.yaml b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/pod.yaml new file mode 100644 index 0000000000..c3575184d9 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/pod.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox +spec: + containers: + - name: busybox-1 + image: busybox:1.35 + env: + - name: ONE + value: "one" + - name: TWO + value: "two" + - name: busybox-2 + image: busybox:1.35 + env: + - name: THREE + value: "three" + - name: FOUR + value: "four" diff --git a/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/policy-assert.yaml b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/policy-assert.yaml new file mode 100644 index 0000000000..368e9a1688 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: foreach-remove-elements +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/policy.yaml b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/policy.yaml new file mode 100644 index 0000000000..bfad47fdaa --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/nested-foreach/remove-all-env-vars/policy.yaml @@ -0,0 +1,23 @@ +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 + foreach: + - list: element0.env + order: Descending + patchesJson6902: |- + - path: /spec/containers/{{elementIndex0}}/env/{{elementIndex1}} + op: remove diff --git a/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/01-policy.yaml new file mode 100644 index 0000000000..f3857739b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/02-resource.yaml b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/02-resource.yaml new file mode 100644 index 0000000000..7e08de156a --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/02-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/README.md b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/README.md new file mode 100644 index 0000000000..1e9be3bf91 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/README.md @@ -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 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/policy-ready.yaml b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/policy-ready.yaml new file mode 100644 index 0000000000..cffd63c835 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/policy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: replace-ingress-hosts +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/policy.yaml b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/policy.yaml new file mode 100644 index 0000000000..929ecfb0c5 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/policy.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: replace-ingress-hosts +--- +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: replace-ingress-hosts + annotations: + policies.kyverno.io/title: Replace Ingress Hosts + policies.kyverno.io/category: Other + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.9.0 + policies.kyverno.io/minversion: 1.9.0 + kyverno.io/kubernetes-version: "1.24" + policies.kyverno.io/subject: Ingress + policies.kyverno.io/description: >- + An Ingress may specify host names at a variety of locations in the same resource. + In some cases, those host names should be modified to, for example, update domain names + silently. The replacement must be done in all the fields where a host name can be specified. + This policy, illustrating the use of nested foreach loops and operable in Kyverno 1.9+, replaces + host names that end with `old.com` with `new.com`. +spec: + background: false + rules: + - name: replace-old-with-new + match: + any: + - resources: + kinds: + - Ingress + mutate: + foreach: + - list: request.object.spec.rules + patchesJson6902: |- + - path: /spec/rules/{{elementIndex}}/host + op: replace + value: {{replace_all('{{element.host}}', '.old.com', '.new.com')}} + - list: request.object.spec.tls[] + foreach: + - list: "element.hosts" + patchesJson6902: |- + - path: /spec/tls/{{elementIndex0}}/hosts/{{elementIndex1}} + op: replace + value: "{{ replace_all('{{element}}', '.old.com', '.new.com') }}" + - list: request.object.spec.tls[] + patchesJson6902: |- + - path: /spec/tls/{{elementIndex}}/secretName + op: replace + value: "{{ replace_all('{{element.secretName}}', '.old.com', '.new.com') }}" \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/resource-mutated.yaml b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/resource-mutated.yaml new file mode 100644 index 0000000000..7127f77a0b --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/resource-mutated.yaml @@ -0,0 +1,37 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + labels: + app: kuard + name: kuard + namespace: replace-ingress-hosts +spec: + rules: + - host: kuard.new.com + http: + paths: + - backend: + service: + name: kuard + port: + number: 8080 + path: / + pathType: ImplementationSpecific + - host: hr.new.com + http: + paths: + - backend: + service: + name: kuard + port: + number: 8090 + path: /myhr + pathType: ImplementationSpecific + tls: + - hosts: + - kuard.new.com + - kuard-foo.new.com + secretName: foosecret.new.com + - hosts: + - hr.new.com + secretName: hr.new.com \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/resource.yaml b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/resource.yaml new file mode 100644 index 0000000000..59f2ecb383 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/replace-ingress-hosts/resource.yaml @@ -0,0 +1,37 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: kuard + namespace: replace-ingress-hosts + labels: + app: kuard +spec: + rules: + - host: kuard.old.com + http: + paths: + - backend: + service: + name: kuard + port: + number: 8080 + path: / + pathType: ImplementationSpecific + - host: hr.old.com + http: + paths: + - backend: + service: + name: kuard + port: + number: 8090 + path: /myhr + pathType: ImplementationSpecific + tls: + - hosts: + - kuard.old.com + - kuard-foo.old.com + secretName: foosecret.old.com + - hosts: + - hr.old.com + secretName: hr.old.com \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/01-policy.yaml new file mode 100644 index 0000000000..404ce85387 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - policy.yaml +assert: + - policy-assert.yaml diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/02-pod.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/02-pod.yaml new file mode 100644 index 0000000000..1c30edc8b6 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/02-pod.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - pod.yaml +assert: + - pod-assert.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/README.md b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/README.md new file mode 100644 index 0000000000..633844c464 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/README.md @@ -0,0 +1,13 @@ +## Description + +This test removes multiple elements from an array iterating in ascending order. + +## Expected Behavior + +Removing in ascending order is usually not giving the expected result as removing one element will modify the index on the following elements. +Hence the path to remove following elements are going to point to the wrong index, removing should be done in descending order. +In this case, the we expect volumes at index 0 and 1 to be removed but as we remove volume at index 0 first, removing the volume at index 1 actually removes the volume at index 2 in the original array. + +## Reference Issue(s) + +5661 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/pod-assert.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/pod-assert.yaml new file mode 100644 index 0000000000..67a5cc838b --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/pod-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox +spec: + volumes: + - name: volume-2 + hostPath: + path: "/var/run/foo-2" + - projected: {} diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/pod.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/pod.yaml new file mode 100644 index 0000000000..64fa05c327 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/pod.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox +spec: + containers: + - name: busybox + image: busybox:1.35 + volumes: + - name: volume-1 + hostPath: + path: "/var/run/foo-1" + - name: volume-2 + hostPath: + path: "/var/run/foo-2" + - name: volume-3 + hostPath: + path: "/var/run/foo-3" diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/policy-assert.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/policy-assert.yaml new file mode 100644 index 0000000000..368e9a1688 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: foreach-remove-elements +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/policy.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/policy.yaml new file mode 100644 index 0000000000..b10c8aa91f --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-ascending-order/policy.yaml @@ -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: + patchesJson6902: |- + - path: /spec/volumes/0 + op: remove + - path: /spec/volumes/1 + op: remove diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/01-policy.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/01-policy.yaml new file mode 100644 index 0000000000..404ce85387 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - policy.yaml +assert: + - policy-assert.yaml diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/02-pod.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/02-pod.yaml new file mode 100644 index 0000000000..1c30edc8b6 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/02-pod.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - pod.yaml +assert: + - pod-assert.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/README.md b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/README.md new file mode 100644 index 0000000000..849197fc3e --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/README.md @@ -0,0 +1,12 @@ +## Description + +This test removes multiple elements from an array iterating in descending order. + +## Expected Behavior + +The two first volumes in the pod are removed. +Removing in descending order is usually prefered as it preserves the index of array elements while iterating. + +## Reference Issue(s) + +5661 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/pod-assert.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/pod-assert.yaml new file mode 100644 index 0000000000..47818ade76 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/pod-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox +spec: + volumes: + - name: volume-3 + hostPath: + path: /var/run/foo-3 + - projected: {} diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/pod.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/pod.yaml new file mode 100644 index 0000000000..a89a2e0c36 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/pod.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox +spec: + containers: + - name: busybox + image: busybox:1.35 + volumes: + - name: volume-1 + hostPath: + path: /var/run/foo-1 + - name: volume-2 + hostPath: + path: /var/run/foo-2 + - name: volume-3 + hostPath: + path: /var/run/foo-3 diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/policy-assert.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/policy-assert.yaml new file mode 100644 index 0000000000..368e9a1688 --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: foreach-remove-elements +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/policy.yaml b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/policy.yaml new file mode 100644 index 0000000000..710234098e --- /dev/null +++ b/test/conformance/kuttl/mutate/refactor/simple/remove-multiple-elements-in-descending-order/policy.yaml @@ -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: + patchesJson6902: |- + - path: /spec/volumes/1 + op: remove + - path: /spec/volumes/0 + op: remove