Skip to content

Commit 01ec3c7

Browse files
committed
fix: hack to flatten broken Option<Enum> schema
This is a temporary workaround for an issue in kube 2.x: #1821 Signed-off-by: Shane Utt <shaneutt@linux.com>
1 parent 7c63f56 commit 01ec3c7

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

kube-core/src/schema.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,15 @@ impl Transform for StructuralSchemaRewriter {
273273
// Untagged enums are serialized using `any_of`
274274
hoist_subschema_properties(any_of, &mut schema.object, &mut schema.instance_type);
275275
}
276+
277+
// FIXME: hack for https://github.com/kube-rs/kube/issues/1821
278+
if let Some(any_of) = &mut subschemas.any_of {
279+
if let Some(new_schema) = optional_enum_flatten_hack(any_of) {
280+
let metadata = schema.metadata;
281+
schema = new_schema.clone();
282+
schema.metadata = metadata;
283+
}
284+
}
276285
}
277286

278287
// check for maps without with properties (i.e. flattened maps)
@@ -424,3 +433,69 @@ fn merge_metadata(
424433
}
425434
}
426435
}
436+
437+
/// In kube 2.x the schema output behavior for `Option<Enum>` types changed.
438+
///
439+
/// Previously given an enum like:
440+
///
441+
/// ```rust
442+
/// enum LogLevel {
443+
/// Debug,
444+
/// Info,
445+
/// Error,
446+
/// }
447+
/// ```
448+
///
449+
/// The following would be generated for Optional<LogLevel>:
450+
///
451+
/// ```json
452+
/// { "enum": ["Debug", "Info", "Error"], "type": "string", "nullable": true }
453+
/// ```
454+
///
455+
/// Now, schemars generates `anyOf` for `Option<LogLevel>` like:
456+
///
457+
/// ```json
458+
/// {
459+
/// "anyOf": [
460+
/// { "enum": ["Debug", "Info", "Error"], "type": "string" },
461+
/// { "enum": [null], "nullable": true }
462+
/// ]
463+
/// }
464+
/// ```
465+
///
466+
/// This is breaking, as Kubernetes validation will reject this structure. This
467+
/// issue was reported in:
468+
///
469+
/// https://github.com/kube-rs/kube/issues/1821
470+
///
471+
/// This hack does a precise check for this "empty" second enum that would
472+
/// break validation, and removes it, flattening the schema object.
473+
///
474+
/// FIXME: This should be removed once the problem is properly resolved.
475+
fn optional_enum_flatten_hack(any_of: &mut Vec<Schema>) -> Option<&SchemaObject> {
476+
if let [
477+
Schema::Object(obj),
478+
Schema::Object(SchemaObject {
479+
enum_values: Some(null_enum),
480+
metadata: None,
481+
instance_type: None,
482+
format: None,
483+
subschemas: None,
484+
array: None,
485+
object: None,
486+
extensions,
487+
other: Value::Object(other),
488+
}),
489+
] = any_of.as_mut_slice()
490+
&& null_enum.as_slice() == [Value::Null]
491+
&& extensions.len() == 1
492+
&& extensions.get("nullable") == Some(&Value::Bool(true))
493+
&& other.len() == 1
494+
&& other.get("nullable") == Some(&Value::Bool(true))
495+
{
496+
obj.extensions.insert("nullable".into(), Value::Bool(true));
497+
return Some(obj);
498+
}
499+
500+
None
501+
}

0 commit comments

Comments
 (0)