Skip to content
Closed
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Added

- YAML module added with a function to serialize a data structure as an
explicit YAML document. The YAML documents generated by the functions in
`crd::CustomResourceExt` are now explicit documents and can be safely
concatenated to produce a YAML stream ([#450]).

### Changed

- Objects are now streamed rather than polled when waiting for them to be deleted ([#452]).
- serde\_yaml 0.8.26 -> 0.9.9 ([#450])

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

## [0.24.0] - 2022-08-04
Expand Down
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ regex = "1.6.0"
schemars = "0.8.10"
serde = { version = "1.0.140", features = ["derive"] }
serde_json = "1.0.82"
serde_yaml = "0.8.26"
serde_yaml = "0.9.9"
strum = { version = "0.24.1", features = ["derive"] }
thiserror = "1.0.31"
tokio = { version = "1.20.1", features = ["macros", "rt-multi-thread"] }
Expand All @@ -38,7 +38,6 @@ stackable-operator-derive = { path = "stackable-operator-derive" }
[dev-dependencies]
rstest = "0.15.0"
tempfile = "3.3.0"
serde_yaml = "0.8"

[features]
default = ["native-tls"]
Expand Down
13 changes: 6 additions & 7 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
//! ```no_run
//! // Handle CLI arguments
//! use clap::{crate_version, Parser};
//! use kube::{CustomResource, CustomResourceExt};
//! use kube::CustomResource;
//! use schemars::JsonSchema;
//! use serde::{Deserialize, Serialize};
//! use stackable_operator::cli;
//! use stackable_operator::{CustomResourceExt, cli};
//! use stackable_operator::error::OperatorResult;
//!
//! #[derive(Clone, CustomResource, Debug, JsonSchema, Serialize, Deserialize)]
Expand Down Expand Up @@ -55,11 +55,10 @@
//! let opts = Opts::from_args();
//!
//! match opts.command {
//! cli::Command::Crd => println!(
//! "{}{}",
//! serde_yaml::to_string(&FooCluster::crd())?,
//! serde_yaml::to_string(&BarCluster::crd())?,
//! ),
//! cli::Command::Crd => {
//! FooCluster::print_yaml_schema()?;
//! BarCluster::print_yaml_schema()?;
//! },
//! cli::Command::Run { .. } => {
//! // Run the operator
//! }
Expand Down
17 changes: 11 additions & 6 deletions src/commons/s3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,11 @@ impl Default for S3AccessStyle {

#[cfg(test)]
mod test {
use std::str;

use crate::commons::s3::{S3AccessStyle, S3ConnectionDef};
use crate::commons::s3::{S3BucketSpec, S3ConnectionSpec};
use crate::yaml;

#[test]
fn test_ser_inline() {
Expand All @@ -238,17 +241,19 @@ mod test {
})),
};

assert_eq!(
serde_yaml::to_string(&bucket).unwrap(),
"---
let mut buf = Vec::new();
yaml::serialize_to_explicit_document(&mut buf, &bucket).expect("serializable value");
let actual_yaml = str::from_utf8(&buf).expect("UTF-8 encoded document");

let expected_yaml = "---
bucketName: test-bucket-name
connection:
inline:
host: host
port: 8080
accessStyle: VirtualHosted
"
.to_owned()
)
";

assert_eq!(expected_yaml, actual_yaml)
}
}
15 changes: 11 additions & 4 deletions src/crd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::error::{Error, OperatorResult};
use crate::yaml;
use std::fs::File;
use std::io::Write;
use std::path::Path;
Expand Down Expand Up @@ -72,28 +73,34 @@ pub trait HasApplication {
/// (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) -> OperatorResult<()>
where
W: Write,
{
let schema = serde_yaml::to_string(&Self::crd())?;
writer.write_all(schema.as_bytes())?;
Ok(())
yaml::serialize_to_explicit_document(&mut writer, &Self::crd())
}

/// 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) -> OperatorResult<()> {
let writer = File::create(path)?;
Self::generate_yaml_schema(writer)
}

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

// Returns the YAML schema of this CustomResourceDefinition as a string.
/// Returns the YAML schema of this CustomResourceDefinition as a string.
///
/// The written YAML string is an explicit document with leading dashes (`---`).
fn yaml_schema() -> OperatorResult<String> {
let mut writer = Vec::new();
Self::generate_yaml_schema(&mut writer)?;
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod product_config_utils;
pub mod role_utils;
pub mod utils;
pub mod validation;
pub mod yaml;

pub use crate::crd::CustomResourceExt;

Expand Down
59 changes: 59 additions & 0 deletions src/yaml.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//! Utility functions for processing data in the YAML file format
use std::io::Write;

use serde::ser;

use crate::error::OperatorResult;

/// Serializes the given data structure as an explicit YAML document and writes it to a [`Write`].
///
/// Enums are serialized as a YAML map containing one entry in which the key identifies the variant
/// name.
///
/// # Example
///
/// ```
/// use serde::Serialize;
/// use stackable_operator::yaml;
///
/// #[derive(Serialize)]
/// #[serde(rename_all = "camelCase")]
/// enum Connection {
/// Inline(String),
/// Reference(String),
/// }
///
/// #[derive(Serialize)]
/// struct Spec {
/// connection: Connection,
/// }
///
/// let value = Spec {
/// connection: Connection::Inline("http://localhost".into()),
/// };
///
/// let mut buf = Vec::new();
/// yaml::serialize_to_explicit_document(&mut buf, &value).unwrap();
/// let actual_yaml = std::str::from_utf8(&buf).unwrap();
///
/// let expected_yaml = "---
/// connection:
/// inline: http://localhost
/// ";
///
/// assert_eq!(expected_yaml, actual_yaml);
/// ```
///
/// # Errors
///
/// Serialization can fail if `T`'s implementation of `Serialize` decides to return an error.
pub fn serialize_to_explicit_document<T, W>(mut writer: W, value: &T) -> OperatorResult<()>
where
T: ser::Serialize,
W: Write,
{
writer.write_all(b"---\n")?;
let mut serializer = serde_yaml::Serializer::new(writer);
serde_yaml::with::singleton_map_recursive::serialize(value, &mut serializer)?;
Ok(())
}