Skip to content

Commit e25c9e0

Browse files
committed
TLS verification struct now reside top-level in the commons module
1 parent 557845f commit e25c9e0

File tree

7 files changed

+163
-162
lines changed

7 files changed

+163
-162
lines changed

crates/stackable-operator/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
1313
### Changed
1414

1515
- BREAKING: `validation` module now uses typed errors ([#851]).
16+
- BREAKING: TLS verification struct now reside top-level in the `commons` module, instead of being placed below `commons::authentication::tls` ([#XXX]).
1617

1718
### Fixed
1819

crates/stackable-operator/src/commons/authentication/ldap.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ use url::{ParseError, Url};
77
use crate::{
88
builder::pod::{container::ContainerBuilder, volume::VolumeMountBuilder, PodBuilder},
99
commons::{
10-
authentication::{
11-
tls::{TlsClientDetails, TlsClientDetailsError},
12-
SECRET_BASE_PATH,
13-
},
10+
authentication::SECRET_BASE_PATH,
1411
networking::Host,
1512
secret_class::{SecretClassVolume, SecretClassVolumeError},
13+
tls_verification::{TlsClientDetails, TlsClientDetailsError},
1614
},
1715
};
1816

crates/stackable-operator/src/commons/authentication/oidc.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use url::{ParseError, Url};
1212
#[cfg(doc)]
1313
use crate::commons::authentication::AuthenticationClass;
1414
use crate::commons::{
15-
authentication::{tls::TlsClientDetails, SECRET_BASE_PATH},
16-
networking::Host,
15+
authentication::SECRET_BASE_PATH, networking::Host, tls_verification::TlsClientDetails,
1716
};
1817

1918
pub type Result<T, E = Error> = std::result::Result<T, E>;
Lines changed: 0 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
1-
use k8s_openapi::api::core::v1::{Volume, VolumeMount};
21
use schemars::JsonSchema;
32
use serde::{Deserialize, Serialize};
4-
use snafu::{ResultExt, Snafu};
5-
6-
use crate::{
7-
builder::pod::{container::ContainerBuilder, volume::VolumeMountBuilder, PodBuilder},
8-
commons::{
9-
authentication::SECRET_BASE_PATH,
10-
secret_class::{SecretClassVolume, SecretClassVolumeError},
11-
},
12-
};
133

144
#[derive(
155
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
@@ -22,148 +12,3 @@ pub struct AuthenticationProvider {
2212
/// will be used to provision client certificates.
2313
pub client_cert_secret_class: Option<String>,
2414
}
25-
26-
#[derive(Debug, PartialEq, Snafu)]
27-
pub enum TlsClientDetailsError {
28-
#[snafu(display("failed to convert secret class volume into named Kubernetes volume"))]
29-
SecretClassVolume { source: SecretClassVolumeError },
30-
}
31-
32-
#[derive(
33-
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
34-
)]
35-
#[serde(rename_all = "camelCase")]
36-
pub struct TlsClientDetails {
37-
/// Use a TLS connection. If not specified no TLS will be used.
38-
pub tls: Option<Tls>,
39-
}
40-
41-
impl TlsClientDetails {
42-
/// This functions adds
43-
///
44-
/// * The needed volumes to the PodBuilder
45-
/// * The needed volume_mounts to all the ContainerBuilder in the list (e.g. init + main container)
46-
///
47-
/// This function will handle
48-
///
49-
/// * Tls secret class used to verify the cert of the LDAP server
50-
pub fn add_volumes_and_mounts(
51-
&self,
52-
pod_builder: &mut PodBuilder,
53-
container_builders: Vec<&mut ContainerBuilder>,
54-
) -> Result<(), TlsClientDetailsError> {
55-
let (volumes, mounts) = self.volumes_and_mounts()?;
56-
pod_builder.add_volumes(volumes);
57-
58-
for cb in container_builders {
59-
cb.add_volume_mounts(mounts.clone());
60-
}
61-
62-
Ok(())
63-
}
64-
65-
/// It is recommended to use [`Self::add_volumes_and_mounts`], this function returns you the
66-
/// volumes and mounts in case you need to add them by yourself.
67-
pub fn volumes_and_mounts(
68-
&self,
69-
) -> Result<(Vec<Volume>, Vec<VolumeMount>), TlsClientDetailsError> {
70-
let mut volumes = Vec::new();
71-
let mut mounts = Vec::new();
72-
73-
if let Some(secret_class) = self.tls_ca_cert_secret_class() {
74-
let volume_name = format!("{secret_class}-ca-cert");
75-
let secret_class_volume = SecretClassVolume::new(secret_class.clone(), None);
76-
let volume = secret_class_volume
77-
.to_volume(&volume_name)
78-
.context(SecretClassVolumeSnafu)?;
79-
80-
volumes.push(volume);
81-
mounts.push(
82-
VolumeMountBuilder::new(volume_name, format!("{SECRET_BASE_PATH}/{secret_class}"))
83-
.build(),
84-
);
85-
}
86-
87-
Ok((volumes, mounts))
88-
}
89-
90-
/// Whether TLS is configured
91-
pub const fn uses_tls(&self) -> bool {
92-
self.tls.is_some()
93-
}
94-
95-
/// Whether TLS verification is configured. Returns `false` if TLS itself isn't configured
96-
pub fn uses_tls_verification(&self) -> bool {
97-
self.tls
98-
.as_ref()
99-
.map(|tls| tls.verification != TlsVerification::None {})
100-
.unwrap_or_default()
101-
}
102-
103-
/// Returns the path of the ca.crt that should be used to verify the LDAP server certificate
104-
/// if TLS verification with a CA cert from a SecretClass is configured.
105-
pub fn tls_ca_cert_mount_path(&self) -> Option<String> {
106-
self.tls_ca_cert_secret_class()
107-
.map(|secret_class| format!("{SECRET_BASE_PATH}/{secret_class}/ca.crt"))
108-
}
109-
110-
/// Extracts the SecretClass that provides the CA cert used to verify the server certificate.
111-
pub(crate) fn tls_ca_cert_secret_class(&self) -> Option<String> {
112-
if let Some(Tls {
113-
verification:
114-
TlsVerification::Server(TlsServerVerification {
115-
ca_cert: CaCert::SecretClass(secret_class),
116-
}),
117-
}) = &self.tls
118-
{
119-
Some(secret_class.to_owned())
120-
} else {
121-
None
122-
}
123-
}
124-
}
125-
126-
#[derive(
127-
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
128-
)]
129-
#[serde(rename_all = "camelCase")]
130-
pub struct Tls {
131-
/// The verification method used to verify the certificates of the server and/or the client.
132-
pub verification: TlsVerification,
133-
}
134-
135-
#[derive(
136-
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
137-
)]
138-
#[serde(rename_all = "camelCase")]
139-
pub enum TlsVerification {
140-
/// Use TLS but don't verify certificates.
141-
None {},
142-
143-
/// Use TLS and a CA certificate to verify the server.
144-
Server(TlsServerVerification),
145-
}
146-
147-
#[derive(
148-
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
149-
)]
150-
#[serde(rename_all = "camelCase")]
151-
pub struct TlsServerVerification {
152-
/// CA cert to verify the server.
153-
pub ca_cert: CaCert,
154-
}
155-
156-
#[derive(
157-
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
158-
)]
159-
#[serde(rename_all = "camelCase")]
160-
pub enum CaCert {
161-
/// Use TLS and the CA certificates trusted by the common web browsers to verify the server.
162-
/// This can be useful when you e.g. use public AWS S3 or other public available services.
163-
WebPki {},
164-
165-
/// Name of the [SecretClass](DOCS_BASE_URL_PLACEHOLDER/secret-operator/secretclass) which will provide the CA certificate.
166-
/// Note that a SecretClass does not need to have a key but can also work with just a CA certificate,
167-
/// so if you got provided with a CA cert but don't have access to the key you can still use this method.
168-
SecretClass(String),
169-
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ pub mod resources;
1313
pub mod s3;
1414
pub mod secret;
1515
pub mod secret_class;
16+
pub mod tls_verification;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use snafu::{ResultExt, Snafu};
1111

1212
use crate::{
1313
client::Client,
14-
commons::{authentication::tls::Tls, networking::Host, secret_class::SecretClassVolume},
14+
commons::{networking::Host, secret_class::SecretClassVolume, tls_verification::Tls},
1515
};
1616

1717
type Result<T, E = Error> = std::result::Result<T, E>;
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
use k8s_openapi::api::core::v1::{Volume, VolumeMount};
2+
use schemars::JsonSchema;
3+
use serde::{Deserialize, Serialize};
4+
use snafu::{ResultExt, Snafu};
5+
6+
use crate::{
7+
builder::pod::{container::ContainerBuilder, volume::VolumeMountBuilder, PodBuilder},
8+
commons::{
9+
authentication::SECRET_BASE_PATH,
10+
secret_class::{SecretClassVolume, SecretClassVolumeError},
11+
},
12+
};
13+
14+
#[derive(Debug, PartialEq, Snafu)]
15+
pub enum TlsClientDetailsError {
16+
#[snafu(display("failed to convert secret class volume into named Kubernetes volume"))]
17+
SecretClassVolume { source: SecretClassVolumeError },
18+
}
19+
20+
#[derive(
21+
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
22+
)]
23+
#[serde(rename_all = "camelCase")]
24+
pub struct TlsClientDetails {
25+
/// Use a TLS connection. If not specified no TLS will be used.
26+
pub tls: Option<Tls>,
27+
}
28+
29+
impl TlsClientDetails {
30+
/// This functions adds
31+
///
32+
/// * The needed volumes to the PodBuilder
33+
/// * The needed volume_mounts to all the ContainerBuilder in the list (e.g. init + main container)
34+
///
35+
/// This function will handle
36+
///
37+
/// * Tls secret class used to verify the cert of the LDAP server
38+
pub fn add_volumes_and_mounts(
39+
&self,
40+
pod_builder: &mut PodBuilder,
41+
container_builders: Vec<&mut ContainerBuilder>,
42+
) -> Result<(), TlsClientDetailsError> {
43+
let (volumes, mounts) = self.volumes_and_mounts()?;
44+
pod_builder.add_volumes(volumes);
45+
46+
for cb in container_builders {
47+
cb.add_volume_mounts(mounts.clone());
48+
}
49+
50+
Ok(())
51+
}
52+
53+
/// It is recommended to use [`Self::add_volumes_and_mounts`], this function returns you the
54+
/// volumes and mounts in case you need to add them by yourself.
55+
pub fn volumes_and_mounts(
56+
&self,
57+
) -> Result<(Vec<Volume>, Vec<VolumeMount>), TlsClientDetailsError> {
58+
let mut volumes = Vec::new();
59+
let mut mounts = Vec::new();
60+
61+
if let Some(secret_class) = self.tls_ca_cert_secret_class() {
62+
let volume_name = format!("{secret_class}-ca-cert");
63+
let secret_class_volume = SecretClassVolume::new(secret_class.clone(), None);
64+
let volume = secret_class_volume
65+
.to_volume(&volume_name)
66+
.context(SecretClassVolumeSnafu)?;
67+
68+
volumes.push(volume);
69+
mounts.push(
70+
VolumeMountBuilder::new(volume_name, format!("{SECRET_BASE_PATH}/{secret_class}"))
71+
.build(),
72+
);
73+
}
74+
75+
Ok((volumes, mounts))
76+
}
77+
78+
/// Whether TLS is configured
79+
pub const fn uses_tls(&self) -> bool {
80+
self.tls.is_some()
81+
}
82+
83+
/// Whether TLS verification is configured. Returns `false` if TLS itself isn't configured
84+
pub fn uses_tls_verification(&self) -> bool {
85+
self.tls
86+
.as_ref()
87+
.map(|tls| tls.verification != TlsVerification::None {})
88+
.unwrap_or_default()
89+
}
90+
91+
/// Returns the path of the ca.crt that should be used to verify the LDAP server certificate
92+
/// if TLS verification with a CA cert from a SecretClass is configured.
93+
pub fn tls_ca_cert_mount_path(&self) -> Option<String> {
94+
self.tls_ca_cert_secret_class()
95+
.map(|secret_class| format!("{SECRET_BASE_PATH}/{secret_class}/ca.crt"))
96+
}
97+
98+
/// Extracts the SecretClass that provides the CA cert used to verify the server certificate.
99+
pub(crate) fn tls_ca_cert_secret_class(&self) -> Option<String> {
100+
if let Some(Tls {
101+
verification:
102+
TlsVerification::Server(TlsServerVerification {
103+
ca_cert: CaCert::SecretClass(secret_class),
104+
}),
105+
}) = &self.tls
106+
{
107+
Some(secret_class.to_owned())
108+
} else {
109+
None
110+
}
111+
}
112+
}
113+
114+
#[derive(
115+
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
116+
)]
117+
#[serde(rename_all = "camelCase")]
118+
pub struct Tls {
119+
/// The verification method used to verify the certificates of the server and/or the client.
120+
pub verification: TlsVerification,
121+
}
122+
123+
#[derive(
124+
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
125+
)]
126+
#[serde(rename_all = "camelCase")]
127+
pub enum TlsVerification {
128+
/// Use TLS but don't verify certificates.
129+
None {},
130+
131+
/// Use TLS and a CA certificate to verify the server.
132+
Server(TlsServerVerification),
133+
}
134+
135+
#[derive(
136+
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
137+
)]
138+
#[serde(rename_all = "camelCase")]
139+
pub struct TlsServerVerification {
140+
/// CA cert to verify the server.
141+
pub ca_cert: CaCert,
142+
}
143+
144+
#[derive(
145+
Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize,
146+
)]
147+
#[serde(rename_all = "camelCase")]
148+
pub enum CaCert {
149+
/// Use TLS and the CA certificates trusted by the common web browsers to verify the server.
150+
/// This can be useful when you e.g. use public AWS S3 or other public available services.
151+
WebPki {},
152+
153+
/// Name of the [SecretClass](DOCS_BASE_URL_PLACEHOLDER/secret-operator/secretclass) which will provide the CA certificate.
154+
/// Note that a SecretClass does not need to have a key but can also work with just a CA certificate,
155+
/// so if you got provided with a CA cert but don't have access to the key you can still use this method.
156+
SecretClass(String),
157+
}

0 commit comments

Comments
 (0)