Skip to content

Commit

Permalink
Rename to CELSchema, simplify derive addition in kube macro
Browse files Browse the repository at this point in the history
Signed-off-by: Danil-Grigorev <danil.grigorev@suse.com>
  • Loading branch information
Danil-Grigorev committed Dec 18, 2024
1 parent 299ace1 commit 529e22b
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 33 deletions.
6 changes: 3 additions & 3 deletions examples/crd_derive_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use kube::{
WatchEvent, WatchParams,
},
runtime::wait::{await_condition, conditions},
Client, CustomResource, CustomResourceExt, ValidateSchema,
Client, CustomResource, CustomResourceExt, CELSchema,
};
use serde::{Deserialize, Serialize};

Expand All @@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize};
// - https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#defaulting
// - https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#defaulting-and-nullable

#[derive(CustomResource, ValidateSchema, Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
#[derive(CustomResource, CELSchema, Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
#[kube(
group = "clux.dev",
version = "v1",
Expand Down Expand Up @@ -100,7 +100,7 @@ pub struct FooSpec {
foo_sub_spec: Option<FooSubSpec>,
}

#[derive(ValidateSchema, Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
#[derive(CELSchema, Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
pub struct FooSubSpec {
#[cel_validate(rule = "self != 'not legal'".into())]
field: String,
Expand Down
33 changes: 9 additions & 24 deletions kube-derive/src/custom_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ enum SchemaMode {
Disabled,
Manual,
Derived,
Validated,
}

impl SchemaMode {
Expand All @@ -170,16 +169,6 @@ impl SchemaMode {
SchemaMode::Disabled => false,
SchemaMode::Manual => false,
SchemaMode::Derived => true,
SchemaMode::Validated => true,
}
}

fn validated(self) -> bool {
match self {
SchemaMode::Disabled => false,
SchemaMode::Manual => false,
SchemaMode::Derived => false,
SchemaMode::Validated => true,
}
}

Expand All @@ -188,7 +177,6 @@ impl SchemaMode {
SchemaMode::Disabled => false,
SchemaMode::Manual => true,
SchemaMode::Derived => true,
SchemaMode::Validated => true,
}
}
}
Expand Down Expand Up @@ -320,16 +308,13 @@ pub(crate) fn derive(input: proc_macro2::TokenStream) -> proc_macro2::TokenStrea
}

// Enable schema generation by default as in v1 it is mandatory.
let schema_mode = schema_mode.unwrap_or(match rules.is_empty() {
true => SchemaMode::Derived,
false => SchemaMode::Validated,
});
let schema_mode = schema_mode.unwrap_or(SchemaMode::Derived);
// 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`.
let schemars_skip = schema_mode.derive().then_some(quote! { #[schemars(skip)] });
if schema_mode.validated() {
derive_paths.push(syn::parse_quote! { #kube::ValidateSchema });
if schema_mode.derive() && !rules.is_empty() {
derive_paths.push(syn::parse_quote! { #kube::CELSchema });
} else if schema_mode.derive() {
derive_paths.push(syn::parse_quote! { #schemars::JsonSchema });
}
Expand Down Expand Up @@ -666,7 +651,7 @@ struct Rule {

#[derive(FromDeriveInput)]
#[darling(attributes(cel_validate), supports(struct_named))]
struct ValidateSchema {
struct CELSchema {
#[darling(default)]
crates: Crates,
ident: Ident,
Expand All @@ -680,7 +665,7 @@ pub(crate) fn derive_validated_schema(input: TokenStream) -> TokenStream {
Ok(di) => di,
};

let ValidateSchema {
let CELSchema {
crates:
Crates {
kube_core,
Expand All @@ -690,7 +675,7 @@ pub(crate) fn derive_validated_schema(input: TokenStream) -> TokenStream {
},
ident,
rules,
} = match ValidateSchema::from_derive_input(&ast) {
} = match CELSchema::from_derive_input(&ast) {
Err(err) => return err.write_errors(),
Ok(attrs) => attrs,
};
Expand Down Expand Up @@ -916,7 +901,7 @@ mod tests {
#[test]
fn test_derive_validated() {
let input = quote! {
#[derive(CustomResource, ValidateSchema, Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(CustomResource, CELSchema, Serialize, Deserialize, Debug, PartialEq, Clone)]
#[kube(group = "clux.dev", version = "v1", kind = "Foo", namespaced)]
#[cel_validate(rule = "self != ''".into())]
struct FooSpec {
Expand All @@ -925,14 +910,14 @@ mod tests {
}
};
let input = syn::parse2(input).unwrap();
let v = ValidateSchema::from_derive_input(&input).unwrap();
let v = CELSchema::from_derive_input(&input).unwrap();
assert_eq!(v.rules.len(), 1);
}

#[test]
fn test_derive_validated_full() {
let input = quote! {
#[derive(ValidateSchema)]
#[derive(CELSchema)]
#[cel_validate(rule = "true".into())]
struct FooSpec {
#[cel_validate(rule = "true".into())]
Expand Down
6 changes: 3 additions & 3 deletions kube-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,13 @@ pub fn derive_custom_resource(input: proc_macro::TokenStream) -> proc_macro::Tok
/// Generates a JsonSchema implementation a set of CEL validation rules applied on the CRD.
///
/// ```rust
/// use kube::ValidateSchema;
/// use kube::CELSchema;
/// use kube::CustomResource;
/// use serde::Deserialize;
/// use serde::Serialize;
/// use kube::core::crd::CustomResourceExt;
///
/// #[derive(CustomResource, ValidateSchema, Serialize, Deserialize, Clone, Debug)]
/// #[derive(CustomResource, CELSchema, Serialize, Deserialize, Clone, Debug)]
/// #[kube(
/// group = "kube.rs",
/// version = "v1",
Expand All @@ -361,7 +361,7 @@ pub fn derive_custom_resource(input: proc_macro::TokenStream) -> proc_macro::Tok
/// assert!(serde_json::to_string(&Struct::crd()).unwrap().contains(r#""default":"value""#));
/// assert!(serde_json::to_string(&Struct::crd()).unwrap().contains(r#""rule":"self.matadata.name == 'singleton'""#));
/// ```
#[proc_macro_derive(ValidateSchema, attributes(cel_validate, schemars))]
#[proc_macro_derive(CELSchema, attributes(cel_validate, schemars))]
pub fn derive_schema_validation(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
custom_resource::derive_validated_schema(input.into()).into()
}
Expand Down
4 changes: 2 additions & 2 deletions kube-derive/tests/crd_schema_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

use assert_json_diff::assert_json_eq;
use chrono::{DateTime, Utc};
use kube::ValidateSchema;
use kube::CELSchema;
use kube_derive::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};

// See `crd_derive_schema` example for how the schema generated from this struct affects defaulting and validation.
#[derive(CustomResource, Serialize, Deserialize, Debug, PartialEq, Clone, ValidateSchema)]
#[derive(CustomResource, Serialize, Deserialize, Debug, PartialEq, Clone, CELSchema)]
#[kube(
group = "clux.dev",
version = "v1",
Expand Down
2 changes: 1 addition & 1 deletion kube/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ pub use kube_derive::Resource;

#[cfg(feature = "derive")]
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
pub use kube_derive::ValidateSchema;
pub use kube_derive::CELSchema;

#[cfg(feature = "runtime")]
#[cfg_attr(docsrs, doc(cfg(feature = "runtime")))]
Expand Down

0 comments on commit 529e22b

Please sign in to comment.