mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +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
|
@ -3,6 +3,7 @@ package engine
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ghodss/yaml"
|
||||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/mutate"
|
"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)
|
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
|
return resource, nil
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/utils"
|
"github.com/kyverno/kyverno/pkg/engine/utils"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
|
|
||||||
var rawPolicy = []byte(`
|
var rawPolicy = []byte(`
|
||||||
|
@ -148,3 +149,194 @@ func Test_ForceMutateSubstituteVarsWithNilContext(t *testing.T) {
|
||||||
|
|
||||||
assert.DeepEqual(t, expectedResource, mutatedResource.UnstructuredContent())
|
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