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:
parent
7215841792
commit
922840b344
5 changed files with 69 additions and 52 deletions
|
@ -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
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue