Skip to content

Commit 51e7e1c

Browse files
chore!: remove thiserror (add module-scoped errors with the help of snafu) (#761)
* remove deprecated exports * refactor: remove thiserror * move error enum to below the Result type-alias * update changelog * use managed_by_labels variable in pdb builder * reorder imports * don't match on metadata * replace map_err with context and remove Box from the error source * remove Ok(..)? * tidy up kube client construction * use proper resource kinds in error * use String Debug impl in error message * rename error variants * upgrade change to breaking * Apply suggestions Co-authored-by: Techassi <[email protected]> * replace map_err with context * remove associated error type * simplify error message * non-java error variants * return Snafu fail() * Apply suggestions Co-authored-by: Techassi <[email protected]> --------- Co-authored-by: Techassi <[email protected]>
1 parent 92eb42d commit 51e7e1c

File tree

34 files changed

+765
-602
lines changed

34 files changed

+765
-602
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ stackable-operator-derive = { path = "stackable-operator-derive" }
5454
strum = { version = "0.26.2", features = ["derive"] }
5555
syn = "2.0.55"
5656
tempfile = "3.10.1"
57-
thiserror = "1.0.58"
5857
time = { version = "0.3.34" }
5958
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread", "fs"] }
6059
tokio-rustls = "0.26.0"

crates/stackable-operator/CHANGELOG.md

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

99
- Bump kube to 0.89.0 and update all dependencies ([#762]).
1010

11+
### Removed
12+
13+
- BREAKING: Remove `thiserror` dependency, and deprecated builder exports ([#761])
14+
15+
[#761]: https://github.com/stackabletech/operator-rs/pull/761
1116
[#762]: https://github.com/stackabletech/operator-rs/pull/762
1217

1318
## [0.66.0] - 2024-03-26

crates/stackable-operator/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ serde_yaml.workspace = true
3636
serde.workspace = true
3737
snafu.workspace = true
3838
strum.workspace = true
39-
thiserror.workspace = true
4039
time = { workspace = true, optional = true }
4140
tokio.workspace = true
4241
tracing-opentelemetry.workspace = true

crates/stackable-operator/src/builder/configmap.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
use crate::error::{Error, OperatorResult};
21
use k8s_openapi::{api::core::v1::ConfigMap, apimachinery::pkg::apis::meta::v1::ObjectMeta};
2+
use snafu::{OptionExt, Snafu};
33
use std::collections::BTreeMap;
44

5+
type Result<T, E = Error> = std::result::Result<T, E>;
6+
7+
#[derive(Snafu, Debug)]
8+
pub enum Error {
9+
#[snafu(display("object is missing key {key:?}"))]
10+
MissingObjectKey { key: &'static str },
11+
}
12+
513
/// A builder to build [`ConfigMap`] objects.
614
#[derive(Clone, Default)]
715
pub struct ConfigMapBuilder {
@@ -41,12 +49,13 @@ impl ConfigMapBuilder {
4149
self
4250
}
4351

44-
pub fn build(&self) -> OperatorResult<ConfigMap> {
52+
pub fn build(&self) -> Result<ConfigMap> {
53+
let metadata = self
54+
.metadata
55+
.clone()
56+
.context(MissingObjectKeySnafu { key: "metadata" })?;
4557
Ok(ConfigMap {
46-
metadata: match self.metadata {
47-
None => return Err(Error::MissingObjectKey { key: "metadata" }),
48-
Some(ref metadata) => metadata.clone(),
49-
},
58+
metadata,
5059
data: self.data.clone(),
5160
..ConfigMap::default()
5261
})

crates/stackable-operator/src/builder/meta.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@ use kube::{Resource, ResourceExt};
33
use snafu::{ResultExt, Snafu};
44
use tracing::warn;
55

6-
use crate::{
7-
error::{Error, OperatorResult},
8-
kvp::{Annotation, Annotations, Label, LabelError, Labels, ObjectLabels},
9-
};
6+
use crate::kvp::{Annotation, Annotations, Label, LabelError, Labels, ObjectLabels};
7+
8+
type Result<T, E = Error> = std::result::Result<T, E>;
109

11-
// NOTE (Techassi): Think about that name
1210
#[derive(Debug, PartialEq, Snafu)]
13-
pub enum ObjectMetaBuilderError {
11+
pub enum Error {
1412
#[snafu(display("failed to set recommended labels"))]
1513
RecommendedLabels { source: LabelError },
14+
15+
#[snafu(display("object is missing key {key:?}"))]
16+
MissingObjectKey { key: &'static str },
1617
}
1718

1819
/// A builder to build [`ObjectMeta`] objects.
@@ -89,7 +90,7 @@ impl ObjectMetaBuilder {
8990
resource: &T,
9091
block_owner_deletion: Option<bool>,
9192
controller: Option<bool>,
92-
) -> OperatorResult<&mut Self> {
93+
) -> Result<&mut Self> {
9394
self.ownerreference = Some(
9495
OwnerReferenceBuilder::new()
9596
.initialize_from_resource(resource)
@@ -151,7 +152,7 @@ impl ObjectMetaBuilder {
151152
pub fn with_recommended_labels<T: Resource>(
152153
&mut self,
153154
object_labels: ObjectLabels<T>,
154-
) -> Result<&mut Self, ObjectMetaBuilderError> {
155+
) -> Result<&mut Self> {
155156
let recommended_labels =
156157
Labels::recommended(object_labels).context(RecommendedLabelsSnafu)?;
157158

@@ -284,24 +285,24 @@ impl OwnerReferenceBuilder {
284285
self
285286
}
286287

287-
pub fn build(&self) -> OperatorResult<OwnerReference> {
288+
pub fn build(&self) -> Result<OwnerReference> {
288289
Ok(OwnerReference {
289290
api_version: match self.api_version {
290-
None => return Err(Error::MissingObjectKey { key: "api_version" }),
291+
None => return MissingObjectKeySnafu { key: "api_version" }.fail(),
291292
Some(ref api_version) => api_version.clone(),
292293
},
293294
block_owner_deletion: self.block_owner_deletion,
294295
controller: self.controller,
295296
kind: match self.kind {
296-
None => return Err(Error::MissingObjectKey { key: "kind" }),
297+
None => return MissingObjectKeySnafu { key: "kind" }.fail(),
297298
Some(ref kind) => kind.clone(),
298299
},
299300
name: match self.name {
300-
None => return Err(Error::MissingObjectKey { key: "name" }),
301+
None => return MissingObjectKeySnafu { key: "name" }.fail(),
301302
Some(ref name) => name.clone(),
302303
},
303304
uid: match self.uid {
304-
None => return Err(Error::MissingObjectKey { key: "uid" }),
305+
None => return MissingObjectKeySnafu { key: "uid" }.fail(),
305306
Some(ref uid) => uid.clone(),
306307
},
307308
})

crates/stackable-operator/src/builder/mod.rs

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,3 @@ pub mod event;
88
pub mod meta;
99
pub mod pdb;
1010
pub mod pod;
11-
12-
#[deprecated(since = "0.15.0", note = "Please use `builder::configmap::*` instead.")]
13-
pub use configmap::*;
14-
15-
#[deprecated(since = "0.15.0", note = "Please use `builder::event::*` instead.")]
16-
pub use event::*;
17-
18-
#[deprecated(since = "0.15.0", note = "Please use `builder::meta::*` instead.")]
19-
pub use meta::*;
20-
21-
#[deprecated(
22-
since = "0.15.0",
23-
note = "Please use `builder::pod::container::*` instead."
24-
)]
25-
pub use pod::container::*;
26-
27-
#[deprecated(
28-
since = "0.15.0",
29-
note = "Please use `builder::pod::security::*` instead."
30-
)]
31-
pub use pod::security::*;
32-
33-
#[deprecated(
34-
since = "0.15.0",
35-
note = "Please use `builder::pod::volume::*` instead."
36-
)]
37-
pub use pod::volume::*;
38-
39-
#[deprecated(since = "0.15.0", note = "Please use `builder::pod::*` instead.")]
40-
pub use pod::*;

crates/stackable-operator/src/builder/pdb.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,27 @@ use k8s_openapi::{
66
},
77
};
88
use kube::{Resource, ResourceExt};
9+
use snafu::{ResultExt, Snafu};
910

1011
use crate::{
11-
builder::ObjectMetaBuilder,
12-
error::OperatorResult,
12+
builder::meta::ObjectMetaBuilder,
1313
kvp::{Label, Labels},
1414
};
1515

16+
type Result<T, E = Error> = std::result::Result<T, E>;
17+
18+
#[derive(Debug, PartialEq, Snafu)]
19+
pub enum Error {
20+
#[snafu(display("failed to create role selector labels"))]
21+
RoleSelectorLabels { source: crate::kvp::LabelError },
22+
23+
#[snafu(display("failed to set owner reference from resource"))]
24+
OwnerReferenceFromResource { source: crate::builder::meta::Error },
25+
26+
#[snafu(display("failed to create app.kubernetes.io/managed-by label"))]
27+
ManagedByLabel { source: crate::kvp::LabelError },
28+
}
29+
1630
/// This builder is used to construct [`PodDisruptionBudget`]s.
1731
/// If you are using this to create [`PodDisruptionBudget`]s according to [ADR 30 on Allowed Pod disruptions][adr],
1832
/// the use of [`PodDisruptionBudgetBuilder::new_with_role`] is recommended.
@@ -70,14 +84,18 @@ impl PodDisruptionBudgetBuilder<(), (), ()> {
7084
role: &str,
7185
operator_name: &str,
7286
controller_name: &str,
73-
) -> OperatorResult<PodDisruptionBudgetBuilder<ObjectMeta, LabelSelector, ()>> {
74-
let role_selector_labels = Labels::role_selector(owner, app_name, role)?;
87+
) -> Result<PodDisruptionBudgetBuilder<ObjectMeta, LabelSelector, ()>> {
88+
let role_selector_labels =
89+
Labels::role_selector(owner, app_name, role).context(RoleSelectorLabelsSnafu)?;
90+
let managed_by_label =
91+
Label::managed_by(operator_name, controller_name).context(ManagedByLabelSnafu)?;
7592
let metadata = ObjectMetaBuilder::new()
7693
.namespace_opt(owner.namespace())
7794
.name(format!("{}-{}", owner.name_any(), role))
78-
.ownerreference_from_resource(owner, None, Some(true))?
95+
.ownerreference_from_resource(owner, None, Some(true))
96+
.context(OwnerReferenceFromResourceSnafu)?
7997
.with_labels(role_selector_labels.clone())
80-
.with_label(Label::managed_by(operator_name, controller_name)?)
98+
.with_label(managed_by_label)
8199
.build();
82100

83101
Ok(PodDisruptionBudgetBuilder {
@@ -191,7 +209,7 @@ mod test {
191209
use schemars::JsonSchema;
192210
use serde::{Deserialize, Serialize};
193211

194-
use crate::builder::{ObjectMetaBuilder, OwnerReferenceBuilder};
212+
use crate::builder::meta::{ObjectMetaBuilder, OwnerReferenceBuilder};
195213

196214
use super::PodDisruptionBudgetBuilder;
197215

crates/stackable-operator/src/builder/pod/container.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
1+
use std::fmt;
2+
13
use k8s_openapi::api::core::v1::{
24
ConfigMapKeySelector, Container, ContainerPort, EnvVar, EnvVarSource, Lifecycle,
35
LifecycleHandler, ObjectFieldSelector, Probe, ResourceRequirements, SecretKeySelector,
46
SecurityContext, VolumeMount,
57
};
6-
use std::fmt;
8+
use snafu::Snafu;
79

810
use crate::{
9-
commons::product_image_selection::ResolvedProductImage, error::Error,
10-
validation::is_rfc_1123_label,
11+
commons::product_image_selection::ResolvedProductImage, validation::is_rfc_1123_label,
1112
};
1213

14+
type Result<T, E = Error> = std::result::Result<T, E>;
15+
16+
#[derive(Debug, PartialEq, Snafu)]
17+
pub enum Error {
18+
#[snafu(display("container name {container_name:?} is invalid: {violation:?}"))]
19+
InvalidContainerName {
20+
container_name: String,
21+
violation: String,
22+
},
23+
}
24+
1325
/// A builder to build [`Container`] objects.
1426
///
1527
/// This will automatically create the necessary volumes and mounts for each `ConfigMap` which is added.
@@ -32,7 +44,7 @@ pub struct ContainerBuilder {
3244
}
3345

3446
impl ContainerBuilder {
35-
pub fn new(name: &str) -> Result<Self, Error> {
47+
pub fn new(name: &str) -> Result<Self> {
3648
Self::validate_container_name(name)?;
3749
Ok(ContainerBuilder {
3850
name: name.to_string(),
@@ -264,7 +276,7 @@ impl ContainerBuilder {
264276

265277
/// Validates a container name is according to the [RFC 1123](https://www.ietf.org/rfc/rfc1123.txt) standard.
266278
/// Returns [Ok] if the name is according to the standard, and [Err] if not.
267-
fn validate_container_name(name: &str) -> Result<(), Error> {
279+
fn validate_container_name(name: &str) -> Result<()> {
268280
let validation_result = is_rfc_1123_label(name);
269281

270282
match validation_result {
@@ -355,8 +367,8 @@ mod tests {
355367

356368
use super::*;
357369
use crate::{
358-
builder::{
359-
pod::container::{ContainerBuilder, ContainerPortBuilder, FieldPathEnvVar},
370+
builder::pod::{
371+
container::{ContainerBuilder, ContainerPortBuilder, FieldPathEnvVar},
360372
resources::ResourceRequirementsBuilder,
361373
},
362374
commons::resources::ResourceRequirementsType,
@@ -490,16 +502,13 @@ mod tests {
490502
panic!("Container name exceeding 63 characters should cause an error");
491503
}
492504
Err(error) => match error {
493-
crate::error::Error::InvalidContainerName {
505+
Error::InvalidContainerName {
494506
container_name,
495507
violation,
496508
} => {
497509
assert_eq!(container_name.as_str(), long_container_name);
498510
assert_eq!(violation.as_str(), "must be no more than 63 characters")
499511
}
500-
_ => {
501-
panic!("InvalidContainerName error expected")
502-
}
503512
},
504513
}
505514
// One characters shorter name is valid
@@ -569,16 +578,13 @@ mod tests {
569578
panic!("Container name exceeding 63 characters should cause an error");
570579
}
571580
Err(error) => match error {
572-
crate::error::Error::InvalidContainerName {
581+
Error::InvalidContainerName {
573582
container_name: _,
574583
violation,
575584
} => {
576585
println!("{violation}");
577586
assert!(violation.contains(expected_err_contains));
578587
}
579-
_ => {
580-
panic!("InvalidContainerName error expected");
581-
}
582588
},
583589
}
584590
}

0 commit comments

Comments
 (0)