Skip to content

Commit

Permalink
Feature: Allow to pass selectableFields for CRD definition (#1605)
Browse files Browse the repository at this point in the history
* Allow to pass selectableFields for CRD definition

Signed-off-by: Danil-Grigorev <[email protected]>

* Make selectableFields key optional to permit pre 1.30 clusters

Signed-off-by: Danil-Grigorev <[email protected]>

* Make it selectable

Signed-off-by: Danil-Grigorev <[email protected]>

* Mention selectable in the lib.rs

Signed-off-by: Danil Grigorev <[email protected]>

* Add a detail about version limitation for using selectableFields

Signed-off-by: Danil-Grigorev <[email protected]>

---------

Signed-off-by: Danil-Grigorev <[email protected]>
Signed-off-by: Danil Grigorev <[email protected]>
  • Loading branch information
Danil-Grigorev authored Oct 17, 2024
1 parent 95cf702 commit 9dd62b9
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 3 deletions.
6 changes: 5 additions & 1 deletion examples/crd_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use serde::{Deserialize, Serialize};
derive = "Default",
shortname = "f",
scale = r#"{"specReplicasPath":".spec.replicas", "statusReplicasPath":".status.replicas"}"#,
printcolumn = r#"{"name":"Spec", "type":"string", "description":"name of foo", "jsonPath":".spec.name"}"#
printcolumn = r#"{"name":"Spec", "type":"string", "description":"name of foo", "jsonPath":".spec.name"}"#,
selectable = "spec.name"
)]
pub struct MyFoo {
name: String,
Expand Down Expand Up @@ -118,6 +119,9 @@ fn verify_crd() {
"type": "string"
}
],
"selectableFields": [{
"jsonPath": "spec.name",
}],
"schema": {
"openAPIV3Schema": {
"description": "Custom resource representing a Foo",
Expand Down
16 changes: 16 additions & 0 deletions kube-derive/src/custom_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ struct KubeAttrs {
shortnames: Vec<String>,
#[darling(multiple, rename = "printcolumn")]
printcolums: Vec<String>,
#[darling(multiple)]
selectable: Vec<String>,
scale: Option<String>,
#[darling(default)]
crates: Crates,
Expand Down Expand Up @@ -159,6 +161,7 @@ pub(crate) fn derive(input: proc_macro2::TokenStream) -> proc_macro2::TokenStrea
categories,
shortnames,
printcolums,
selectable,
scale,
crates:
Crates {
Expand Down Expand Up @@ -353,6 +356,11 @@ pub(crate) fn derive(input: proc_macro2::TokenStream) -> proc_macro2::TokenStrea

// Compute a bunch of crd props
let printers = format!("[ {} ]", printcolums.join(",")); // hacksss
let fields: Vec<String> = selectable
.iter()
.map(|s| format!(r#"{{ "jsonPath": "{s}" }}"#))
.collect();
let fields = format!("[ {} ]", fields.join(","));
let scale_code = if let Some(s) = scale { s } else { "".to_string() };

// Ensure it generates for the correct CRD version (only v1 supported now)
Expand Down Expand Up @@ -397,6 +405,12 @@ pub(crate) fn derive(input: proc_macro2::TokenStream) -> proc_macro2::TokenStrea
}
};

let selectable = if !selectable.is_empty() {
quote! { "selectableFields": fields, }
} else {
quote! {}
};

let jsondata = quote! {
#schemagen

Expand All @@ -420,6 +434,7 @@ pub(crate) fn derive(input: proc_macro2::TokenStream) -> proc_macro2::TokenStrea
"openAPIV3Schema": schema,
},
"additionalPrinterColumns": columns,
#selectable
"subresources": subres,
}],
}
Expand All @@ -432,6 +447,7 @@ pub(crate) fn derive(input: proc_macro2::TokenStream) -> proc_macro2::TokenStrea

fn crd() -> #apiext::CustomResourceDefinition {
let columns : Vec<#apiext::CustomResourceColumnDefinition> = #serde_json::from_str(#printers).expect("valid printer column json");
let fields : Vec<#apiext::SelectableField> = #serde_json::from_str(#fields).expect("valid selectableField column json");
let scale: Option<#apiext::CustomResourceSubresourceScale> = if #scale_code.is_empty() {
None
} else {
Expand Down
7 changes: 6 additions & 1 deletion kube-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ mod resource;
/// ## `#[kube(category = "apps")]`
/// Add a single category to `crd.spec.names.categories`.
///
/// ## `#[kube(selectable = "fieldSelectorPath")]`
/// Adds a Kubernetes >=1.30 `selectableFields` property ([KEP-4358](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/4358-custom-resource-field-selectors/README.md)) to the schema.
/// Unlocks `kubectl get kind --field-selector fieldSelectorPath`.
///
/// ## `#[kube(doc = "description")]`
/// Sets the description of the schema in the generated CRD. If not specified
/// `Auto-generated derived type for {customResourceName} via CustomResource` will be used instead.
Expand All @@ -165,7 +169,8 @@ mod resource;
/// plural = "feetz",
/// shortname = "f",
/// scale = r#"{"specReplicasPath":".spec.replicas", "statusReplicasPath":".status.replicas"}"#,
/// printcolumn = r#"{"name":"Spec", "type":"string", "description":"name of foo", "jsonPath":".spec.name"}"#
/// printcolumn = r#"{"name":"Spec", "type":"string", "description":"name of foo", "jsonPath":".spec.name"}"#,
/// selectable = "spec.replicasCount"
/// )]
/// #[serde(rename_all = "camelCase")]
/// struct FooSpec {
Expand Down
9 changes: 8 additions & 1 deletion kube-derive/tests/crd_schema_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use std::collections::{HashMap, HashSet};
doc = "Custom resource representing a Foo",
derive = "PartialEq",
shortname = "fo",
shortname = "f"
shortname = "f",
selectable = ".spec.nonNullable",
selectable = ".spec.nullable"
)]
#[serde(rename_all = "camelCase")]
struct FooSpec {
Expand Down Expand Up @@ -198,6 +200,11 @@ fn test_crd_schema_matches_expected() {
"served": true,
"storage": true,
"additionalPrinterColumns": [],
"selectableFields": [{
"jsonPath": ".spec.nonNullable"
}, {
"jsonPath": ".spec.nullable"
}],
"schema": {
"openAPIV3Schema": {
"description": "Custom resource representing a Foo",
Expand Down

0 comments on commit 9dd62b9

Please sign in to comment.