1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-04-08 10:04:25 +00:00

Merge branch 'master' into 50-at-least-one-exist

This commit is contained in:
Denis Belyshev 2019-06-18 19:34:31 +03:00
commit 21a8ac8416
4 changed files with 185 additions and 11 deletions

View file

@ -8,10 +8,9 @@ relativeURLs=true
[params]
description = "Kubernetes Native Policy Management"
long_description = '''
Manage policies as Kuberneres resources using YAML or JSON. Easily validate,
mutate, or generate Kubernetes resources. Match resources based on label selectors
and wildcards. View policy results as events, and policy violations as events or
in policy status.'''
Manage policies as Kubernetes resources. Validate, mutate, and generate configurations.
Select resources based on labels and wildcards. View policy enforcement as events. Detect
policy violations for existing resources.'''
author_name = "Nirmata"
author_url = "https://nirmata.com"
project_url = "https://github.com/nirmata/kyverno/"

View file

@ -113,10 +113,11 @@ func applyOverlayToMap(resourceMap, overlayMap map[string]interface{}, path stri
continue
}
currentPath := path + key + "/"
resourcePart, ok := resourceMap[key]
noAnchorKey := removeAnchor(key)
currentPath := path + noAnchorKey + "/"
resourcePart, ok := resourceMap[noAnchorKey]
if ok {
if ok && !isAddingAnchor(key) {
// Key exists - go down through the overlay and resource trees
patches, res := applyOverlay(resourcePart, value, currentPath)
overlayResult.MergeWith(&res)
@ -124,7 +125,9 @@ func applyOverlayToMap(resourceMap, overlayMap map[string]interface{}, path stri
if result.Success == overlayResult.GetReason() {
appliedPatches = append(appliedPatches, patches...)
}
} else {
}
if !ok {
// Key does not exist - insert entire overlay subtree
patch, res := insertSubtree(value, currentPath)
overlayResult.MergeWith(&res)

View file

@ -430,3 +430,166 @@ func TestApplyOverlay_ImagePullPolicy(t *testing.T) {
compareJsonAsMap(t, expectedResult, doc)
}
func TestApplyOverlay_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, res := applyOverlay(resource, overlay, "/")
assert.NilError(t, res.ToError())
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 TestApplyOverlay_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, res := applyOverlay(resource, overlay, "/")
assert.NilError(t, res.ToError())
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)
}

View file

@ -159,6 +159,17 @@ func isExistanceAnchor(str string) bool {
return (str[:len(left)] == left && str[len(str)-len(right):] == right)
}
func isAddingAnchor(key string) bool {
const left = "+("
const right = ")"
if len(key) < len(left)+len(right) {
return false
}
return left == key[:len(left)] && right == key[len(key)-len(right):]
}
// Checks if array object matches anchors. If not - skip - return true
func skipArrayObject(object, anchors map[string]interface{}) bool {
for key, pattern := range anchors {
@ -183,12 +194,10 @@ func removeAnchor(key string) string {
return key[1 : len(key)-1]
}
if isExistanceAnchor(key) {
if isExistanceAnchor(key) || isAddingAnchor(key) {
return key[2 : len(key)-1]
}
// TODO: Add logic for other anchors here
return key
}