Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions kube-core/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,11 +403,13 @@ impl Transform for OptionalEnum {
return;
};

if first.contains_key("enum")
&& !first.contains_key("nullable")
// Check if this is an Option<T> pattern:
// anyOf with two elements where second is { "enum": [null], "nullable": true }
if !first.contains_key("nullable")
&& second.get("enum") == Some(&json!([null]))
&& second.get("nullable") == Some(&json!(true))
{
// Remove anyOf and hoist first element's properties to root
obj.remove("anyOf");
obj.append(&mut first.clone());
obj.insert("nullable".to_string(), Value::Bool(true));
Expand Down
93 changes: 93 additions & 0 deletions kube-derive/tests/crd_complex_enum_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ struct ComplexEnumTestSpec {
foo: ComplexEnum,
}

#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[kube(group = "clux.dev", version = "v1", kind = "OptionalComplexEnumTest")]
struct OptionalComplexEnumTestSpec {
/// Optional complex enum field
foo: Option<ComplexEnum>,
}

#[test]
fn complex_enum() {
assert_json_eq!(
Expand Down Expand Up @@ -384,3 +391,89 @@ fn normal_enum_without_descriptions() {
)
);
}

#[test]
fn optional_complex_enum() {
assert_json_eq!(
OptionalComplexEnumTest::crd(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessary now, but i think if we did

-        OptionalComplexEnumTest::crd(),
+        OptionalComplexEnumTest::crd().spec.versions?[0].schema?.open_api_v3_schema?,

on the left hand side of the assert in the future, these tests would be a lot shorter, less indented, and more focused on the actual statement we want to test

json!({
"apiVersion": "apiextensions.k8s.io/v1",
"kind": "CustomResourceDefinition",
"metadata": {
"name": "optionalcomplexenumtests.clux.dev"
},
"spec": {
"group": "clux.dev",
"names": {
"categories": [],
"kind": "OptionalComplexEnumTest",
"plural": "optionalcomplexenumtests",
"shortNames": [],
"singular": "optionalcomplexenumtest"
},
"scope": "Cluster",
"versions": [{
"additionalPrinterColumns": [],
"name": "v1",
"schema": {
"openAPIV3Schema": {
"description": "Auto-generated derived type for OptionalComplexEnumTestSpec via `CustomResource`",
"properties": {
"spec": {
"properties": {
"foo": {
"description": "Optional complex enum field",
"nullable": true,
Comment thread
clux marked this conversation as resolved.
"oneOf": [
{
"required": ["Normal"]
},
{
"required": ["Hardcore"]
}
],
"properties": {
"Hardcore": {
"description": "Documentation on the Hardcore variant",
"properties": {
"core": {
"description": "A very simple enum with unit variants",
"enum": ["C", "D", "A", "B"],
"type": "string"
},
"hard": {
"type": "string"
},
"without_description": {
"enum": ["A", "B", "C", "D"],
"type": "string"
}
},
"required": ["core", "hard", "without_description"],
"type": "object"
},
"Normal": {
"description": "Override documentation on the Normal variant",
"enum": ["C", "D", "A", "B"],
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
}
},
"required": ["spec"],
"title": "OptionalComplexEnumTest",
"type": "object"
}
},
"served": true,
"storage": true,
"subresources": {}
}]
}
})
);
}