1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

fix anchors in the list of map VS anchors on different list

This commit is contained in:
Shuting Zhao 2019-07-26 17:52:12 -07:00
parent ff45794455
commit a70d253828
4 changed files with 23 additions and 606 deletions

View file

@ -6,6 +6,7 @@ import (
"fmt"
"reflect"
"strconv"
"strings"
"github.com/golang/glog"
@ -19,19 +20,27 @@ import (
func ProcessOverlay(rule kubepolicy.Rule, rawResource []byte, gvk metav1.GroupVersionKind) ([][]byte, error) {
var resource interface{}
var appliedPatches [][]byte
err := json.Unmarshal(rawResource, &resource)
if err != nil {
if err := json.Unmarshal(rawResource, &resource); err != nil {
return nil, err
}
patches, err := mutateResourceWithOverlay(resource, *rule.Mutation.Overlay)
if err != nil {
return nil, err
resourceInfo := ParseResourceInfoFromObject(rawResource)
patches, err := processOverlayPatches(resource, *rule.Mutation.Overlay)
if err != nil && strings.Contains(err.Error(), "Conditions are not met") {
glog.Infof("Resource does not meet conditions in overlay pattern, resource=%s, rule=%s\n", resourceInfo, rule.Name)
return nil, nil
}
appliedPatches = append(appliedPatches, patches...)
return appliedPatches, err
return patches, err
}
func processOverlayPatches(resource, overlay interface{}) ([][]byte, error) {
if !meetConditions(resource, overlay) {
return nil, errors.New("Conditions are not met")
}
return mutateResourceWithOverlay(resource, overlay)
}
// mutateResourceWithOverlay is a start of overlaying process

View file

@ -143,7 +143,12 @@ func isConditionMet(resource []interface{}, anchors map[string]interface{}) bool
continue
}
if ValidateValueWithPattern(value, pattern) {
if len(resource) == 1 {
if !ValidateValueWithPattern(value, pattern) {
return false
}
} else {
ValidateValueWithPattern(value, pattern)
return true
}
}

View file

@ -2,7 +2,6 @@ package engine
import (
"encoding/json"
"errors"
"strings"
"github.com/golang/glog"
@ -24,12 +23,3 @@ func patchOverlay(rule kubepolicy.Rule, rawResource []byte) ([][]byte, error) {
return patches, err
}
func processOverlayPatches(resource, overlay interface{}) ([][]byte, error) {
if !meetConditions(resource, overlay) {
return nil, errors.New("Conditions are not met")
}
return mutateResourceWithOverlay(resource, overlay)
}

View file

@ -1,587 +0,0 @@
package engine
import (
"encoding/json"
"testing"
jsonpatch "github.com/evanphx/json-patch"
"gotest.tools/assert"
)
func TestProcessOverlayPatches_NestedListWithAnchor(t *testing.T) {
resourceRaw := []byte(`
{
"apiVersion":"v1",
"kind":"Endpoints",
"metadata":{
"name":"test-endpoint",
"labels":{
"label":"test"
}
},
"subsets":[
{
"addresses":[
{
"ip":"192.168.10.171"
}
],
"ports":[
{
"name":"secure-connection",
"port":443,
"protocol":"TCP"
}
]
}
]
}`)
overlayRaw := []byte(`
{
"subsets":[
{
"ports":[
{
"(name)":"secure-connection",
"port":444,
"protocol":"UDP"
}
]
}
]
}`)
var resource, overlay interface{}
json.Unmarshal(resourceRaw, &resource)
json.Unmarshal(overlayRaw, &overlay)
patches, err := processOverlayPatches(resource, overlay)
assert.NilError(t, err)
assert.Assert(t, patches != nil)
patch := JoinPatches(patches)
decoded, err := jsonpatch.DecodePatch(patch)
assert.NilError(t, err)
assert.Assert(t, decoded != nil)
patched, err := decoded.Apply(resourceRaw)
assert.NilError(t, err)
assert.Assert(t, patched != nil)
expectedResult := []byte(`
{
"apiVersion":"v1",
"kind":"Endpoints",
"metadata":{
"name":"test-endpoint",
"labels":{
"label":"test"
}
},
"subsets":[
{
"addresses":[
{
"ip":"192.168.10.171"
}
],
"ports":[
{
"name":"secure-connection",
"port":444.000000,
"protocol":"UDP"
}
]
}
]
}`)
compareJSONAsMap(t, expectedResult, patched)
}
func TestProcessOverlayPatches_InsertIntoArray(t *testing.T) {
resourceRaw := []byte(`
{
"apiVersion":"v1",
"kind":"Endpoints",
"metadata":{
"name":"test-endpoint",
"labels":{
"label":"test"
}
},
"subsets":[
{
"addresses":[
{
"ip":"192.168.10.171"
}
],
"ports":[
{
"name":"secure-connection",
"port":443,
"protocol":"TCP"
}
]
}
]
}`)
overlayRaw := []byte(`
{
"subsets":[
{
"addresses":[
{
"ip":"192.168.10.172"
},
{
"ip":"192.168.10.173"
}
],
"ports":[
{
"name":"insecure-connection",
"port":80,
"protocol":"UDP"
}
]
}
]
}`)
var resource, overlay interface{}
json.Unmarshal(resourceRaw, &resource)
json.Unmarshal(overlayRaw, &overlay)
patches, err := processOverlayPatches(resource, overlay)
assert.NilError(t, err)
assert.Assert(t, patches != nil)
patch := JoinPatches(patches)
decoded, err := jsonpatch.DecodePatch(patch)
assert.NilError(t, err)
assert.Assert(t, decoded != nil)
patched, err := decoded.Apply(resourceRaw)
assert.NilError(t, err)
assert.Assert(t, patched != nil)
expectedResult := []byte(`{
"apiVersion":"v1",
"kind":"Endpoints",
"metadata":{
"name":"test-endpoint",
"labels":{
"label":"test"
}
},
"subsets":[
{
"addresses":[
{
"ip":"192.168.10.171"
}
],
"ports":[
{
"name":"secure-connection",
"port":443,
"protocol":"TCP"
}
]
},
{
"addresses":[
{
"ip":"192.168.10.172"
},
{
"ip":"192.168.10.173"
}
],
"ports":[
{
"name":"insecure-connection",
"port":80,
"protocol":"UDP"
}
]
}
]
}`)
compareJSONAsMap(t, expectedResult, patched)
}
func TestProcessOverlayPatches_TestInsertToArray(t *testing.T) {
overlayRaw := []byte(`
{
"spec":{
"template":{
"spec":{
"containers":[
{
"name":"pi1",
"image":"vasylev.perl"
}
]
}
}
}
}`)
resourceRaw := []byte(`{
"apiVersion":"batch/v1",
"kind":"Job",
"metadata":{
"name":"pi"
},
"spec":{
"template":{
"spec":{
"containers":[
{
"name":"piv0",
"image":"perl",
"command":[
"perl"
]
},
{
"name":"pi",
"image":"perl",
"command":[
"perl"
]
},
{
"name":"piv1",
"image":"perl",
"command":[
"perl"
]
}
],
"restartPolicy":"Never"
}
},
"backoffLimit":4
}
}`)
var resource, overlay interface{}
json.Unmarshal(resourceRaw, &resource)
json.Unmarshal(overlayRaw, &overlay)
patches, err := processOverlayPatches(resource, overlay)
assert.NilError(t, err)
assert.Assert(t, patches != nil)
patch := JoinPatches(patches)
decoded, err := jsonpatch.DecodePatch(patch)
assert.NilError(t, err)
assert.Assert(t, decoded != nil)
patched, err := decoded.Apply(resourceRaw)
assert.NilError(t, err)
assert.Assert(t, patched != nil)
}
func TestProcessOverlayPatches_ImagePullPolicy(t *testing.T) {
overlayRaw := []byte(`{
"spec": {
"template": {
"spec": {
"containers": [
{
"(image)": "*:latest",
"imagePullPolicy": "IfNotPresent",
"ports": [
{
"containerPort": 8080
}
]
}
]
}
}
}
}`)
resourceRaw := []byte(`{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "nginx-deployment",
"labels": {
"app": "nginx"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app": "nginx"
}
},
"template": {
"metadata": {
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:latest",
"ports": [
{
"containerPort": 80
}
]
},
{
"name": "ghost",
"image": "ghost:latest"
}
]
}
}
}
}`)
var resource, overlay interface{}
json.Unmarshal(resourceRaw, &resource)
json.Unmarshal(overlayRaw, &overlay)
patches, err := processOverlayPatches(resource, overlay)
assert.NilError(t, err)
assert.Assert(t, len(patches) != 0)
doc, err := ApplyPatches(resourceRaw, patches)
assert.NilError(t, err)
expectedResult := []byte(`{
"apiVersion":"apps/v1",
"kind":"Deployment",
"metadata":{
"name":"nginx-deployment",
"labels":{
"app":"nginx"
}
},
"spec":{
"replicas":1,
"selector":{
"matchLabels":{
"app":"nginx"
}
},
"template":{
"metadata":{
"labels":{
"app":"nginx"
}
},
"spec":{
"containers":[
{
"image":"nginx:latest",
"imagePullPolicy":"IfNotPresent",
"name":"nginx",
"ports":[
{
"containerPort":80
},
{
"containerPort":8080
}
]
},
{
"image":"ghost:latest",
"imagePullPolicy":"IfNotPresent",
"name":"ghost",
"ports":[
{
"containerPort":8080
}
]
}
]
}
}
}
}`)
compareJSONAsMap(t, expectedResult, doc)
}
func TestProcessOverlayPatches_AddingAnchor(t *testing.T) {
overlayRaw := []byte(`{
"metadata": {
"name": "nginx-deployment",
"labels": {
"+(app)": "should-not-be-here",
"+(key1)": "value1"
}
}
}`)
resourceRaw := []byte(`{
"metadata": {
"name": "nginx-deployment",
"labels": {
"app": "nginx"
}
}
}`)
var resource, overlay interface{}
json.Unmarshal(resourceRaw, &resource)
json.Unmarshal(overlayRaw, &overlay)
patches, err := processOverlayPatches(resource, overlay)
assert.NilError(t, err)
assert.Assert(t, len(patches) != 0)
doc, err := ApplyPatches(resourceRaw, patches)
assert.NilError(t, err)
expectedResult := []byte(`{
"metadata":{
"labels":{
"app":"nginx",
"key1":"value1"
},
"name":"nginx-deployment"
}
}`)
compareJSONAsMap(t, expectedResult, doc)
}
func TestProcessOverlayPatches_AddingAnchorInsideListElement(t *testing.T) {
overlayRaw := []byte(`
{
"spec": {
"template": {
"spec": {
"containers": [
{
"(image)": "*:latest",
"+(imagePullPolicy)": "IfNotPresent"
}
]
}
}
}
}`)
resourceRaw := []byte(`
{
"apiVersion":"apps/v1",
"kind":"Deployment",
"metadata":{
"name":"nginx-deployment",
"labels":{
"app":"nginx"
}
},
"spec":{
"replicas":1,
"selector":{
"matchLabels":{
"app":"nginx"
}
},
"template":{
"metadata":{
"labels":{
"app":"nginx"
}
},
"spec":{
"containers":[
{
"image":"nginx:latest"
},
{
"image":"ghost:latest",
"imagePullPolicy":"Always"
},
{
"image":"debian:10"
},
{
"image":"ubuntu:18.04",
"imagePullPolicy":"Always"
}
]
}
}
}
}`)
var resource, overlay interface{}
json.Unmarshal(resourceRaw, &resource)
json.Unmarshal(overlayRaw, &overlay)
patches, err := processOverlayPatches(resource, overlay)
assert.NilError(t, err)
assert.Assert(t, len(patches) != 0)
doc, err := ApplyPatches(resourceRaw, patches)
assert.NilError(t, err)
expectedResult := []byte(`
{
"apiVersion":"apps/v1",
"kind":"Deployment",
"metadata":{
"name":"nginx-deployment",
"labels":{
"app":"nginx"
}
},
"spec":{
"replicas":1,
"selector":{
"matchLabels":{
"app":"nginx"
}
},
"template":{
"metadata":{
"labels":{
"app":"nginx"
}
},
"spec":{
"containers":[
{
"image":"nginx:latest",
"imagePullPolicy":"IfNotPresent"
},
{
"image":"ghost:latest",
"imagePullPolicy":"Always"
},
{
"image":"debian:10"
},
{
"image":"ubuntu:18.04",
"imagePullPolicy":"Always"
}
]
}
}
}
}`)
compareJSONAsMap(t, expectedResult, doc)
}