Skip to content

Commit fb6202e

Browse files
committed
chore: Merge branch 'main' into chore/add-crd-versioning
2 parents a1c5a52 + a6d8db5 commit fb6202e

File tree

26 files changed

+375
-352
lines changed

26 files changed

+375
-352
lines changed

Cargo.lock

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

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ insta = { version= "1.40", features = ["glob"] }
3030
hyper = { version = "1.4.1", features = ["full"] }
3131
hyper-util = "0.1.8"
3232
itertools = "0.14.0"
33-
json-patch = "3.0.1"
33+
json-patch = "4.0.0"
3434
k8s-openapi = { version = "0.24.0", default-features = false, features = ["schemars", "v1_32"] }
3535
# 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
36-
kube = { version = "0.98.0", default-features = false, features = ["client", "jsonpatch", "runtime", "derive", "rustls-tls"] }
36+
kube = { version = "0.99.0", default-features = false, features = ["client", "jsonpatch", "runtime", "derive", "rustls-tls"] }
3737
opentelemetry = "0.23.0"
3838
opentelemetry_sdk = { version = "0.23.0", features = ["rt-tokio"] }
3939
opentelemetry-appender-tracing = "0.4.0"

crates/stackable-certs/src/ca/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ where
380380
key_certificate: &str,
381381
key_private_key: &str,
382382
) -> Result<Self, SecretError<S::Error>> {
383-
if !secret.type_.as_ref().is_some_and(|s| s == TLS_SECRET_TYPE) {
383+
if secret.type_.as_ref().is_none_or(|s| s != TLS_SECRET_TYPE) {
384384
return InvalidSecretTypeSnafu.fail();
385385
}
386386

crates/stackable-operator/CHANGELOG.md

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

55
## [Unreleased]
66

7+
## [0.87.4] - 2025-03-17
8+
9+
## [0.87.3] - 2025-03-14
10+
11+
### Added
12+
13+
- Add a `Region::is_default_config` function to determine if a region sticks to the default config ([#983]).
14+
15+
[#983]: https://github.com/stackabletech/operator-rs/pull/983
16+
17+
## [0.87.2] - 2025-03-10
18+
19+
### Changed
20+
21+
- Make `region.name` field in in S3ConnectionSpec public ([#980]).
22+
23+
[#980]: https://github.com/stackabletech/operator-rs/pull/980
24+
25+
## [0.87.1] - 2025-03-10
26+
27+
### Changed
28+
29+
- Refactor `region` field in S3ConnectionSpec ([#976]).
30+
31+
[#976]: https://github.com/stackabletech/operator-rs/pull/976
32+
733
## [0.87.0] - 2025-02-28
834

935
### Changed
@@ -24,7 +50,7 @@ All notable changes to this project will be documented in this file.
2450

2551
### Added
2652

27-
- Add `region` field to S3ConnectionSpec ([#959]).
53+
- BREAKING: Add `region` field to S3ConnectionSpec (defaults to `us-east-1`) ([#959]).
2854

2955
[#959]: https://github.com/stackabletech/operator-rs/pull/959
3056

crates/stackable-operator/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "stackable-operator"
33
description = "Stackable Operator Framework"
4-
version = "0.87.0"
4+
version = "0.87.4"
55
authors.workspace = true
66
license.workspace = true
77
edition.workspace = true

crates/stackable-operator/src/commons/rbac.rs

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ pub enum Error {
3030
/// Build RBAC objects for the product workloads.
3131
/// The `product_name` is meant to be the product name, for example: zookeeper, airflow, etc.
3232
/// and it is a assumed that a ClusterRole named `{product_name}-clusterrole` exists.
33-
3433
pub fn build_rbac_resources<T: Clone + Resource<DynamicType = ()>>(
3534
resource: &T,
3635
// 'product_name' is not used to build the names of the serviceAccount and roleBinding objects,

crates/stackable-operator/src/config/fragment.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct Validator<'a> {
2626
parent: Option<&'a Validator<'a>>,
2727
}
2828

29-
impl<'a> Validator<'a> {
29+
impl Validator<'_> {
3030
/// Creates a `Validator` for a subfield of the current object
3131
pub fn field<'b>(&'b self, ident: &'b dyn Display) -> Validator<'b> {
3232
Validator {

crates/stackable-operator/src/config/merge.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ impl Atomic for bool {}
146146
impl Atomic for String {}
147147
impl Atomic for Quantity {}
148148
impl Atomic for Duration {}
149-
impl<'a> Atomic for &'a str {}
149+
impl Atomic for &str {}
150150
impl Atomic for LabelSelector {}
151151
impl Atomic for PodAffinity {}
152152
impl Atomic for PodAntiAffinity {}

crates/stackable-operator/src/cpu.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl<'de> Deserialize<'de> for CpuQuantity {
7070
{
7171
struct CpuQuantityVisitor;
7272

73-
impl<'de> Visitor<'de> for CpuQuantityVisitor {
73+
impl Visitor<'_> for CpuQuantityVisitor {
7474
type Value = CpuQuantity;
7575

7676
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {

crates/stackable-operator/src/crd/s3/connection.rs

+28-57
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,19 @@ pub struct ConnectionSpec {
7373
#[serde(default, skip_serializing_if = "Option::is_none")]
7474
pub port: Option<u16>,
7575

76-
/// AWS service API region used by the AWS SDK when using AWS S3 buckets.
76+
/// Bucket region used for signing headers (sigv4).
7777
///
78-
/// This defaults to `us-east-1` and can be ignored if not using AWS S3
79-
/// buckets.
78+
/// This defaults to `us-east-1` which is compatible with other implementations such as Minio.
8079
///
81-
/// NOTE: This is not the bucket region, and is used by the AWS SDK to
82-
/// construct endpoints for various AWS service APIs. It is only useful when
83-
/// using AWS S3 buckets.
84-
///
85-
/// When using AWS S3 buckets, you can configure optimal AWS service API
86-
/// connections in the following ways:
87-
/// - From **inside** AWS: Use an auto-discovery source (eg: AWS IMDS).
88-
/// - From **outside** AWS, or when IMDS is disabled, explicity set the
89-
/// region name nearest to where the client application is running from.
80+
/// WARNING: Some products use the Hadoop S3 implementation which falls back to us-east-2.
9081
#[serde(default)]
91-
pub region: AwsRegion,
82+
pub region: Region,
9283

9384
/// Which access style to use.
9485
/// Defaults to virtual hosted-style as most of the data products out there.
9586
/// Have a look at the [AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html).
9687
#[serde(default)]
97-
pub access_style: AccessStyle,
88+
pub access_style: S3AccessStyle,
9889

9990
/// If the S3 uses authentication you have to specify you S3 credentials.
10091
/// In the most cases a [SecretClass](DOCS_BASE_URL_PLACEHOLDER/secret-operator/secretclass)
@@ -111,7 +102,7 @@ pub struct ConnectionSpec {
111102
strum::Display, Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize,
112103
)]
113104
#[strum(serialize_all = "PascalCase")]
114-
pub enum AccessStyle {
105+
pub enum S3AccessStyle {
115106
/// Use path-style access as described in <https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#path-style-access>
116107
Path,
117108

@@ -120,60 +111,40 @@ pub enum AccessStyle {
120111
VirtualHosted,
121112
}
122113

123-
/// Set a named AWS region, or defer to an auto-discovery mechanism.
114+
/// Set a named S3 Bucket region.
124115
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
125116
#[serde(rename_all = "camelCase")]
126-
pub enum AwsRegion {
127-
/// Defer region detection to an auto-discovery mechanism.
128-
Source(AwsRegionAutoDiscovery),
129-
130-
/// An explicit region, eg: eu-central-1
131-
Name(String),
117+
pub struct Region {
118+
#[serde(default = "Region::default_region_name")]
119+
pub name: String,
132120
}
133121

134-
impl AwsRegion {
135-
/// Get the AWS region name.
136-
///
137-
/// Returns `None` if an auto-discovery source has been selected. Otherwise,
138-
/// it returns the configured region name.
139-
///
140-
/// Example usage:
122+
impl Region {
123+
/// Having it as `const &str` as well, so we don't always allocate a [`String`] just for comparisons
124+
pub const DEFAULT_REGION_NAME: &str = "us-east-1";
125+
126+
fn default_region_name() -> String {
127+
Self::DEFAULT_REGION_NAME.to_string()
128+
}
129+
130+
/// Returns if the region sticks to the Stackable defaults.
141131
///
142-
/// ```
143-
/// # use stackable_operator::commons::s3::AwsRegion;
144-
/// # fn set_property(key: &str, value: &str) {}
145-
/// # fn example(aws_region: AwsRegion) {
146-
/// if let Some(region_name) = aws_region.name() {
147-
/// // set some property if the region is set, or is the default.
148-
/// set_property("aws.region", region_name);
149-
/// };
150-
/// # }
151-
/// ```
152-
pub fn name(&self) -> Option<&str> {
153-
match self {
154-
AwsRegion::Name(name) => Some(name),
155-
AwsRegion::Source(_) => None,
156-
}
132+
/// Some products don't really support configuring the region.
133+
/// This function can be used to determine if a warning or error should be raised to inform the
134+
/// user of this situation.
135+
pub fn is_default_config(&self) -> bool {
136+
self.name == Self::DEFAULT_REGION_NAME
157137
}
158138
}
159139

160-
impl Default for AwsRegion {
140+
impl Default for Region {
161141
fn default() -> Self {
162-
Self::Name("us-east-1".to_owned())
142+
Self {
143+
name: Self::default_region_name(),
144+
}
163145
}
164146
}
165147

166-
/// AWS region auto-discovery mechanism.
167-
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
168-
#[serde(rename_all = "PascalCase")]
169-
pub enum AwsRegionAutoDiscovery {
170-
/// AWS Instance Meta Data Service.
171-
///
172-
/// This variant should result in no region being given to the AWS SDK,
173-
/// which should, in turn, query the AWS IMDS.
174-
AwsImds,
175-
}
176-
177148
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
178149
#[serde(rename_all = "camelCase")]
179150
// TODO: This probably should be serde(untagged), but this would be a breaking change

crates/stackable-operator/src/memory.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ impl<'de> Deserialize<'de> for MemoryQuantity {
347347
{
348348
struct MemoryQuantityVisitor;
349349

350-
impl<'de> Visitor<'de> for MemoryQuantityVisitor {
350+
impl Visitor<'_> for MemoryQuantityVisitor {
351351
type Value = MemoryQuantity;
352352

353353
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {

crates/stackable-operator/src/status/condition/operations.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub struct ClusterOperationsConditionBuilder<'a> {
1313
cluster_operation: &'a ClusterOperation,
1414
}
1515

16-
impl<'a> ConditionBuilder for ClusterOperationsConditionBuilder<'a> {
16+
impl ConditionBuilder for ClusterOperationsConditionBuilder<'_> {
1717
fn build_conditions(&self) -> ClusterConditionSet {
1818
vec![self.reconciliation_paused(), self.cluster_stopped()].into()
1919
}

crates/stackable-operator/src/time/serde_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::time::Duration;
44

55
struct DurationVisitor;
66

7-
impl<'de> Visitor<'de> for DurationVisitor {
7+
impl Visitor<'_> for DurationVisitor {
88
type Value = Duration;
99

1010
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {

crates/stackable-telemetry/src/instrumentation/axum/extractor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use opentelemetry::{propagation::Extractor, Context};
1818
/// [4]: https://docs.rs/opentelemetry-http/latest/opentelemetry_http/struct.HeaderExtractor.html
1919
pub struct HeaderExtractor<'a>(pub(crate) &'a HeaderMap);
2020

21-
impl<'a> Extractor for HeaderExtractor<'a> {
21+
impl Extractor for HeaderExtractor<'_> {
2222
fn get(&self, key: &str) -> Option<&str> {
2323
self.0
2424
.get(key)

crates/stackable-telemetry/src/instrumentation/axum/injector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use opentelemetry::{propagation::Injector, Context};
2020
/// [5]: https://docs.rs/opentelemetry-http/latest/opentelemetry_http/struct.HeaderInjector.html
2121
pub struct HeaderInjector<'a>(pub(crate) &'a mut HeaderMap);
2222

23-
impl<'a> Injector for HeaderInjector<'a> {
23+
impl Injector for HeaderInjector<'_> {
2424
fn set(&mut self, key: &str, value: String) {
2525
if let Ok(header_name) = HeaderName::from_bytes(key.as_bytes()) {
2626
if let Ok(header_value) = HeaderValue::from_str(&value) {

crates/stackable-versioned-macros/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "stackable-versioned-macros"
3-
version = "0.6.0"
3+
version = "0.7.0"
44
authors.workspace = true
55
license.workspace = true
66
edition.workspace = true

crates/stackable-versioned-macros/src/attrs/k8s.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub(crate) struct KubernetesArguments {
3030
pub(crate) namespaced: Flag,
3131
// root
3232
pub(crate) crates: Option<KubernetesCrateArguments>,
33-
pub(crate) status: Option<String>,
33+
pub(crate) status: Option<Path>,
3434
// derive
3535
// schema
3636
// scale

crates/stackable-versioned-macros/src/codegen/changes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ where
6666
where
6767
F: Fn(&V) -> bool,
6868
{
69-
self.get(key).map_or(false, f)
69+
self.get(key).is_some_and(f)
7070
}
7171

7272
fn lo_bound(&self, bound: Bound<&K>) -> Option<(&K, &V)> {

crates/stackable-versioned-macros/src/codegen/container/enum.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl Container {
3434
.common
3535
.options
3636
.skip
37-
.map_or(false, |s| s.from.is_present()),
37+
.is_some_and(|s| s.from.is_present()),
3838
};
3939

4040
let idents = ContainerIdents::from(item_enum.ident, None);
@@ -68,10 +68,7 @@ impl Container {
6868

6969
let options = ContainerOptions {
7070
kubernetes_options: None,
71-
skip_from: attributes
72-
.options
73-
.skip
74-
.map_or(false, |s| s.from.is_present()),
71+
skip_from: attributes.options.skip.is_some_and(|s| s.from.is_present()),
7572
};
7673

7774
let idents = ContainerIdents::from(item_enum.ident, None);
@@ -209,7 +206,7 @@ impl Enum {
209206
// cannot be deprecated). Then we retrieve the status of the variant and
210207
// ensure it is deprecated.
211208
self.variants.iter().any(|f| {
212-
f.changes.as_ref().map_or(false, |c| {
209+
f.changes.as_ref().is_some_and(|c| {
213210
c.value_is(&version.inner, |a| {
214211
matches!(
215212
a,

crates/stackable-versioned-macros/src/codegen/container/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ pub(crate) struct KubernetesOptions {
275275
pub(crate) namespaced: bool,
276276
// root
277277
pub(crate) crates: KubernetesCrateOptions,
278-
pub(crate) status: Option<String>,
278+
pub(crate) status: Option<Path>,
279279
// derive
280280
// schema
281281
// scale
@@ -302,7 +302,7 @@ impl From<KubernetesArguments> for KubernetesOptions {
302302
.map_or_else(KubernetesCrateOptions::default, |crates| crates.into()),
303303
status: args.status,
304304
shortnames: args.shortnames,
305-
skip_merged_crd: args.skip.map_or(false, |s| s.merged_crd.is_present()),
305+
skip_merged_crd: args.skip.is_some_and(|s| s.merged_crd.is_present()),
306306
}
307307
}
308308
}

crates/stackable-versioned-macros/src/codegen/container/struct.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl Container {
4747
.common
4848
.options
4949
.skip
50-
.map_or(false, |s| s.from.is_present()),
50+
.is_some_and(|s| s.from.is_present()),
5151
kubernetes_options,
5252
};
5353

@@ -90,10 +90,7 @@ impl Container {
9090
}
9191

9292
let options = ContainerOptions {
93-
skip_from: attributes
94-
.options
95-
.skip
96-
.map_or(false, |s| s.from.is_present()),
93+
skip_from: attributes.options.skip.is_some_and(|s| s.from.is_present()),
9794
kubernetes_options,
9895
};
9996

@@ -245,7 +242,7 @@ impl Struct {
245242
// cannot be deprecated). Then we retrieve the status of the field and
246243
// ensure it is deprecated.
247244
self.fields.iter().any(|f| {
248-
f.changes.as_ref().map_or(false, |c| {
245+
f.changes.as_ref().is_some_and(|c| {
249246
c.value_is(&version.inner, |a| {
250247
matches!(
251248
a,

0 commit comments

Comments
 (0)