Skip to content

Commit 194d33e

Browse files
authored
feat!: Add stackable-shared crate (#883)
* feat: Add stackable-shared crate This crate initially contains code to be able to use our custom YAML serialization across workspace members. Previously, to get access to the specialized helper functions and traits one needed to import the complete stackable-operator crate. That's why this commit moves that piece of code into a shared place, which is way lighter to be imported by other workspace members. It additionally reworks the helpers to be slightly more generic. It still contains the docs URL replacer, which replaces the placeholder with the correct Stackable doc URL in doc comments and thus in OpenAPI schema descriptions. * chore: Use shared YAML code * chore: Split CRD and YAML specific code * chore: Update changelogs * chore: Parse SemVer when creating DocUrlReplacer
1 parent 32a749d commit 194d33e

File tree

14 files changed

+303
-193
lines changed

14 files changed

+303
-193
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Please see the relevant crate changelogs:
66
- [stackable-certs](./crates/stackable-certs/CHANGELOG.md)
77
- [stackable-operator](./crates/stackable-operator/CHANGELOG.md)
88
- [stackable-operator-derive](./crates/stackable-operator-derive/CHANGELOG.md)
9+
- [stackable-shared](./crates/stackable-shared/CHANGELOG.md)
910
- [stackable-telemetry](./crates/stackable-telemetry/CHANGELOG.md)
1011
- [stackable-versioned](./crates/stackable-versioned/CHANGELOG.md)
1112
- [stackable-webhook](./crates/stackable-webhook/CHANGELOG.md)

Cargo.lock

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/stackable-operator/CHANGELOG.md

+17
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Added
8+
9+
- Re-export the `YamlSchema` trait and the `stackable-shared` crate as the `shared` module ([#883]).
10+
11+
### Changed
12+
13+
- BREAKING: The `CustomResourceExt` trait is now re-exported from the `stackable-shared` crate. The
14+
trait functions use the same parameters but return a different error type ([#883]).
15+
16+
### Removed
17+
18+
- BREAKING: The `CustomResourceExt` trait doesn't provide a `generate_yaml_schema` function any
19+
more. Instead, use the high-level functions to write the schema to a file, write it to stdout or
20+
use it as a `String`.
21+
22+
[#883]: https://github.com/stackabletech/operator-rs/pull/883
23+
724
## [0.78.0] - 2024-09-30
825

926
### Added

crates/stackable-operator/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ repository.workspace = true
1111
time = ["dep:time"]
1212

1313
[dependencies]
14-
stackable-operator-derive = { path = "../stackable-operator-derive" }
14+
stackable-operator-derive = { path = "../stackable-operator-derive", version = "0.3.1" }
15+
stackable-shared = { path = "../stackable-shared", version = "0.0.1" }
1516

1617
chrono.workspace = true
1718
clap.workspace = true

crates/stackable-operator/src/cli.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//! use kube::CustomResource;
1515
//! use schemars::JsonSchema;
1616
//! use serde::{Deserialize, Serialize};
17-
//! use stackable_operator::{CustomResourceExt, cli, crd};
17+
//! use stackable_operator::{CustomResourceExt, cli, shared::crd};
1818
//!
1919
//! const OPERATOR_VERSION: &str = "23.1.1";
2020
//!
@@ -106,16 +106,17 @@
106106
//! ```
107107
//!
108108
//!
109-
use crate::logging::TracingTarget;
110-
use crate::namespace::WatchNamespace;
111-
use clap::Args;
112-
use product_config::ProductConfigManager;
113-
use snafu::{ResultExt, Snafu};
114109
use std::{
115110
ffi::OsStr,
116111
path::{Path, PathBuf},
117112
};
118113

114+
use clap::Args;
115+
use product_config::ProductConfigManager;
116+
use snafu::{ResultExt, Snafu};
117+
118+
use crate::{logging::TracingTarget, namespace::WatchNamespace};
119+
119120
pub const AUTHOR: &str = "Stackable GmbH - info@stackable.tech";
120121

121122
type Result<T, E = Error> = std::result::Result<T, E>;

crates/stackable-operator/src/crd.rs

-110
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,7 @@ use std::marker::PhantomData;
22

33
use derivative::Derivative;
44
use schemars::JsonSchema;
5-
use semver::Version;
65
use serde::{Deserialize, Serialize};
7-
use snafu::{ResultExt, Snafu};
8-
9-
use crate::yaml;
10-
use std::fs::File;
11-
use std::io::Write;
12-
use std::path::Path;
13-
14-
const DOCS_HOME_URL_PLACEHOLDER: &str = "DOCS_BASE_URL_PLACEHOLDER";
15-
const DOCS_HOME_BASE_URL: &str = "https://docs.stackable.tech/home";
16-
17-
type Result<T, E = Error> = std::result::Result<T, E>;
18-
19-
#[derive(Debug, Snafu)]
20-
pub enum Error {
21-
#[snafu(display("cannot parse version {version:?} as a semantic version"))]
22-
InvalidSemverVersion {
23-
source: semver::Error,
24-
version: String,
25-
},
26-
27-
#[snafu(display("error converting CRD byte array to UTF-8"))]
28-
ConvertByteArrayToUtf8 { source: std::string::FromUtf8Error },
29-
30-
#[snafu(display("failed to serialize YAML"))]
31-
SerializeYaml { source: yaml::Error },
32-
33-
#[snafu(display("failed to write YAML"))]
34-
WriteYamlSchema { source: std::io::Error },
35-
36-
#[snafu(display("failed to create YAML file"))]
37-
CreateYamlFile { source: std::io::Error },
38-
}
396

407
/// A reference to a product cluster (for example, a `ZookeeperCluster`)
418
///
@@ -96,83 +63,6 @@ pub trait HasApplication {
9663
fn get_application_name() -> &'static str;
9764
}
9865

99-
/// Takes an operator version and returns a docs version
100-
fn docs_version(operator_version: &str) -> Result<String> {
101-
if operator_version == "0.0.0-dev" {
102-
Ok("nightly".to_owned())
103-
} else {
104-
let v = Version::parse(operator_version).context(InvalidSemverVersionSnafu {
105-
version: operator_version.to_owned(),
106-
})?;
107-
Ok(format!("{}.{}", v.major, v.minor))
108-
}
109-
}
110-
111-
/// Given an operator version like 0.0.0-dev or 23.1.1, generate a docs home
112-
/// component base URL like `https://docs.stackable.tech/home/nightly/` or
113-
/// `https://docs.stackable.tech/home/23.1/`.
114-
fn docs_home_versioned_base_url(operator_version: &str) -> Result<String> {
115-
Ok(format!(
116-
"{}/{}",
117-
DOCS_HOME_BASE_URL,
118-
docs_version(operator_version)?
119-
))
120-
}
121-
122-
/// This trait can be implemented to allow automatic handling
123-
/// (e.g. creation) of `CustomResourceDefinition`s in Kubernetes.
124-
pub trait CustomResourceExt: kube::CustomResourceExt {
125-
/// Generates a YAML CustomResourceDefinition and writes it to a `Write`.
126-
///
127-
/// The generated YAML string is an explicit document with leading dashes (`---`).
128-
fn generate_yaml_schema<W>(mut writer: W, operator_version: &str) -> Result<()>
129-
where
130-
W: Write,
131-
{
132-
let mut buffer = Vec::new();
133-
yaml::serialize_to_explicit_document(&mut buffer, &Self::crd())
134-
.context(SerializeYamlSnafu)?;
135-
136-
let yaml_schema = String::from_utf8(buffer)
137-
.context(ConvertByteArrayToUtf8Snafu)?
138-
.replace(
139-
DOCS_HOME_URL_PLACEHOLDER,
140-
&docs_home_versioned_base_url(operator_version)?,
141-
);
142-
143-
writer
144-
.write_all(yaml_schema.as_bytes())
145-
.context(WriteYamlSchemaSnafu)
146-
}
147-
148-
/// Generates a YAML CustomResourceDefinition and writes it to the specified file.
149-
///
150-
/// The written YAML string is an explicit document with leading dashes (`---`).
151-
fn write_yaml_schema<P: AsRef<Path>>(path: P, operator_version: &str) -> Result<()> {
152-
let writer = File::create(path).context(CreateYamlFileSnafu)?;
153-
Self::generate_yaml_schema(writer, operator_version)
154-
}
155-
156-
/// Generates a YAML CustomResourceDefinition and prints it to stdout.
157-
///
158-
/// The printed YAML string is an explicit document with leading dashes (`---`).
159-
fn print_yaml_schema(operator_version: &str) -> Result<()> {
160-
let writer = std::io::stdout();
161-
Self::generate_yaml_schema(writer, operator_version)
162-
}
163-
164-
/// Returns the YAML schema of this CustomResourceDefinition as a string.
165-
///
166-
/// The written YAML string is an explicit document with leading dashes (`---`).
167-
fn yaml_schema(operator_version: &str) -> Result<String> {
168-
let mut writer = Vec::new();
169-
Self::generate_yaml_schema(&mut writer, operator_version)?;
170-
String::from_utf8(writer).context(ConvertByteArrayToUtf8Snafu)
171-
}
172-
}
173-
174-
impl<T> CustomResourceExt for T where T: kube::CustomResourceExt {}
175-
17666
#[cfg(test)]
17767
mod tests {
17868
use k8s_openapi::api::core::v1::ConfigMap;

crates/stackable-operator/src/helm/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ mod tests {
7979

8080
use rstest::rstest;
8181

82-
use crate::yaml::serialize_to_explicit_document;
82+
use stackable_shared::yaml::{serialize as ser, SerializeOptions};
8383

8484
use super::*;
8585

@@ -102,7 +102,7 @@ mod tests {
102102
let expected = std::fs::read_to_string("fixtures/helm/output.yaml").unwrap();
103103

104104
let mut output = Vec::new();
105-
serialize_to_explicit_document(&mut output, &values).unwrap();
105+
ser(&values, &mut output, SerializeOptions::default()).unwrap();
106106

107107
assert_eq!(std::str::from_utf8(&output).unwrap(), expected);
108108
}

crates/stackable-operator/src/lib.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@ pub mod status;
2020
pub mod time;
2121
pub mod utils;
2222
pub mod validation;
23-
pub mod yaml;
2423

25-
pub use crate::crd::CustomResourceExt;
24+
// Internal re-exports
25+
pub use stackable_shared::{crd::CustomResourceExt, yaml::YamlSchema};
2626

27+
pub mod shared {
28+
pub use stackable_shared::*;
29+
}
30+
31+
// External re-exports
2732
pub use ::k8s_openapi;
2833
pub use ::kube;
2934
pub use ::schemars;

crates/stackable-operator/src/yaml.rs

-72
This file was deleted.

crates/stackable-shared/CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## [0.0.1]
6+
7+
### Added
8+
9+
- Add YAML and CRD helper functions and traits ([#883]).
10+
11+
[#883]: https://github.com/stackabletech/operator-rs/pull/883

crates/stackable-shared/Cargo.toml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "stackable-shared"
3+
version = "0.0.1"
4+
authors.workspace = true
5+
license.workspace = true
6+
edition.workspace = true
7+
repository.workspace = true
8+
9+
[dependencies]
10+
kube.workspace = true
11+
semver.workspace = true
12+
serde.workspace = true
13+
serde_yaml.workspace = true
14+
snafu.workspace = true
15+
16+
[dev-dependencies]
17+
k8s-openapi.workspace = true

0 commit comments

Comments
 (0)