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:
parent
306b22a5db
commit
2dc54e5c1b
7 changed files with 31 additions and 57 deletions
|
@ -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 {
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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",
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue