Skip to content

Commit

Permalink
add validation for changes to minimum constraints for CRD fields
Browse files Browse the repository at this point in the history
Signed-off-by: everettraven <[email protected]>
  • Loading branch information
everettraven committed Apr 29, 2024
1 parent 6321d10 commit 868776f
Show file tree
Hide file tree
Showing 16 changed files with 1,850 additions and 1 deletion.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
k8s.io/apimachinery v0.29.3
k8s.io/client-go v0.29.3
k8s.io/component-helpers v0.29.3
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
sigs.k8s.io/yaml v1.4.0
)

Expand Down Expand Up @@ -65,7 +66,6 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.110.1 // indirect
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)
92 changes: 92 additions & 0 deletions pkg/kapp/crdupgradesafety/change_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,98 @@ func EnumChangeValidation(diff FieldDiff) (bool, error) {
return handled(), nil
}

func MinimumChangeValidation(diff FieldDiff) (bool, error) {
handled := func() bool {
diff.Old.Minimum = nil
diff.New.Minimum = nil
return reflect.DeepEqual(diff.Old, diff.New)
}

switch {
case diff.Old.Minimum == nil && diff.New.Minimum != nil:
m := *diff.New.Minimum
return handled(), fmt.Errorf("minimum constraint added when one did not exist previously: %+v", m)
case diff.Old.Minimum != nil && diff.New.Minimum != nil:
oldMin := *diff.Old.Minimum
newMin := *diff.New.Minimum
if oldMin < newMin {
return handled(), fmt.Errorf("minimum constraint increased from %+v to %+v", oldMin, newMin)
}
fallthrough
default:
return handled(), nil
}
}

func MinimumLengthChangeValidation(diff FieldDiff) (bool, error) {
handled := func() bool {
diff.Old.MinLength = nil
diff.New.MinLength = nil
return reflect.DeepEqual(diff.Old, diff.New)
}

switch {
case diff.Old.MinLength == nil && diff.New.MinLength != nil:
m := *diff.New.MinLength
return handled(), fmt.Errorf("minimum length constraint added when one did not exist previously: %+v", m)
case diff.Old.MinLength != nil && diff.New.MinLength != nil:
oldMin := *diff.Old.MinLength
newMin := *diff.New.MinLength
if oldMin < newMin {
return handled(), fmt.Errorf("minimum length constraint increased from %+v to %+v", oldMin, newMin)
}
fallthrough
default:
return handled(), nil
}
}

func MinimumItemsChangeValidation(diff FieldDiff) (bool, error) {
handled := func() bool {
diff.Old.MinItems = nil
diff.New.MinItems = nil
return reflect.DeepEqual(diff.Old, diff.New)
}

switch {
case diff.Old.MinItems == nil && diff.New.MinItems != nil:
m := *diff.New.MinItems
return handled(), fmt.Errorf("minimum items constraint added when one did not exist previously: %+v", m)
case diff.Old.MinItems != nil && diff.New.MinItems != nil:
oldMin := *diff.Old.MinItems
newMin := *diff.New.MinItems
if oldMin < newMin {
return handled(), fmt.Errorf("minimum items constraint increased from %+v to %+v", oldMin, newMin)
}
fallthrough
default:
return handled(), nil
}
}

func MinimumPropertiesChangeValidation(diff FieldDiff) (bool, error) {
handled := func() bool {
diff.Old.MinProperties = nil
diff.New.MinProperties = nil
return reflect.DeepEqual(diff.Old, diff.New)
}

switch {
case diff.Old.MinProperties == nil && diff.New.MinProperties != nil:
m := *diff.New.MinProperties
return handled(), fmt.Errorf("minimum properties constraint added when one did not exist previously: %+v", m)
case diff.Old.MinProperties != nil && diff.New.MinProperties != nil:
oldMin := *diff.Old.MinProperties
newMin := *diff.New.MinProperties
if oldMin < newMin {
return handled(), fmt.Errorf("minimum properties constraint increased from %+v to %+v", oldMin, newMin)
}
fallthrough
default:
return handled(), nil
}
}

// ChangeValidator is a Validation implementation focused on
// handling updates to existing fields in a CRD
type ChangeValidator struct {
Expand Down
Loading

0 comments on commit 868776f

Please sign in to comment.