mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-29 19:05:27 +00:00
* Fix #1737: forceMutate does not handle StrategicMerge patchesJson6902 Signed-off-by: Max Goncharenko <kacejot@fex.net> * go fmt Signed-off-by: Max Goncharenko <kacejot@fex.net> * updated PR due to the comments Signed-off-by: Max Goncharenko <kacejot@fex.net>
This commit is contained in:
parent
64f49caa84
commit
9da2d44ee1
2 changed files with 215 additions and 0 deletions
pkg/engine
|
@ -3,6 +3,7 @@ package engine
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/mutate"
|
||||
|
@ -86,6 +87,28 @@ func ForceMutate(ctx context.EvalInterface, policy kyverno.ClusterPolicy, resour
|
|||
return unstructured.Unstructured{}, fmt.Errorf(resp.Message)
|
||||
}
|
||||
}
|
||||
|
||||
if rule.Mutation.PatchStrategicMerge != nil {
|
||||
var resp response.RuleResponse
|
||||
resp, resource = mutate.ProcessStrategicMergePatch(rule.Name, rule.Mutation.PatchStrategicMerge, resource, logger.WithValues("rule", rule.Name))
|
||||
if !resp.Success {
|
||||
return unstructured.Unstructured{}, fmt.Errorf(resp.Message)
|
||||
}
|
||||
}
|
||||
|
||||
if rule.Mutation.PatchesJSON6902 != "" {
|
||||
var resp response.RuleResponse
|
||||
jsonPatches, err := yaml.YAMLToJSON([]byte(rule.Mutation.PatchesJSON6902))
|
||||
if err != nil {
|
||||
return unstructured.Unstructured{}, err
|
||||
}
|
||||
|
||||
resp, resource = mutate.ProcessPatchJSON6902(rule.Name, jsonPatches, resource, logger.WithValues("rule", rule.Name))
|
||||
if !resp.Success {
|
||||
return unstructured.Unstructured{}, fmt.Errorf(resp.Message)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return resource, nil
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
"gotest.tools/assert"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
var rawPolicy = []byte(`
|
||||
|
@ -148,3 +149,194 @@ func Test_ForceMutateSubstituteVarsWithNilContext(t *testing.T) {
|
|||
|
||||
assert.DeepEqual(t, expectedResource, mutatedResource.UnstructuredContent())
|
||||
}
|
||||
|
||||
func Test_ForceMutateSubstituteVarsWithPatchStrategicMerge(t *testing.T) {
|
||||
rawPolicy := []byte(`
|
||||
{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "strategic-merge-patch"
|
||||
},
|
||||
"spec": {
|
||||
"rules": [
|
||||
{
|
||||
"name": "set-image-pull-policy-add-command",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mutate": {
|
||||
"patchStrategicMerge": {
|
||||
"spec": {
|
||||
"volumes": [
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory"
|
||||
},
|
||||
"name": "cache-volume"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
rawResource := []byte(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "check-root-user"
|
||||
},
|
||||
"spec": {
|
||||
"volumes": [
|
||||
{
|
||||
"name": "cache-volume",
|
||||
"emptyDir": { }
|
||||
},
|
||||
{
|
||||
"name": "cache-volume2",
|
||||
"emptyDir": {
|
||||
"medium": "Memory"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
expectedRawResource := []byte(`
|
||||
{"apiVersion":"v1","kind":"Pod","metadata":{"name":"check-root-user"},"spec":{"volumes":[{"emptyDir":{"medium":"Memory"},"name":"cache-volume"},{"emptyDir":{"medium":"Memory"},"name":"cache-volume2"}]}}
|
||||
`)
|
||||
|
||||
var expectedResource interface{}
|
||||
assert.NilError(t, json.Unmarshal(expectedRawResource, &expectedResource))
|
||||
|
||||
var policy kyverno.ClusterPolicy
|
||||
err := json.Unmarshal(rawPolicy, &policy)
|
||||
assert.NilError(t, err)
|
||||
|
||||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
mutatedResource, err := ForceMutate(ctx, policy, *resourceUnstructured)
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.DeepEqual(t, expectedResource, mutatedResource.UnstructuredContent())
|
||||
}
|
||||
|
||||
func Test_ForceMutateSubstituteVarsWithPatchesJson6902(t *testing.T) {
|
||||
rawPolicy := []byte(`
|
||||
{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "insert-container"
|
||||
},
|
||||
"spec": {
|
||||
"rules": [
|
||||
{
|
||||
"name": "insert-container",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mutate": {
|
||||
"patchesJson6902": "- op: add\n path: \"/spec/template/spec/containers/0/command/0\"\n value: ls"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
rawResource := []byte(`
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"name": "myDeploy"
|
||||
},
|
||||
"spec": {
|
||||
"replica": 2,
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"old-label": "old-value"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"command": ["ll", "rm"],
|
||||
"image": "nginx",
|
||||
"name": "nginx"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
rawExpected := []byte(`
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"name": "myDeploy"
|
||||
},
|
||||
"spec": {
|
||||
"replica": 2,
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"old-label": "old-value"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"command": ["ls", "ll", "rm"],
|
||||
"image": "nginx",
|
||||
"name": "nginx"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
var expectedResource unstructured.Unstructured
|
||||
assert.NilError(t, json.Unmarshal(rawExpected, &expectedResource))
|
||||
|
||||
var policy kyverno.ClusterPolicy
|
||||
err := json.Unmarshal(rawPolicy, &policy)
|
||||
assert.NilError(t, err)
|
||||
|
||||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
mutatedResource, err := ForceMutate(ctx, policy, *resourceUnstructured)
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.DeepEqual(t, expectedResource.UnstructuredContent(), mutatedResource.UnstructuredContent())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue