diff --git a/cmd/cli/kubectl-kyverno/utils/common/common.go b/cmd/cli/kubectl-kyverno/utils/common/common.go index 5612e829d9..0ef5269fe1 100644 --- a/cmd/cli/kubectl-kyverno/utils/common/common.go +++ b/cmd/cli/kubectl-kyverno/utils/common/common.go @@ -49,9 +49,9 @@ type Policy struct { } type Rule struct { - Name string `json:"name"` - Values map[string]string `json:"values"` - ForeachValues map[string][]string `json:"foreachValues"` + Name string `json:"name"` + Values map[string]interface{} `json:"values"` + ForeachValues map[string][]interface{} `json:"foreachValues"` } type Values struct { @@ -61,8 +61,8 @@ type Values struct { } type Resource struct { - Name string `json:"name"` - Values map[string]string `json:"values"` + Name string `json:"name"` + Values map[string]interface{} `json:"values"` } type NamespaceSelector struct { @@ -297,7 +297,7 @@ func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit } } else { if r.Values == nil { - r.Values = make(map[string]string) + r.Values = make(map[string]interface{}) } r.Values["request.operation"] = "CREATE" log.Log.V(3).Info("No request.operation found, defaulting it to CREATE", "policy", p.Name) @@ -376,7 +376,7 @@ func MutatePolicies(policies []v1.PolicyInterface) ([]v1.PolicyInterface, error) // ApplyPolicyOnResource - function to apply policy on resource func ApplyPolicyOnResource(policy v1.PolicyInterface, resource *unstructured.Unstructured, - mutateLogPath string, mutateLogPathIsDir bool, variables map[string]string, userInfo v1beta1.RequestInfo, policyReport bool, + mutateLogPath string, mutateLogPathIsDir bool, variables map[string]interface{}, userInfo v1beta1.RequestInfo, policyReport bool, namespaceSelectorMap map[string]map[string]string, stdin bool, rc *ResultCounts, printPatchResource bool) ([]*response.EngineResponse, policyreport.Info, error) { @@ -827,7 +827,7 @@ func SetInStoreContext(mutatedPolicies []v1.PolicyInterface, variables map[strin for _, policy := range mutatedPolicies { storeRules := make([]store.Rule, 0) for _, rule := range autogen.ComputeRules(policy) { - contextVal := make(map[string]string) + contextVal := make(map[string]interface{}) if len(rule.Context) != 0 { for _, contextVar := range rule.Context { for k, v := range variables { @@ -936,9 +936,9 @@ func PrintMutatedPolicy(mutatedPolicies []v1.PolicyInterface) error { return nil } -func CheckVariableForPolicy(valuesMap map[string]map[string]Resource, globalValMap map[string]string, policyName string, resourceName string, resourceKind string, variables map[string]string, kindOnwhichPolicyIsApplied map[string]struct{}, variable string) (map[string]string, error) { +func CheckVariableForPolicy(valuesMap map[string]map[string]Resource, globalValMap map[string]string, policyName string, resourceName string, resourceKind string, variables map[string]string, kindOnwhichPolicyIsApplied map[string]struct{}, variable string) (map[string]interface{}, error) { // get values from file for this policy resource combination - thisPolicyResourceValues := make(map[string]string) + thisPolicyResourceValues := make(map[string]interface{}) if len(valuesMap[policyName]) != 0 && !reflect.DeepEqual(valuesMap[policyName][resourceName], Resource{}) { thisPolicyResourceValues = valuesMap[policyName][resourceName].Values } @@ -948,7 +948,7 @@ func CheckVariableForPolicy(valuesMap map[string]map[string]Resource, globalValM } if thisPolicyResourceValues == nil && len(globalValMap) > 0 { - thisPolicyResourceValues = make(map[string]string) + thisPolicyResourceValues = make(map[string]interface{}) } for k, v := range globalValMap { diff --git a/cmd/cli/kubectl-kyverno/utils/store/store.go b/cmd/cli/kubectl-kyverno/utils/store/store.go index e580be8f6f..b3b7b0591a 100644 --- a/cmd/cli/kubectl-kyverno/utils/store/store.go +++ b/cmd/cli/kubectl-kyverno/utils/store/store.go @@ -73,7 +73,7 @@ type Policy struct { } type Rule struct { - Name string `json:"name"` - Values map[string]string `json:"values"` - ForeachValues map[string][]string `json:"foreachValues"` + Name string `json:"name"` + Values map[string]interface{} `json:"values"` + ForeachValues map[string][]interface{} `json:"foreachValues"` } diff --git a/pkg/common/common.go b/pkg/common/common.go index e79771539b..0dfd2bc993 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -2,7 +2,6 @@ package common import ( "encoding/json" - "fmt" "strings" "time" @@ -71,36 +70,6 @@ func GetNamespaceLabels(namespaceObj *v1.Namespace, logger logr.Logger) map[stri return namespaceUnstructured.GetLabels() } -func VariableToJSON(key, value string) []byte { - var subString string - splitBySlash := strings.Split(key, "\"") - if len(splitBySlash) > 1 { - subString = splitBySlash[1] - } - - startString := "" - endString := "" - lenOfVariableString := 0 - addedSlashString := false - for _, k := range strings.Split(splitBySlash[0], ".") { - if k != "" { - startString += fmt.Sprintf(`{"%s":`, k) - endString += `}` - lenOfVariableString = lenOfVariableString + len(k) + 1 - if lenOfVariableString >= len(splitBySlash[0]) && len(splitBySlash) > 1 && !addedSlashString { - startString += fmt.Sprintf(`{"%s":`, subString) - endString += `}` - addedSlashString = true - } - } - } - - midString := fmt.Sprintf(`"%s"`, strings.Replace(value, `"`, `\"`, -1)) - finalString := startString + midString + endString - var jsonData = []byte(finalString) - return jsonData -} - // RetryFunc allows retrying a function on error within a given timeout func RetryFunc(retryInterval, timeout time.Duration, run func() error, msg string, logger logr.Logger) func() error { return func() error { diff --git a/pkg/engine/context/context.go b/pkg/engine/context/context.go index 74025997fe..a0a0bf647e 100644 --- a/pkg/engine/context/context.go +++ b/pkg/engine/context/context.go @@ -8,7 +8,6 @@ import ( jsonpatch "github.com/evanphx/json-patch/v5" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" - pkgcommon "github.com/kyverno/kyverno/pkg/common" apiutils "github.com/kyverno/kyverno/pkg/utils/api" "github.com/pkg/errors" admissionv1 "k8s.io/api/admission/v1" @@ -36,7 +35,7 @@ type Interface interface { AddRequest(request *admissionv1.AdmissionRequest) error // AddVariable adds a variable to the context - AddVariable(key, value string) error + AddVariable(key string, value interface{}) error // AddContextEntry adds a context entry to the context AddContextEntry(name string, dataRaw []byte) error @@ -129,8 +128,8 @@ func (ctx *context) AddRequest(request *admissionv1.AdmissionRequest) error { return addToContext(ctx, request, "request") } -func (ctx *context) AddVariable(key, value string) error { - return ctx.addJSON(pkgcommon.VariableToJSON(key, value)) +func (ctx *context) AddVariable(key string, value interface{}) error { + return addToContext(ctx, value, strings.Split(key, ".")...) } func (ctx *context) AddContextEntry(name string, dataRaw []byte) error { diff --git a/pkg/engine/mutation_test.go b/pkg/engine/mutation_test.go index bf4f28675e..76f71b2bda 100644 --- a/pkg/engine/mutation_test.go +++ b/pkg/engine/mutation_test.go @@ -232,7 +232,7 @@ func Test_variableSubstitutionCLI(t *testing.T) { Rules: []store.Rule{ { Name: "example-configmap-lookup", - Values: map[string]string{ + Values: map[string]interface{}{ "dictionary.data.env": "dev1", }, }, diff --git a/pkg/engine/validation_test.go b/pkg/engine/validation_test.go index 495c9d05d8..b23ba76891 100644 --- a/pkg/engine/validation_test.go +++ b/pkg/engine/validation_test.go @@ -2223,7 +2223,7 @@ func TestValidate_context_variable_substitution_CLI(t *testing.T) { Rules: []store.Rule{ { Name: "restrict-pod-count", - Values: map[string]string{ + Values: map[string]interface{}{ "podcounts": "12", }, }, @@ -2738,7 +2738,7 @@ func Test_foreach_context_preconditions(t *testing.T) { Rules: []store.Rule{ { Name: "test", - Values: map[string]string{ + Values: map[string]interface{}{ "img.data.podvalid": "nginx/nginx:v1", "img.data.podinvalid": "nginx/nginx:v2", }, @@ -2833,7 +2833,7 @@ func Test_foreach_context_preconditions_fail(t *testing.T) { Rules: []store.Rule{ { Name: "test", - Values: map[string]string{ + Values: map[string]interface{}{ "img.data.podvalid": "nginx/nginx:v1", "img.data.podinvalid": "nginx/nginx:v1", }, diff --git a/test/cli/test/variables/variables.yaml b/test/cli/test/variables/variables.yaml index 60cb0b2f41..66b38a953e 100644 --- a/test/cli/test/variables/variables.yaml +++ b/test/cli/test/variables/variables.yaml @@ -9,7 +9,9 @@ policies: rules: - name: example-configmap-lookup values: - dictionary.data.env: test + dictionary: + data: + env: test resources: - name: test-env-test values: @@ -64,8 +66,12 @@ policies: imageData.configData.config.User: "" - name: test-pod-with-non-trusted-registry values: - element.name: "not-kyverno" - imageData.registry: "gcr.io" - imageData.configData.config.User: "" + element: + name: "not-kyverno" + imageData: + registry: "gcr.io" + configData: + config: + User: "" globalValues: request.mode: dev