Skip to content

Commit

Permalink
allow not implementing the crd method - for #355
Browse files Browse the repository at this point in the history
for people wishing to minise their dependencies, add a skip_crd kube
attr.
  • Loading branch information
clux committed Dec 24, 2020
1 parent 71d570d commit ecacff7
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 26 deletions.
1 change: 1 addition & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ 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"
static_assertions = "1.1.0"

[[example]]
name = "configmapgen_controller"
Expand Down
20 changes: 20 additions & 0 deletions examples/crd_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use k8s_openapi::Resource;
use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[macro_use] extern crate static_assertions;

/// Our spec for Foo
///
Expand Down Expand Up @@ -137,6 +138,7 @@ fn verify_resource() {
assert_eq!(Foo::GROUP, "clux.dev");
assert_eq!(Foo::VERSION, "v1");
assert_eq!(Foo::API_VERSION, "clux.dev/v1");
assert_impl_all!(Foo: k8s_openapi::Resource, k8s_openapi::Metadata, Default);
}

#[test]
Expand All @@ -151,3 +153,21 @@ spec:
name: """#;
assert_eq!(exp, ser);
}

/// CustomResource without ::crd generated (skip_crd)
#[derive(CustomResource, Serialize, Deserialize, Debug, Clone)]
#[kube(group = "clux.dev", version = "v1", kind = "Bar", namespaced)]
#[kube(skip_crd)]
pub struct MyBar {
bars: u32,
}

// Verify CustomResource derivable with skip_crd
#[test]
fn verify_bar_is_a_custom_resource() {
println!("Kind {}", Bar::KIND);
let bar = Bar::new("five", MyBar { bars: 5 });
println!("Spec: {:?}", bar.spec);
assert_impl_all!(Bar: k8s_openapi::Resource, k8s_openapi::Metadata);
// TODO: not asserting crd trait (if we make it a trait)
}
63 changes: 37 additions & 26 deletions kube-derive/src/custom_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct KubeAttrs {
kind_struct: String,
/// lowercase plural of kind (inferred if omitted)
plural: Option<String>,
skip_crdgen: bool,
namespaced: bool,
apiextensions: String,
derives: Vec<String>,
Expand Down Expand Up @@ -163,6 +164,9 @@ impl CustomDerive for CustomResource {
if path.is_ident("namespaced") {
ka.namespaced = true;
continue;
} else if path.is_ident("skip_crd") {
ka.skip_crdgen = true;
continue;
} else {
&meta
}
Expand Down Expand Up @@ -216,6 +220,7 @@ impl CustomDerive for CustomResource {
kind_struct,
version,
namespaced,
skip_crdgen,
derives,
status,
plural,
Expand Down Expand Up @@ -264,7 +269,7 @@ impl CustomDerive for CustomResource {

// Schema generation is always enabled for v1 because it's mandatory.
// TODO Enable schema generation for v1beta1 if the spec derives `JsonSchema`.
let schema_gen_enabled = apiextensions == "v1";
let schema_gen_enabled = apiextensions == "v1" && !skip_crdgen;
// We exclude fields `apiVersion`, `kind`, and `metadata` from our schema because
// these are validated by the API server implicitly. Also, we can't generate the
// schema for `metadata` (`ObjectMeta`) because it doesn't implement `JsonSchema`.
Expand Down Expand Up @@ -372,7 +377,9 @@ impl CustomDerive for CustomResource {
let short_json = serde_json::to_string(&shortnames).unwrap();
let crd_meta_name = format!("{}.{}", plural, group);
let crd_meta = quote! { { "name": #crd_meta_name } };
let jsondata = if apiextensions == "v1" {
let jsondata = if skip_crdgen {
quote! {}
} else if apiextensions == "v1" {
quote! {
// Don't use definitions and don't include `$schema` because these are not allowed.
let gen = schemars::gen::SchemaSettings::openapi3().with(|s| {
Expand Down Expand Up @@ -432,32 +439,36 @@ impl CustomDerive for CustomResource {
};

// TODO: should ::crd be from a trait?
let impl_crd = quote! {
impl #rootident {
pub fn crd() -> #apiext::CustomResourceDefinition {
let columns : Vec<#apiext::CustomResourceColumnDefinition> = serde_json::from_str(#printers).expect("valid printer column json");
let scale: Option<#apiext::CustomResourceSubresourceScale> = if #scale_code.is_empty() {
None
} else {
serde_json::from_str(#scale_code).expect("valid scale subresource json")
};
let shorts : Vec<String> = serde_json::from_str(#short_json).expect("valid shortnames");
let subres = if #has_status {
if let Some(s) = &scale {
serde_json::json!({
"status": {},
"scale": scale
})
let impl_crd = if skip_crdgen {
quote! {}
} else {
quote! {
impl #rootident {
pub fn crd() -> #apiext::CustomResourceDefinition {
let columns : Vec<#apiext::CustomResourceColumnDefinition> = serde_json::from_str(#printers).expect("valid printer column json");
let scale: Option<#apiext::CustomResourceSubresourceScale> = if #scale_code.is_empty() {
None
} else {
serde_json::json!({"status": {} })
}
} else {
serde_json::json!({})
};
serde_json::from_str(#scale_code).expect("valid scale subresource json")
};
let shorts : Vec<String> = serde_json::from_str(#short_json).expect("valid shortnames");
let subres = if #has_status {
if let Some(s) = &scale {
serde_json::json!({
"status": {},
"scale": scale
})
} else {
serde_json::json!({"status": {} })
}
} else {
serde_json::json!({})
};

#jsondata
serde_json::from_value(jsondata)
.expect("valid custom resource from #[kube(attrs..)]")
#jsondata
serde_json::from_value(jsondata)
.expect("valid custom resource from #[kube(attrs..)]")
}
}
}
};
Expand Down
3 changes: 3 additions & 0 deletions kube-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ use custom_resource::CustomResource;
///
/// **NOTE**: Support for `v1` requires deriving the openapi v3 `JsonSchema` via the `schemars` dependency.
///
/// ### `#[kube(skip_crd)]`
/// To indicate that the generated `::crd()` method is not required. Allow eliding the `schemars` dependency.
///
/// ### `#[kube(namespaced)]`
/// To specify that this is a namespaced resource rather than cluster level.
///
Expand Down

0 comments on commit ecacff7

Please sign in to comment.