Skip to content
/ kube-rs Public
forked from kube-rs/kube

Commit

Permalink
Generate schema for CRD v1
Browse files Browse the repository at this point in the history
Schema is generated with `schemars`.

Also fixed the location of `subresources` and `additionalPrinterColumns`.

See kube-rs#264
  • Loading branch information
kazk committed Dec 19, 2020
1 parent 08859fc commit 39d814a
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 19 deletions.
1 change: 1 addition & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ snafu = { version = "0.6.8", features = ["futures"] }
either = "1.6.0"
# Some configuration tweaking require reqwest atm
reqwest = { version = "0.10.8", default-features = false, features = ["json", "gzip", "stream"] }
schemars = "0.8.0"

[[example]]
name = "configmapgen_controller"
Expand Down
61 changes: 44 additions & 17 deletions examples/crd_derive.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use k8s_openapi::Resource;
use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// Our spec for Foo
///
/// A struct with our chosen Kind will be created for us, using the following kube attrs
#[derive(CustomResource, Serialize, Deserialize, Default, Debug, PartialEq, Clone)]
#[derive(CustomResource, Serialize, Deserialize, Default, Debug, PartialEq, Clone, JsonSchema)]
#[kube(
group = "clux.dev",
version = "v1",
Expand All @@ -18,7 +19,7 @@ use serde::{Deserialize, Serialize};
scale = r#"{"specReplicasPath":".spec.replicas", "statusReplicasPath":".status.replicas"}"#,
printcolumn = r#"{"name":"Spec", "type":"string", "description":"name of foo", "jsonPath":".spec.name"}"#
)]
#[kube(apiextensions = "v1beta1")] // kubernetes <= 1.16
#[kube(apiextensions = "v1")]
pub struct MyFoo {
name: String,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -49,7 +50,7 @@ fn verify_crd() {
use serde_json::{self, json};
let crd = Foo::crd();
let output = json!({
"apiVersion": "apiextensions.k8s.io/v1beta1",
"apiVersion": "apiextensions.k8s.io/v1",
"kind": "CustomResourceDefinition",
"metadata": {
"name": "foos.clux.dev"
Expand All @@ -62,26 +63,52 @@ fn verify_crd() {
"shortNames": ["f"],
"singular": "foo"
},
"additionalPrinterColumns": [
{
"description": "name of foo",
"JSONPath": ".spec.name",
"name": "Spec",
"type": "string"
}
],
"scope": "Namespaced",
"versions": [
{
"name": "v1",
"served": true,
"storage": true
"storage": true,
"additionalPrinterColumns": [
{
"description": "name of foo",
"jsonPath": ".spec.name",
"name": "Spec",
"type": "string"
}
],
"schema": {
"openAPIV3Schema": {
"properties": {
"spec": {
"description": "Our spec for Foo\n\nA struct with our chosen Kind will be created for us, using the following kube attrs",
"properties": {
"info": {
"nullable": true,
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"name"
],
"type": "object"
}
},
"type": "object"
}
},
"subresources": {
"scale": {
"specReplicasPath": ".spec.replicas",
"statusReplicasPath": ".status.replicas"
},
"status": {}
},
}
],
"subresources": {
"scale": {"specReplicasPath":".spec.replicas", "statusReplicasPath":".status.replicas"},
"status": {}
}
]
}
});
let outputcrd = serde_json::from_value(output).expect("expected output is valid");
Expand Down
27 changes: 25 additions & 2 deletions kube-derive/src/custom_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,18 @@ impl CustomDerive for CustomResource {
// => No default impl
let rootident = Ident::new(&kind_struct, Span::call_site());

let schemars_skip = if apiextensions == "v1" {
quote! { #[schemars(skip)] }
} else {
quote! {}
};

// if status set, also add that
let (statusq, statusdef) = if let Some(status_name) = &status {
let ident = format_ident!("{}", status_name);
// TODO Generate schema for status. Requires the struct to have JsonSchema.
let fst = quote! {
#schemars_skip
#[serde(skip_serializing_if = "Option::is_none")]
#visibility status: Option<#ident>,
};
Expand All @@ -261,6 +269,9 @@ impl CustomDerive for CustomResource {
derive_paths.push(syn::parse_str(d)?);
}
}
if apiextensions == "v1" {
derive_paths.push(syn::parse_str("::schemars::JsonSchema")?);
}

let docstr = format!(" Auto-generated derived type for {} via `CustomResource`", ident);
let root_obj = quote! {
Expand All @@ -270,6 +281,7 @@ impl CustomDerive for CustomResource {
#visibility struct #rootident {
#visibility api_version: String,
#visibility kind: String,
#schemars_skip
#visibility metadata: k8s_openapi::apimachinery::pkg::apis::meta::v1::ObjectMeta,
#visibility spec: #ident,
#statusq
Expand Down Expand Up @@ -401,6 +413,9 @@ impl CustomDerive for CustomResource {
}
})
} else {
let gen = schemars::gen::SchemaSettings::openapi3().into_generator();
let schema = gen.into_root_schema_for::<Self>();
let spec_schema = &schema.definitions.get(stringify!(#ident)).unwrap();
serde_json::json!({
"metadata": #crd_meta,
"spec": {
Expand All @@ -416,9 +431,17 @@ impl CustomDerive for CustomResource {
"name": #version,
"served": true,
"storage": true,
"schema": {
"openAPIV3Schema": {
"type": "object",
"properties": {
"spec": spec_schema,
}
}
},
"additionalPrinterColumns": columns,
"subresources": subres,
}],
"additionalPrinterColumns": columns,
"subresources": subres,
}
})
};
Expand Down

0 comments on commit 39d814a

Please sign in to comment.