mirror of https://github.com/k3s-io/k3s
apiextensions: generalize nullable to arbitrary types
parent
975d537ff8
commit
23b7d8b7b9
|
@ -20,7 +20,7 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/google/gofuzz"
|
||||
fuzz "github.com/google/gofuzz"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -113,6 +113,9 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
|||
validRef := "validRef"
|
||||
obj.Ref = &validRef
|
||||
}
|
||||
if len(obj.Type) == 0 {
|
||||
obj.Nullable = false // because this does not roundtrip through go-openapi
|
||||
}
|
||||
},
|
||||
func(obj *apiextensions.JSONSchemaPropsOrBool, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
|
|
|
@ -647,9 +647,6 @@ func (v *specStandardValidatorV3) validate(schema *apiextensions.JSONSchemaProps
|
|||
if schema.Type == "null" {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("type"), "type cannot be set to null, use nullable as an alternative"))
|
||||
}
|
||||
if schema.Nullable && schema.Type != "object" && schema.Type != "array" {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("nullable"), "nullable can only be set for object and array types"))
|
||||
}
|
||||
|
||||
if schema.Items != nil && len(schema.Items.JSONSchemas) != 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("items"), "items must be a schema object and not an array"))
|
||||
|
|
|
@ -1259,24 +1259,10 @@ func TestValidateCustomResourceDefinitionValidation(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
wantError: true,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "nullable with wrong type",
|
||||
input: apiextensions.CustomResourceValidation{
|
||||
OpenAPIV3Schema: &apiextensions.JSONSchemaProps{
|
||||
Properties: map[string]apiextensions.JSONSchemaProps{
|
||||
"string": {
|
||||
Type: "string",
|
||||
Nullable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantError: true,
|
||||
},
|
||||
{
|
||||
name: "nullable with right types",
|
||||
name: "nullable with types",
|
||||
input: apiextensions.CustomResourceValidation{
|
||||
OpenAPIV3Schema: &apiextensions.JSONSchemaProps{
|
||||
Properties: map[string]apiextensions.JSONSchemaProps{
|
||||
|
@ -1288,6 +1274,14 @@ func TestValidateCustomResourceDefinitionValidation(t *testing.T) {
|
|||
Type: "array",
|
||||
Nullable: true,
|
||||
},
|
||||
"number": {
|
||||
Type: "number",
|
||||
Nullable: true,
|
||||
},
|
||||
"string": {
|
||||
Type: "string",
|
||||
Nullable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -70,10 +70,9 @@ func ConvertJSONSchemaPropsWithPostProcess(in *apiextensions.JSONSchemaProps, ou
|
|||
out.Description = in.Description
|
||||
if in.Type != "" {
|
||||
out.Type = spec.StringOrArray([]string{in.Type})
|
||||
}
|
||||
if in.Nullable {
|
||||
// by validation, in.Type is either "object" or "array"
|
||||
out.Type = append(out.Type, "null")
|
||||
if in.Nullable {
|
||||
out.Type = append(out.Type, "null")
|
||||
}
|
||||
}
|
||||
out.Format = in.Format
|
||||
out.Title = in.Title
|
||||
|
|
|
@ -46,6 +46,7 @@ func TestRoundTrip(t *testing.T) {
|
|||
}
|
||||
|
||||
seed := rand.Int63()
|
||||
t.Logf("seed: %d", seed)
|
||||
fuzzerFuncs := fuzzer.MergeFuzzerFuncs(apiextensionsfuzzer.Funcs)
|
||||
f := fuzzer.FuzzerFor(fuzzerFuncs, rand.NewSource(seed), codecs)
|
||||
|
||||
|
@ -90,7 +91,7 @@ func TestRoundTrip(t *testing.T) {
|
|||
}
|
||||
|
||||
if !apiequality.Semantic.DeepEqual(internal, internalRoundTripped) {
|
||||
t.Fatalf("expected\n\t%#v, got \n\t%#v", internal, internalRoundTripped)
|
||||
t.Fatalf("%d: expected\n\t%#v, got \n\t%#v", i, internal, internalRoundTripped)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,6 +215,26 @@ func TestNullable(t *testing.T) {
|
|||
},
|
||||
map[string]interface{}{},
|
||||
}, false},
|
||||
{"nullable and no type against non-nil", args{
|
||||
apiextensions.JSONSchemaProps{
|
||||
Properties: map[string]apiextensions.JSONSchemaProps{
|
||||
"field": {
|
||||
Nullable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{"field": 42},
|
||||
}, false},
|
||||
{"nullable and no type against nil", args{
|
||||
apiextensions.JSONSchemaProps{
|
||||
Properties: map[string]apiextensions.JSONSchemaProps{
|
||||
"field": {
|
||||
Nullable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{"field": nil},
|
||||
}, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue