diff --git a/Cargo.lock b/Cargo.lock index 5c6175d..6023fb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1445,17 +1445,6 @@ dependencies = [ "serde", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive_more" version = "0.99.18" @@ -3339,17 +3328,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "json-patch" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b" -dependencies = [ - "serde", - "serde_json", - "thiserror 1.0.63", -] - [[package]] name = "json-patch" version = "2.0.0" @@ -3388,19 +3366,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "k8s-openapi" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19501afb943ae5806548bc3ebd7f3374153ca057a38f480ef30adfde5ef09755" -dependencies = [ - "base64 0.22.1", - "chrono", - "serde", - "serde-value", - "serde_json", -] - [[package]] name = "k8s-openapi" version = "0.23.0" @@ -3415,67 +3380,17 @@ dependencies = [ "serde_json", ] -[[package]] -name = "kube" -version = "0.91.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "264461a7ebf4fb0fcf23e4c7e4f9387c5696ee61d003de207d9b5a895ff37bfa" -dependencies = [ - "k8s-openapi 0.22.0", - "kube-client 0.91.0", - "kube-core 0.91.0", - "kube-derive 0.91.0", - "kube-runtime 0.91.0", -] - [[package]] name = "kube" version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efffeb3df0bd4ef3e5d65044573499c0e4889b988070b08c50b25b1329289a1f" dependencies = [ - "k8s-openapi 0.23.0", - "kube-client 0.96.0", - "kube-core 0.96.0", - "kube-derive 0.96.0", - "kube-runtime 0.96.0", -] - -[[package]] -name = "kube-client" -version = "0.91.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47164ad6c47398ee4bdf90509c7b44026229721cb1377eb4623a1ec2a00a85e9" -dependencies = [ - "base64 0.22.1", - "bytes", - "chrono", - "either", - "futures", - "home", - "http 1.1.0", - "http-body 1.0.1", - "http-body-util", - "hyper 1.5.2", - "hyper-rustls", - "hyper-timeout 0.5.2", - "hyper-util", - "jsonpath-rust", - "k8s-openapi 0.22.0", - "kube-core 0.91.0", - "pem", - "rustls", - "rustls-pemfile", - "secrecy 0.8.0", - "serde", - "serde_json", - "serde_yaml", - "thiserror 1.0.63", - "tokio", - "tokio-util", - "tower 0.4.13", - "tower-http 0.5.2", - "tracing", + "k8s-openapi", + "kube-client", + "kube-core", + "kube-derive", + "kube-runtime", ] [[package]] @@ -3499,12 +3414,12 @@ dependencies = [ "hyper-timeout 0.5.2", "hyper-util", "jsonpath-rust", - "k8s-openapi 0.23.0", - "kube-core 0.96.0", + "k8s-openapi", + "kube-core", "pem", "rustls", "rustls-pemfile", - "secrecy 0.10.3", + "secrecy", "serde", "serde_json", "serde_yaml", @@ -3516,23 +3431,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "kube-core" -version = "0.91.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2797d3044a238825432129cd9537e12c2a6dacbbb5352381af5ea55e1505ed4f" -dependencies = [ - "chrono", - "form_urlencoded", - "http 1.1.0", - "json-patch 1.4.0", - "k8s-openapi 0.22.0", - "schemars", - "serde", - "serde_json", - "thiserror 1.0.63", -] - [[package]] name = "kube-core" version = "0.96.0" @@ -3542,8 +3440,8 @@ dependencies = [ "chrono", "form_urlencoded", "http 1.1.0", - "json-patch 2.0.0", - "k8s-openapi 0.23.0", + "json-patch", + "k8s-openapi", "schemars", "serde", "serde-value", @@ -3551,19 +3449,6 @@ dependencies = [ "thiserror 1.0.63", ] -[[package]] -name = "kube-derive" -version = "0.91.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf837edaa0c478f85e9a3cddb17fa80d58a57c1afa722b3a9e55753ea162f41" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.87", -] - [[package]] name = "kube-derive" version = "0.96.0" @@ -3577,34 +3462,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "kube-runtime" -version = "0.91.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e463e89a1fb222c65a5469b568803153d1bf13d084a8dd42b659e6cca66edc6e" -dependencies = [ - "ahash", - "async-broadcast", - "async-stream", - "async-trait", - "backoff", - "derivative", - "futures", - "hashbrown 0.14.5", - "json-patch 1.4.0", - "k8s-openapi 0.22.0", - "kube-client 0.91.0", - "parking_lot", - "pin-project", - "serde", - "serde_json", - "smallvec", - "thiserror 1.0.63", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "kube-runtime" version = "0.96.0" @@ -3619,10 +3476,10 @@ dependencies = [ "educe", "futures", "hashbrown 0.14.5", - "json-patch 2.0.0", + "json-patch", "jsonptr", - "k8s-openapi 0.23.0", - "kube-client 0.96.0", + "k8s-openapi", + "kube-client", "parking_lot", "pin-project", "serde", @@ -5743,8 +5600,6 @@ dependencies = [ "futures", "http 1.1.0", "hyper 1.5.2", - "k8s-openapi 0.22.0", - "kube 0.91.0", "opentelemetry 0.20.0", "opentelemetry-otlp", "product-config", @@ -6186,16 +6041,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "secrecy" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" -dependencies = [ - "serde", - "zeroize", -] - [[package]] name = "secrecy" version = "0.10.3" @@ -6651,21 +6496,21 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stackable-operator" -version = "0.82.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.82.0#415bbd031bd52e9c0c5392060235030e9930b46b" +version = "0.83.0" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.83.0#3ce7bcbdb58097cde0c0f19488a104c96f69dbc3" dependencies = [ "chrono", "clap", "const_format", "delegate", - "derivative", "dockerfile-parser", + "educe", "either", "futures", "indexmap 2.7.1", - "json-patch 2.0.0", - "k8s-openapi 0.23.0", - "kube 0.96.0", + "json-patch", + "k8s-openapi", + "kube", "opentelemetry-jaeger", "opentelemetry_sdk 0.23.0", "product-config", @@ -6690,7 +6535,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.82.0#415bbd031bd52e9c0c5392060235030e9930b46b" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.83.0#3ce7bcbdb58097cde0c0f19488a104c96f69dbc3" dependencies = [ "darling", "proc-macro2", @@ -6701,9 +6546,9 @@ dependencies = [ [[package]] name = "stackable-shared" version = "0.0.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.82.0#415bbd031bd52e9c0c5392060235030e9930b46b" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.83.0#3ce7bcbdb58097cde0c0f19488a104c96f69dbc3" dependencies = [ - "kube 0.96.0", + "kube", "semver", "serde", "serde_yaml", @@ -7306,17 +7151,14 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "base64 0.21.7", "bitflags 2.6.0", "bytes", "http 1.1.0", "http-body 1.0.1", "http-body-util", - "mime", "pin-project-lite", "tower-layer", "tower-service", - "tracing", ] [[package]] diff --git a/rhio-operator/Cargo.toml b/rhio-operator/Cargo.toml index 9e53304..4f56a1a 100644 --- a/rhio-operator/Cargo.toml +++ b/rhio-operator/Cargo.toml @@ -2,14 +2,12 @@ name = "rhio-operator" version = "0.1.0" edition = "2021" -default-run = "rhio-operator" -license = "Apache-2.0" publish = false -[[bin]] -doc = false -name = "rhio-operator" -path = "src/main.rs" +# [[bin]] +# doc = false +# name = "rhio-operator" +# path = "src/main.rs" [[bin]] doc = false @@ -28,7 +26,7 @@ telemetry = ["tonic", "opentelemetry-otlp"] actix-web = "4.4.0" futures = "0.3.28" tokio = { version = "1.40", features = ["full"] } -k8s-openapi = { version = "0.22.0", features = ["latest"] } +# k8s-openapi = { version = "0.22.0", features = ["latest"] } schemars = { version = "0.8.12", features = ["chrono"] } serde = { version = "1.0.215", features = ["derive"] } serde_json = "1.0" @@ -45,7 +43,7 @@ thiserror = "1.0.47" anyhow = "1.0.75" snafu = "0.8" strum = { version = "0.26", features = ["derive"] } -stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.82.0" } +stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.83.0" } product-config = { git = "https://github.com/stackabletech/product-config.git", tag = "0.7.0" } [dev-dependencies] @@ -57,9 +55,9 @@ tower-test = "0.4.0" [build-dependencies] built = { version = "0.7", features = ["chrono", "git2"] } -[dependencies.kube] -features = ["runtime", "client", "derive" ] -version = "0.91.0" +# [dependencies.kube] +# features = ["runtime", "client", "derive" ] +# version = "0.91.0" # testing new releases - ignore #git = "https://github.com/kube-rs/kube.git" diff --git a/rhio-operator/src/api/message_stream.rs b/rhio-operator/src/api/message_stream.rs new file mode 100644 index 0000000..5cac62b --- /dev/null +++ b/rhio-operator/src/api/message_stream.rs @@ -0,0 +1,25 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use stackable_operator::kube::CustomResource; + +#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)] +#[cfg_attr(test, derive(Default))] +#[kube( + kind = "ReplicatedMessageStream", + group = "rhio.io", + version = "v1", + namespaced, + crates( + kube_core = "stackable_operator::kube::core", + k8s_openapi = "stackable_operator::k8s_openapi", + schemars = "stackable_operator::schemars" + ) +)] +#[kube(status = "ReplicatedMessageStreamStatus", shortname = "ross")] +pub struct ReplicatedMessageStreamSpec { + pub public_key: String, + pub subjects: Vec, +} + +#[derive(Deserialize, Serialize, Clone, Default, Debug, JsonSchema)] +pub struct ReplicatedMessageStreamStatus {} diff --git a/rhio-operator/src/api/message_stream_subscription.rs b/rhio-operator/src/api/message_stream_subscription.rs new file mode 100644 index 0000000..99fbbf4 --- /dev/null +++ b/rhio-operator/src/api/message_stream_subscription.rs @@ -0,0 +1,34 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use stackable_operator::kube::CustomResource; + +#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)] +#[cfg_attr(test, derive(Default))] +#[kube( + kind = "ReplicatedMessageStreamSubscription", + group = "rhio.io", + version = "v1", + namespaced, + crates( + kube_core = "stackable_operator::kube::core", + k8s_openapi = "stackable_operator::k8s_openapi", + schemars = "stackable_operator::schemars" + ) +)] +#[kube( + status = "ReplicatedMessageStreamSubscriptionStatus", + shortname = "ross" +)] +pub struct ReplicatedMessageStreamSubscriptionSpec { + pub public_key: String, + pub subscriptions: Vec, +} + +#[derive(Deserialize, Serialize, Clone, Default, Debug, JsonSchema)] +pub struct SubjectSpec { + subject: String, + stream: String, +} + +#[derive(Deserialize, Serialize, Clone, Default, Debug, JsonSchema)] +pub struct ReplicatedMessageStreamSubscriptionStatus {} diff --git a/rhio-operator/src/api/mod.rs b/rhio-operator/src/api/mod.rs new file mode 100644 index 0000000..1ce4d29 --- /dev/null +++ b/rhio-operator/src/api/mod.rs @@ -0,0 +1,5 @@ +pub mod message_stream; +pub mod message_stream_subscription; +pub mod object_store; +pub mod object_store_subscription; +pub mod service; diff --git a/rhio-operator/src/api/object_store.rs b/rhio-operator/src/api/object_store.rs new file mode 100644 index 0000000..9c92230 --- /dev/null +++ b/rhio-operator/src/api/object_store.rs @@ -0,0 +1,28 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use stackable_operator::kube::CustomResource; + +/// Generate the Kubernetes wrapper struct `ReplicatedObjectStore` from our Spec and Status struct +/// +/// This provides a hook for generating the CRD yaml (in crdgen.rs) +#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)] +#[cfg_attr(test, derive(Default))] +#[kube( + kind = "ReplicatedObjectStore", + group = "rhio.io", + version = "v1", + namespaced, + crates( + kube_core = "stackable_operator::kube::core", + k8s_openapi = "stackable_operator::k8s_openapi", + schemars = "stackable_operator::schemars" + ) +)] +#[kube(status = "ReplicatedObjectStoreStatus", shortname = "ros")] +#[serde(rename_all = "camelCase")] +pub struct ReplicatedObjectStoreSpec { + pub buckets: Vec, +} + +#[derive(Deserialize, Serialize, Clone, Default, Debug, JsonSchema)] +pub struct ReplicatedObjectStoreStatus {} diff --git a/rhio-operator/src/api/object_store_subscription.rs b/rhio-operator/src/api/object_store_subscription.rs new file mode 100644 index 0000000..7be82d1 --- /dev/null +++ b/rhio-operator/src/api/object_store_subscription.rs @@ -0,0 +1,31 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use stackable_operator::kube::CustomResource; + +#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)] +#[cfg_attr(test, derive(Default))] +#[kube( + kind = "ReplicatedObjectStoreSubscription", + group = "rhio.io", + version = "v1", + namespaced, + crates( + kube_core = "stackable_operator::kube::core", + k8s_openapi = "stackable_operator::k8s_openapi", + schemars = "stackable_operator::schemars" + ) +)] +#[kube(status = "ReplicatedObjectStoreSubscriptionStatus", shortname = "ross")] +pub struct ReplicatedObjectStoreSubscriptionSpec { + pub subscriptions: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default)] +#[serde(rename_all = "camelCase")] +pub struct SubscriptionsSpec { + pub public_key: String, + pub buckets: Vec, +} + +#[derive(Deserialize, Serialize, Clone, Default, Debug, JsonSchema)] +pub struct ReplicatedObjectStoreSubscriptionStatus {} diff --git a/rhio-operator/src/api/service.rs b/rhio-operator/src/api/service.rs new file mode 100644 index 0000000..c310f31 --- /dev/null +++ b/rhio-operator/src/api/service.rs @@ -0,0 +1,213 @@ +use std::collections::BTreeMap; + +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use stackable_operator::commons::cluster_operation::ClusterOperation; +use stackable_operator::config::fragment::Fragment; +use stackable_operator::config::merge::Merge; +use stackable_operator::kube::CustomResource; +use stackable_operator::product_config_utils::Configuration; +use stackable_operator::status::condition::ClusterCondition; +use stackable_operator::status::condition::HasStatusCondition; + +#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)] +#[cfg_attr(test, derive(Default))] +#[kube( + kind = "RhioService", + group = "rhio.io", + version = "v1", + namespaced, + plural = "rhioservices", + status = "RhioServiceStatus", + shortname = "rhio", + crates( + kube_core = "stackable_operator::kube::core", + k8s_openapi = "stackable_operator::k8s_openapi", + schemars = "stackable_operator::schemars" + ) +)] +pub struct RhioServiceSpec { + pub configuration: RhioConfig, + pub app_version_label: String, + pub nodes: Vec, + pub network_id: String, + pub s3: S3ConfigSpec, + pub nats: NatsConfigSpec, + #[serde(default)] + pub cluster_operation: ClusterOperation, + pub status: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default)] +#[serde(rename_all = "camelCase")] +pub struct S3ConfigSpec { + pub endpoint: String, + pub region: String, + pub credential_secret: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default)] +#[serde(rename_all = "camelCase")] +pub struct NatsConfigSpec { + pub endpoint: String, + pub credential_secret: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default)] +#[serde(rename_all = "camelCase")] +pub struct NodePeerConfigSpec { + pub public_key: String, + pub endpoints: Vec, +} + +#[derive(Deserialize, Serialize, Clone, Default, Debug, JsonSchema)] +pub struct RhioServiceStatus { + #[serde(default)] + pub conditions: Vec, +} + +impl HasStatusCondition for RhioServiceSpec { + fn conditions(&self) -> Vec { + match &self.status { + Some(status) => status.conditions.clone(), + None => vec![], + } + } +} + +#[derive(Clone, Deserialize, Debug, Eq, JsonSchema, PartialEq, Fragment, Serialize, Default)] +#[fragment_attrs( + derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq, Serialize), + serde(rename_all = "camelCase") +)] +pub struct RhioConfig { + pub bind_port: u16, + pub http_bind_port: u16, + pub network_id: String, + + #[fragment_attrs(serde(default))] + pub private_key_path: String, + + #[fragment_attrs(serde(default))] + pub s3: Option, + + #[fragment_attrs(serde(default))] + pub nats: Option, +} + +impl RhioConfig { + pub fn default_config(network_name: &str) -> RhioConfigFragment { + RhioConfigFragment { + bind_port: Some(9102), + http_bind_port: Some(8080), + network_id: Some(network_name.into()), + private_key_path: Some("/etc/rhio/private_key.txt".into()), + s3: None, + nats: None, + } + } +} + +impl Configuration for RhioConfigFragment { + type Configurable = RhioConfig; + + fn compute_env( + &self, + _resource: &Self::Configurable, + _role_name: &str, + ) -> Result>, stackable_operator::product_config_utils::Error> + { + Ok(BTreeMap::new()) + } + + fn compute_cli( + &self, + _resource: &Self::Configurable, + _role_name: &str, + ) -> Result>, stackable_operator::product_config_utils::Error> + { + Ok(BTreeMap::new()) + } + + fn compute_files( + &self, + _resource: &Self::Configurable, + _role_name: &str, + _file: &str, + ) -> Result>, stackable_operator::product_config_utils::Error> + { + let config = BTreeMap::new(); + + Ok(config) + } +} + +#[derive(Clone, Deserialize, Debug, Eq, JsonSchema, PartialEq, Fragment, Serialize, Default)] +#[fragment_attrs( + derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq, Serialize), + serde(rename_all = "camelCase") +)] +pub struct S3Config { + pub endpoint: String, + pub region: String, + pub credentials: Option, +} + +#[derive(Clone, Deserialize, Debug, Eq, JsonSchema, PartialEq, Fragment, Serialize, Default)] +#[fragment_attrs( + derive( + Clone, + Debug, + Default, + Deserialize, + JsonSchema, + Merge, + PartialEq, + Serialize + ), + serde(rename_all = "camelCase") +)] +pub struct S3Credentials { + pub access_key: String, + pub secret_key: String, +} + +#[derive(Clone, Deserialize, Debug, Eq, JsonSchema, PartialEq, Fragment, Serialize, Default)] +#[fragment_attrs( + derive( + Clone, + Debug, + Default, + Deserialize, + JsonSchema, + // Merge, + PartialEq, + Serialize + ), + serde(rename_all = "camelCase") +)] +pub struct NatsConfig { + pub endpoint: String, + + pub credentials: Option, +} + +#[derive(Clone, Deserialize, Debug, Eq, JsonSchema, PartialEq, Fragment, Serialize, Default)] +#[fragment_attrs( + derive( + Clone, + Debug, + Default, + Deserialize, + JsonSchema, + Merge, + PartialEq, + Serialize + ), + serde(rename_all = "camelCase") +)] + +pub struct NatsCredentials { + pub username: String, + pub password: String, +} diff --git a/rhio-operator/src/crdgen.rs b/rhio-operator/src/crdgen.rs new file mode 100644 index 0000000..e516bd0 --- /dev/null +++ b/rhio-operator/src/crdgen.rs @@ -0,0 +1,30 @@ +use rhio_operator::api::message_stream::ReplicatedMessageStream; +use rhio_operator::api::message_stream_subscription::ReplicatedMessageStreamSubscription; +use rhio_operator::api::object_store::ReplicatedObjectStore; +use rhio_operator::api::object_store_subscription::ReplicatedObjectStoreSubscription; +use rhio_operator::api::service::RhioService; +use stackable_operator::kube::CustomResourceExt; + +fn main() { + print!( + "{}", + serde_yaml::to_string(&ReplicatedObjectStore::crd()).unwrap() + ); + println!("---"); + print!( + "{}", + serde_yaml::to_string(&ReplicatedObjectStoreSubscription::crd()).unwrap() + ); + println!("---"); + print!( + "{}", + serde_yaml::to_string(&ReplicatedMessageStream::crd()).unwrap() + ); + println!("---"); + print!( + "{}", + serde_yaml::to_string(&ReplicatedMessageStreamSubscription::crd()).unwrap() + ); + println!("---"); + print!("{}", serde_yaml::to_string(&RhioService::crd()).unwrap()); +} diff --git a/rhio-operator/src/lib.rs b/rhio-operator/src/lib.rs new file mode 100644 index 0000000..e5fdf85 --- /dev/null +++ b/rhio-operator/src/lib.rs @@ -0,0 +1 @@ +pub mod api;