Unverified Commit 3ea3cfc3 authored by k8s-ci-robot's avatar k8s-ci-robot Committed by GitHub

Merge pull request #71137 from sttts/sttts-crd-openapi-spec-recursive-v2-prune

apiextensions: prune {any,one}Of + Not recursively on OpenAPI v2 conversion
parents fab70099 0d9a0225
...@@ -36,7 +36,6 @@ import ( ...@@ -36,7 +36,6 @@ import (
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion" informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion"
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion" listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion"
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
...@@ -131,18 +130,10 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error { ...@@ -131,18 +130,10 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
if err != nil { if err != nil {
return err return err
} }
// Convert internal CustomResourceValidation to versioned CustomResourceValidation
versionedSchema := new(v1beta1.CustomResourceValidation)
if validationSchema == nil {
versionedSchema = nil
} else {
if err := v1beta1.Convert_apiextensions_CustomResourceValidation_To_v1beta1_CustomResourceValidation(validationSchema, versionedSchema, nil); err != nil {
return err
}
}
// We aggregate the schema even if it's nil as it maybe a removal of the schema for this CRD, // We aggregate the schema even if it's nil as it maybe a removal of the schema for this CRD,
// and the aggreated OpenAPI spec should reflect this change. // and the aggreated OpenAPI spec should reflect this change.
crdspec, etag, err := apiextensionsopenapi.CustomResourceDefinitionOpenAPISpec(&crd.Spec, version.Version, versionedSchema) crdspec, etag, err := apiextensionsopenapi.CustomResourceDefinitionOpenAPISpec(&crd.Spec, version.Version, validationSchema)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -50,8 +50,17 @@ func ValidateCustomResource(customResource interface{}, validator *validate.Sche ...@@ -50,8 +50,17 @@ func ValidateCustomResource(customResource interface{}, validator *validate.Sche
return nil return nil
} }
// ConvertJSONSchemaProps converts the schema from apiextensions.JSONSchemaPropos to go-openapi/spec.Schema // ConvertJSONSchemaProps converts the schema from apiextensions.JSONSchemaPropos to go-openapi/spec.Schema.
func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) error { func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) error {
return ConvertJSONSchemaPropsWithPostProcess(in, out, nil)
}
// PostProcessFunc post-processes one node of a spec.Schema.
type PostProcessFunc func(*spec.Schema) error
// ConvertJSONSchemaPropsWithPostProcess converts the schema from apiextensions.JSONSchemaPropos to go-openapi/spec.Schema
// and run a post process step on each JSONSchemaProps node.
func ConvertJSONSchemaPropsWithPostProcess(in *apiextensions.JSONSchemaProps, out *spec.Schema, postProcess PostProcessFunc) error {
if in == nil { if in == nil {
return nil return nil
} }
...@@ -86,41 +95,43 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) ...@@ -86,41 +95,43 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema)
out.Example = *(in.Example) out.Example = *(in.Example)
} }
out.Enum = make([]interface{}, len(in.Enum)) if in.Enum != nil {
for k, v := range in.Enum { out.Enum = make([]interface{}, len(in.Enum))
out.Enum[k] = v for k, v := range in.Enum {
out.Enum[k] = v
}
} }
if err := convertSliceOfJSONSchemaProps(&in.AllOf, &out.AllOf); err != nil { if err := convertSliceOfJSONSchemaProps(&in.AllOf, &out.AllOf, postProcess); err != nil {
return err return err
} }
if err := convertSliceOfJSONSchemaProps(&in.OneOf, &out.OneOf); err != nil { if err := convertSliceOfJSONSchemaProps(&in.OneOf, &out.OneOf, postProcess); err != nil {
return err return err
} }
if err := convertSliceOfJSONSchemaProps(&in.AnyOf, &out.AnyOf); err != nil { if err := convertSliceOfJSONSchemaProps(&in.AnyOf, &out.AnyOf, postProcess); err != nil {
return err return err
} }
if in.Not != nil { if in.Not != nil {
in, out := &in.Not, &out.Not in, out := &in.Not, &out.Not
*out = new(spec.Schema) *out = new(spec.Schema)
if err := ConvertJSONSchemaProps(*in, *out); err != nil { if err := ConvertJSONSchemaPropsWithPostProcess(*in, *out, postProcess); err != nil {
return err return err
} }
} }
var err error var err error
out.Properties, err = convertMapOfJSONSchemaProps(in.Properties) out.Properties, err = convertMapOfJSONSchemaProps(in.Properties, postProcess)
if err != nil { if err != nil {
return err return err
} }
out.PatternProperties, err = convertMapOfJSONSchemaProps(in.PatternProperties) out.PatternProperties, err = convertMapOfJSONSchemaProps(in.PatternProperties, postProcess)
if err != nil { if err != nil {
return err return err
} }
out.Definitions, err = convertMapOfJSONSchemaProps(in.Definitions) out.Definitions, err = convertMapOfJSONSchemaProps(in.Definitions, postProcess)
if err != nil { if err != nil {
return err return err
} }
...@@ -135,7 +146,7 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) ...@@ -135,7 +146,7 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema)
if in.AdditionalProperties != nil { if in.AdditionalProperties != nil {
in, out := &in.AdditionalProperties, &out.AdditionalProperties in, out := &in.AdditionalProperties, &out.AdditionalProperties
*out = new(spec.SchemaOrBool) *out = new(spec.SchemaOrBool)
if err := convertJSONSchemaPropsorBool(*in, *out); err != nil { if err := convertJSONSchemaPropsorBool(*in, *out, postProcess); err != nil {
return err return err
} }
} }
...@@ -143,7 +154,7 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) ...@@ -143,7 +154,7 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema)
if in.AdditionalItems != nil { if in.AdditionalItems != nil {
in, out := &in.AdditionalItems, &out.AdditionalItems in, out := &in.AdditionalItems, &out.AdditionalItems
*out = new(spec.SchemaOrBool) *out = new(spec.SchemaOrBool)
if err := convertJSONSchemaPropsorBool(*in, *out); err != nil { if err := convertJSONSchemaPropsorBool(*in, *out, postProcess); err != nil {
return err return err
} }
} }
...@@ -151,7 +162,7 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) ...@@ -151,7 +162,7 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = new(spec.SchemaOrArray) *out = new(spec.SchemaOrArray)
if err := convertJSONSchemaPropsOrArray(*in, *out); err != nil { if err := convertJSONSchemaPropsOrArray(*in, *out, postProcess); err != nil {
return err return err
} }
} }
...@@ -161,7 +172,7 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) ...@@ -161,7 +172,7 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema)
*out = make(spec.Dependencies, len(*in)) *out = make(spec.Dependencies, len(*in))
for key, val := range *in { for key, val := range *in {
newVal := new(spec.SchemaOrStringArray) newVal := new(spec.SchemaOrStringArray)
if err := convertJSONSchemaPropsOrStringArray(&val, newVal); err != nil { if err := convertJSONSchemaPropsOrStringArray(&val, newVal, postProcess); err != nil {
return err return err
} }
(*out)[key] = *newVal (*out)[key] = *newVal
...@@ -174,14 +185,20 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) ...@@ -174,14 +185,20 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema)
out.ExternalDocs.URL = in.ExternalDocs.URL out.ExternalDocs.URL = in.ExternalDocs.URL
} }
if postProcess != nil {
if err := postProcess(out); err != nil {
return err
}
}
return nil return nil
} }
func convertSliceOfJSONSchemaProps(in *[]apiextensions.JSONSchemaProps, out *[]spec.Schema) error { func convertSliceOfJSONSchemaProps(in *[]apiextensions.JSONSchemaProps, out *[]spec.Schema, postProcess PostProcessFunc) error {
if in != nil { if in != nil {
for _, jsonSchemaProps := range *in { for _, jsonSchemaProps := range *in {
schema := spec.Schema{} schema := spec.Schema{}
if err := ConvertJSONSchemaProps(&jsonSchemaProps, &schema); err != nil { if err := ConvertJSONSchemaPropsWithPostProcess(&jsonSchemaProps, &schema, postProcess); err != nil {
return err return err
} }
*out = append(*out, schema) *out = append(*out, schema)
...@@ -190,25 +207,27 @@ func convertSliceOfJSONSchemaProps(in *[]apiextensions.JSONSchemaProps, out *[]s ...@@ -190,25 +207,27 @@ func convertSliceOfJSONSchemaProps(in *[]apiextensions.JSONSchemaProps, out *[]s
return nil return nil
} }
func convertMapOfJSONSchemaProps(in map[string]apiextensions.JSONSchemaProps) (map[string]spec.Schema, error) { func convertMapOfJSONSchemaProps(in map[string]apiextensions.JSONSchemaProps, postProcess PostProcessFunc) (map[string]spec.Schema, error) {
if in == nil {
return nil, nil
}
out := make(map[string]spec.Schema) out := make(map[string]spec.Schema)
if len(in) != 0 { for k, jsonSchemaProps := range in {
for k, jsonSchemaProps := range in { schema := spec.Schema{}
schema := spec.Schema{} if err := ConvertJSONSchemaPropsWithPostProcess(&jsonSchemaProps, &schema, postProcess); err != nil {
if err := ConvertJSONSchemaProps(&jsonSchemaProps, &schema); err != nil { return nil, err
return nil, err
}
out[k] = schema
} }
out[k] = schema
} }
return out, nil return out, nil
} }
func convertJSONSchemaPropsOrArray(in *apiextensions.JSONSchemaPropsOrArray, out *spec.SchemaOrArray) error { func convertJSONSchemaPropsOrArray(in *apiextensions.JSONSchemaPropsOrArray, out *spec.SchemaOrArray, postProcess PostProcessFunc) error {
if in.Schema != nil { if in.Schema != nil {
in, out := &in.Schema, &out.Schema in, out := &in.Schema, &out.Schema
*out = new(spec.Schema) *out = new(spec.Schema)
if err := ConvertJSONSchemaProps(*in, *out); err != nil { if err := ConvertJSONSchemaPropsWithPostProcess(*in, *out, postProcess); err != nil {
return err return err
} }
} }
...@@ -216,7 +235,7 @@ func convertJSONSchemaPropsOrArray(in *apiextensions.JSONSchemaPropsOrArray, out ...@@ -216,7 +235,7 @@ func convertJSONSchemaPropsOrArray(in *apiextensions.JSONSchemaPropsOrArray, out
in, out := &in.JSONSchemas, &out.Schemas in, out := &in.JSONSchemas, &out.Schemas
*out = make([]spec.Schema, len(*in)) *out = make([]spec.Schema, len(*in))
for i := range *in { for i := range *in {
if err := ConvertJSONSchemaProps(&(*in)[i], &(*out)[i]); err != nil { if err := ConvertJSONSchemaPropsWithPostProcess(&(*in)[i], &(*out)[i], postProcess); err != nil {
return err return err
} }
} }
...@@ -224,24 +243,24 @@ func convertJSONSchemaPropsOrArray(in *apiextensions.JSONSchemaPropsOrArray, out ...@@ -224,24 +243,24 @@ func convertJSONSchemaPropsOrArray(in *apiextensions.JSONSchemaPropsOrArray, out
return nil return nil
} }
func convertJSONSchemaPropsorBool(in *apiextensions.JSONSchemaPropsOrBool, out *spec.SchemaOrBool) error { func convertJSONSchemaPropsorBool(in *apiextensions.JSONSchemaPropsOrBool, out *spec.SchemaOrBool, postProcess PostProcessFunc) error {
out.Allows = in.Allows out.Allows = in.Allows
if in.Schema != nil { if in.Schema != nil {
in, out := &in.Schema, &out.Schema in, out := &in.Schema, &out.Schema
*out = new(spec.Schema) *out = new(spec.Schema)
if err := ConvertJSONSchemaProps(*in, *out); err != nil { if err := ConvertJSONSchemaPropsWithPostProcess(*in, *out, postProcess); err != nil {
return err return err
} }
} }
return nil return nil
} }
func convertJSONSchemaPropsOrStringArray(in *apiextensions.JSONSchemaPropsOrStringArray, out *spec.SchemaOrStringArray) error { func convertJSONSchemaPropsOrStringArray(in *apiextensions.JSONSchemaPropsOrStringArray, out *spec.SchemaOrStringArray, postProcess PostProcessFunc) error {
out.Property = in.Property out.Property = in.Property
if in.Schema != nil { if in.Schema != nil {
in, out := &in.Schema, &out.Schema in, out := &in.Schema, &out.Schema
*out = new(spec.Schema) *out = new(spec.Schema)
if err := ConvertJSONSchemaProps(*in, *out); err != nil { if err := ConvertJSONSchemaPropsWithPostProcess(*in, *out, postProcess); err != nil {
return err return err
} }
} }
......
...@@ -14,7 +14,7 @@ go_library( ...@@ -14,7 +14,7 @@ go_library(
deps = [ deps = [
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library", "//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", "//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/validation:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//vendor/github.com/go-openapi/spec:go_default_library", "//vendor/github.com/go-openapi/spec:go_default_library",
...@@ -28,7 +28,8 @@ go_test( ...@@ -28,7 +28,8 @@ go_test(
srcs = ["conversion_test.go"], srcs = ["conversion_test.go"],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", "//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//vendor/github.com/go-openapi/spec:go_default_library", "//vendor/github.com/go-openapi/spec:go_default_library",
], ],
) )
......
...@@ -17,33 +17,29 @@ limitations under the License. ...@@ -17,33 +17,29 @@ limitations under the License.
package openapi package openapi
import ( import (
"encoding/json"
"github.com/go-openapi/spec" "github.com/go-openapi/spec"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
"k8s.io/apiextensions-apiserver/pkg/apiserver/validation"
) )
// ConvertJSONSchemaPropsToOpenAPIv2Schema converts our internal OpenAPI v3 schema // ConvertJSONSchemaPropsToOpenAPIv2Schema converts our internal OpenAPI v3 schema
// (*apiextensions.JSONSchemaProps) to an OpenAPI v2 schema (*spec.Schema). // (*apiextensions.JSONSchemaProps) to an OpenAPI v2 schema (*spec.Schema).
// NOTE: we use versioned type (v1beta1) here so that we can properly marshal the object // NOTE: we use versioned type (v1beta1) here so that we can properly marshal the object
// using the JSON tags // using the JSON tags
func ConvertJSONSchemaPropsToOpenAPIv2Schema(in *v1beta1.JSONSchemaProps) (*spec.Schema, error) { func ConvertJSONSchemaPropsToOpenAPIv2Schema(in *apiextensions.JSONSchemaProps) (*spec.Schema, error) {
if in == nil { if in == nil {
return nil, nil return nil, nil
} }
// Marshal JSONSchemaProps into JSON and unmarshal the data into spec.Schema
data, err := json.Marshal(*in)
if err != nil {
return nil, err
}
out := new(spec.Schema) out := new(spec.Schema)
if err := out.UnmarshalJSON(data); err != nil { validation.ConvertJSONSchemaPropsWithPostProcess(in, out, func(p *spec.Schema) error {
return nil, err // Remove unsupported fields in OpenAPI v2
} p.OneOf = nil
// Remove unsupported fields in OpenAPI v2 p.AnyOf = nil
out.OneOf = nil p.Not = nil
out.AnyOf = nil
out.Not = nil return nil
})
return out, nil return out, nil
} }
...@@ -24,7 +24,6 @@ import ( ...@@ -24,7 +24,6 @@ import (
"github.com/go-openapi/spec" "github.com/go-openapi/spec"
autoscalingv1 "k8s.io/api/autoscaling/v1" autoscalingv1 "k8s.io/api/autoscaling/v1"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
...@@ -206,7 +205,7 @@ func scaleStatusSchema() *spec.Schema { ...@@ -206,7 +205,7 @@ func scaleStatusSchema() *spec.Schema {
// NOTE: in apiserver we general operates on internal types. We are using versioned (v1beta1) // NOTE: in apiserver we general operates on internal types. We are using versioned (v1beta1)
// validation schema here because we need the json tags to properly marshal the object to // validation schema here because we need the json tags to properly marshal the object to
// JSON. // JSON.
func CustomResourceDefinitionOpenAPISpec(crdSpec *apiextensions.CustomResourceDefinitionSpec, version string, validationSchema *v1beta1.CustomResourceValidation) (*spec.Swagger, string, error) { func CustomResourceDefinitionOpenAPISpec(crdSpec *apiextensions.CustomResourceDefinitionSpec, version string, validationSchema *apiextensions.CustomResourceValidation) (*spec.Swagger, string, error) {
schema := &spec.Schema{} schema := &spec.Schema{}
if validationSchema != nil && validationSchema.OpenAPIV3Schema != nil { if validationSchema != nil && validationSchema.OpenAPIV3Schema != nil {
var err error var err error
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment