1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

Fix variable substitution for foreach preconditions (#2993)

Signed-off-by: Sambhav Kothari <sambhavs.email@gmail.com>

Co-authored-by: Jim Bugwadia <jim@nirmata.com>
This commit is contained in:
Sambhav Kothari 2022-01-16 05:33:34 +00:00 committed by GitHub
parent 665d2022d8
commit f42092208f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 76 additions and 6 deletions

View file

@ -83,12 +83,19 @@ func SubstituteAll(log logr.Logger, ctx context.EvalInterface, document interfac
}
func SubstituteAllInPreconditions(log logr.Logger, ctx context.EvalInterface, document interface{}) (_ interface{}, err error) {
return substituteAll(log, ctx, document, newPreconditionsVariableResolver(log))
// We must convert all incoming conditions to JSON data i.e.
// string, []interface{}, map[string]interface{}
// we cannot use structs otherwise json traverse doesn't work
untypedDoc, err := DocumentToUntyped(document)
if err != nil {
return document, err
}
return substituteAll(log, ctx, untypedDoc, newPreconditionsVariableResolver(log))
}
func SubstituteAllInRule(log logr.Logger, ctx context.EvalInterface, typedRule kyverno.Rule) (_ kyverno.Rule, err error) {
var rule interface{}
rule, err = RuleToUntyped(typedRule)
rule, err = DocumentToUntyped(typedRule)
if err != nil {
return typedRule, err
}
@ -101,14 +108,14 @@ func SubstituteAllInRule(log logr.Logger, ctx context.EvalInterface, typedRule k
return UntypedToRule(rule)
}
func RuleToUntyped(rule kyverno.Rule) (interface{}, error) {
jsonRule, err := json.Marshal(rule)
func DocumentToUntyped(doc interface{}) (interface{}, error) {
jsonDoc, err := json.Marshal(doc)
if err != nil {
return nil, err
}
var untyped interface{}
err = json.Unmarshal(jsonRule, &untyped)
err = json.Unmarshal(jsonDoc, &untyped)
if err != nil {
return nil, err
}
@ -185,7 +192,7 @@ func substituteAll(log logr.Logger, ctx context.EvalInterface, document interfac
func SubstituteAllForceMutate(log logr.Logger, ctx *context.Context, typedRule kyverno.Rule) (_ kyverno.Rule, err error) {
var rule interface{}
rule, err = RuleToUntyped(typedRule)
rule, err = DocumentToUntyped(typedRule)
if err != nil {
return kyverno.Rule{}, err
}

View file

@ -86,6 +86,16 @@ var tests = []struct {
ResourceRaw: kyverno_2316_resource,
ExpectedPatternRaw: kyverno_2316_pattern,
},
{
TestDescription: "checks that preconditions are substituted correctly",
PolicyName: "replace-docker-hub",
PolicyRaw: kyverno_2971_policy,
ResourceName: "nginx",
ResourceNamespace: "test-mutate",
ResourceGVR: podGVR,
ResourceRaw: kyverno_2971_resource,
ExpectedPatternRaw: kyverno_2971_pattern,
},
}
var ingressTests = struct {

View file

@ -363,3 +363,56 @@ metadata:
annotations:
fluentbit.io/exclude-busybox: "true"
`)
var kyverno_2971_policy = []byte(`
apiVersion : kyverno.io/v1
kind: ClusterPolicy
metadata:
name: replace-docker-hub
spec:
rules:
- name: replace-docker-hub
match:
resources:
kinds:
- Pod
preconditions:
all:
- key: "{{request.operation}}"
operator: In
value:
- CREATE
- UPDATE
mutate:
foreach:
- list: "request.object.spec.containers"
preconditions:
all:
- key: '{{images.containers."{{element.name}}".registry}}'
operator: Equals
value: 'docker.io'
patchStrategicMerge:
spec:
containers:
- name: "{{ element.name }}"
image: 'my-private-registry/{{images.containers."{{element.name}}".path}}:{{images.containers."{{element.name}}".tag}}'
`)
var kyverno_2971_resource = []byte(`
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: test-mutate
spec:
containers:
- name: nginx
image: nginx:1.14.2
`)
var kyverno_2971_pattern = []byte(`
spec:
containers:
- name: "nginx"
image: 'my-private-registry/nginx:1.14.2'
`)