mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
fix ordering of mutate element (#3468)
Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
parent
4efcabffb5
commit
58b1fd6210
3 changed files with 128 additions and 0 deletions
|
@ -182,6 +182,9 @@ func mutateElements(name string, foreach *kyverno.ForEachMutation, ctx *PolicyCo
|
|||
|
||||
patchedResource := resource
|
||||
var allPatches [][]byte
|
||||
if foreach.RawPatchStrategicMerge != nil {
|
||||
invertedElement(elements)
|
||||
}
|
||||
|
||||
for i, e := range elements {
|
||||
ctx.JSONContext.Reset()
|
||||
|
|
|
@ -909,3 +909,121 @@ func Test_Container_InitContainer_foreach(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_foreach_order_mutation_(t *testing.T) {
|
||||
policyRaw := []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "replace-image"
|
||||
},
|
||||
"spec": {
|
||||
"background": false,
|
||||
"rules": [
|
||||
{
|
||||
"name": "replace-image",
|
||||
"match": {
|
||||
"all": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mutate": {
|
||||
"foreach": [
|
||||
{
|
||||
"list": "request.object.spec.containers",
|
||||
"patchStrategicMerge": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"(name)": "{{ element.name }}",
|
||||
"image": "replaced"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
resourceRaw := []byte(`{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "mongodb",
|
||||
"labels": {
|
||||
"app": "mongodb"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"image": "docker.io/mongo:5.0.3",
|
||||
"name": "mongod"
|
||||
},
|
||||
{
|
||||
"image": "nginx",
|
||||
"name": "nginx"
|
||||
},
|
||||
{
|
||||
"image": "nginx",
|
||||
"name": "nginx3"
|
||||
},
|
||||
{
|
||||
"image": "quay.io/mongodb/mongodb-agent:11.0.5.6963-1",
|
||||
"name": "mongodb-agent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
var policy kyverno.ClusterPolicy
|
||||
err := json.Unmarshal(policyRaw, &policy)
|
||||
assert.NilError(t, err)
|
||||
|
||||
resource, err := utils.ConvertToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResourceAsObject(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
Policy: policy,
|
||||
JSONContext: ctx,
|
||||
NewResource: *resource,
|
||||
}
|
||||
|
||||
err = ctx.AddImageInfo(resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = context.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := Mutate(policyContext)
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
|
||||
|
||||
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
|
||||
assert.NilError(t, err)
|
||||
|
||||
for i, c := range containers {
|
||||
ctnr := c.(map[string]interface{})
|
||||
switch i {
|
||||
case 0:
|
||||
assert.Equal(t, ctnr["name"], "mongod")
|
||||
case 1:
|
||||
assert.Equal(t, ctnr["name"], "nginx")
|
||||
case 3:
|
||||
assert.Equal(t, ctnr["name"], "mongodb-agent")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -494,3 +494,10 @@ func incrementAppliedCount(resp *response.EngineResponse) {
|
|||
func incrementErrorCount(resp *response.EngineResponse) {
|
||||
resp.PolicyResponse.RulesErrorCount++
|
||||
}
|
||||
|
||||
// invertedElement inverted the order of element for patchStrategicMerge policies as kustomize patch revering the order of patch resources.
|
||||
func invertedElement(elements []interface{}) {
|
||||
for i, j := 0, len(elements)-1; i < j; i, j = i+1, j-1 {
|
||||
elements[i], elements[j] = elements[j], elements[i]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue