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:
parent
cab87f24ba
commit
9f7b6eaaf6
6 changed files with 36 additions and 23 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
Loading…
Add table
Reference in a new issue