Skip to content

Commit 90d4a2f

Browse files
siegfriedweberTechassiadwk67labrenbesbernauer
authored
Smooth operator (#1225)
* chore: Import framework code from opensearch-operator This commit imports the framework code from the opensearch-operator by first moving over the relevant files (located at rust/operator-binary/ src/framework) commit-by-commit, then squashing them in a interactive rebase. This commit message includes a list of the individual commit titles. It also includes all authore and co-authors of the original commits as co-authors. List of commits: - feat: Add listener support (opensearch-operator#17) - feat: Make OPENSEARCH_HOME and OPENSEARCH_PATH_CONF overridable (opensearch-operator#18) - Fix technical debts (opensearch-operator#20) - test: Add unit tests (opensearch-operator#32) - feat: Improve name types (opensearch-operator#35) - chore: Upgrade dependencies (opensearch-operator#37) - feat: Support log configuration and log aggregation (opensearch-operator#40) - feat: Support regular expressions in attributed_string_type (opensearch-operator#88) - feat: TLS support (opensearch-operator#55) - feat: Support objectOverrides (opensearch-operator#93) - chore: Use anchors in regular expressions (opensearch-operator#102) - chore: Move controller utility functions to separate module (opensearch-operator#104) - chore: Add Port type (opensearch-operator#105) - feat: Service discovery and exposition (opensearch-operator#94) - chore: Bump OpenSearch version 3.4.0 (opensearch-operator#108) - chore: Bump to stackable-operator 0.106.1 (opensearch-operator#116) - feat: Allow the configuration of the security plugin (opensearch-operator#117) - feat: Support hot-reloading for security configuration files (opensearch-operator#130) - chore: Upgrade stackable-operator to 0.110.1 (opensearch-operator#137) Co-authored-by: Andrew Kenworthy <1712947+adwk67@users.noreply.github.com> Co-authored-by: Benedikt Labrenz <benedikt@labrenz.org> Co-authored-by: Sebastian Bernauer <sebastian.bernauer@stackable.tech> Co-authored-by: Siegfried Weber <mail@siegfriedweber.net> Co-authored-by: Malte Sander <malte.sander.it@gmail.com> * fix: make config_overrides public (#1210) fix(config_overrides): make config_overrides public, fix clippy & doc checks * Fix/make role and group utils pub (#1212) * deps: add uuid crate 1.23 * fix: add missing traits; macros and types pub. * fix: adapt pathes * fix: make builder pub * fix: make role-utils and role-group-utils pub * fix: correct fragment and merge macro path * fix: remaining precommit * fix: doc tests * fix: make missing v2 framework utils pub (#1216) * refactor: Add config file writers to v2 (#1217) * feat(v2): add shared config-file writers (java-properties/Hadoop-XML + Flask) Adds v2::config_file_writer (to_java_properties_string + to_hadoop_xml, backed by the java-properties and xml crates) and v2::flask_config_writer (the Flask App Builder Python config writer), both originally from the product-config crate's writer modules and until now vendored separately into the operators (hdfs/hbase/hive byte-identical full copies; kafka/nifi/zookeeper java-only subsets; airflow/superset identical Flask copies). Unit tests moved along with the code; minor lint-driven cleanups only (use_self, format_push_string, identical match arms, no unwrap in Result-returning tests) — rendered output is unchanged and pinned by the tests. Operators will migrate to these in follow-up commits, deleting their vendored copies. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: fix rustdoc warnings (broken intra-doc links, bare URLs) stackable-operator: intra-doc links within the crate must use `crate::` rather than the package name `stackable_operator::`, which is not in scope and produced `broken_intra_doc_links` warnings. Also wrap two bare URLs in the scaler docs in angle brackets so rustdoc renders them as hyperlinks. stackable-telemetry: `SettingsBuilder` is not imported in `tracing/mod.rs` (only `Settings` is), so the four doc links to it did not resolve. Point them at `settings::SettingsBuilder` via the child module, keeping the rendered link text unchanged. `cargo doc --document-private-items` is now warning-free across the workspace. * Update crates/stackable-operator/src/v2/config_file_writer.rs Co-authored-by: maltesander <malte.sander.it@gmail.com> * Apply suggestions from code review Co-authored-by: maltesander <malte.sander.it@gmail.com> * remove error suffix and clippy --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: maltesander <malte.sander.it@gmail.com> * fix: remove option part for properties writer (#1218) * fix: remove option part for properties writer (now takes <String,String> instead of <String,<Option<String>> * fix: precommit * Change KeyValueConfigOverrides to `BTreeMap<String, String>` (#1219) * Make JvmArgumentOverrides mergeable (#1220) * Add function to build a metrics Service name (#1221) * Relax the length constraints of cluster, role and role group name (#1222) * Relax the length constraints of cluster, role and role group name * Adapt compile-time assertions * Check that ensure_max_length is only called with ASCII resource names * Fix: make rolegroup replicas optional (#1223) refactor: make replicas optional for HPA support * chore(stackable-operator): Update changelog * stackable-operator: Add feature test-support * Remove unnecessary Clippy hints * Improve code style * Use attributed string type for EnvVarName * Allow expressions in the constant macro * Add types for DaemonSetName and DeploymentName * Add functions to create Prometheus labels and annotations --------- Co-authored-by: Techassi <git@techassi.dev> Co-authored-by: Andrew Kenworthy <1712947+adwk67@users.noreply.github.com> Co-authored-by: Benedikt Labrenz <benedikt@labrenz.org> Co-authored-by: Sebastian Bernauer <sebastian.bernauer@stackable.tech> Co-authored-by: Malte Sander <malte.sander.it@gmail.com> Co-authored-by: Razvan-Daniel Mihai <84674+razvan@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent f6ec283 commit 90d4a2f

36 files changed

Lines changed: 5382 additions & 106 deletions

Cargo.lock

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

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ insta = { version = "1.40", features = ["glob"] }
3838
hyper = { version = "1.4.1", features = ["full"] }
3939
hyper-util = "0.1.8"
4040
itertools = "0.14.0"
41+
java-properties = "2.0"
4142
json-patch = "4.0.0"
4243
k8s-openapi = { version = "0.27.0", default-features = false, features = ["schemars", "v1_35"] }
4344
# We use rustls instead of openssl for easier portability, e.g. so that we can build stackablectl without the need to vendor (build from source) openssl
@@ -86,8 +87,10 @@ tracing-opentelemetry = "0.33.0"
8687
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "json"] }
8788
trybuild = "1.0.99"
8889
url = { version = "2.5.2", features = ["serde"] }
90+
uuid = "1.23"
8991
winnow = "1.0.3"
9092
x509-cert = { version = "0.2.5", features = ["builder"] }
93+
xml = "1.3"
9194
zeroize = "1.8.1"
9295

