mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 07:26:55 +00:00
feat: obey the order field in patchStrategicMerge method (#7336)
* feat: obey the order field in patchStrategicMerge method Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * default Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * tests Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
60fd1ccda9
commit
271a568693
2 changed files with 204 additions and 2 deletions
|
@ -65,10 +65,12 @@ func (f *forEachMutator) mutateElements(ctx context.Context, foreach kyvernov1.F
|
|||
|
||||
patchedResource := f.resource
|
||||
reverse := false
|
||||
// if it's a patch strategic merge, reverse by default
|
||||
if foreach.RawPatchStrategicMerge != nil {
|
||||
reverse = true
|
||||
} else if foreach.Order != nil && *foreach.Order == kyvernov1.Descending {
|
||||
reverse = true
|
||||
}
|
||||
if foreach.Order != nil {
|
||||
reverse = *foreach.Order == kyvernov1.Descending
|
||||
}
|
||||
if reverse {
|
||||
engineutils.InvertedElement(elements)
|
||||
|
|
|
@ -977,6 +977,206 @@ func Test_foreach_order_mutation_(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_patchStrategicMerge_descending(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",
|
||||
"order": "Descending",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
||||
resource := loadUnstructured(t, resourceRaw)
|
||||
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
||||
|
||||
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_patchStrategicMerge_ascending(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",
|
||||
"order": "Ascending",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
policy := loadResource[kyverno.ClusterPolicy](t, policyRaw)
|
||||
resource := loadUnstructured(t, resourceRaw)
|
||||
policyContext := createContext(t, &policy, resource, kyverno.Create)
|
||||
|
||||
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext, nil)
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status(), engineapi.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"], "mongodb-agent")
|
||||
case 1:
|
||||
assert.Equal(t, ctnr["name"], "nginx3")
|
||||
case 3:
|
||||
assert.Equal(t, ctnr["name"], "mongod")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_mutate_nested_foreach(t *testing.T) {
|
||||
policyRaw := []byte(`{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
|
|
Loading…
Add table
Reference in a new issue