1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 07:26:55 +00:00

CLI: Global variables (#2401)

* CLI: Global variables

Signed-off-by: Kumar Mallikarjuna <kumarmallikarjuna1@gmail.com>

* Removed redundant reference

Signed-off-by: Kumar Mallikarjuna <kumarmallikarjuna1@gmail.com>

* Changed error message

Signed-off-by: Kumar Mallikarjuna <kumarmallikarjuna1@gmail.com>
This commit is contained in:
Kumar Mallikarjuna 2021-09-20 22:16:57 +05:30 committed by GitHub
parent 17d0fc16b2
commit 6d6dc8f1bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 11 deletions

View file

@ -150,7 +150,7 @@ func applyCommandHelper(resourcePaths []string, cluster bool, policyReport bool,
return rc, resources, skippedPolicies, pvInfos, sanitizederror.NewWithError("pass the values either using set flag or values_file flag", err)
}
variables, valuesMap, namespaceSelectorMap, err := common.GetVariable(variablesString, valuesFile, fs, false, "")
variables, globalValMap, valuesMap, namespaceSelectorMap, err := common.GetVariable(variablesString, valuesFile, fs, false, "")
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
@ -281,7 +281,7 @@ func applyCommandHelper(resourcePaths []string, cluster bool, policyReport bool,
kindOnwhichPolicyIsApplied := common.GetKindsFromPolicy(policy)
for _, resource := range resources {
thisPolicyResourceValues, err := common.CheckVariableForPolicy(valuesMap, policy.GetName(), resource.GetName(), resource.GetKind(), variables, kindOnwhichPolicyIsApplied, variable)
thisPolicyResourceValues, err := common.CheckVariableForPolicy(valuesMap, globalValMap, policy.GetName(), resource.GetName(), resource.GetKind(), variables, kindOnwhichPolicyIsApplied, variable)
if err != nil {
return rc, resources, skippedPolicies, pvInfos, sanitizederror.NewWithError(fmt.Sprintf("policy `%s` have variables. pass the values for the variables for resource `%s` using set/values_file flag", policy.Name, resource.GetName()), err)
}

View file

@ -57,6 +57,7 @@ type Rule struct {
type Values struct {
Policies []Policy `json:"policies"`
GlobalValues map[string]string `json:"globalValues"`
NamespaceSelectors []NamespaceSelector `json:"namespaceSelector"`
}
@ -392,11 +393,12 @@ func RemoveDuplicateAndObjectVariables(matches [][]string) string {
return variableStr
}
func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit bool, policyResourcePath string) (map[string]string, map[string]map[string]Resource, map[string]map[string]string, error) {
func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit bool, policyResourcePath string) (map[string]string, map[string]string, map[string]map[string]Resource, map[string]map[string]string, error) {
valuesMapResource := make(map[string]map[string]Resource)
valuesMapRule := make(map[string]map[string]Rule)
namespaceSelectorMap := make(map[string]map[string]string)
variables := make(map[string]string)
globalValMap := make(map[string]string)
reqObjVars := ""
var yamlFile []byte
@ -431,19 +433,21 @@ func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit
}
if err != nil {
return variables, valuesMapResource, namespaceSelectorMap, sanitizederror.NewWithError("unable to read yaml", err)
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, sanitizederror.NewWithError("unable to read yaml", err)
}
valuesBytes, err := yaml.ToJSON(yamlFile)
if err != nil {
return variables, valuesMapResource, namespaceSelectorMap, sanitizederror.NewWithError("failed to convert json", err)
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, sanitizederror.NewWithError("failed to convert json", err)
}
values := &Values{}
if err := json.Unmarshal(valuesBytes, values); err != nil {
return variables, valuesMapResource, namespaceSelectorMap, sanitizederror.NewWithError("failed to decode yaml", err)
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, sanitizederror.NewWithError("failed to decode yaml", err)
}
globalValMap = values.GlobalValues
for _, p := range values.Policies {
resourceMap := make(map[string]Resource)
for _, r := range p.Resources {
@ -497,7 +501,7 @@ func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit
Policies: storePolices,
})
return variables, valuesMapResource, namespaceSelectorMap, nil
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, nil
}
// MutatePolices - function to apply mutation on policies
@ -947,16 +951,27 @@ func PrintMutatedPolicy(mutatedPolicies []*v1.ClusterPolicy) error {
return nil
}
func CheckVariableForPolicy(valuesMap map[string]map[string]Resource, 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]string, error) {
// get values from file for this policy resource combination
thisPolicyResourceValues := make(map[string]string)
if len(valuesMap[policyName]) != 0 && !reflect.DeepEqual(valuesMap[policyName][resourceName], Resource{}) {
thisPolicyResourceValues = valuesMap[policyName][resourceName].Values
}
for k, v := range variables {
thisPolicyResourceValues[k] = v
}
if thisPolicyResourceValues == nil && len(globalValMap) > 0 {
thisPolicyResourceValues = make(map[string]string)
}
for k, v := range globalValMap {
if _, ok := thisPolicyResourceValues[k]; !ok {
thisPolicyResourceValues[k] = v
}
}
// skipping the variable check for non matching kind
if _, ok := kindOnwhichPolicyIsApplied[resourceKind]; ok {
if len(variable) > 0 && len(thisPolicyResourceValues) == 0 && len(store.GetContext().Policies) == 0 {

View file

@ -335,7 +335,7 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, valuesFile s
fmt.Printf("\nExecuting %s...", values.Name)
variables, valuesMap, namespaceSelectorMap, err := common.GetVariable(variablesString, values.Variables, fs, isGit, policyResourcePath)
variables, globalValMap, valuesMap, namespaceSelectorMap, err := common.GetVariable(variablesString, values.Variables, fs, isGit, policyResourcePath)
if err != nil {
if !sanitizederror.IsErrorSanitized(err) {
return sanitizederror.NewWithError("failed to decode yaml", err)
@ -409,7 +409,7 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, valuesFile s
kindOnwhichPolicyIsApplied := common.GetKindsFromPolicy(policy)
for _, resource := range resources {
thisPolicyResourceValues, err := common.CheckVariableForPolicy(valuesMap, policy.GetName(), resource.GetName(), resource.GetKind(), variables, kindOnwhichPolicyIsApplied, variable)
thisPolicyResourceValues, err := common.CheckVariableForPolicy(valuesMap, globalValMap, policy.GetName(), resource.GetName(), resource.GetKind(), variables, kindOnwhichPolicyIsApplied, variable)
if err != nil {
return sanitizederror.NewWithError(fmt.Sprintf("policy `%s` have variables. pass the values for the variables for resource `%s` using set/values_file flag", policy.Name, resource.GetName()), err)
}

View file

@ -0,0 +1,20 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: cm-globalval-example
spec:
validationFailureAction: enforce
background: false
rules:
- name: validate-mode
match:
resources:
kinds:
- Pod
validate:
message: "The value {{ request.mode }} for val1 is not equal to 'dev'."
deny:
conditions:
- key: "{{ request.mode }}"
operator: NotEquals
value: dev

View file

@ -63,3 +63,21 @@ spec:
containers:
- name: nginx
image: nginx:1.12
---
apiVersion: v1
kind: Pod
metadata:
name: test-global-prod
spec:
containers:
- name: nginx
image: nginx:latest
---
apiVersion: v1
kind: Pod
metadata:
name: test-global-dev
spec:
containers:
- name: nginx
image: nginx:1.12

View file

@ -3,6 +3,7 @@ policies:
- cm-variable-example.yaml
- cm-array-example.yaml
- cm-blk-scalar-example.yaml
- cm-globalval-example.yaml
resources:
- resources.yaml
variables: variables.yaml
@ -31,3 +32,11 @@ results:
rule: validate-blk-role-annotation
resource: test-blk-app
result: pass
- policy: cm-globalval-example
rule: validate-mode
resource: test-global-dev
result: pass
- policy: cm-globalval-example
rule: validate-mode
resource: test-global-prod
result: fail

View file

@ -15,7 +15,7 @@ policies:
rules:
- name: validate-role-annotation
values:
roles-dictionary.data.allowed-roles: "[\"app\",\"test\"]"
roles-dictionary.data.allowed-roles: '["app","test"]'
resources:
- name: test-web
values:
@ -37,3 +37,10 @@ policies:
- name: test-blk-app
values:
request.object.metadata.annotations.role: app
- name: cm-globalval-example
resources:
- name: test-global-prod
values:
request.mode: prod
globalValues:
request.mode: dev