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:
parent
17d0fc16b2
commit
6d6dc8f1bc
7 changed files with 80 additions and 11 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
20
test/cli/test/variables/cm-globalval-example.yaml
Normal file
20
test/cli/test/variables/cm-globalval-example.yaml
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue