func MutatePolicy(policy *v1.ClusterPolicy, logger logr.Logger) (*v1.ClusterPolicy, error) {
	patches, _ := policymutation.GenerateJSONPatchesForDefaults(policy, logger)
	if len(patches) == 0 {
		return policy, nil
	}
	type jsonPatch struct {
		Path  string      `json:"path"`
		Op    string      `json:"op"`
		Value interface{} `json:"value"`
	}
	var jsonPatches []jsonPatch
	err := json.Unmarshal(patches, &jsonPatches)
	if err != nil {
		return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to unmarshal patches for %s policy", policy.Name), err)
	}
	patch, err := jsonpatch.DecodePatch(patches)
	if err != nil {
		return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to decode patch for %s policy", policy.Name), err)
	}
	policyBytes, _ := json.Marshal(policy)
	if err != nil {
		return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to marshal %s policy", policy.Name), err)
	}
	modifiedPolicy, err := patch.Apply(policyBytes)
	if err != nil {
		return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to apply %s policy", policy.Name), err)
	}
	var p v1.ClusterPolicy
	err = json.Unmarshal(modifiedPolicy, &p)
	if err != nil {
		return nil, sanitizederror.NewWithError(fmt.Sprintf("failed to unmarshal %s policy", policy.Name), err)
	}
	return &p, nil
}
MutatePolicy - applies mutation to a policy
package common
import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	jsonpatch "github.com/evanphx/json-patch/v5"
	"github.com/go-git/go-billy/v5"
	"github.com/go-logr/logr"
	v1 "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
	report "github.com/kyverno/kyverno/pkg/api/policyreport/v1alpha2"
	pkgcommon "github.com/kyverno/kyverno/pkg/common"
	client "github.com/kyverno/kyverno/pkg/dclient"
	"github.com/kyverno/kyverno/pkg/engine"
	"github.com/kyverno/kyverno/pkg/engine/context"
	"github.com/kyverno/kyverno/pkg/engine/response"
	"github.com/kyverno/kyverno/pkg/engine/variables"
	sanitizederror "github.com/kyverno/kyverno/pkg/kyverno/sanitizedError"
	"github.com/kyverno/kyverno/pkg/kyverno/store"
	"github.com/kyverno/kyverno/pkg/policymutation"
	"github.com/kyverno/kyverno/pkg/policyreport"
	"github.com/kyverno/kyverno/pkg/utils"
	ut "github.com/kyverno/kyverno/pkg/utils"
	yamlv2 "gopkg.in/yaml.v2"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/util/yaml"
	"sigs.k8s.io/controller-runtime/pkg/log"
	yaml_v2 "sigs.k8s.io/yaml"
)
type ResultCounts struct {
	Pass  int
	Fail  int
	Warn  int
	Error int
	Skip  int
}
type Policy struct {
	Name      string     `json:"name"`
	Resources []Resource `json:"resources"`
	Rules     []Rule     `json:"rules"`
}
type Rule struct {
	Name   string            `json:"name"`
	Values map[string]string `json:"values"`
}
type Values struct {
	Policies           []Policy            `json:"policies"`
	GlobalValues       map[string]string   `json:"globalValues"`
	NamespaceSelectors []NamespaceSelector `json:"namespaceSelector"`
}
type Resource struct {
	Name   string            `json:"name"`
	Values map[string]string `json:"values"`
}
type NamespaceSelector struct {
	Name   string            `json:"name"`
	Labels map[string]string `json:"labels"`
}
func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, errors []error) {
	for _, path := range paths {
		log.Log.V(5).Info("reading policies", "path", path)
		var (
			fileDesc os.FileInfo
			err      error
		)
		isHttpPath := IsHttpRegex.MatchString(path)
		if !isHttpPath {
			path = filepath.Clean(path)
			fileDesc, err = os.Stat(path)
			if err != nil {
				err := fmt.Errorf("failed to process %v: %v", path, err.Error())
				errors = append(errors, err)
				continue
			}
		}
		if !isHttpPath && fileDesc.IsDir() {
			files, err := ioutil.ReadDir(path)
			if err != nil {
				err := fmt.Errorf("failed to process %v: %v", path, err.Error())
				errors = append(errors, err)
				continue
			}
			listOfFiles := make([]string, 0)
			for _, file := range files {
				ext := filepath.Ext(file.Name())
				if ext == "" || ext == ".yaml" || ext == ".yml" {
					listOfFiles = append(listOfFiles, filepath.Join(path, file.Name()))
				}
			}
			policiesFromDir, errorsFromDir := GetPolicies(listOfFiles)
			errors = append(errors, errorsFromDir...)
			policies = append(policies, policiesFromDir...)
		} else {
			var fileBytes []byte
			if isHttpPath {
				resp, err := http.Get(path)  
				if err != nil {
					err := fmt.Errorf("failed to process %v: %v", path, err.Error())
					errors = append(errors, err)
					continue
				}
				defer resp.Body.Close()
				if resp.StatusCode != http.StatusOK {
					err := fmt.Errorf("failed to process %v: %v", path, err.Error())
					errors = append(errors, err)
					continue
				}
				fileBytes, err = ioutil.ReadAll(resp.Body)
				if err != nil {
					err := fmt.Errorf("failed to process %v: %v", path, err.Error())
					errors = append(errors, err)
					continue
				}
			} else {
				path = filepath.Clean(path)
				fileBytes, err = ioutil.ReadFile(path)  
				if err != nil {
					err := fmt.Errorf("failed to process %v: %v", path, err.Error())
					errors = append(errors, err)
					continue
				}
			}
			policiesFromFile, errFromFile := utils.GetPolicy(fileBytes)
			if errFromFile != nil {
				err := fmt.Errorf("failed to process %s: %v", path, errFromFile.Error())
				errors = append(errors, err)
				continue
			}
			policies = append(policies, policiesFromFile...)
		}
	}
	log.Log.V(3).Info("read policies", "policies", len(policies), "errors", len(errors))
	return policies, errors
}
func PolicyHasVariables(policy v1.ClusterPolicy) [][]string {
	policyRaw, _ := json.Marshal(policy)
	matches := RegexVariables.FindAllStringSubmatch(string(policyRaw), -1)
	return matches
}
func ruleForbiddenSectionsHaveVariables(rule *v1.Rule) error {
	var err error
	err = JSONPatchPathHasVariables(rule.Mutation.PatchesJSON6902)
	if err != nil {
		return fmt.Errorf("Rule \"%s\" should not have variables in patchesJSON6902 path section", rule.Name)
	}
	err = objectHasVariables(rule.ExcludeResources)
	if err != nil {
		return fmt.Errorf("Rule \"%s\" should not have variables in exclude section", rule.Name)
	}
	err = objectHasVariables(rule.MatchResources)
	if err != nil {
		return fmt.Errorf("Rule \"%s\" should not have variables in match section", rule.Name)
	}
	return nil
}
func JSONPatchPathHasVariables(patch string) error {
	jsonPatch, err := yaml.ToJSON([]byte(patch))
	if err != nil {
		return err
	}
	decodedPatch, err := jsonpatch.DecodePatch(jsonPatch)
	if err != nil {
		return err
	}
	for _, operation := range decodedPatch {
		path, err := operation.Path()
		if err != nil {
			return err
		}
		vars := variables.RegexVariables.FindAllString(path, -1)
		if len(vars) > 0 {
			return fmt.Errorf("Operation \"%s\" has forbidden variables", operation.Kind())
		}
	}
	return nil
}
func objectHasVariables(object interface{}) error {
	var err error
	objectJSON, err := json.Marshal(object)
	if err != nil {
		return err
	}
	if len(RegexVariables.FindAllStringSubmatch(string(objectJSON), -1)) > 0 {
		return fmt.Errorf("Object has forbidden variables")
	}
	return nil
}
func PolicyHasNonAllowedVariables(policy v1.ClusterPolicy) error {
	for _, r := range policy.Spec.Rules {
		rule := r.DeepCopy()
		for _, vi := range rule.VerifyImages {
			vi.Attestations = nil
		}
		var err error
		ruleJSON, err := json.Marshal(rule)
		if err != nil {
			return err
		}
		err = ruleForbiddenSectionsHaveVariables(rule)
		if err != nil {
			return err
		}
		matchesAll := RegexVariables.FindAllStringSubmatch(string(ruleJSON), -1)
		matchesAllowed := AllowedVariables.FindAllStringSubmatch(string(ruleJSON), -1)
		if (len(matchesAll) > len(matchesAllowed)) && len(rule.Context) == 0 {
			allowed := "{{request.*}}, {{element.*}}, {{serviceAccountName}}, {{serviceAccountNamespace}}, {{@}}, and context variables"
			return fmt.Errorf("rule \"%s\" has forbidden variables. Allowed variables are: %s", rule.Name, allowed)
		}
	}
	return nil
}