Skip to content

Commit 17ff823

Browse files
committed
feat(stackable-versioned): Add flux-converter
1 parent ffc7697 commit 17ff823

File tree

39 files changed

+4764
-20
lines changed

39 files changed

+4764
-20
lines changed

Cargo.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/stackable-operator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ versioned = []
1616

1717
[dependencies]
1818
stackable-telemetry = { path = "../stackable-telemetry", features = ["clap"] }
19-
stackable-versioned = { path = "../stackable-versioned", features = ["k8s"] }
19+
stackable-versioned = { path = "../stackable-versioned", features = ["k8s", "flux-converter"] }
2020
stackable-operator-derive = { path = "../stackable-operator-derive" }
2121
stackable-shared = { path = "../stackable-shared" }
2222

crates/stackable-operator/src/commons/resources.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
//! crates(
3939
//! kube_core = "stackable_operator::kube::core",
4040
//! k8s_openapi = "stackable_operator::k8s_openapi",
41-
//! schemars = "stackable_operator::schemars"
41+
//! schemars = "stackable_operator::schemars",
4242
//! )
4343
//! )]
4444
//! #[serde(rename_all = "camelCase")]

crates/stackable-operator/src/crd/authentication/core/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub mod versioned {
3232
crates(
3333
kube_core = "kube::core",
3434
k8s_openapi = "k8s_openapi",
35-
schemars = "schemars"
35+
schemars = "schemars",
3636
)
3737
))]
3838
#[derive(

crates/stackable-operator/src/crd/s3/bucket/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub mod versioned {
2121
crates(
2222
kube_core = "kube::core",
2323
k8s_openapi = "k8s_openapi",
24-
schemars = "schemars"
24+
schemars = "schemars",
2525
),
2626
namespaced
2727
))]

crates/stackable-operator/src/crd/s3/connection/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub mod versioned {
3131
crates(
3232
kube_core = "kube::core",
3333
k8s_openapi = "k8s_openapi",
34-
schemars = "schemars"
34+
schemars = "schemars",
3535
),
3636
namespaced
3737
))]

crates/stackable-versioned-macros/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ serde.workspace = true
5353
serde_json.workspace = true
5454
serde_yaml.workspace = true
5555
snafu.workspace = true
56+
tracing.workspace = true
5657
trybuild.workspace = true

crates/stackable-versioned-macros/src/codegen/container/mod.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,28 +105,50 @@ impl Container {
105105
}
106106
}
107107

