1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

- fix violations re-create on the same resource - skip background processing if a resource is to be deleted

This commit is contained in:
Shuting Zhao 2020-05-26 13:56:07 -07:00
parent bc0c733fa2
commit fd0e96b551
5 changed files with 72 additions and 14 deletions

View file

@ -32,7 +32,7 @@ func applyPolicy(policy kyverno.ClusterPolicy, resource unstructured.Unstructure
}() }()
var engineResponses []response.EngineResponse var engineResponses []response.EngineResponse
var engineResponse response.EngineResponse var engineResponseMutation, engineResponseValidation response.EngineResponse
var err error var err error
// build context // build context
ctx := context.NewContext() ctx := context.NewContext()
@ -41,15 +41,14 @@ func applyPolicy(policy kyverno.ClusterPolicy, resource unstructured.Unstructure
logger.Error(err, "enable to add transform resource to ctx") logger.Error(err, "enable to add transform resource to ctx")
} }
//MUTATION //MUTATION
engineResponse, err = mutation(policy, resource, ctx, logger) engineResponseMutation, err = mutation(policy, resource, ctx, logger)
engineResponses = append(engineResponses, engineResponse)
if err != nil { if err != nil {
logger.Error(err, "failed to process mutation rule") logger.Error(err, "failed to process mutation rule")
} }
//VALIDATION //VALIDATION
engineResponse = engine.Validate(engine.PolicyContext{Policy: policy, Context: ctx, NewResource: resource}) engineResponseValidation = engine.Validate(engine.PolicyContext{Policy: policy, Context: ctx, NewResource: resource})
engineResponses = append(engineResponses, engineResponse) engineResponses = append(engineResponses, mergeRuleRespose(engineResponseMutation, engineResponseValidation))
//TODO: GENERATION //TODO: GENERATION
return engineResponses return engineResponses
@ -81,27 +80,31 @@ func getFailedOverallRuleInfo(resource unstructured.Unstructured, engineResponse
// resource does not match so there was a mutation rule violated // resource does not match so there was a mutation rule violated
for index, rule := range engineResponse.PolicyResponse.Rules { for index, rule := range engineResponse.PolicyResponse.Rules {
log.V(4).Info("veriying if policy rule was applied before", "rule", rule.Name) log.V(4).Info("veriying if policy rule was applied before", "rule", rule.Name)
if len(rule.Patches) == 0 {
patches := dropKyvernoAnnotation(rule.Patches, log)
if len(patches) == 0 {
continue continue
} }
patch, err := jsonpatch.DecodePatch(utils.JoinPatches(rule.Patches))
patch, err := jsonpatch.DecodePatch(utils.JoinPatches(patches))
if err != nil { if err != nil {
log.Error(err, "failed to decode JSON patch", "patches", rule.Patches) log.Error(err, "failed to decode JSON patch", "patches", patches)
return response.EngineResponse{}, err return response.EngineResponse{}, err
} }
// apply the patches returned by mutate to the original resource // apply the patches returned by mutate to the original resource
patchedResource, err := patch.Apply(rawResource) patchedResource, err := patch.Apply(rawResource)
if err != nil { if err != nil {
log.Error(err, "failed to apply JSON patch", "patches", rule.Patches) log.Error(err, "failed to apply JSON patch", "patches", patches)
return response.EngineResponse{}, err return response.EngineResponse{}, err
} }
if !jsonpatch.Equal(patchedResource, rawResource) { if !jsonpatch.Equal(patchedResource, rawResource) {
log.V(4).Info("policy rule conditions not satisfied by resource", "rule", rule.Name) log.V(4).Info("policy rule conditions not satisfied by resource", "rule", rule.Name)
engineResponse.PolicyResponse.Rules[index].Success = false engineResponse.PolicyResponse.Rules[index].Success = false
engineResponse.PolicyResponse.Rules[index].Message = fmt.Sprintf("mutation json patches not found at resource path %s", extractPatchPath(rule.Patches, log)) engineResponse.PolicyResponse.Rules[index].Message = fmt.Sprintf("mutation json patches not found at resource path %s", extractPatchPath(patches, log))
} }
} }
return engineResponse, nil return engineResponse, nil
} }
@ -125,3 +128,26 @@ func extractPatchPath(patches [][]byte, log logr.Logger) string {
} }
return strings.Join(resultPath, ";") return strings.Join(resultPath, ";")
} }
func dropKyvernoAnnotation(patches [][]byte, log logr.Logger) (resultPathes [][]byte) {
for _, patch := range patches {
var data jsonPatch
if err := json.Unmarshal(patch, &data); err != nil {
log.Error(err, "failed to decode the generate patch", "patch", string(patch))
continue
}
value := fmt.Sprintf("%v", data.Value)
if strings.Contains(value, engine.PodTemplateAnnotation) {
continue
}
resultPathes = append(resultPathes, patch)
}
return
}
func mergeRuleRespose(mutation, validation response.EngineResponse) response.EngineResponse {
mutation.PolicyResponse.Rules = append(mutation.PolicyResponse.Rules, validation.PolicyResponse.Rules...)
return mutation
}

