Merge pull request #65256 from liggitt/crd-schema-openapi

Automatic merge from submit-queue (batch tested with PRs 65256, 64236, 64919, 64879, 57932). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Fix CRD OpenAPI schema

fixes #65243
depends on https://github.com/kubernetes/kube-openapi/pull/84

without this PR, kubectl complains about creating this CRD with a validation schema (which worked in 1.10):
```yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: resources.mygroup.example.com
spec:
  group: mygroup.example.com
  version: v1alpha1
  scope: Namespaced
  names:
    plural: resources
    singular: resource
    kind: Kind
    listKind: KindList
  validation:
    openAPIV3Schema:
      properties:
        spec:
          type: array
          items:
            type: number
```

> error: error validating "/Users/jliggitt/projects/snippets/crd/crd.yaml": error validating data: [ValidationError(CustomResourceDefinition.spec.validation.openAPIV3Schema.properties.spec.items): unknown field "type" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrArray, ValidationError(CustomResourceDefinition.spec.validation.openAPIV3Schema.properties.spec.items): missing required field "Schema" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrArray, ValidationError(CustomResourceDefinition.spec.validation.openAPIV3Schema.properties.spec.items): missing required field "JSONSchemas" in io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrArray]; if you choose to ignore these errors, turn validation off with --validate=false

that is because the types used to serialize JSONSchema require custom marshaling/unmarshaling, and the OpenAPI generator was not informed of that, so it produced this:
```json
{
    "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrArray": {
    "description": "JSONSchemaPropsOrArray represents a value that can either be a JSONSchemaProps or an array of JSONSchemaProps. Mainly here for serialization purposes.",
    "required": [
     "Schema",
     "JSONSchemas"
    ],
    "properties": {
     "JSONSchemas": {
      "type": "array",
      "items": {
       "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaProps"
      }
     },
     "Schema": {
      "$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaProps"
     }
    }
   }
}
```

OpenAPI isn't able to represent oneOf/anyOf types correctly currently. Until it can, we definitely shouldn't publish a schema containing required fields which aren't even part of the JSON serialization. This PR implements custom openapi type functions, which omit the properties/required/schema attributes for four specific JSONSchema types. This allows kubectl to continue creating these objects without complaining.

/sig api-machinery
/assign @sttts

```release-note
fixed incorrect OpenAPI schema for CustomResourceDefinition objects
```
This commit is contained in:
Kubernetes Submit Queue 2018-06-20 17:22:08 -07:00 committed by GitHub
commit ed6c8b7326
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 164 additions and 107 deletions

18
Godeps/Godeps.json generated
View File

@ -3357,39 +3357,39 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/aggregator",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/generators",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto/testing",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto/validation",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/utils/clock",

View File

@ -85607,16 +85607,7 @@
}
},
"io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSON": {
"description": "JSON represents any valid JSON value. These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.",
"required": [
"Raw"
],
"properties": {
"Raw": {
"type": "string",
"format": "byte"
}
}
"description": "JSON represents any valid JSON value. These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil."
},
"io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaProps": {
"description": "JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).",
@ -85768,57 +85759,16 @@
}
},
"io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrArray": {
"description": "JSONSchemaPropsOrArray represents a value that can either be a JSONSchemaProps or an array of JSONSchemaProps. Mainly here for serialization purposes.",
"required": [
"Schema",
"JSONSchemas"
],
"properties": {
"JSONSchemas": {
"type": "array",
"items": {
"$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaProps"
}
},
"Schema": {
"$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaProps"
}
}
"description": "JSONSchemaPropsOrArray represents a value that can either be a JSONSchemaProps or an array of JSONSchemaProps. Mainly here for serialization purposes."
},
"io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrBool": {
"description": "JSONSchemaPropsOrBool represents JSONSchemaProps or a boolean value. Defaults to true for the boolean property.",
"required": [
"Allows",
"Schema"
],
"properties": {
"Allows": {
"type": "boolean"
},
"Schema": {
"$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaProps"
}
}
"description": "JSONSchemaPropsOrBool represents JSONSchemaProps or a boolean value. Defaults to true for the boolean property."
},
"io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrStringArray": {
"description": "JSONSchemaPropsOrStringArray represents a JSONSchemaProps or a string array.",
"required": [
"Schema",
"Property"
],
"properties": {
"Property": {
"type": "array",
"items": {
"type": "string"
}
},
"Schema": {
"$ref": "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaProps"
}
}
"description": "JSONSchemaPropsOrStringArray represents a JSONSchemaProps or a string array."
},
"io.k8s.apimachinery.pkg.api.resource.Quantity": {
"description": "Quantity is a fixed-point representation of a number. It provides convenient marshaling/unmarshaling in JSON and YAML, in addition to String() and Int64() accessors.\n\nThe serialization format is:\n\n\u003cquantity\u003e ::= \u003csignedNumber\u003e\u003csuffix\u003e\n (Note that \u003csuffix\u003e may be empty, from the \"\" case in \u003cdecimalSI\u003e.)\n\u003cdigit\u003e ::= 0 | 1 | ... | 9 \u003cdigits\u003e ::= \u003cdigit\u003e | \u003cdigit\u003e\u003cdigits\u003e \u003cnumber\u003e ::= \u003cdigits\u003e | \u003cdigits\u003e.\u003cdigits\u003e | \u003cdigits\u003e. | .\u003cdigits\u003e \u003csign\u003e ::= \"+\" | \"-\" \u003csignedNumber\u003e ::= \u003cnumber\u003e | \u003csign\u003e\u003cnumber\u003e \u003csuffix\u003e ::= \u003cbinarySI\u003e | \u003cdecimalExponent\u003e | \u003cdecimalSI\u003e \u003cbinarySI\u003e ::= Ki | Mi | Gi | Ti | Pi | Ei\n (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)\n\u003cdecimalSI\u003e ::= m | \"\" | k | M | G | T | P | E\n (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)\n\u003cdecimalExponent\u003e ::= \"e\" \u003csignedNumber\u003e | \"E\" \u003csignedNumber\u003e\n\nNo matter which of the three exponent forms is used, no quantity may represent a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal places. Numbers larger or more precise will be capped or rounded up. (E.g.: 0.1m will rounded up to 1m.) This may be extended in the future if we require larger or smaller quantities.\n\nWhen a Quantity is parsed from a string, it will remember the type of suffix it had, and will use the same type again when it is serialized.\n\nBefore serializing, Quantity will be put in \"canonical form\". This means that Exponent/suffix will be adjusted up or down (with a corresponding increase or decrease in Mantissa) such that:\n a. No precision is lost\n b. No fractional digits will be emitted\n c. The exponent (or suffix) is as large as possible.\nThe sign will be omitted unless the number is negative.\n\nExamples:\n 1.5 will be serialized as \"1500m\"\n 1.5Gi will be serialized as \"1536Mi\"\n\nNote that the quantity will NEVER be internally represented by a floating point number. That is the whole point of this exercise.\n\nNon-canonical values will still parse as long as they are well formed, but will be re-emitted in their canonical form. (So always use canonical form, or don't diff.)\n\nThis format is intended to make it difficult to use these numbers without writing some sort of special handling code in the hopes that that will cause implementors to also use a fixed point implementation.",
"type": "string"
},
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
@ -86342,6 +86292,7 @@
}
},
"io.k8s.apimachinery.pkg.apis.meta.v1.MicroTime": {
"description": "MicroTime is version of Time with microsecond level precision.",
"type": "string",
"format": "date-time"
},
@ -86591,6 +86542,7 @@
}
},
"io.k8s.apimachinery.pkg.apis.meta.v1.Time": {
"description": "Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers.",
"type": "string",
"format": "date-time"
},
@ -86796,6 +86748,7 @@
}
},
"io.k8s.apimachinery.pkg.util.intstr.IntOrString": {
"description": "IntOrString is a type that can hold an int32 or a string. When used in JSON or YAML marshalling and unmarshalling, it produces or consumes the inner type. This allows you to have, for example, a JSON field that can accept a name or number.",
"type": "string",
"format": "int-or-string"
},

View File

@ -1777,12 +1777,49 @@ __EOF__
# Post-Condition: assertion crd with non-matching kind and resource exists
kube::test::get_object_assert customresourcedefinitions "{{range.items}}{{$id_field}}:{{end}}" 'bars.company.com:foos.company.com:resources.mygroup.example.com:'
# This test ensures that we can create complex validation without client-side validation complaining
kubectl "${kube_flags_with_token[@]}" create -f - << __EOF__
{
"kind": "CustomResourceDefinition",
"apiVersion": "apiextensions.k8s.io/v1beta1",
"metadata": {
"name": "validfoos.company.com"
},
"spec": {
"group": "company.com",
"version": "v1",
"scope": "Namespaced",
"names": {
"plural": "validfoos",
"kind": "ValidFoo"
},
"validation": {
"openAPIV3Schema": {
"properties": {
"spec": {
"type": "array",
"items": {
"type": "number"
}
}
}
}
}
}
}
__EOF__
# Post-Condition: assertion crd with non-matching kind and resource exists
kube::test::get_object_assert customresourcedefinitions "{{range.items}}{{$id_field}}:{{end}}" 'bars.company.com:foos.company.com:resources.mygroup.example.com:validfoos.company.com:'
run_non_native_resource_tests
# teardown
kubectl delete customresourcedefinitions/foos.company.com "${kube_flags_with_token[@]}"
kubectl delete customresourcedefinitions/bars.company.com "${kube_flags_with_token[@]}"
kubectl delete customresourcedefinitions/resources.mygroup.example.com "${kube_flags_with_token[@]}"
kubectl delete customresourcedefinitions/validfoos.company.com "${kube_flags_with_token[@]}"
set +o nounset
set +o errexit
}

View File

@ -2036,23 +2036,23 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",

View File

@ -62,6 +62,19 @@ type JSON struct {
Raw []byte `protobuf:"bytes,1,opt,name=raw"`
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ JSON) OpenAPISchemaType() []string {
// TODO: return actual types when anyOf is supported
return []string{}
}
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ JSON) OpenAPISchemaFormat() string { return "" }
// JSONSchemaURL represents a schema url.
type JSONSchemaURL string
@ -72,6 +85,19 @@ type JSONSchemaPropsOrArray struct {
JSONSchemas []JSONSchemaProps `protobuf:"bytes,2,rep,name=jSONSchemas"`
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ JSONSchemaPropsOrArray) OpenAPISchemaType() []string {
// TODO: return actual types when anyOf is supported
return []string{}
}
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ JSONSchemaPropsOrArray) OpenAPISchemaFormat() string { return "" }
// JSONSchemaPropsOrBool represents JSONSchemaProps or a boolean value.
// Defaults to true for the boolean property.
type JSONSchemaPropsOrBool struct {
@ -79,6 +105,19 @@ type JSONSchemaPropsOrBool struct {
Schema *JSONSchemaProps `protobuf:"bytes,2,opt,name=schema"`
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ JSONSchemaPropsOrBool) OpenAPISchemaType() []string {
// TODO: return actual types when anyOf is supported
return []string{}
}
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ JSONSchemaPropsOrBool) OpenAPISchemaFormat() string { return "" }
// JSONSchemaDependencies represent a dependencies property.
type JSONSchemaDependencies map[string]JSONSchemaPropsOrStringArray
@ -88,6 +127,19 @@ type JSONSchemaPropsOrStringArray struct {
Property []string `protobuf:"bytes,2,rep,name=property"`
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ JSONSchemaPropsOrStringArray) OpenAPISchemaType() []string {
// TODO: return actual types when anyOf is supported
return []string{}
}
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ JSONSchemaPropsOrStringArray) OpenAPISchemaFormat() string { return "" }
// JSONSchemaDefinitions contains the models explicitly defined in this spec.
type JSONSchemaDefinitions map[string]JSONSchemaProps

View File

@ -180,7 +180,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
}
]
}

View File

@ -1764,23 +1764,23 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/client-go/discovery",

View File

@ -588,7 +588,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
}
]
}

View File

@ -260,11 +260,11 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/generators",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
}
]
}

View File

@ -1684,27 +1684,27 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/aggregator",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
}
]
}

View File

@ -492,7 +492,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
}
]
}

View File

@ -1648,23 +1648,23 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
}
]
}

View File

@ -1076,7 +1076,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
}
]
}

View File

@ -58,7 +58,7 @@ func BuildOpenAPIDefinitionsForResource(model interface{}, config *common.Config
o := newOpenAPI(config)
// We can discard the return value of toSchema because all we care about is the side effect of calling it.
// All the models created for this resource get added to o.swagger.Definitions
_, err := o.toSchema(model)
_, err := o.toSchema(getCanonicalTypeName(model))
if err != nil {
return nil, err
}
@ -69,6 +69,21 @@ func BuildOpenAPIDefinitionsForResource(model interface{}, config *common.Config
return &swagger.Definitions, nil
}
// BuildOpenAPIDefinitionsForResources returns the OpenAPI spec which includes the definitions for the
// passed type names.
func BuildOpenAPIDefinitionsForResources(config *common.Config, names ...string) (*spec.Swagger, error) {
o := newOpenAPI(config)
// We can discard the return value of toSchema because all we care about is the side effect of calling it.
// All the models created for this resource get added to o.swagger.Definitions
for _, name := range names {
_, err := o.toSchema(name)
if err != nil {
return nil, err
}
}
return o.finalizeSwagger()
}
// newOpenAPI sets up the openAPI object so we can build the spec.
func newOpenAPI(config *common.Config) openAPI {
o := openAPI{
@ -120,7 +135,11 @@ func (o *openAPI) finalizeSwagger() (*spec.Swagger, error) {
return o.swagger, nil
}
func getCanonicalizeTypeName(t reflect.Type) string {
func getCanonicalTypeName(model interface{}) string {
t := reflect.TypeOf(model)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.PkgPath() == "" {
return t.Name()
}
@ -165,12 +184,7 @@ func (o *openAPI) buildDefinitionRecursively(name string) error {
// buildDefinitionForType build a definition for a given type and return a referable name to its definition.
// This is the main function that keep track of definitions used in this spec and is depend on code generated
// by k8s.io/kubernetes/cmd/libs/go2idl/openapi-gen.
func (o *openAPI) buildDefinitionForType(sample interface{}) (string, error) {
t := reflect.TypeOf(sample)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
name := getCanonicalizeTypeName(t)
func (o *openAPI) buildDefinitionForType(name string) (string, error) {
if err := o.buildDefinitionRecursively(name); err != nil {
return "", err
}
@ -321,7 +335,7 @@ func (o *openAPI) buildOperations(route restful.Route, inPathCommonParamsMap map
}
func (o *openAPI) buildResponse(model interface{}, description string) (spec.Response, error) {
schema, err := o.toSchema(model)
schema, err := o.toSchema(getCanonicalTypeName(model))
if err != nil {
return spec.Response{}, err
}
@ -366,8 +380,8 @@ func (o *openAPI) findCommonParameters(routes []restful.Route) (map[interface{}]
return commonParamsMap, nil
}
func (o *openAPI) toSchema(model interface{}) (_ *spec.Schema, err error) {
if openAPIType, openAPIFormat := common.GetOpenAPITypeFormat(getCanonicalizeTypeName(reflect.TypeOf(model))); openAPIType != "" {
func (o *openAPI) toSchema(name string) (_ *spec.Schema, err error) {
if openAPIType, openAPIFormat := common.GetOpenAPITypeFormat(name); openAPIType != "" {
return &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{openAPIType},
@ -375,7 +389,7 @@ func (o *openAPI) toSchema(model interface{}) (_ *spec.Schema, err error) {
},
}, nil
} else {
ref, err := o.buildDefinitionForType(model)
ref, err := o.buildDefinitionForType(name)
if err != nil {
return nil, err
}
@ -399,7 +413,7 @@ func (o *openAPI) buildParameter(restParam restful.ParameterData, bodySample int
case restful.BodyParameterKind:
if bodySample != nil {
ret.In = "body"
ret.Schema, err = o.toSchema(bodySample)
ret.Schema, err = o.toSchema(getCanonicalTypeName(bodySample))
return ret, err
} else {
// There is not enough information in the body parameter to build the definition.

View File

@ -383,8 +383,9 @@ func (g openAPITypeWriter) generate(t *types.Type) error {
if hasOpenAPIDefinitionMethods(t) {
g.Do("return $.OpenAPIDefinition|raw${\n"+
"Schema: spec.Schema{\n"+
"SchemaProps: spec.SchemaProps{\n"+
"Type:$.type|raw${}.OpenAPISchemaType(),\n"+
"SchemaProps: spec.SchemaProps{\n", args)
g.generateDescription(t.CommentLines)
g.Do("Type:$.type|raw${}.OpenAPISchemaType(),\n"+
"Format:$.type|raw${}.OpenAPISchemaFormat(),\n"+
"},\n"+
"},\n"+