From a0baf182f231d8fa563bad5ddbfffaa4e796bcbe Mon Sep 17 00:00:00 2001 From: shravan Date: Fri, 6 Mar 2020 01:54:36 +0530 Subject: [PATCH] 522 moving force mutate to a seperate file --- pkg/engine/forceMutate.go | 107 ++++++++++++++++++++++++++++++++++++++ pkg/engine/mutation.go | 100 ----------------------------------- 2 files changed, 107 insertions(+), 100 deletions(-) create mode 100644 pkg/engine/forceMutate.go diff --git a/pkg/engine/forceMutate.go b/pkg/engine/forceMutate.go new file mode 100644 index 0000000000..14ba42c468 --- /dev/null +++ b/pkg/engine/forceMutate.go @@ -0,0 +1,107 @@ +package engine + +import ( + "encoding/json" + "fmt" + "regexp" + + kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1" + "github.com/nirmata/kyverno/pkg/engine/context" + "github.com/nirmata/kyverno/pkg/engine/mutate" + "github.com/nirmata/kyverno/pkg/engine/response" + "github.com/nirmata/kyverno/pkg/engine/utils" + "github.com/nirmata/kyverno/pkg/engine/variables" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func mutateResourceWithOverlay(resource unstructured.Unstructured, overlay interface{}) (unstructured.Unstructured, error) { + patches, err := mutate.MutateResourceWithOverlay(resource.UnstructuredContent(), overlay) + if err != nil { + return unstructured.Unstructured{}, err + } + if len(patches) == 0 { + return resource, nil + } + + // convert to RAW + resourceRaw, err := resource.MarshalJSON() + if err != nil { + return unstructured.Unstructured{}, err + } + + var patchResource []byte + patchResource, err = utils.ApplyPatches(resourceRaw, patches) + if err != nil { + return unstructured.Unstructured{}, err + } + + resource = unstructured.Unstructured{} + err = resource.UnmarshalJSON(patchResource) + if err != nil { + return unstructured.Unstructured{}, err + } + + return resource, nil +} + +// ForceMutate does not check any conditions, it simply mutates the given resource +func ForceMutate(ctx context.EvalInterface, policy kyverno.ClusterPolicy, resource unstructured.Unstructured) (unstructured.Unstructured, error) { + var err error + for _, rule := range policy.Spec.Rules { + if !rule.HasMutate() { + continue + } + + mutation := rule.Mutation.DeepCopy() + + if mutation.Overlay != nil { + overlay := mutation.Overlay + if ctx != nil { + if overlay, err = variables.SubstituteVars(ctx, overlay); err != nil { + return unstructured.Unstructured{}, err + } + } else { + overlay = replaceSubstituteVariables(overlay) + } + + resource, err = mutateResourceWithOverlay(resource, overlay) + if err != nil { + return unstructured.Unstructured{}, fmt.Errorf("could not mutate resource with overlay on rule %v:%v", rule.Name, err) + } + } + + if rule.Mutation.Patches != nil { + var resp response.RuleResponse + resp, resource = mutate.ProcessPatches(rule, resource) + if !resp.Success { + return unstructured.Unstructured{}, fmt.Errorf(resp.Message) + } + } + } + + return resource, nil +} + +func replaceSubstituteVariables(overlay interface{}) interface{} { + overlayRaw, err := json.Marshal(overlay) + if err != nil { + return overlay + } + + regex := regexp.MustCompile(`\{\{([^{}]*)\}\}`) + for { + if len(regex.FindAllStringSubmatch(string(overlayRaw), -1)) > 0 { + overlayRaw = regex.ReplaceAll(overlayRaw, []byte(`placeholderValue`)) + } else { + break + } + } + + var output interface{} + err = json.Unmarshal(overlayRaw, &output) + if err != nil { + return overlay + } + + return output +} diff --git a/pkg/engine/mutation.go b/pkg/engine/mutation.go index 625b0b2371..d1fab46211 100644 --- a/pkg/engine/mutation.go +++ b/pkg/engine/mutation.go @@ -1,17 +1,10 @@ package engine import ( - "encoding/json" - "fmt" "reflect" - "regexp" "strings" "time" - "github.com/nirmata/kyverno/pkg/engine/utils" - - "github.com/nirmata/kyverno/pkg/engine/context" - "github.com/golang/glog" kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1" "github.com/nirmata/kyverno/pkg/engine/mutate" @@ -129,99 +122,6 @@ func Mutate(policyContext PolicyContext) (resp response.EngineResponse) { resp.PatchedResource = patchedResource return resp } - -func mutateResourceWithOverlay(resource unstructured.Unstructured, overlay interface{}) (unstructured.Unstructured, error) { - patches, err := mutate.MutateResourceWithOverlay(resource.UnstructuredContent(), overlay) - if err != nil { - return unstructured.Unstructured{}, err - } - if len(patches) == 0 { - return resource, nil - } - - // convert to RAW - resourceRaw, err := resource.MarshalJSON() - if err != nil { - return unstructured.Unstructured{}, err - } - - var patchResource []byte - patchResource, err = utils.ApplyPatches(resourceRaw, patches) - if err != nil { - return unstructured.Unstructured{}, err - } - - resource = unstructured.Unstructured{} - err = resource.UnmarshalJSON(patchResource) - if err != nil { - return unstructured.Unstructured{}, err - } - - return resource, nil -} - -// ForceMutate does not check any conditions, it simply mutates the given resource -func ForceMutate(ctx context.EvalInterface, policy kyverno.ClusterPolicy, resource unstructured.Unstructured) (unstructured.Unstructured, error) { - var err error - for _, rule := range policy.Spec.Rules { - if !rule.HasMutate() { - continue - } - - mutation := rule.Mutation.DeepCopy() - - if mutation.Overlay != nil { - overlay := mutation.Overlay - if ctx != nil { - if overlay, err = variables.SubstituteVars(ctx, overlay); err != nil { - return unstructured.Unstructured{}, err - } - } else { - overlay = replaceSubstituteVariables(overlay) - } - - resource, err = mutateResourceWithOverlay(resource, overlay) - if err != nil { - return unstructured.Unstructured{}, fmt.Errorf("could not mutate resource with overlay on rule %v:%v", rule.Name, err) - } - } - - if rule.Mutation.Patches != nil { - var resp response.RuleResponse - resp, resource = mutate.ProcessPatches(rule, resource) - if !resp.Success { - return unstructured.Unstructured{}, fmt.Errorf(resp.Message) - } - } - } - - return resource, nil -} - -func replaceSubstituteVariables(overlay interface{}) interface{} { - overlayRaw, err := json.Marshal(overlay) - if err != nil { - return overlay - } - - regex := regexp.MustCompile(`\{\{([^{}]*)\}\}`) - for { - if len(regex.FindAllStringSubmatch(string(overlayRaw), -1)) > 0 { - overlayRaw = regex.ReplaceAll(overlayRaw, []byte(`placeholderValue`)) - } else { - break - } - } - - var output interface{} - err = json.Unmarshal(overlayRaw, &output) - if err != nil { - return overlay - } - - return output -} - func incrementAppliedRuleCount(resp *response.EngineResponse) { resp.PolicyResponse.RulesAppliedCount++ }