Skip to content

Commit 0e9329a

Browse files
committed
fix: split fetch and validate auth class steps
1 parent 9a98434 commit 0e9329a

5 files changed

Lines changed: 62 additions & 48 deletions

File tree

rust/operator-binary/src/crd/authentication.rs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,35 @@ pub struct ResolvedAuthenticationClasses {
5757
}
5858

5959
impl ResolvedAuthenticationClasses {
60+
/// Fetch the referenced AuthenticationClasses from the Kubernetes API without validating them.
61+
///
62+
/// Call [`Self::validate`] on the result to enforce the constraints documented there.
63+
pub async fn fetch_references(
64+
client: &Client,
65+
auth_classes: &Vec<v1alpha1::ZookeeperAuthentication>,
66+
) -> Result<ResolvedAuthenticationClasses, Error> {
67+
let mut resolved_authentication_classes: Vec<core::v1alpha1::AuthenticationClass> = vec![];
68+
69+
for auth_class in auth_classes {
70+
resolved_authentication_classes.push(
71+
core::v1alpha1::AuthenticationClass::resolve(
72+
client,
73+
&auth_class.authentication_class,
74+
)
75+
.await
76+
.context(AuthenticationClassRetrievalSnafu {
77+
authentication_class: ObjectRef::<core::v1alpha1::AuthenticationClass>::new(
78+
&auth_class.authentication_class,
79+
),
80+
})?,
81+
);
82+
}
83+
84+
Ok(ResolvedAuthenticationClasses {
85+
resolved_authentication_classes,
86+
})
87+
}
88+
6089
/// Return the (first) TLS `AuthenticationClass` if available
6190
pub fn get_tls_authentication_class(&self) -> Option<&core::v1alpha1::AuthenticationClass> {
6291
self.resolved_authentication_classes.iter().find(|auth| {
@@ -101,31 +130,3 @@ impl ResolvedAuthenticationClasses {
101130
}
102131
}
103132
}
104-
105-
/// Resolve provided AuthenticationClasses via API calls and validate the contents.
106-
/// Currently errors out if:
107-
/// - AuthenticationClass could not be resolved
108-
/// - Validation failed
109-
pub async fn resolve_authentication_classes(
110-
client: &Client,
111-
auth_classes: &Vec<v1alpha1::ZookeeperAuthentication>,
112-
) -> Result<ResolvedAuthenticationClasses, Error> {
113-
let mut resolved_authentication_classes: Vec<core::v1alpha1::AuthenticationClass> = vec![];
114-
115-
for auth_class in auth_classes {
116-
resolved_authentication_classes.push(
117-
core::v1alpha1::AuthenticationClass::resolve(client, &auth_class.authentication_class)
118-
.await
119-
.context(AuthenticationClassRetrievalSnafu {
120-
authentication_class: ObjectRef::<core::v1alpha1::AuthenticationClass>::new(
121-
&auth_class.authentication_class,
122-
),
123-
})?,
124-
);
125-
}
126-
127-
ResolvedAuthenticationClasses {
128-
resolved_authentication_classes,
129-
}
130-
.validate()
131-
}

rust/operator-binary/src/zk_controller/dereference.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ use crate::crd::{
1515

1616
#[derive(Snafu, Debug)]
1717
pub enum Error {
18-
#[snafu(display("failed to resolve authentication classes"))]
19-
ResolveAuthenticationClasses { source: authentication::Error },
18+
#[snafu(display("failed to fetch authentication classes"))]
19+
FetchAuthenticationClasses { source: authentication::Error },
2020
}
2121

2222
type Result<T, E = Error> = std::result::Result<T, E>;
2323

24-
/// Kubernetes objects referenced from the [`v1alpha1::ZookeeperCluster`] spec, already fetched.
24+
/// Kubernetes objects referenced from the [`v1alpha1::ZookeeperCluster`] spec, already fetched but
25+
/// not yet validated.
2526
pub struct DereferencedObjects {
2627
pub resolved_authentication_classes: ResolvedAuthenticationClasses,
2728
}
@@ -31,12 +32,12 @@ pub async fn dereference(
3132
client: &Client,
3233
zk: &v1alpha1::ZookeeperCluster,
3334
) -> Result<DereferencedObjects> {
34-
let resolved_authentication_classes = authentication::resolve_authentication_classes(
35+
let resolved_authentication_classes = ResolvedAuthenticationClasses::fetch_references(
3536
client,
3637
&zk.spec.cluster_config.authentication,
3738
)
3839
.await
39-
.context(ResolveAuthenticationClassesSnafu)?;
40+
.context(FetchAuthenticationClassesSnafu)?;
4041

4142
Ok(DereferencedObjects {
4243
resolved_authentication_classes,

rust/operator-binary/src/zk_controller/validate.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use stackable_operator::{
1717
use crate::{
1818
crd::{
1919
CONTAINER_IMAGE_BASE_NAME, JVM_SECURITY_PROPERTIES_FILE, ZOOKEEPER_PROPERTIES_FILE,
20-
ZookeeperRole, security::ZookeeperSecurity, v1alpha1,
20+
ZookeeperRole, authentication, security::ZookeeperSecurity, v1alpha1,
2121
},
2222
zk_controller::dereference::DereferencedObjects,
2323
};
@@ -29,6 +29,9 @@ pub enum Error {
2929
source: product_image_selection::Error,
3030
},
3131

32+
#[snafu(display("failed to validate authentication classes"))]
33+
InvalidAuthenticationClassConfiguration { source: authentication::Error },
34+
3235
#[snafu(display("object defines no server role"))]
3336
NoServerRole,
3437

@@ -69,10 +72,12 @@ pub fn validate(
6972
)
7073
.context(ResolveProductImageSnafu)?;
7174

72-
let zookeeper_security = ZookeeperSecurity::new(
73-
zk,
74-
dereferenced_objects.resolved_authentication_classes.clone(),
75-
);
75+
let resolved_authentication_classes = dereferenced_objects
76+
.resolved_authentication_classes
77+
.validate()
78+
.context(InvalidAuthenticationClassConfigurationSnafu)?;
79+
80+
let zookeeper_security = ZookeeperSecurity::new(zk, resolved_authentication_classes);
7681

7782
let validated_role_config =
7883
validated_product_config(zk, &resolved_product_image.product_version, product_config)?;

rust/operator-binary/src/znode_controller/dereference.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
//!
33
//! Fetches the parent [`v1alpha1::ZookeeperCluster`] referenced by the znode's
44
//! `spec.clusterRef`, plus the [`ResolvedAuthenticationClasses`] of that cluster. Both Apply
5-
//! and Cleanup paths in `reconcile_znode` share this output.
5+
//! and Cleanup paths in `reconcile_znode` share this output. Synchronous validation of the
6+
//! fetched objects happens in the validate step.
67
78
use snafu::{ResultExt, Snafu};
89
use stackable_operator::{
@@ -32,8 +33,8 @@ pub enum Error {
3233
zk: ObjectRef<v1alpha1::ZookeeperCluster>,
3334
},
3435

35-
#[snafu(display("failed to resolve authentication classes"))]
36-
ResolveAuthenticationClasses { source: authentication::Error },
36+
#[snafu(display("failed to fetch authentication classes"))]
37+
FetchAuthenticationClasses { source: authentication::Error },
3738
}
3839

3940
type Result<T, E = Error> = std::result::Result<T, E>;
@@ -51,12 +52,12 @@ pub async fn dereference(
5152
) -> Result<DereferencedObjects> {
5253
let zk = find_zk_of_znode(client, znode).await?;
5354

54-
let resolved_authentication_classes = authentication::resolve_authentication_classes(
55+
let resolved_authentication_classes = ResolvedAuthenticationClasses::fetch_references(
5556
client,
5657
&zk.spec.cluster_config.authentication,
5758
)
5859
.await
59-
.context(ResolveAuthenticationClassesSnafu)?;
60+
.context(FetchAuthenticationClassesSnafu)?;
6061

6162
Ok(DereferencedObjects {
6263
zk,

rust/operator-binary/src/znode_controller/validate.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use stackable_operator::{
1010
};
1111

1212
use crate::{
13-
crd::{CONTAINER_IMAGE_BASE_NAME, security::ZookeeperSecurity, v1alpha1},
13+
crd::{CONTAINER_IMAGE_BASE_NAME, authentication, security::ZookeeperSecurity, v1alpha1},
1414
znode_controller::dereference::DereferencedObjects,
1515
};
1616

@@ -20,6 +20,9 @@ pub enum Error {
2020
ResolveProductImage {
2121
source: product_image_selection::Error,
2222
},
23+
24+
#[snafu(display("failed to validate authentication classes"))]
25+
InvalidAuthenticationClassConfiguration { source: authentication::Error },
2326
}
2427

2528
type Result<T, E = Error> = std::result::Result<T, E>;
@@ -47,10 +50,13 @@ pub fn validate(
4750
)
4851
.context(ResolveProductImageSnafu)?;
4952

50-
let zookeeper_security = ZookeeperSecurity::new(
51-
&dereferenced_objects.zk,
52-
dereferenced_objects.resolved_authentication_classes.clone(),
53-
);
53+
let resolved_authentication_classes = dereferenced_objects
54+
.resolved_authentication_classes
55+
.validate()
56+
.context(InvalidAuthenticationClassConfigurationSnafu)?;
57+
58+
let zookeeper_security =
59+
ZookeeperSecurity::new(&dereferenced_objects.zk, resolved_authentication_classes);
5460

5561
Ok(ValidatedInputs {
5662
resolved_product_image,

0 commit comments

Comments
 (0)