View file

@ -109,6 +109,10 @@ func getResourcesPerNamespace(kind string, client *client.Client, namespace stri
} }
// filter based on name // filter based on name
for _, r := range list.Items { for _, r := range list.Items {
if r.GetDeletionTimestamp() != nil {
continue
}
// match name // match name
if rule.MatchResources.Name != "" { if rule.MatchResources.Name != "" {
if !wildcard.Match(rule.MatchResources.Name, r.GetName()) { if !wildcard.Match(rule.MatchResources.Name, r.GetName()) {

View file

@ -93,8 +93,17 @@ func (cpv *clusterPV) createPV(newPv *kyverno.ClusterPolicyViolation) error {
if err != nil { if err != nil {
return fmt.Errorf("failed to retry getting resource for policy violation %s/%s: %v", newPv.Name, newPv.Spec.Policy, err) return fmt.Errorf("failed to retry getting resource for policy violation %s/%s: %v", newPv.Name, newPv.Spec.Policy, err)
} }
if obj.GetDeletionTimestamp() != nil {
return nil
}
// set owner reference to resource // set owner reference to resource
ownerRef := createOwnerReference(obj) ownerRef, ok := createOwnerReference(obj)
if !ok {
return nil
}
newPv.SetOwnerReferences([]metav1.OwnerReference{ownerRef}) newPv.SetOwnerReferences([]metav1.OwnerReference{ownerRef})
// create resource // create resource

View file

@ -14,9 +14,19 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log"
) )
func createOwnerReference(resource *unstructured.Unstructured) metav1.OwnerReference { func createOwnerReference(resource *unstructured.Unstructured) (metav1.OwnerReference, bool) {
controllerFlag := true controllerFlag := true
blockOwnerDeletionFlag := true blockOwnerDeletionFlag := true
apiversion := resource.GetAPIVersion()
kind := resource.GetKind()
name := resource.GetName()
uid := resource.GetUID()
if apiversion == "" || kind == "" || name == "" || uid == "" {
return metav1.OwnerReference{}, false
}
ownerRef := metav1.OwnerReference{ ownerRef := metav1.OwnerReference{
APIVersion: resource.GetAPIVersion(), APIVersion: resource.GetAPIVersion(),
Kind: resource.GetKind(), Kind: resource.GetKind(),
@ -25,7 +35,7 @@ func createOwnerReference(resource *unstructured.Unstructured) metav1.OwnerRefer
Controller: &controllerFlag, Controller: &controllerFlag,
BlockOwnerDeletion: &blockOwnerDeletionFlag, BlockOwnerDeletion: &blockOwnerDeletionFlag,
} }
return ownerRef return ownerRef, true
} }
func retryGetResource(client *client.Client, rspec kyverno.ResourceSpec) (*unstructured.Unstructured, error) { func retryGetResource(client *client.Client, rspec kyverno.ResourceSpec) (*unstructured.Unstructured, error) {

View file

@ -92,8 +92,17 @@ func (nspv *namespacedPV) createPV(newPv *kyverno.PolicyViolation) error {
if err != nil { if err != nil {
return fmt.Errorf("failed to retry getting resource for policy violation %s/%s: %v", newPv.Name, newPv.Spec.Policy, err) return fmt.Errorf("failed to retry getting resource for policy violation %s/%s: %v", newPv.Name, newPv.Spec.Policy, err)
} }
if obj.GetDeletionTimestamp() != nil {
return nil
}
// set owner reference to resource // set owner reference to resource
ownerRef := createOwnerReference(obj) ownerRef, ok := createOwnerReference(obj)
if !ok {
return nil
}
newPv.SetOwnerReferences([]metav1.OwnerReference{ownerRef}) newPv.SetOwnerReferences([]metav1.OwnerReference{ownerRef})
// create resource // create resource