108-
/// Generates Kubernetes specific code to merge two or more CRDs into one.
108+
/// Generates Kubernetes specific code to merge two CRDs or convert between different versions.
109109
///
110110
/// This function only returns `Some` if it is a struct. Enums cannot be used to define
111111
/// Kubernetes custom resources.
112-
pub fn generate_kubernetes_merge_crds(
112+
pub fn generate_kubernetes_code(
113113
&self,
114114
enum_variant_idents: &[IdentString],
115115
enum_variant_strings: &[String],
116116
fn_calls: &[TokenStream],
117117
vis: &Visibility,
118118
is_nested: bool,
119119
) -> Option<TokenStream> {
120-
match self {
121-
Container::Struct(s) => s.generate_kubernetes_merge_crds(
120+
let Container::Struct(s) = self else {
121+
return None;
122+
};
123+
let kubernetes_options = s.common.options.kubernetes_options.as_ref()?;
124+
125+
let mut tokens = TokenStream::new();
126+
127+
if !kubernetes_options.skip_merged_crd {
128+
tokens.extend(s.generate_kubernetes_merge_crds(
122129
enum_variant_idents,
123130
enum_variant_strings,
124131
fn_calls,
125132
vis,
126133
is_nested,
127-
),
128-
Container::Enum(_) => None,
134+
));
129135
}
136+
137+
tokens.extend(s.generate_from_functions(
138+
enum_variant_idents,
139+
enum_variant_strings,
140+
is_nested,
141+
));
142+
// TODO: Do we need a kubernetes_options.skip_conversion as well?
143+
tokens.extend(super::flux_converter::generate_kubernetes_conversion(
144+
&s.common.idents.kubernetes,
145+
&s.common.idents.original,
146+
enum_variant_idents,
147+
enum_variant_strings,
148+
kubernetes_options,
149+
));
150+
151+
Some(tokens)
130152
}
131153

132154
pub fn generate_kubernetes_status_struct(&self) -> Option<TokenStream> {
@@ -251,7 +273,7 @@ impl StandaloneContainer {
251273
});
252274
}
253275

254-
tokens.extend(self.container.generate_kubernetes_merge_crds(
276+
tokens.extend(self.container.generate_kubernetes_code(
255277
&kubernetes_enum_variant_idents,
256278
&kubernetes_enum_variant_strings,
257279
&kubernetes_merge_crds_fn_calls,

crates/stackable-versioned-macros/src/codegen/container/struct.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,8 @@ impl Struct {
419419
vis: &Visibility,
420420
is_nested: bool,
421421
) -> Option<TokenStream> {
422+
assert_eq!(enum_variant_idents.len(), enum_variant_strings.len());
423+
422424
let kubernetes_options = self.common.options.kubernetes_options.as_ref()?;
423425

424426
if !kubernetes_options.skip_merged_crd {
@@ -452,7 +454,10 @@ impl Struct {
452454
/// Generates a merged CRD containing all versions and marking `stored_apiversion` as stored.
453455
pub fn merged_crd(
454456
stored_apiversion: Self
455-
) -> ::std::result::Result<#k8s_openapi_path::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition, #kube_core_path::crd::MergeError> {
457+
) -> ::std::result::Result<
458+
#k8s_openapi_path::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition,
459+
#kube_core_path::crd::MergeError>
460+
{
456461
#kube_core_path::crd::merge_crds(vec![#(#fn_calls),*], &stored_apiversion.to_string())
457462
}
458463
}
@@ -462,6 +467,57 @@ impl Struct {
462467
}
463468
}
464469

470+
pub fn generate_from_functions(
471+
&self,
472+
enum_variant_idents: &[IdentString],
473+
enum_variant_strings: &[String],
474+
is_nested: bool,
475+
) -> Option<TokenStream> {
476+
assert_eq!(enum_variant_idents.len(), enum_variant_strings.len());
477+
478+
let enum_ident = &self.common.idents.kubernetes;
479+
let kubernetes_options = self.common.options.kubernetes_options.as_ref()?;
480+
let k8s_group = &kubernetes_options.group;
481+
let api_versions = enum_variant_strings
482+
.iter()
483+
.map(|version| format!("{k8s_group}/{version}"));
484+
485+
let versioned_path = &*kubernetes_options.crates.versioned;
486+
487+
// Only add the #[automatically_derived] attribute if this impl is used outside of a
488+
// module (in standalone mode).
489+
let automatically_derived = is_nested.not().then(|| quote! {#[automatically_derived]});
490+
491+
Some(quote! {
492+
#automatically_derived
493+
/// Parses the version, such as `v1alpha1`
494+
impl ::std::str::FromStr for #enum_ident {
495+
type Err = #versioned_path::ParseResourceVersionError;
496+
497+
fn from_str(version: &str) -> Result<Self, Self::Err> {
498+
match version {
499+
#(#enum_variant_strings => Ok(Self::#enum_variant_idents),)*
500+
_ => Err(#versioned_path::ParseResourceVersionError::UnknownResourceVersion{
501+
version: version.to_string()
502+
}),
503+
}
504+
}
505+
}
506+
507+
/// Parses the entire `apiVersion`, such as `zookeeper.stackable.tech/v1alpha1`.
508+
impl #enum_ident {
509+
pub fn from_api_version(api_version: &str) -> Result<Self, #versioned_path::ParseResourceVersionError> {
510+
match api_version {
511+
#(#api_versions => Ok(Self::#enum_variant_idents),)*
512+
_ => Err(#versioned_path::ParseResourceVersionError::UnknownApiVersion{
513+
api_version: api_version.to_string()
514+
}),
515+
}
516+
}
517+
}
518+
})
519+
}
520+
465521
pub fn generate_kubernetes_status_struct(&self) -> Option<TokenStream> {
466522
let kubernetes_options = self.common.options.kubernetes_options.as_ref()?;
467523

0 commit comments

Comments
 (0)