1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00
kyverno/pkg/engine/mutate/patch/strategicPreprocessing_test.go
Arnaud Tournier 1e09f22e59
give public access to PreProcessPattern (#9887)
Signed-off-by: Arnaud Tournier <ltearno@gmail.com>
2024-03-12 09:25:00 +00:00

1317 lines
25 KiB
Go

package patch
import (
"encoding/json"
"testing"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/engine/anchor"
"gotest.tools/assert"
yaml "sigs.k8s.io/kustomize/kyaml/yaml"
)
func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) {
testCases := []struct {
rawPolicy []byte
rawResource []byte
expectedPatch []byte
}{
{
rawPolicy: []byte(`{
"spec": {
"containers": [
{
"(name)": "*",
"securityContext": {
"+(allowPrivilegeEscalation)": false,
"+(capabilities)": {
"drop": [
"NET_CAP"
]
},
"+(privileged)": false
}
}
],
"initContainers": [
{
"(name)": "*",
"securityContext": {
"+(allowPrivilegeEscalation)": false,
"+(capabilities)": {
"drop": [
"NET_ADMIN"
]
},
"+(privileged)": false
}
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "mutation-debug",
"namespace": "amritapuri"
},
"spec": {
"containers": [
{
"name": "sleepy-container-1",
"image": "docker.io/library/ubuntu"
},
{
"name": "sleepy-container-2",
"image": "docker.io/library/ubuntu"
}
],
"initContainers": [
{
"name": "init-container-1",
"image": "docker.io/library/ubuntu"
},
{
"name": "init-container-2",
"image": "docker.io/library/ubuntu"
}
]
}
}`),
expectedPatch: []byte(`{
"spec": {
"containers": [
{
"name": "sleepy-container-1",
"securityContext": {
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"NET_CAP"
]
},
"privileged": false
}
},
{
"name": "sleepy-container-2",
"securityContext": {
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"NET_CAP"
]
},
"privileged": false
}
}
],
"initContainers": [
{
"name": "init-container-1",
"securityContext": {
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"NET_ADMIN"
]
},
"privileged": false
}
},
{
"name": "init-container-2",
"securityContext": {
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"NET_ADMIN"
]
},
"privileged": false
}
}
]
}
}`),
},
{
rawPolicy: []byte(`{
"metadata": {
"annotations": {
"+(cluster-autoscaler.kubernetes.io/safe-to-evict)": "true"
}
},
"spec": {
"volumes": [
{
"<(emptyDir)": {}
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "static-web",
"labels": {
"role": "myrole"
}
},
"spec": {
"containers": [
{
"name": "web",
"image": "1nginx"
}
],
"volumes": [
{
"emptyDir": {},
"name": "cache-volume"
},
{
"secret": {
"secretName": "default-token-6gplg"
},
"name": "default-token-6gplg"
}
]
}
}`),
expectedPatch: []byte(`{
"metadata": {
"annotations": {
"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"
}
}
}`),
},
{
rawPolicy: []byte(`{
"metadata": null
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "hello"
},
"spec": {
"containers": [
{
"name": "hello",
"image": "busybox"
}
]
}
}`),
expectedPatch: []byte(`{
"metadata": null
}`),
},
{
rawPolicy: []byte(`{
"spec": {
"containers": [
{
"(name)": "*",
"image": "gcr.io/google-containers/busybox:latest"
}
],
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "hello"
},
"spec": {
"containers": [
{
"name": "hello",
"image": "busybox"
}
]
}
}`),
expectedPatch: []byte(`{
"spec": {
"containers": [
{
"name": "hello",
"image": "gcr.io/google-containers/busybox:latest"
}
],
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
},
{
rawPolicy: []byte(`{
"spec": {
"containers": [
{
"(name)": "*",
"(image)": "gcr.io/google-containers/busybox:*",
"new_filed": "must be inserted"
}
],
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "hello2"
},
"spec": {
"containers": [
{
"name": "hello",
"image": "gcr.io/google-containers/busybox:latest"
}
]
}
}`),
expectedPatch: []byte(`{
"spec": {
"containers": [{
"name": "hello",
"new_filed": "must be inserted"
}],
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
},
{
rawPolicy: []byte(`{
"spec": {
"containers": [
{
"(image)": "gcr.io/google-containers/busybox:latest"
}
],
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "hello2"
},
"spec": {
"containers": [
{
"name": "hello",
"image": "gcr.io/google-containers/busybox:latest"
}
]
}
}`),
expectedPatch: []byte(`{
"spec": {
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
},
{
rawPolicy: []byte(`{
"spec": {
"containers": [
{
"(image)": "gcr.io/google-containers/busybox:*"
}
],
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "hello2"
},
"spec": {
"containers": [
{
"name": "hello",
"image": "gcr.io/google-containers/busybox:latest"
}
]
}
}`),
expectedPatch: []byte(`{
"spec": {
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
},
{
// only the third container does not match the given condition
rawPolicy: []byte(`{
"spec": {
"containers": [
{
"(image)": "gcr.io/google-containers/busybox:*"
}
],
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "hello"
},
"spec": {
"containers": [
{
"name": "hello",
"image": "gcr.io/google-containers/busybox:latest"
},
{
"name": "hello2",
"image": "gcr.io/google-containers/busybox:latest"
},
{
"name": "hello3",
"image": "gcr.io/google-containers/nginx:latest"
}
]
}
}`),
expectedPatch: []byte(`{
"spec": {
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`),
},
{
rawPolicy: []byte(`{
"metadata": {
"annotations": {
"+(cluster-autoscaler.kubernetes.io/safe-to-evict)": true
},
"labels": {
"+(add-labels)": "add"
}
},
"spec": {
"volumes": [
{
"<(hostPath)": {
"path": "*"
}
}
]
}
}`),
rawResource: []byte(`{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "nginx"
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:latest",
"imagePullPolicy": "Never",
"volumeMounts": [
{
"mountPath": "/cache",
"name": "cache-volume"
}
]
}
],
"volumes": [
{
"name": "cache-volume",
"hostPath": {
"path": "/data",
"type": "Directory"
}
}
]
}
}`),
expectedPatch: []byte(`{
"metadata": {
"annotations": {
"cluster-autoscaler.kubernetes.io/safe-to-evict": true
},
"labels": {
"add-labels": "add"
}
}
}`),
},
{
rawPolicy: []byte(`{
"metadata": {
"annotations": {
"+(cluster-autoscaler.kubernetes.io/safe-to-evict)": true
}
},
"spec": {
"volumes": [
{
"<(hostPath)": {
"path": "*"
}
}
]
}
}`),
rawResource: []byte(`{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "nginx",
"annotations": {
"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:latest",
"imagePullPolicy": "Never",
"volumeMounts": [
{
"mountPath": "/cache",
"name": "cache-volume"
}
]
}
],
"volumes": [
{
"name": "cache-volume",
"hostPath": {
"path": "/data",
"type": "Directory"
}
}
]
}
}`),
expectedPatch: []byte(`{}`),
},
{
rawPolicy: []byte(`{
"metadata": {
"annotations": {
"+(alb.ingress.kubernetes.io/backend-protocol)": "HTTPS",
"+(alb.ingress.kubernetes.io/healthcheck-protocol)": "HTTPS",
"+(alb.ingress.kubernetes.io/scheme)": "internal",
"+(alb.ingress.kubernetes.io/target-type)": "ip",
"+(kubernetes.io/ingress.class)": "alb"
}
}
}`),
rawResource: []byte(`{
"apiVersion": "extensions/v1beta1",
"kind": "Ingress",
"metadata": {
"annotations": {
"alb.ingress.kubernetes.io/backend-protocol": "HTTPS",
"alb.ingress.kubernetes.io/healthcheck-protocol": "HTTPS",
"alb.ingress.kubernetes.io/scheme": "internal",
"alb.ingress.kubernetes.io/target-type": "ip",
"external-dns.alpha.kubernetes.io/hostname": "argo",
"kubernetes.io/ingress.class": "test"
},
"labels": {
"app": "argocd-server",
"app.kubernetes.io/name": "argocd-server"
},
"name": "argocd",
"namespace": "default"
}
}`),
expectedPatch: []byte(`{}`),
},
{
rawPolicy: []byte(`{
"spec": {
"template": {
"spec": {
"containers": [
{
"(name)": "*",
"resources": {
"limits": {
"+(memory)": "300Mi",
"+(cpu)": "100"
}
}
}
]
}
}
}
}`),
rawResource: []byte(`{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "qos-demo",
"labels": {
"test": "qos"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app": "nginx"
}
},
"template": {
"metadata": {
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:latest",
"resources": {
"limits": {
"cpu": "50m"
}
}
}
]
}
}
}
}`),
expectedPatch: []byte(`{
"spec": {
"template": {
"spec": {
"containers": [
{
"resources": {
"limits": {
"memory": "300Mi"
}
},
"name": "nginx"
}
]
}
}
}
}`),
},
{
rawPolicy: []byte(`{
"metadata": {
"annotations": {
"+(annotation1)": "atest1",
"+(annotation2)": "atest2"
},
"labels": {
"+(label1)": "test1"
}
},
"spec": {
"(volumes)": [
{
"(hostPath)": {
"path": "/var/run/docker.sock"
}
}
],
"containers": [
{
"(image)": "*:latest",
"command": [
"ls"
],
"imagePullPolicy": "Always"
}
]
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"annotations": {
"annotation1": "atest2"
},
"labels": {
"label1": "test2",
"label2": "test2"
},
"name": "check-root-user"
},
"spec": {
"containers": [
{
"command": [
"ll"
],
"image": "nginx:latest",
"imagePullPolicy": "Never",
"name": "nginx"
},
{
"image": "busybox:latest",
"imagePullPolicy": "Never",
"name": "busybox"
}
],
"volumes": [
{
"hostPath": {
"path": "/var/run/docker.sock"
},
"name": "test-volume"
}
]
}
}`),
expectedPatch: []byte(`{
"metadata": {
"annotations": {
"annotation2": "atest2"
}
},
"spec": {
"containers": [
{
"command": [
"ls"
],
"imagePullPolicy": "Always",
"name": "nginx"
},
{
"command": [
"ls"
],
"imagePullPolicy": "Always",
"name": "busybox"
}
]
}
}`),
},
{
rawPolicy: []byte(`{
"metadata": {
"annotations": {
"+(annotation1)": "atest1",
}
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"annotations": {
"annotation1": "atest2"
},
"labels": {
"label1": "test2",
"label2": "test2"
},
"name": "check-root-user"
}
}`),
expectedPatch: []byte(`{}`),
},
{
rawPolicy: []byte(`{
"metadata": {
"annotations": {
"annotation1": null
}
}
}`),
rawResource: []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"annotations": {
"annotation1": "atest2"
},
"labels": {
"label1": "test2",
"label2": "test2"
},
"name": "check-root-user"
}
}`),
expectedPatch: []byte(`{
"metadata": {
"annotations": {
"annotation1": null
}
}
}`),
},
{
rawPolicy: []byte(`{
"metadata": {
"annotations": {
"+(cluster-autoscaler.kubernetes.io/safe-to-evict)": true
}
},
"spec": {
"volumes": [
{
"hostPath": {
"<(path)": "*data"
}
}
]
}
}`),
rawResource: []byte(`{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "nginx"
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:latest",
"imagePullPolicy": "Never",
"volumeMounts": [
{
"mountPath": "/cache",
"name": "cache-volume"
}
]
}
],
"volumes": [
{
"name": "cache-volume",
"hostPath": {
"path": "/data",
"type": "Directory"
}
}
]
}
}`),
expectedPatch: []byte(`{
"metadata": {
"annotations": {
"cluster-autoscaler.kubernetes.io/safe-to-evict": true
}
}
}`),
},
{
rawPolicy: []byte(`{
"spec": {
"securityContext": {
"runAsNonRoot": true
},
"initContainers": [
{
"(name)": "*",
"securityContext": {
"runAsNonRoot": true
}
}
],
"containers": [
{
"(name)": "*",
"securityContext": {
"runAsNonRoot": true
}
}
]
}
}`),
rawResource: []byte(`{
"spec":{
"initContainers":[
{
"name":"initbusy",
"image":"busybox:1.28",
"command":[
"sleep",
"9999"
]
}
],
"containers":[
{
"image":"busybox:1.28",
"name":"busybox",
"command":[
"sleep",
"9999"
]
}
],
"affinity":{
"podAntiAffinity":{
"requiredDuringSchedulingIgnoredDuringExecution":[
{
"labelSelector":{
"matchExpressions":[
{
"key":"app",
"operator":"In",
"values":[
"foo",
"bar"
]
}
]
},
"topologyKey":"kubernetes.io/hostname"
}
]
}
}
}
}`),
expectedPatch: []byte(`{
"spec": {
"securityContext": {
"runAsNonRoot": true
},
"initContainers": [
{
"name": "initbusy",
"securityContext": {
"runAsNonRoot": true
}
}
],
"containers": [
{
"name": "busybox",
"securityContext": {
"runAsNonRoot": true
}
}
]
}
}`),
},
}
for i, test := range testCases {
t.Logf("Running test %d...", i)
preProcessedPolicy, err := preProcessStrategicMergePatch(logr.Discard(), string(test.rawPolicy), string(test.rawResource))
assert.NilError(t, err)
output, err := preProcessedPolicy.MarshalJSON()
assert.NilError(t, err)
assert.DeepEqual(t, toJSON(t, []byte(test.expectedPatch)), toJSON(t, output))
}
}
func toJSON(t *testing.T, b []byte) interface{} {
var i interface{}
err := json.Unmarshal(b, &i)
assert.NilError(t, err)
return i
}
func Test_FilterKeys_NoConditions(t *testing.T) {
patternRaw := []byte(`{
"key1": "value1",
"key2": "value2"
}`)
pattern := yaml.MustParse(string(patternRaw))
conditions, err := filterKeys(pattern, anchor.IsCondition)
assert.NilError(t, err)
assert.Equal(t, len(conditions), 0)
}
func Test_FilterKeys_ConditionsArePresent(t *testing.T) {
patternRaw := []byte(`{
"key1": "value1",
"(key2)": "value2",
"(key3)": "value3"
}`)
pattern := yaml.MustParse(string(patternRaw))
conditions, err := filterKeys(pattern, anchor.IsCondition)
assert.NilError(t, err)
assert.Equal(t, len(conditions), 2)
assert.Equal(t, conditions[0].String(), "(key2)")
assert.Equal(t, conditions[1].String(), "(key3)")
}
func Test_FilterKeys_EmptyList(t *testing.T) {
patternRaw := []byte(`{}`)
pattern := yaml.MustParse(string(patternRaw))
conditions, err := filterKeys(pattern, anchor.IsCondition)
assert.NilError(t, err)
assert.Equal(t, len(conditions), 0)
}
func Test_CheckConditionAnchor_Matches(t *testing.T) {
patternRaw := []byte(`{ "key1": "value*" }`)
resourceRaw := []byte(`{ "key1": "value1" }`)
pattern := yaml.MustParse(string(patternRaw))
resource := yaml.MustParse(string(resourceRaw))
err := checkCondition(logr.Discard(), pattern, resource)
assert.Equal(t, err, nil)
}
func Test_CheckConditionAnchor_DoesNotMatch(t *testing.T) {
patternRaw := []byte(`{ "key1": "value*" }`)
resourceRaw := []byte(`{ "key1": "sample" }`)
pattern := yaml.MustParse(string(patternRaw))
resource := yaml.MustParse(string(resourceRaw))
err := checkCondition(logr.Discard(), pattern, resource)
assert.Error(t, err, "resource value 'sample' does not match 'value*' at path /key1/")
}
func Test_ValidateConditions_MapWithOneCondition_Matches(t *testing.T) {
patternRaw := []byte(`{
"(key1)": "value*",
"key2": "value2"
}`)
resourceRaw := []byte(`{
"key1": "value1",
"key2": "sample"
}`)
pattern := yaml.MustParse(string(patternRaw))
resource := yaml.MustParse(string(resourceRaw))
err := validateConditions(logr.Discard(), pattern, resource)
assert.NilError(t, err)
}
func Test_ValidateConditions_MapWithOneCondition_DoesNotMatch(t *testing.T) {
patternRaw := []byte(`{
"(key1)": "value*",
"key2": "value2"
}`)
resourceRaw := []byte(`{
"key1": "text",
"key2": "sample"
}`)
pattern := yaml.MustParse(string(patternRaw))
resource := yaml.MustParse(string(resourceRaw))
err := validateConditions(logr.Discard(), pattern, resource)
_, ok := err.(ConditionError)
assert.Assert(t, ok)
}
func Test_RenameField(t *testing.T) {
patternRaw := []byte(`{
"+(key1)": "value",
}`)
pattern := yaml.MustParse(string(patternRaw))
renameField("+(key1)", "key1", pattern)
actual := pattern.Field("key1").Value.YNode().Value
expected := "value"
fields, err := pattern.Fields()
assert.NilError(t, err)
assert.Equal(t, len(fields), 1)
assert.Equal(t, actual, expected)
}
func Test_RenameField_NonExisting(t *testing.T) {
patternRaw := []byte(`{
"+(key1)": "value",
}`)
pattern := yaml.MustParse(string(patternRaw))
renameField("non_existing_field", "key1", pattern)
actual := pattern.Field("+(key1)").Value.YNode().Value
expected := "value"
fields, err := pattern.Fields()
assert.NilError(t, err)
assert.Equal(t, len(fields), 1)
assert.Equal(t, actual, expected)
}
func Test_deleteRNode(t *testing.T) {
patternRaw := []byte(`{
"list": [
"first": {
"a": "b"
},
"second": {
"a": "b"
},
"third": {
"a": "b"
},
],
}`)
pattern := yaml.MustParse(string(patternRaw))
list := pattern.Field("list").Value
elements, err := list.Elements()
assert.NilError(t, err)
assert.Equal(t, len(elements), 3)
deleteListElement(list, 0)
elements, err = list.Elements()
assert.NilError(t, err)
assert.Equal(t, len(elements), 2)
}
func Test_DeleteConditions(t *testing.T) {
patternRaw := []byte(`{
"spec": {
"containers": [
{
"(name)": "*",
"image": "gcr.io/google-containers/busybox:latest"
},
{
"image": "gcr.io/google-containers/busybox:latest",
"name": "hello"
}
],
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`)
pattern := yaml.MustParse(string(patternRaw))
containers, err := pattern.Field("spec").Value.Field("containers").Value.Elements()
assert.NilError(t, err)
assert.Equal(t, len(containers), 2)
_, err = deleteAnchors(pattern, false, false)
assert.NilError(t, err)
containers, err = pattern.Field("spec").Value.Field("containers").Value.Elements()
assert.NilError(t, err)
assert.Equal(t, len(containers), 1)
name := containers[0].Field("name").Value.YNode().Value
assert.Equal(t, name, "hello")
}
func Test_ConditionCheck_SeveralElementsMatchExceptOne(t *testing.T) {
patternRaw := []byte(`{
"containers": [
{
"(name)": "hello?",
"image": "gcr.io/google-containers/busybox:1"
}
]
}`)
containersRaw := []byte(`{
"containers": [
{
"name": "hello",
"image": "gcr.io/google-containers/busybox:latest"
},
{
"name": "hello2",
"image": "gcr.io/google-containers/busybox:latest"
},
{
"name": "hello3",
"image": "gcr.io/google-containers/nginx:latest"
}
]
}`)
pattern := yaml.MustParse(string(patternRaw))
containers := yaml.MustParse(string(containersRaw))
err := PreProcessPattern(logr.Discard(), pattern, containers)
assert.NilError(t, err)
patternContainers := pattern.Field("containers")
assert.Assert(t, patternContainers != nil)
assert.Assert(t, patternContainers.Value != nil)
elements, err := patternContainers.Value.Elements()
assert.NilError(t, err)
assert.Equal(t, len(elements), 2)
}
func Test_NonExistingKeyMustFailPreprocessing(t *testing.T) {
rawPattern := []byte(`{
"metadata": {
"labels": {
"(key1)": "value1",
}
},
"spec": {
"containers": [
{
"name": "busybox",
"image": "gcr.io/google-containers/busybox:latest"
}
],
"imagePullSecrets": [
{
"name": "regcred"
}
]
}
}`)
rawResource := []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "hello"
},
"spec": {
"containers": [
{
"name": "hello",
"image": "busybox"
}
]
}
}`)
pattern := yaml.MustParse(string(rawPattern))
resource := yaml.MustParse(string(rawResource))
err := PreProcessPattern(logr.Discard(), pattern, resource)
assert.Error(t, err, "condition failed: could not found \"key1\" key in the resource")
}
func Test_NestedConditionals(t *testing.T) {
rawPattern := `{"spec":{"template":{"spec":{"volumes":[{"(emptyDir)":{"+(sizeLimit)":"20Mi"},"name":"*"}]}}}}`
rawResource := `{"spec":{"template":{"spec":{"volumes":[{"emptyDir":{},"name":"vol02"}]}}}}`
expectedPattern := `{"spec":{"template":{"spec":{"volumes":[{"emptyDir":{"sizeLimit":"20Mi"},"name":"vol02"}]}}}}`
pattern := yaml.MustParse(rawPattern)
resource := yaml.MustParse(rawResource)
err := PreProcessPattern(logr.Discard(), pattern, resource)
assert.NilError(t, err)
resultPattern, _ := pattern.String()
assert.DeepEqual(t, toJSON(t, []byte(expectedPattern)), toJSON(t, []byte(resultPattern)))
}
func Test_GlobalCondition_Fail(t *testing.T) {
rawPattern := []byte(`{
"metadata": {
"annotations": {
"+(cluster-autoscaler.kubernetes.io/safe-to-evict)": "true"
}
},
"spec": {
"volumes": [
{
"<(emptyDir)": {}
}
]
}
}`)
rawResource := []byte(`{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "pod-without-emptydir-hostpath"
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx"
}
]
}
}`)
pattern := yaml.MustParse(string(rawPattern))
resource := yaml.MustParse(string(rawResource))
err := PreProcessPattern(logr.Discard(), pattern, resource)
assert.Error(t, err, "global condition failed: could not found \"emptyDir\" key in the resource")
}