Skip to content

Commit 7c448e3

Browse files
DirectXMan12liggitt
authored andcommitted
Give a reason when rejecting defaulting in CRDs
The current message for rejecting defaulting is fairly unclear -- I wasn't sure why it was happening till I read the kubernetes source code. That's probably not something we want our users to have to do, so this adds more reasons for rejecting the defaulting to the message given to the user. We previously added reasons in certain cases, but did not in the common cases of using apiextensions/v1beta1 or having defaulting disabled in a feature gate. Now we have reasons for all cases.
1 parent 2c7d431 commit 7c448e3

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ func ValidateCustomResourceDefinition(obj *apiextensions.CustomResourceDefinitio
5555
return ret
5656
}
5757

58+
allowDefaults, rejectDefaultsReason := allowDefaults(requestGV, nil)
5859
opts := validationOptions{
59-
allowDefaults: allowDefaults(requestGV, nil),
60+
allowDefaults: allowDefaults,
61+
disallowDefaultsReason: rejectDefaultsReason,
6062
requireRecognizedConversionReviewVersion: true,
6163
requireImmutableNames: false,
6264
requireOpenAPISchema: requireOpenAPISchema(requestGV, nil),
@@ -80,6 +82,8 @@ func ValidateCustomResourceDefinition(obj *apiextensions.CustomResourceDefinitio
8082
type validationOptions struct {
8183
// allowDefaults permits the validation schema to contain default attributes
8284
allowDefaults bool
85+
// disallowDefaultsReason gives a reason as to why allowDefaults is false (for better user feedback)
86+
disallowDefaultsReason string
8387
// requireRecognizedConversionReviewVersion requires accepted webhook conversion versions to contain a recognized version
8488
requireRecognizedConversionReviewVersion bool
8589
// requireImmutableNames disables changing spec.names
@@ -102,8 +106,10 @@ type validationOptions struct {
102106

103107
// ValidateCustomResourceDefinitionUpdate statically validates
104108
func ValidateCustomResourceDefinitionUpdate(obj, oldObj *apiextensions.CustomResourceDefinition, requestGV schema.GroupVersion) field.ErrorList {
109+
allowDefaults, rejectDefaultsReason := allowDefaults(requestGV, &oldObj.Spec)
105110
opts := validationOptions{
106-
allowDefaults: allowDefaults(requestGV, &oldObj.Spec),
111+
allowDefaults: allowDefaults,
112+
disallowDefaultsReason: rejectDefaultsReason,
107113
requireRecognizedConversionReviewVersion: oldObj.Spec.Conversion == nil || hasValidConversionReviewVersionOrEmpty(oldObj.Spec.Conversion.ConversionReviewVersions),
108114
requireImmutableNames: apiextensions.IsCRDConditionTrue(oldObj, apiextensions.Established),
109115
requireOpenAPISchema: requireOpenAPISchema(requestGV, &oldObj.Spec),
@@ -661,6 +667,7 @@ func validateCustomResourceDefinitionValidation(customResourceValidation *apiext
661667

662668
openAPIV3Schema := &specStandardValidatorV3{
663669
allowDefaults: opts.allowDefaults,
670+
disallowDefaultsReason: opts.disallowDefaultsReason,
664671
requireValidPropertyType: opts.requireValidPropertyType,
665672
}
666673

@@ -1110,16 +1117,17 @@ func allVersionsSpecifyOpenAPISchema(spec *apiextensions.CustomResourceDefinitio
11101117
return true
11111118
}
11121119

1113-
// allowDefaults returns true if the defaulting feature is enabled and the request group version allows adding defaults
1114-
func allowDefaults(requestGV schema.GroupVersion, oldCRDSpec *apiextensions.CustomResourceDefinitionSpec) bool {
1120+
// allowDefaults returns true if the defaulting feature is enabled and the request group version allows adding defaults,
1121+
// or false and a reason for the user if defaults are not allowed.
1122+
func allowDefaults(requestGV schema.GroupVersion, oldCRDSpec *apiextensions.CustomResourceDefinitionSpec) (bool, string) {
11151123
if oldCRDSpec != nil && specHasDefaults(oldCRDSpec) {
11161124
// don't tighten validation on existing persisted data
1117-
return true
1125+
return true, ""
11181126
}
11191127
if requestGV == apiextensionsv1beta1.SchemeGroupVersion {
1120-
return false
1128+
return false, "(cannot set default values in apiextensions.k8s.io/v1beta1 CRDs, must use apiextensions.k8s.io/v1)"
11211129
}
1122-
return true
1130+
return true, ""
11231131
}
11241132

11251133
func specHasDefaults(spec *apiextensions.CustomResourceDefinitionSpec) bool {

staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
type validationMatch struct {
3939
path *field.Path
4040
errorType field.ErrorType
41+
contains string
4142
}
4243

4344
func required(path ...string) validationMatch {
@@ -58,9 +59,12 @@ func immutable(path ...string) validationMatch {
5859
func forbidden(path ...string) validationMatch {
5960
return validationMatch{path: field.NewPath(path[0], path[1:]...), errorType: field.ErrorTypeForbidden}
6061
}
62+
func forbiddenContains(contains string, path ...string) validationMatch {
63+
return validationMatch{path: field.NewPath(path[0], path[1:]...), errorType: field.ErrorTypeForbidden, contains: contains}
64+
}
6165

6266
func (v validationMatch) matches(err *field.Error) bool {
63-
return err.Type == v.errorType && err.Field == v.path.String()
67+
return err.Type == v.errorType && err.Field == v.path.String() && strings.Contains(err.Error(), v.contains)
6468
}
6569

6670
func strPtr(s string) *string { return &s }
@@ -1641,7 +1645,7 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
16411645
},
16421646
requestGV: apiextensionsv1beta1.SchemeGroupVersion,
16431647
errors: []validationMatch{
1644-
forbidden("spec", "validation", "openAPIV3Schema", "properties[a]", "default"), // disallowed via v1beta1
1648+
forbiddenContains("cannot set default values in apiextensions.k8s.io/v1beta1", "spec", "validation", "openAPIV3Schema", "properties[a]", "default"), // disallowed via v1beta1
16451649
},
16461650
},
16471651
{

0 commit comments

Comments
 (0)