-
-
Notifications
You must be signed in to change notification settings - Fork 314
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
test out enum variants in jsonschemas #398
Conversation
Tried a few variants on turning #[serde(tag = "type", content = "value")]
enum VariantType {
VaraintA(u32),
VariantB(String),
} but same error :/ |
I'll have to pull this branch and start digging into the individual error statements. Overall, I was originally thinking that going down the path of using OpenAPI Discriminators would be the best option, alas k8s does not yet support that approach. As such, it would seem that we will need to stick with generating the full schema inline. This mostly seems to be an issue with how we are generating the Hopefully some of that info is useful. |
We don't support generating structural schema yet. Go frameworks doesn't either as far as I know. A workaround is to use We should first find some examples of non-structural to structural transformations and see if it's something we can support, or at least document how to do it. I wish Kubernetes had documentation about this transformation. |
I write a workaround for this: use schemars::{
schema::{Schema, SchemaObject},
visit::{visit_schema_object, Visitor},
JsonSchema,
};
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
#[serde(tag = "runtime")]
pub enum Runtime {
Deno(DenoManifest),
Python(PythonManifest),
}
fn to_k8s(gen: &mut schemars::gen::SchemaGenerator) -> Schema {
const TAG: &str = "runtime"; // keep sync with #[serde(tag = "")]
fn as_ref<'a>(s: &'a Schema) -> &'a SchemaObject {
match s {
Schema::Object(o) => o,
Schema::Bool(_) => unreachable!(),
}
}
fn as_mut<'a>(s: &'a mut Schema) -> &'a mut SchemaObject {
match s {
Schema::Object(o) => o,
Schema::Bool(_) => unreachable!(),
}
}
pub struct K8sStructualPurge;
impl Visitor for K8sStructualPurge {
fn visit_schema_object(&mut self, schema: &mut SchemaObject) {
let meta = schema.metadata();
meta.description = None;
meta.default = None;
schema.instance_type = None;
schema.object().additional_properties = None;
if schema.extensions.contains_key("nullable") {
schema.extensions.remove("nullable");
}
visit_schema_object(self, schema);
}
}
let mut runtime = gen.subschema_for::<Runtime>().into_object();
let sub = runtime.subschemas();
let subschemas = &mut sub.any_of.as_mut().unwrap();
let mut root = subschemas[0].clone();
let mut tags = Vec::new();
for s in subschemas.iter_mut() {
// FIXME: This is unpublic api
root = root.flatten(s.clone());
{
let props = &mut as_mut(s).object().properties;
let enums = &as_ref(&props[TAG]).enum_values.as_ref().unwrap();
assert_eq!(enums.len(), 1);
tags.push(enums[0].clone());
}
let mut visitor = K8sStructualPurge;
visitor.visit_schema_object(as_mut(s));
}
assert!(runtime.object.is_none());
let mut object_validation = root.into_object().object.unwrap();
let tag = object_validation.properties.get_mut(TAG).unwrap();
let enums = as_mut(tag).enum_values.as_mut().unwrap();
*enums = tags;
object_validation.as_mut().required = schemars::Set::new();
runtime.object = Some(object_validation);
runtime.instance_type = Some(schemars::schema::SingleOrVec::Single(Box::new(
schemars::schema::InstanceType::Object,
)));
runtime.into()
} |
Fixed by #779 |
Indeed correct what is said in #129 (comment)
By default, enum variants is not well-received by kubernetes api, as they are not structural: