1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 16:06:56 +00:00
kyverno/pkg/admissionpolicy/mutate_test.go
Mariam Fahmy 77a7e5193a
feat: add MAP's mutation logic for the CLI (#11946)
Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
2025-01-17 15:16:34 +00:00

577 lines
14 KiB
Go

package admissionpolicy
import (
"encoding/json"
"testing"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"gotest.tools/assert"
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
)
func Test_MutateResource(t *testing.T) {
tests := []struct {
name string
rawPolicy []byte
rawResource []byte
expectedRawResource []byte
}{
{
name: "MAP ApplyConfiguration",
rawPolicy: []byte(`{
"apiVersion": "admissionregistration.k8s.io/v1alpha1",
"kind": "MutatingAdmissionPolicy",
"metadata": {
"name": "mutate-policy"
},
"spec": {
"matchConstraints": {
"resourceRules": [
{
"apiGroups": [
""
],
"apiVersions": [
"v1"
],
"operations": [
"CREATE"
],
"resources": [
"configmaps"
]
}
]
},
"failurePolicy": "Fail",
"mutations": [
{
"patchType": "ApplyConfiguration",
"applyConfiguration": {
"expression": "object.metadata.?labels[\"lfx-mentorship\"].hasValue() ? \n Object{} :\n Object{ metadata: Object.metadata{ labels: {\"lfx-mentorship\": \"kyverno\"}}}\n"
}
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "game-demo",
"labels": {
"app": "game"
}
},
"data": {
"player_initial_lives": "3"
}
}`),
expectedRawResource: []byte(`{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "game-demo",
"labels": {
"app": "game",
"lfx-mentorship": "kyverno"
}
},
"data": {
"player_initial_lives": "3"
}
}`),
},
{
name: "MAP JSONPatch",
rawPolicy: []byte(`{
"apiVersion": "admissionregistration.k8s.io/v1alpha1",
"kind": "MutatingAdmissionPolicy",
"metadata": {
"name": "mutate-policy"
},
"spec": {
"matchConstraints": {
"resourceRules": [
{
"apiGroups": [
"discovery.k8s.io"
],
"apiVersions": [
"v1"
],
"operations": [
"CREATE"
],
"resources": [
"endpointslices"
]
}
]
},
"failurePolicy": "Fail",
"reinvocationPolicy": "Never",
"mutations": [
{
"patchType": "JSONPatch",
"jsonPatch": {
"expression": "[\n JSONPatch{\n op: \"add\", path: \"/ports\",\n value: object.ports.map(\n p, \n {\n \"name\": p.name,\n \"port\": dyn(p.name.contains(\"secure\") ? 6443 : p.port)\n }\n )\n }\n]\n"
}
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "discovery.k8s.io/v1",
"kind": "EndpointSlice",
"metadata": {
"name": "example-abc",
"labels": {
"kubernetes.io/service-name": "example"
}
},
"addressType": "IPv4",
"ports": [
{
"name": "http",
"protocol": "TCP",
"port": 80
},
{
"name": "secure",
"protocol": "TCP"
}
],
"endpoints": [
{
"addresses": [
"10.1.2.3"
],
"conditions": {
"ready": true
},
"hostname": "pod-1",
"nodeName": "node-1",
"zone": "us-west2-a"
}
]
}`),
expectedRawResource: []byte(`{
"apiVersion": "discovery.k8s.io/v1",
"kind": "EndpointSlice",
"metadata": {
"name": "example-abc",
"labels": {
"kubernetes.io/service-name": "example"
}
},
"addressType": "IPv4",
"ports": [
{
"name": "http",
"port": 80
},
{
"name": "secure",
"port": 6443
}
],
"endpoints": [
{
"addresses": [
"10.1.2.3"
],
"conditions": {
"ready": true
},
"hostname": "pod-1",
"nodeName": "node-1",
"zone": "us-west2-a"
}
]
}`),
},
{
name: "MAP JSONPatch and ApplyConfiguration",
rawPolicy: []byte(`{
"apiVersion": "admissionregistration.k8s.io/v1alpha1",
"kind": "MutatingAdmissionPolicy",
"metadata": {
"name": "sample-policy"
},
"spec": {
"matchConstraints": {
"resourceRules": [
{
"apiGroups": [
"apps"
],
"apiVersions": [
"v1"
],
"operations": [
"CREATE"
],
"resources": [
"deployments"
]
}
]
},
"failurePolicy": "Fail",
"mutations": [
{
"patchType": "ApplyConfiguration",
"applyConfiguration": {
"expression": "Object{\n spec: Object.spec{\n replicas: object.spec.replicas + 100\n }\n}\n"
}
},
{
"patchType": "JSONPatch",
"jsonPatch": {
"expression": "[\n JSONPatch{\n op: \"replace\", \n path: \"/spec/replicas\", \n value: object.spec.replicas + 10\n }\n]\n"
}
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "nginx-deployment",
"labels": {
"app": "nginx"
}
},
"spec": {
"replicas": 3,
"selector": {
"matchLabels": {
"app": "nginx"
}
},
"template": {
"metadata": {
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:1.14.2",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}`),
expectedRawResource: []byte(`{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "nginx-deployment",
"labels": {
"app": "nginx"
}
},
"spec": {
"replicas": 113,
"selector": {
"matchLabels": {
"app": "nginx"
}
},
"template": {
"metadata": {
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:1.14.2",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}`),
},
{
name: "Two mutations of type ApplyConfigurations",
rawPolicy: []byte(`{
"apiVersion": "admissionregistration.k8s.io/v1alpha1",
"kind": "MutatingAdmissionPolicy",
"metadata": {
"name": "sample-policy"
},
"spec": {
"matchConstraints": {
"resourceRules": [
{
"apiGroups": [
"apps"
],
"apiVersions": [
"v1"
],
"operations": [
"CREATE"
],
"resources": [
"deployments"
]
}
]
},
"failurePolicy": "Fail",
"mutations": [
{
"patchType": "ApplyConfiguration",
"applyConfiguration": {
"expression": "Object{\n spec: Object.spec{\n replicas: object.spec.replicas + 100\n }\n}\n"
}
},
{
"patchType": "ApplyConfiguration",
"applyConfiguration": {
"expression": "Object{\n spec: Object.spec{\n replicas: object.spec.replicas + 100\n }\n}\n"
}
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "nginx-deployment",
"labels": {
"app": "nginx"
}
},
"spec": {
"replicas": 3,
"selector": {
"matchLabels": {
"app": "nginx"
}
},
"template": {
"metadata": {
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:1.14.2",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}`),
expectedRawResource: []byte(`{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "nginx-deployment",
"labels": {
"app": "nginx"
}
},
"spec": {
"replicas": 203,
"selector": {
"matchLabels": {
"app": "nginx"
}
},
"template": {
"metadata": {
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:1.14.2",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}`),
},
{
name: "Two mutations of type JSONPatch",
rawPolicy: []byte(`{
"apiVersion": "admissionregistration.k8s.io/v1alpha1",
"kind": "MutatingAdmissionPolicy",
"metadata": {
"name": "sample-policy"
},
"spec": {
"matchConstraints": {
"resourceRules": [
{
"apiGroups": [
"apps"
],
"apiVersions": [
"v1"
],
"operations": [
"CREATE"
],
"resources": [
"deployments"
]
}
]
},
"failurePolicy": "Fail",
"mutations": [
{
"patchType": "JSONPatch",
"jsonPatch": {
"expression": "[\n JSONPatch{\n op: \"replace\", \n path: \"/spec/replicas\", \n value: object.spec.replicas + 10\n }\n]\n"
}
},
{
"patchType": "JSONPatch",
"jsonPatch": {
"expression": "[\n JSONPatch{\n op: \"replace\", \n path: \"/spec/replicas\", \n value: object.spec.replicas + 10\n }\n]\n"
}
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "nginx-deployment",
"labels": {
"app": "nginx"
}
},
"spec": {
"replicas": 3,
"selector": {
"matchLabels": {
"app": "nginx"
}
},
"template": {
"metadata": {
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:1.14.2",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}`),
expectedRawResource: []byte(`{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "nginx-deployment",
"labels": {
"app": "nginx"
}
},
"spec": {
"replicas": 23,
"selector": {
"matchLabels": {
"app": "nginx"
}
},
"template": {
"metadata": {
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:1.14.2",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}`),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
expectedResource, err := kubeutils.BytesToUnstructured(tt.expectedRawResource)
assert.NilError(t, err)
var policy admissionregistrationv1alpha1.MutatingAdmissionPolicy
err = json.Unmarshal(tt.rawPolicy, &policy)
assert.NilError(t, err)
resource, err := kubeutils.BytesToUnstructured(tt.rawResource)
assert.NilError(t, err)
response, err := mutateResource(policy, *resource)
assert.NilError(t, err)
assert.DeepEqual(t, expectedResource.Object, response.PatchedResource.Object)
})
}
}