1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 02:18:15 +00:00

skip applying mutate rule if condition key is not present in the resource, consider the rule as success

This commit is contained in:
Shuting Zhao 2019-11-05 16:27:06 -08:00
parent cab87f24ba
commit 9f7b6eaaf6
6 changed files with 36 additions and 23 deletions

View file

@ -1,7 +1,7 @@
package engine
import (
"reflect"
"strings"
"time"
"github.com/golang/glog"
@ -52,7 +52,7 @@ func Mutate(policy kyverno.ClusterPolicy, resource unstructured.Unstructured) (r
if rule.Mutation.Overlay != nil {
var ruleResponse RuleResponse
ruleResponse, patchedResource = processOverlay(rule, resource)
if reflect.DeepEqual(ruleResponse, (RuleResponse{})) {
if strings.Contains(ruleResponse.Message, "policy not applied") {
// overlay pattern does not match the resource conditions
continue
}

View file

@ -29,13 +29,25 @@ func processOverlay(rule kyverno.Rule, resource unstructured.Unstructured) (resp
}()
patches, err := processOverlayPatches(resource.UnstructuredContent(), rule.Mutation.Overlay)
// resource does not satisfy the overlay pattern, we dont apply this rule
if err != nil && strings.Contains(err.Error(), "Conditions are not met") {
glog.Errorf("Resource %s/%s/%s does not meet the conditions in the rule %s with overlay pattern %s", resource.GetKind(), resource.GetNamespace(), resource.GetName(), rule.Name, rule.Mutation.Overlay)
//TODO: send zero response and not consider this as applied?
response.Success = false
response.Message = fmt.Sprintf("Resource %s/%s/%s: %v.", resource.GetKind(), resource.GetNamespace(), resource.GetName(), err)
return response, resource
// resource does not satisfy the overlay pattern, we don't apply this rule
if err != nil {
// condition key is not present in the resource, don't apply this rule
// consider as success
if strings.Contains(err.Error(), "policy not applied") {
response.Success = true
response.Message = fmt.Sprintf("Resource %s/%s/%s: %v.", resource.GetKind(), resource.GetNamespace(), resource.GetName(), err)
return response, resource
}
// conditions are not met, don't apply this rule
// consider as failure
if strings.Contains(err.Error(), "Conditions are not met") {
glog.Errorf("Resource %s/%s/%s does not meet the conditions in the rule %s with overlay pattern %s", resource.GetKind(), resource.GetNamespace(), resource.GetName(), rule.Name, rule.Mutation.Overlay)
//TODO: send zero response and not consider this as applied?
response.Success = false
response.Message = fmt.Sprintf("Resource %s/%s/%s: %v.", resource.GetKind(), resource.GetNamespace(), resource.GetName(), err)
return response, resource
}
}
if err != nil {
@ -78,8 +90,14 @@ func processOverlay(rule kyverno.Rule, resource unstructured.Unstructured) (resp
}
func processOverlayPatches(resource, overlay interface{}) ([][]byte, error) {
if path, err := meetConditions(resource, overlay); err != nil {
// anchor key does not exist in the resource, skip applying policy
if strings.Contains(err.Error(), "resource field is not present") {
glog.V(4).Infof("Mutate rule: policy not applied: %v at %s", err, path)
return nil, fmt.Errorf("policy not applied: %v at %s", err, path)
}
// anchor key is not satisfied in the resource, skip applying policy
glog.V(4).Infof("Mutate rule: failed to validate condition at %s, err: %v", path, err)
return nil, fmt.Errorf("Conditions are not met at %s, %v", path, err)
}

View file

@ -96,7 +96,7 @@ func validateConditionAnchorMap(resourceMap, anchors map[string]interface{}, pat
}
} else {
// noAnchorKey doesn't exist in resource
return curPath, fmt.Errorf("resource field %s is not present", noAnchorKey)
return curPath, fmt.Errorf("resource field is not present %s", noAnchorKey)
}
}
return "", nil

View file

@ -202,8 +202,8 @@ func validateGeneratedResources(t *testing.T, client *client.Client, policy kyve
}
func validateResource(t *testing.T, responseResource unstructured.Unstructured, expectedResourceFile string) {
resourcePrint := func(obj unstructured.Unstructured) {
t.Log("-----patched resource----")
resourcePrint := func(obj unstructured.Unstructured, msg string) {
t.Logf("-----%s----", msg)
if data, err := obj.MarshalJSON(); err == nil {
t.Log(string(data))
}
@ -219,8 +219,8 @@ func validateResource(t *testing.T, responseResource unstructured.Unstructured,
return
}
resourcePrint(responseResource)
resourcePrint(*expectedResource)
resourcePrint(responseResource, "response resource")
resourcePrint(*expectedResource, "expected resource")
// compare the resources
if !reflect.DeepEqual(responseResource, *expectedResource) {
t.Error("failed: response resource returned does not match expected resource")

View file

@ -2,9 +2,8 @@ apiVersion: v1
kind: Pod
metadata:
name: pod-with-hostpath
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: true
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: true
spec:
containers:
- image: k8s.gcr.io/test-webserver

View file

@ -16,8 +16,4 @@ expected:
- name: empty-dir-add-safe-to-evict
type: Mutation
success: true
message: "successfully processed overlay"
- name: host-path-add-safe-to-evict
type: Mutation
success: false
message: "Resource Pod//pod-with-emptydir: Conditions are not met at /spec/volumes/0/hostPath/, resource field hostPath is not present."
message: "successfully processed overlay"