1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 10:28:36 +00:00

Allow variables of any kind to be defined (#3828)

Signed-off-by: Sambhav Kothari <skothari44@bloomberg.net>
This commit is contained in:
Sambhav Kothari 2022-05-07 21:30:11 +01:00 committed by GitHub
parent 306b22a5db
commit 2dc54e5c1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 31 additions and 57 deletions

View file

@ -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 {

View file

@ -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"`
}

View file

@ -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 {

View file

@ -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 {

View file

@ -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",
},
},

View file

@ -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",
},

View file

@ -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