Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Add stackable-shared crate #883

Merged
merged 5 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Please see the relevant crate changelogs:
- [stackable-certs](./crates/stackable-certs/CHANGELOG.md)
- [stackable-operator](./crates/stackable-operator/CHANGELOG.md)
- [stackable-operator-derive](./crates/stackable-operator-derive/CHANGELOG.md)
- [stackable-shared](./crates/stackable-shared/CHANGELOG.md)
- [stackable-telemetry](./crates/stackable-telemetry/CHANGELOG.md)
- [stackable-versioned](./crates/stackable-versioned/CHANGELOG.md)
- [stackable-webhook](./crates/stackable-webhook/CHANGELOG.md)
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions crates/stackable-operator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Added

- Re-export the `YamlSchema` trait and the `stackable-shared` crate as the `shared` module ([#883]).

### Changed

- BREAKING: The `CustomResourceExt` trait is now re-exported from the `stackable-shared` crate. The
trait functions use the same parameters but return a different error type ([#883]).

### Removed

- BREAKING: The `CustomResourceExt` trait doesn't provide a `generate_yaml_schema` function any
more. Instead, use the high-level functions to write the schema to a file, write it to stdout or
use it as a `String`.

[#883]: https://github.com/stackabletech/operator-rs/pull/883

## [0.78.0] - 2024-09-30

### Added
Expand Down
3 changes: 2 additions & 1 deletion crates/stackable-operator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ repository.workspace = true
time = ["dep:time"]

[dependencies]
stackable-operator-derive = { path = "../stackable-operator-derive" }
stackable-operator-derive = { path = "../stackable-operator-derive", version = "0.3.1" }
stackable-shared = { path = "../stackable-shared", version = "0.0.1" }

chrono.workspace = true
clap.workspace = true
Expand Down
13 changes: 7 additions & 6 deletions crates/stackable-operator/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//! use kube::CustomResource;
//! use schemars::JsonSchema;
//! use serde::{Deserialize, Serialize};
//! use stackable_operator::{CustomResourceExt, cli, crd};
//! use stackable_operator::{CustomResourceExt, cli, shared::crd};
//!
//! const OPERATOR_VERSION: &str = "23.1.1";
//!
Expand Down Expand Up @@ -106,16 +106,17 @@
//! ```
//!
//!
use crate::logging::TracingTarget;
use crate::namespace::WatchNamespace;
use clap::Args;
use product_config::ProductConfigManager;
use snafu::{ResultExt, Snafu};
use std::{
ffi::OsStr,
path::{Path, PathBuf},
};

use clap::Args;
use product_config::ProductConfigManager;
use snafu::{ResultExt, Snafu};

use crate::{logging::TracingTarget, namespace::WatchNamespace};

pub const AUTHOR: &str = "Stackable GmbH - info@stackable.tech";

type Result<T, E = Error> = std::result::Result<T, E>;
Expand Down
110 changes: 0 additions & 110 deletions crates/stackable-operator/src/crd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,7 @@ use std::marker::PhantomData;

use derivative::Derivative;
use schemars::JsonSchema;
use semver::Version;
use serde::{Deserialize, Serialize};
use snafu::{ResultExt, Snafu};

use crate::yaml;
use std::fs::File;
use std::io::Write;
use std::path::Path;

const DOCS_HOME_URL_PLACEHOLDER: &str = "DOCS_BASE_URL_PLACEHOLDER";
const DOCS_HOME_BASE_URL: &str = "https://docs.stackable.tech/home";

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

#[derive(Debug, Snafu)]
pub enum Error {
#[snafu(display("cannot parse version {version:?} as a semantic version"))]
InvalidSemverVersion {
source: semver::Error,
version: String,
},

#[snafu(display("error converting CRD byte array to UTF-8"))]
ConvertByteArrayToUtf8 { source: std::string::FromUtf8Error },

#[snafu(display("failed to serialize YAML"))]
SerializeYaml { source: yaml::Error },

#[snafu(display("failed to write YAML"))]
WriteYamlSchema { source: std::io::Error },

#[snafu(display("failed to create YAML file"))]
CreateYamlFile { source: std::io::Error },
}

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

/// Takes an operator version and returns a docs version
fn docs_version(operator_version: &str) -> Result<String> {
if operator_version == "0.0.0-dev" {
Ok("nightly".to_owned())
} else {
let v = Version::parse(operator_version).context(InvalidSemverVersionSnafu {
version: operator_version.to_owned(),
})?;
Ok(format!("{}.{}", v.major, v.minor))
}
}

/// Given an operator version like 0.0.0-dev or 23.1.1, generate a docs home
/// component base URL like `https://docs.stackable.tech/home/nightly/` or
/// `https://docs.stackable.tech/home/23.1/`.
fn docs_home_versioned_base_url(operator_version: &str) -> Result<String> {
Ok(format!(
"{}/{}",
DOCS_HOME_BASE_URL,
docs_version(operator_version)?
))
}

/// This trait can be implemented to allow automatic handling
/// (e.g. creation) of `CustomResourceDefinition`s in Kubernetes.
pub trait CustomResourceExt: kube::CustomResourceExt {
/// Generates a YAML CustomResourceDefinition and writes it to a `Write`.
///
/// The generated YAML string is an explicit document with leading dashes (`---`).
fn generate_yaml_schema<W>(mut writer: W, operator_version: &str) -> Result<()>
where
W: Write,
{
let mut buffer = Vec::new();
yaml::serialize_to_explicit_document(&mut buffer, &Self::crd())
.context(SerializeYamlSnafu)?;

let yaml_schema = String::from_utf8(buffer)
.context(ConvertByteArrayToUtf8Snafu)?
.replace(
DOCS_HOME_URL_PLACEHOLDER,
&docs_home_versioned_base_url(operator_version)?,
);

writer
.write_all(yaml_schema.as_bytes())
.context(WriteYamlSchemaSnafu)
}

/// Generates a YAML CustomResourceDefinition and writes it to the specified file.
///
/// The written YAML string is an explicit document with leading dashes (`---`).
fn write_yaml_schema<P: AsRef<Path>>(path: P, operator_version: &str) -> Result<()> {
let writer = File::create(path).context(CreateYamlFileSnafu)?;
Self::generate_yaml_schema(writer, operator_version)
}

/// Generates a YAML CustomResourceDefinition and prints it to stdout.
///
/// The printed YAML string is an explicit document with leading dashes (`---`).
fn print_yaml_schema(operator_version: &str) -> Result<()> {
let writer = std::io::stdout();
Self::generate_yaml_schema(writer, operator_version)
}

/// Returns the YAML schema of this CustomResourceDefinition as a string.
///
/// The written YAML string is an explicit document with leading dashes (`---`).
fn yaml_schema(operator_version: &str) -> Result<String> {
let mut writer = Vec::new();
Self::generate_yaml_schema(&mut writer, operator_version)?;
String::from_utf8(writer).context(ConvertByteArrayToUtf8Snafu)
}
}

impl<T> CustomResourceExt for T where T: kube::CustomResourceExt {}

#[cfg(test)]
mod tests {
use k8s_openapi::api::core::v1::ConfigMap;
Expand Down
4 changes: 2 additions & 2 deletions crates/stackable-operator/src/helm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ mod tests {

use rstest::rstest;

use crate::yaml::serialize_to_explicit_document;
use stackable_shared::yaml::{serialize as ser, SerializeOptions};

use super::*;

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

let mut output = Vec::new();
serialize_to_explicit_document(&mut output, &values).unwrap();
ser(&values, &mut output, SerializeOptions::default()).unwrap();

assert_eq!(std::str::from_utf8(&output).unwrap(), expected);
}
Expand Down
9 changes: 7 additions & 2 deletions crates/stackable-operator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@ pub mod status;
pub mod time;
pub mod utils;
pub mod validation;
pub mod yaml;

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

pub mod shared {
pub use stackable_shared::*;
}

// External re-exports
pub use ::k8s_openapi;
pub use ::kube;
pub use ::schemars;
72 changes: 0 additions & 72 deletions crates/stackable-operator/src/yaml.rs

This file was deleted.

11 changes: 11 additions & 0 deletions crates/stackable-shared/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

All notable changes to this project will be documented in this file.

## [0.0.1]

### Added

- Add YAML and CRD helper functions and traits ([#883]).

[#883]: https://github.com/stackabletech/operator-rs/pull/883
17 changes: 17 additions & 0 deletions crates/stackable-shared/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "stackable-shared"
version = "0.0.1"
authors.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true

[dependencies]
kube.workspace = true
semver.workspace = true
serde.workspace = true
serde_yaml.workspace = true
snafu.workspace = true

[dev-dependencies]
k8s-openapi.workspace = true
Loading
Loading