1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-04-08 10:04:25 +00:00

added deep copy for rule; changed rule deep copy logic (#2216)

* added deep copy for rule; changed rule deep copy logic

Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>

* fixed linter error

Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>
This commit is contained in:
Max Goncharenko 2021-07-30 22:07:01 +03:00 committed by GitHub
parent 7215841792
commit 922840b344
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 52 deletions

View file

@ -139,33 +139,47 @@ func (in *Deny) DeepCopyInto(out *Deny) {
}
}
func (in *Rule) DeepCopyInto(out *Rule) {
*out = *in
if in.Context != nil {
in, out := &in.Context, &out.Context
*out = make([]ContextEntry, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
//deepcopy.Copy(in, out)
//*out = *in
temp, err := json.Marshal(in)
if err != nil {
// never should get here
return
}
in.MatchResources.DeepCopyInto(&out.MatchResources)
in.ExcludeResources.DeepCopyInto(&out.ExcludeResources)
if in.AnyAllConditions != nil {
out.AnyAllConditions = in.AnyAllConditions
}
in.Mutation.DeepCopyInto(&out.Mutation)
in.Validation.DeepCopyInto(&out.Validation)
in.Generation.DeepCopyInto(&out.Generation)
if in.VerifyImages != nil {
in, out := &in.VerifyImages, &out.VerifyImages
*out = make([]*ImageVerification, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(ImageVerification)
**out = **in
}
}
err = json.Unmarshal(temp, out)
if err != nil {
// never should get here
return
}
// *out = *in
// if in.Context != nil {
// in, out := &in.Context, &out.Context
// *out = make([]ContextEntry, len(*in))
// for i := range *in {
// (*in)[i].DeepCopyInto(&(*out)[i])
// }
// }
// in.MatchResources.DeepCopyInto(&out.MatchResources)
// in.ExcludeResources.DeepCopyInto(&out.ExcludeResources)
// if in.AnyAllConditions != nil {
// out.AnyAllConditions = in.AnyAllConditions
// }
// in.Mutation.DeepCopyInto(&out.Mutation)
// in.Validation.DeepCopyInto(&out.Validation)
// in.Generation.DeepCopyInto(&out.Generation)
// if in.VerifyImages != nil {
// in, out := &in.VerifyImages, &out.VerifyImages
// *out = make([]*ImageVerification, len(*in))
// for i := range *in {
// if (*in)[i] != nil {
// in, out := &(*in)[i], &(*out)[i]
// *out = new(ImageVerification)
// **out = **in
// }
// }
// }
}
//ToKey generates the key string used for adding label to polivy violation

View file

@ -101,14 +101,15 @@ func filterRule(rule kyverno.Rule, policyContext *PolicyContext) *response.RuleR
return nil
}
rule.AnyAllConditions, err = variables.SubstituteAllInPreconditions(logger, ctx, rule.AnyAllConditions)
ruleCopy := rule.DeepCopy()
ruleCopy.AnyAllConditions, err = variables.SubstituteAllInPreconditions(logger, ctx, ruleCopy.AnyAllConditions)
if err != nil {
logger.V(4).Info("failed to substitute vars in preconditions, skip current rule", "rule name", rule.Name)
logger.V(4).Info("failed to substitute vars in preconditions, skip current rule", "rule name", ruleCopy.Name)
return nil
}
// operate on the copy of the conditions, as we perform variable substitution
copyConditions, err := copyConditions(rule.AnyAllConditions)
copyConditions, err := transformConditions(ruleCopy.AnyAllConditions)
if err != nil {
logger.V(4).Info("cannot copy AnyAllConditions", "reason", err.Error())
return nil
@ -116,13 +117,13 @@ func filterRule(rule kyverno.Rule, policyContext *PolicyContext) *response.RuleR
// evaluate pre-conditions
if !variables.EvaluateConditions(logger, ctx, copyConditions) {
logger.V(4).Info("preconditions not satisfied, skipping rule", "rule", rule.Name)
logger.V(4).Info("preconditions not satisfied, skipping rule", "rule", ruleCopy.Name)
return nil
}
// build rule Response
return &response.RuleResponse{
Name: rule.Name,
Name: ruleCopy.Name,
Type: "Generation",
Success: true,
RuleStats: response.RuleStats{

View file

@ -93,14 +93,15 @@ func Mutate(policyContext *PolicyContext) (resp *response.EngineResponse) {
continue
}
rule.AnyAllConditions, err = variables.SubstituteAllInPreconditions(logger, ctx, rule.AnyAllConditions)
ruleCopy := rule.DeepCopy()
ruleCopy.AnyAllConditions, err = variables.SubstituteAllInPreconditions(logger, ctx, ruleCopy.AnyAllConditions)
if err != nil {
logger.V(3).Info("failed to substitute vars in preconditions, skip current rule", "rule name", rule.Name)
continue
}
// operate on the copy of the conditions, as we perform variable substitution
copyConditions, err := copyConditions(rule.AnyAllConditions)
copyConditions, err := transformConditions(rule.AnyAllConditions)
if err != nil {
logger.V(2).Info("failed to load context", "reason", err.Error())
continue
@ -112,23 +113,23 @@ func Mutate(policyContext *PolicyContext) (resp *response.EngineResponse) {
continue
}
if rule, err = variables.SubstituteAllInRule(logger, ctx, rule); err != nil {
if *ruleCopy, err = variables.SubstituteAllInRule(logger, ctx, *ruleCopy); err != nil {
ruleResp := response.RuleResponse{
Name: rule.Name,
Name: ruleCopy.Name,
Type: utils.Validation.String(),
Message: fmt.Sprintf("variable substitution failed for rule %s: %s", rule.Name, err.Error()),
Message: fmt.Sprintf("variable substitution failed for rule %s: %s", ruleCopy.Name, err.Error()),
Success: true,
}
incrementAppliedCount(resp)
resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, ruleResp)
logger.Error(err, "failed to substitute variables, skip current rule", "rule name", rule.Name)
logger.Error(err, "failed to substitute variables, skip current rule", "rule name", ruleCopy.Name)
continue
}
mutation := rule.Mutation.DeepCopy()
mutateHandler := mutate.CreateMutateHandler(rule.Name, mutation, patchedResource, ctx, logger)
mutation := ruleCopy.Mutation.DeepCopy()
mutateHandler := mutate.CreateMutateHandler(ruleCopy.Name, mutation, patchedResource, ctx, logger)
ruleResponse, patchedResource = mutateHandler.Handle()
if ruleResponse.Success {
// - overlay pattern does not match the resource conditions
@ -136,7 +137,7 @@ func Mutate(policyContext *PolicyContext) (resp *response.EngineResponse) {
continue
}
logger.V(4).Info("mutate rule applied successfully", "ruleName", rule.Name)
logger.V(4).Info("mutate rule applied successfully", "ruleName", ruleCopy.Name)
}
if err := ctx.AddResourceAsObject(patchedResource.Object); err != nil {

View file

@ -380,7 +380,7 @@ func copyOldConditions(original []kyverno.Condition) []kyverno.Condition {
return copies
}
func copyConditions(original apiextensions.JSON) (interface{}, error) {
func transformConditions(original apiextensions.JSON) (interface{}, error) {
// conditions are currently in the form of []interface{}
kyvernoOriginalConditions, err := utils.ApiextensionsJsonToKyvernoConditions(original)
if err != nil {

View file

@ -111,31 +111,31 @@ func validateResource(log logr.Logger, ctx *PolicyContext) *response.EngineRespo
log.V(3).Info("matched validate rule")
rule.AnyAllConditions, err = variables.SubstituteAllInPreconditions(log, ctx.JSONContext, rule.AnyAllConditions)
ruleCopy := rule.DeepCopy()
ruleCopy.AnyAllConditions, err = variables.SubstituteAllInPreconditions(log, ctx.JSONContext, ruleCopy.AnyAllConditions)
if err != nil {
log.V(4).Info("failed to substitute vars in preconditions, skip current rule", "rule name", rule.Name)
return nil
}
// operate on the copy of the conditions, as we perform variable substitution
preconditionsCopy, err := copyConditions(rule.AnyAllConditions)
preconditions, err := transformConditions(ruleCopy.AnyAllConditions)
if err != nil {
log.V(2).Info("wrongfully configured data", "reason", err.Error())
continue
}
// evaluate pre-conditions
if !variables.EvaluateConditions(log, ctx.JSONContext, preconditionsCopy) {
if !variables.EvaluateConditions(log, ctx.JSONContext, preconditions) {
log.V(4).Info("resource fails the preconditions")
continue
}
if rule.Validation.Pattern != nil || rule.Validation.AnyPattern != nil {
if rule, err = substituteAll(log, ctx, rule, resp); err != nil {
if *ruleCopy, err = substituteAll(log, ctx, *ruleCopy, resp); err != nil {
continue
}
ruleResponse := validateResourceWithRule(log, ctx, rule)
ruleResponse := validateResourceWithRule(log, ctx, *ruleCopy)
if ruleResponse != nil {
if !common.IsConditionalAnchorError(ruleResponse.Message) {
incrementAppliedCount(resp)
@ -143,26 +143,27 @@ func validateResource(log logr.Logger, ctx *PolicyContext) *response.EngineRespo
}
}
} else if rule.Validation.Deny != nil {
rule.Validation.Deny.AnyAllConditions, err = variables.SubstituteAllInPreconditions(log, ctx.JSONContext, rule.Validation.Deny.AnyAllConditions)
ruleCopy.Validation.Deny.AnyAllConditions, err = variables.SubstituteAllInPreconditions(log, ctx.JSONContext, ruleCopy.Validation.Deny.AnyAllConditions)
if err != nil {
log.V(4).Info("failed to substitute vars in preconditions, skip current rule", "rule name", rule.Name)
continue
}
if rule, err = substituteAll(log, ctx, rule, resp); err != nil {
if *ruleCopy, err = substituteAll(log, ctx, *ruleCopy, resp); err != nil {
continue
}
denyConditionsCopy, err := copyConditions(rule.Validation.Deny.AnyAllConditions)
denyConditions, err := transformConditions(ruleCopy.Validation.Deny.AnyAllConditions)
if err != nil {
log.V(2).Info("wrongfully configured data", "reason", err.Error())
continue
}
deny := variables.EvaluateConditions(log, ctx.JSONContext, denyConditionsCopy)
deny := variables.EvaluateConditions(log, ctx.JSONContext, denyConditions)
ruleResp := response.RuleResponse{
Name: rule.Name,
Name: ruleCopy.Name,
Type: utils.Validation.String(),
Message: rule.Validation.Message,
Message: ruleCopy.Validation.Message,
Success: !deny,
}