9396
[workspace.lints.clippy]

crates/stackable-operator/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
88

99
- Add `Client::{get_feature_gates,get_enabled_feature_gates,get_disabled_feature_gates}` associated
1010
functions to retrieve all, enabled, or disabled feature gates from the Kubernetes apiserver ([#1207], [#1208]).
11+
- Add a new `v2` module that provides more type-safe variants of the existing functions ([#1225]).
1112

1213
### Changed
1314

@@ -16,6 +17,7 @@ All notable changes to this project will be documented in this file.
1617
[#1206]: https://github.com/stackabletech/operator-rs/pull/1206
1718
[#1207]: https://github.com/stackabletech/operator-rs/pull/1207
1819
[#1208]: https://github.com/stackabletech/operator-rs/pull/1208
20+
[#1225]: https://github.com/stackabletech/operator-rs/pull/1225
1921

2022
## [0.111.1] - 2026-04-28
2123

crates/stackable-operator/Cargo.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ repository.workspace = true
99

1010
[features]
1111
default = ["crds"]
12-
full = ["client-feature-gates", "crds", "certs", "time", "webhook", "kube-ws"]
12+
full = ["client-feature-gates", "crds", "certs", "test-support", "time", "webhook", "kube-ws"]
1313

1414
client-feature-gates = ["dep:winnow"]
1515
crds = ["dep:stackable-versioned"]
1616
certs = ["dep:stackable-certs"]
17+
test-support = []
1718
time = ["stackable-shared/time"]
1819
webhook = ["dep:stackable-webhook"]
1920
kube-ws = ["kube/ws"]
@@ -36,8 +37,9 @@ educe.workspace = true
3637
futures.workspace = true
3738
http.workspace = true
3839
indexmap.workspace = true
40+
java-properties.workspace = true
3941
jiff.workspace = true
40-
json-patch.workspace = true
42+
json-patch = { workspace = true, features = ["schemars"] }
4143
k8s-openapi.workspace = true
4244
kube.workspace = true
4345
product-config.workspace = true
@@ -48,14 +50,17 @@ semver.workspace = true
4850
serde_json.workspace = true
4951
serde_yaml.workspace = true
5052
serde.workspace = true
53+
sha2.workspace = true
5154
snafu.workspace = true
5255
strum.workspace = true
5356
tokio.workspace = true
5457
tracing.workspace = true
5558
tracing-appender.workspace = true
5659
tracing-subscriber.workspace = true
5760
url.workspace = true
61+
uuid.workspace = true
5862
winnow = { workspace = true, optional = true }
63+
xml.workspace = true
5964

6065
[dev-dependencies]
6166
indoc.workspace = true

crates/stackable-operator/crds/Scaler.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ spec:
3333
3434
Upstream issues:
3535
36-
- https://github.com/kubernetes/kubernetes/issues/105533
37-
- https://github.com/Arnavion/k8s-openapi/issues/136
36+
- <https://github.com/kubernetes/kubernetes/issues/105533>
37+
- <https://github.com/Arnavion/k8s-openapi/issues/136>
3838
format: uint16
3939
maximum: 65535.0
4040
minimum: 0.0

crates/stackable-operator/src/crd/scaler/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ pub mod versioned {
3131
///
3232
/// Upstream issues:
3333
///
34-
/// - https://github.com/kubernetes/kubernetes/issues/105533
35-
/// - https://github.com/Arnavion/k8s-openapi/issues/136
34+
/// - <https://github.com/kubernetes/kubernetes/issues/105533>
35+
/// - <https://github.com/Arnavion/k8s-openapi/issues/136>
3636
pub replicas: u16,
3737
}
3838
}

crates/stackable-operator/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub mod role_utils;
3333
pub mod status;
3434
pub mod test_utils;
3535
pub mod utils;
36+
pub mod v2;
3637
pub mod validation;
3738

3839
// External re-exports
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub mod meta;
2+
pub mod pdb;
3+
pub mod pod;
4+
pub mod service;
5+
pub mod statefulset;
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
use crate::{
2+
builder::meta::OwnerReferenceBuilder,
3+
k8s_openapi::apimachinery::pkg::apis::meta::v1::OwnerReference,
4+
kube::Resource,
5+
v2::{HasName, HasUid},
6+
};
7+
8+
/// Infallible variant of
9+
/// [`crate::builder::meta::ObjectMetaBuilder::ownerreference_from_resource`]
10+
pub fn ownerreference_from_resource(
11+
resource: &(impl Resource<DynamicType = ()> + HasName + HasUid),
12+
block_owner_deletion: Option<bool>,
13+
controller: Option<bool>,
14+
) -> OwnerReference {
15+
OwnerReferenceBuilder::new()
16+
// Set api_version, kind, name and additionally the UID if it exists.
17+
.initialize_from_resource(resource)
18+
// Ensure that the name is set.
19+
.name(resource.to_name())
20+
// Ensure that the UID is set.
21+
.uid(resource.to_uid().to_string())
22+
.block_owner_deletion_opt(block_owner_deletion)
23+
.controller_opt(controller)
24+
.build()
25+
.expect(
26+
"OwnerReference should be created because the resource has an api_version, kind, name \
27+
and uid.",
28+
)
29+
}
30+
31+
#[cfg(test)]
32+
mod tests {
33+
use std::borrow::Cow;
34+
35+
use crate::{
36+
k8s_openapi::apimachinery::pkg::apis::meta::v1::{ObjectMeta, OwnerReference},
37+
kube::Resource,
38+
v2::{HasName, HasUid, Uid, builder::meta::ownerreference_from_resource},
39+
};
40+
41+
struct Cluster {
42+
object_meta: ObjectMeta,
43+
}
44+
45+
impl Cluster {
46+
fn new() -> Self {
47+
Self {
48+
object_meta: ObjectMeta {
49+
name: Some("cluster-name".to_owned()),
50+
uid: Some("a6b89911-d48e-4328-88d6-b9251226583d".to_owned()),
51+
..ObjectMeta::default()
52+
},
53+
}
54+
}
55+
}
56+
57+
impl Resource for Cluster {
58+
type DynamicType = ();
59+
type Scope = ();
60+
61+
fn kind(_dt: &Self::DynamicType) -> Cow<'_, str> {
62+
Cow::from("kind")
63+
}
64+
65+
fn group(_dt: &Self::DynamicType) -> Cow<'_, str> {
66+
Cow::from("group")
67+
}
68+
69+
fn version(_dt: &Self::DynamicType) -> Cow<'_, str> {
70+
Cow::from("version")
71+
}
72+
73+
fn plural(_dt: &Self::DynamicType) -> Cow<'_, str> {
74+
Cow::from("plural")
75+
}
76+
77+
fn meta(&self) -> &ObjectMeta {
78+
&self.object_meta
79+
}
80+
81+
fn meta_mut(&mut self) -> &mut ObjectMeta {
82+
&mut self.object_meta
83+
}
84+
}
85+
86+
impl HasName for Cluster {
87+
fn to_name(&self) -> String {
88+
self.object_meta
89+
.name
90+
.clone()
91+
.expect("should be set in Cluster::new")
92+
}
93+
}
94+
95+
impl HasUid for Cluster {
96+
fn to_uid(&self) -> Uid {
97+
Uid::from_str_unsafe(
98+
&self
99+
.object_meta
100+
.uid
101+
.clone()
102+
.expect("should be set in Cluster::new"),
103+
)
104+
}
105+
}
106+
107+
#[test]
108+
fn test_ownerreference_from_resource() {
109+
let actual_owner_reference =
110+
ownerreference_from_resource(&Cluster::new(), Some(true), Some(true));
111+
112+
let expected_owner_reference = OwnerReference {
113+
api_version: "group/version".to_owned(),
114+
block_owner_deletion: Some(true),
115+
controller: Some(true),
116+
kind: "kind".to_owned(),
117+
name: "cluster-name".to_owned(),
118+
uid: "a6b89911-d48e-4328-88d6-b9251226583d".to_owned(),
119+
};
120+
121+
assert_eq!(expected_owner_reference, actual_owner_reference);
122+
}
123+
}

0 commit comments

Comments
 (0)