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:
commit
21a8ac8416
4 changed files with 185 additions and 11 deletions
|
@ -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/"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue