Skip to content

Autogenerated OpenAPI schema classes don't work as expected #417

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
macsux opened this issue Apr 16, 2020 · 5 comments
Closed

Autogenerated OpenAPI schema classes don't work as expected #417

macsux opened this issue Apr 16, 2020 · 5 comments

Comments

@macsux
Copy link
Contributor

macsux commented Apr 16, 2020

CustomResourceDefinition includes support for specifying OpenAPI schema. The generated classes that define the model for OpenAPI seem to be having issues with some types of common schema semantics. Here's an OpenAPI schema as generated by NJsonSchema

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "MyCustomResource",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "spec": {
      "x-nullable": true,
      "oneOf": [
        {
          "$ref": "#/definitions/MyCustomResourceSpec"
        }
      ]
    },
    "status": {
      "x-nullable": true,
      "oneOf": [
        {
          "$ref": "#/definitions/MyCustomResourceStatus"
        }
      ]
    }
  },
  "definitions": {
    "MyCustomResourceSpec": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "type": "string",
          "x-nullable": true
        },
        "item": {
          "type": "string",
          "x-nullable": true
        },
        "Replicas": {
          "type": "integer",
          "format": "int32"
        }
      }
    },
    "MyCustomResourceStatus": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "Replicas": {
          "type": "integer",
          "format": "int32"
        }
      }
    }
  }
}

When we try to deserialize this into V1beta1JSONSchemaProps ex.JsonConvert.DeserializeObject<V1beta1JSONSchemaProps>(schema.ToJson()), it generates a single item in Properties["spec"].OneOf with null value. This is incorrect and should have resulted in value being another V1beta1JSONSchemaProps with RefProperty set to what we see as part of the $ref in the schema.

This is currently acting as a bottleneck for a PR I was getting ready to submit that allows generating and installing CRDs, but I suspect will cause the same issue when trying to read CustomResourceDefinition from API server as it will fail correct deserialization (and can potentially corrupt the CRD if used to modify its structure).

@brendandburns
Copy link
Contributor

Take a look at the spec here:
https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json

I think the issue is that v1beta1.JSONSchemaProps is JSONSchema, not OpenAPI.

v1.JSONSchemaProps is OpenAPI v3

There's a big discussion here:
kubernetes/kubernetes#49879

So I think you need to use the v1JSONSchemaProps object:
https://github.com/kubernetes-client/csharp/blob/master/src/KubernetesClient/generated/Models/V1JSONSchemaProps.cs

and I think it will work.

@macsux
Copy link
Contributor Author

macsux commented Apr 16, 2020

But you can't really use a different version - the type is hardcoded as part of the object tree. It appears as part of V1beta1CustomResourceDefinition in Spec.Validation.OpenAPIV3Schema and Spec.Versions.Schema.OpenAPIV3Schema. This bug essentially makes it impossible to do CRDs for v1beta1 k8s using the using models.

@macsux
Copy link
Contributor Author

macsux commented Apr 16, 2020

We could probably fix this up by changing the type of the two places mentioned above to the V1 type. This can be done as part of the c# second phase gen project

@macsux
Copy link
Contributor Author

macsux commented Apr 17, 2020

I checked the newer type (V1) and it has the same issue. I propose the following:

  1. Replace autogenerated type with JsonSchema from NJsonSchema package (it's already referenced as part of CustomResources PR)
  2. Attach a custom converter to properly serialize/deserialize JsonSchema as the property of the object tree

@macsux
Copy link
Contributor Author

macsux commented Apr 17, 2020

Ok, I got the bottom of this whole thing. Kubernetes does not support $ref as normal JsonSchema or OpenAPI do. See ongoing issue kubernetes/kubernetes#54579
Therefore any schemas being created/generated need to be massaged to inline schemas (which does work with the autogenerated classes).

@macsux macsux closed this as completed Apr 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants