Skip to content
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

Generating CRD for Internally tagged enums fails #1279

Open
kevroletin opened this issue Aug 16, 2023 · 2 comments
Open

Generating CRD for Internally tagged enums fails #1279

kevroletin opened this issue Aug 16, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@kevroletin
Copy link

Current and expected behavior

A structure below has Internally tagged enum representation (which is enabled by #[serde(tag="tag")])).

#[serde(tag="tag")]
pub enum TaggedUnion {
    Left {
        left_value: String
    },
    Right {
        right_value: String
    }
}

Calling TestObject::crd() causes an error like:

Property "tag" has the schema ... enum_values: Some([String("Right")]) ... but was already defined as ... enum_values: Some([String("Left")]) ... in another subschema. The schemas for a property used in multiple subschemas must be identical'...

The whole error message:

thread 'main' panicked at 'Property "tag" has the schema Object(SchemaObject { metadata: None, instance_type: Some(Single(String)), format: None, enum_values: Some([String("Right")]), const_value: None, subschemas: None, number: None, string: None, array: None, object: None, reference: None, extensions: {} }) but was already defined as Object(SchemaObject { metadata: None, instance_type: Some(Single(String)), format: None, enum_values: Some([String("Left")]), const_value: None, subschemas: None, number: None, string: None, array: None, object: None, reference: None, extensions: {} }) in another subschema. The schemas for a property used in multiple subschemas must be identical'...

The test case is here https://github.com/kevroletin/kube.rs-tagged-union-test

Possible solution

No response

Additional context

This is an example of Internally tagged representation:

{
  "tag": "Left",
  "left_value": "123"
}

This is an example of Externally tagged representation. This is default and generating crd for that representations works:

{
  "Left": {
    "left_value": "123"
  }
}

It seems that the problem is related to Schema postprocesing done by kube.rs

Environment

Client Version: v1.24.3
Kustomize Version: v4.5.4
Server Version: v1.23.17-eks-2d98532

Configuration and features

[dependencies]
k8s-openapi = { version = "0.19.0", features = ["v1_25", "schemars"] }
kube = { version = "0.85.0", features = ["runtime", "client", "derive"] }
kube-derive = "0.85.0"
schemars = "0.8.12"
serde = { version = "1.0.183", features = ["derive"] }
serde_json = "1.0.105"
serde_yaml = "0.9.25"

Affected crates

kube-derive

Would you like to work on fixing this bug?

None

@kevroletin kevroletin added the bug Something isn't working label Aug 16, 2023
@kevroletin
Copy link
Author

Specifying a structural schema section of k8s docs says:

for each field in an object and each item in an array which is specified within any of allOf, anyOf, oneOf or not, the schema also specifies the field/item outside of those logical junctors (compare example 1 and 2).

If I understood it correctly, then internally tagged representation of rust enums in k8s crds is not possible.

I also saw KEP-1027: Union types not sure if it's relevant here.

@clux
Copy link
Member

clux commented Aug 16, 2023

Yeah, unfortunately this is an expected failure. We have some enum requirements in the docs for the CustomResource derive. If you know what you are doing you might be able to override certain problematic parts of the schema - but do not know how practical that is for most people / most use-cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants