diff --git a/pkg/engine/mutate/strategicPreprocessing.go b/pkg/engine/mutate/strategicPreprocessing.go index 33e453843d..44a9940449 100644 --- a/pkg/engine/mutate/strategicPreprocessing.go +++ b/pkg/engine/mutate/strategicPreprocessing.go @@ -10,12 +10,40 @@ import ( yaml "sigs.k8s.io/kustomize/kyaml/yaml" ) +type ValidationError struct { + err error +} + +func (ve ValidationError) Error() string { + return ve.err.Error() +} + +func NewValidationError(err error) error { + return ValidationError{err} +} + +type KeyNotFoundError struct { + key string +} + +func (e KeyNotFoundError) Error() string { + return fmt.Sprintf("could not found \"%s\" key in the resource", e.key) +} + +func NewKeyNotFoundError(message string) error { + return KeyNotFoundError{message} +} + type ConditionError struct { errorChain error } func (ce ConditionError) Error() string { - return fmt.Sprintf("Condition failed: %s", ce.errorChain.Error()) + return fmt.Sprintf("condition failed: %s", ce.errorChain.Error()) +} + +func (ce ConditionError) Inner() error { + return ce.errorChain } func NewConditionError(err error) error { @@ -27,7 +55,11 @@ type GlobalConditionError struct { } func (ce GlobalConditionError) Error() string { - return fmt.Sprintf("Global condition failed: %s", ce.errorChain.Error()) + return fmt.Sprintf("global condition failed: %s", ce.errorChain.Error()) +} + +func (ce GlobalConditionError) Inner() error { + return ce.errorChain } func NewGlobalConditionError(err error) error { @@ -141,7 +173,7 @@ func processListOfMaps(logger logr.Logger, pattern, resource *yaml.RNode) error for _, resourceElement := range resourceElements { err := preProcessRecursive(logger, patternElement, resourceElement) if err != nil { - if _, ok := err.(ConditionError); ok { + if shouldSkipArrayElement(err) { // Skip element, if condition has failed continue } @@ -496,14 +528,27 @@ func validateConditionsInternal(logger logr.Logger, pattern, resource *yaml.RNod for _, condition := range conditions { conditionKey := removeAnchor(condition) if resource == nil || resource.Field(conditionKey) == nil { - return fmt.Errorf("could not found \"%s\" key in the resource", conditionKey) + return NewKeyNotFoundError(conditionKey) } err = checkCondition(logger, pattern.Field(condition).Value, resource.Field(conditionKey).Value) if err != nil { - return err + return NewValidationError(err) } } return nil } + +func shouldSkipArrayElement(err error) bool { + globalErr, isGlobal := err.(GlobalConditionError) + _, isCondition := err.(ConditionError) + + if isGlobal { + if _, ok := globalErr.Inner().(KeyNotFoundError); ok { + return true + } + } + + return isCondition +}