Skip to content

Commit 76ba31c

Browse files
committed
refactor: use ConfigMapName, SecretName, ListenerName in CRD
1 parent ff9b9b5 commit 76ba31c

9 files changed

Lines changed: 84 additions & 42 deletions

File tree

extra/crds.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ spec:
491491
properties:
492492
listenerClass:
493493
default: cluster-internal
494+
maxLength: 253
495+
minLength: 1
496+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
494497
type: string
495498
podDisruptionBudget:
496499
default:
@@ -1091,6 +1094,9 @@ spec:
10911094
The [discovery ConfigMap](https://docs.stackable.tech/home/nightly/concepts/service_discovery)
10921095
for the HDFS instance. When running an HDFS cluster with the Stackable operator, the operator
10931096
will create this ConfigMap for you. It has the same name as your HDFSCluster resource.
1097+
maxLength: 253
1098+
minLength: 1
1099+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
10941100
type: string
10951101
directory:
10961102
description: The directory inside of HDFS where Druid should store its data.
@@ -1574,7 +1580,10 @@ spec:
15741580
- If TLS encryption is used at all
15751581
- Which cert the servers should use to authenticate themselves against the clients
15761582
- Which cert the servers should use to authenticate themselves among each other
1583+
maxLength: 253
1584+
minLength: 1
15771585
nullable: true
1586+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
15781587
type: string
15791588
type: object
15801589
vectorAggregatorConfigMapName:
@@ -1583,14 +1592,20 @@ spec:
15831592
It must contain the key `ADDRESS` with the address of the Vector aggregator.
15841593
Follow the [logging tutorial](https://docs.stackable.tech/home/nightly/tutorials/logging-vector-aggregator)
15851594
to learn how to configure log aggregation with Vector.
1595+
maxLength: 253
1596+
minLength: 1
15861597
nullable: true
1598+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
15871599
type: string
15881600
zookeeperConfigMapName:
15891601
description: |-
15901602
Druid requires a ZooKeeper cluster connection to run.
15911603
Provide the name of the ZooKeeper [discovery ConfigMap](https://docs.stackable.tech/home/nightly/concepts/service_discovery)
15921604
here. When using the [Stackable operator for Apache ZooKeeper](https://docs.stackable.tech/home/nightly/zookeeper/)
15931605
to deploy a ZooKeeper cluster, this will simply be the name of your ZookeeperCluster resource.
1606+
maxLength: 253
1607+
minLength: 1
1608+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
15941609
type: string
15951610
required:
15961611
- deepStorage
@@ -2090,6 +2105,9 @@ spec:
20902105
properties:
20912106
listenerClass:
20922107
default: cluster-internal
2108+
maxLength: 253
2109+
minLength: 1
2110+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
20932111
type: string
20942112
podDisruptionBudget:
20952113
default:
@@ -5118,6 +5136,9 @@ spec:
51185136
properties:
51195137
listenerClass:
51205138
default: cluster-internal
5139+
maxLength: 253
5140+
minLength: 1
5141+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
51215142
type: string
51225143
podDisruptionBudget:
51235144
default:

rust/operator-binary/src/controller/build/resource/statefulset.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ fn add_hdfs_cm_volume_and_volume_mounts(
404404
.context(AddVolumeMountSnafu)?;
405405
pb.add_volume(
406406
VolumeBuilder::new(HDFS_CONFIG_VOLUME_NAME)
407-
.with_config_map(&hdfs.config_map_name)
407+
.with_config_map(hdfs.config_map_name.to_string())
408408
.build(),
409409
)
410410
.context(AddVolumeSnafu)?;

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ pub async fn dereference(
8484
.as_deref()
8585
.context(ObjectHasNoNamespaceSnafu)?;
8686

87-
let zk_confmap = druid.spec.cluster_config.zookeeper_config_map_name.clone();
87+
let zk_confmap = druid
88+
.spec
89+
.cluster_config
90+
.zookeeper_config_map_name
91+
.to_string();
8892
let zookeeper_connection_string = client
8993
.get::<ConfigMap>(&zk_confmap, namespace)
9094
.await

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn get_affinity(
3939
{
4040
vec![affinity_between_role_pods(
4141
"hdfs",
42-
hdfs_discovery_cm_name, // The discovery cm has the same name as the HdfsCluster itself
42+
hdfs_discovery_cm_name.as_ref(), // The discovery cm has the same name as the HdfsCluster itself
4343
"datanode",
4444
50,
4545
)]

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,11 @@ impl AuthenticationClassesResolved {
128128
.context(AuthenticationClassRetrievalFailedSnafu)?;
129129

130130
let auth_class_name = auth_class.name_any();
131-
let server_and_internal_secret_class = cluster_config
132-
.tls
133-
.as_ref()
134-
.and_then(|tls| tls.server_and_internal_secret_class.to_owned());
131+
let server_and_internal_secret_class = cluster_config.tls.as_ref().and_then(|tls| {
132+
tls.server_and_internal_secret_class
133+
.as_ref()
134+
.map(|secret_class| secret_class.to_string())
135+
});
135136

136137
match &auth_class.spec.provider {
137138
core::v1alpha1::AuthenticationClassProvider::Tls(provider) => {

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

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use stackable_operator::{
4545
},
4646
role_utils::{JavaCommonConfig, RoleGroupConfig, with_validated_config},
4747
types::{
48-
kubernetes::ConfigMapName,
48+
kubernetes::{ConfigMapName, ListenerClassName},
4949
operator::{RoleGroupName, RoleName},
5050
},
5151
},
@@ -199,11 +199,6 @@ pub enum Error {
199199
"the Vector agent is enabled but the Vector aggregator ConfigMap name is missing"
200200
))]
201201
MissingVectorAggregatorConfigMapName,
202-
203-
#[snafu(display("invalid Vector aggregator ConfigMap name"))]
204-
ParseVectorAggregatorConfigMapName {
205-
source: stackable_operator::v2::macros::attributed_string_type::Error,
206-
},
207202
}
208203

209204
#[versioned(
@@ -328,14 +323,14 @@ pub mod versioned {
328323
/// Provide the name of the ZooKeeper [discovery ConfigMap](DOCS_BASE_URL_PLACEHOLDER/concepts/service_discovery)
329324
/// here. When using the [Stackable operator for Apache ZooKeeper](DOCS_BASE_URL_PLACEHOLDER/zookeeper/)
330325
/// to deploy a ZooKeeper cluster, this will simply be the name of your ZookeeperCluster resource.
331-
pub zookeeper_config_map_name: String,
326+
pub zookeeper_config_map_name: ConfigMapName,
332327

333328
/// Name of the Vector aggregator [discovery ConfigMap](DOCS_BASE_URL_PLACEHOLDER/concepts/service_discovery).
334329
/// It must contain the key `ADDRESS` with the address of the Vector aggregator.
335330
/// Follow the [logging tutorial](DOCS_BASE_URL_PLACEHOLDER/tutorials/logging-vector-aggregator)
336331
/// to learn how to configure log aggregation with Vector.
337332
#[serde(skip_serializing_if = "Option::is_none")]
338-
pub vector_aggregator_config_map_name: Option<String>,
333+
pub vector_aggregator_config_map_name: Option<ConfigMapName>,
339334

340335
/// Extra volumes similar to `.spec.volumes` on a Pod to mount into every container, this can be useful to for
341336
/// example make client certificates, keytabs or similar things available to processors. These volumes will be
@@ -351,7 +346,7 @@ pub mod versioned {
351346
pub generic: GenericRoleConfig,
352347

353348
#[serde(default = "druid_default_listener_class")]
354-
pub listener_class: String,
349+
pub listener_class: ListenerClassName,
355350
}
356351
}
357352

@@ -468,16 +463,14 @@ impl v1alpha1::DruidCluster {
468463
let deep_storage = &self.spec.cluster_config.deep_storage;
469464
let name = self.name_any();
470465

471-
// The Vector aggregator discovery ConfigMap name (validated here so an invalid name fails
472-
// up-front). It is only required when the Vector agent is enabled for a role group.
466+
// The Vector aggregator discovery ConfigMap name (a typed `ConfigMapName`, so an invalid
467+
// name is already rejected at deserialization). It is only required when the Vector agent
468+
// is enabled for a role group.
473469
let vector_aggregator_config_map_name = self
474470
.spec
475471
.cluster_config
476472
.vector_aggregator_config_map_name
477-
.as_deref()
478-
.map(ConfigMapName::from_str)
479-
.transpose()
480-
.context(ParseVectorAggregatorConfigMapNameSnafu)?;
473+
.clone();
481474

482475
// All roles erase to an identical `ValidatedDruidConfig`; only the typed config, the role
483476
// config type and the `RoleResource` variant (historicals carry typed storage) differ.
@@ -705,8 +698,8 @@ impl Default for v1alpha1::DruidRoleConfig {
705698
}
706699
}
707700

708-
fn druid_default_listener_class() -> String {
709-
"cluster-internal".to_string()
701+
fn druid_default_listener_class() -> ListenerClassName {
702+
ListenerClassName::from_str("cluster-internal").expect("a valid listener class name")
710703
}
711704

712705
#[derive(
@@ -851,7 +844,7 @@ impl DruidRole {
851844
}
852845
}
853846

854-
pub fn listener_class_name(&self, druid: &v1alpha1::DruidCluster) -> Option<String> {
847+
pub fn listener_class_name(&self, druid: &v1alpha1::DruidCluster) -> Option<ListenerClassName> {
855848
match self {
856849
Self::Broker => Some(druid.spec.brokers.role_config.listener_class.to_owned()),
857850
Self::Coordinator => Some(
@@ -893,7 +886,7 @@ pub struct HdfsDeepStorageSpec {
893886
/// The [discovery ConfigMap](DOCS_BASE_URL_PLACEHOLDER/concepts/service_discovery)
894887
/// for the HDFS instance. When running an HDFS cluster with the Stackable operator, the operator
895888
/// will create this ConfigMap for you. It has the same name as your HDFSCluster resource.
896-
pub config_map_name: String,
889+
pub config_map_name: ConfigMapName,
897890
/// The directory inside of HDFS where Druid should store its data.
898891
pub directory: String,
899892
}

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,13 @@ impl DruidTlsSecurity {
119119
) -> Self {
120120
DruidTlsSecurity {
121121
auth_classes: auth_classes.clone(),
122-
server_and_internal_secret_class: druid
123-
.spec
124-
.cluster_config
125-
.tls
126-
.as_ref()
127-
.and_then(|tls| tls.server_and_internal_secret_class.clone()),
122+
server_and_internal_secret_class: druid.spec.cluster_config.tls.as_ref().and_then(
123+
|tls| {
124+
tls.server_and_internal_secret_class
125+
.as_ref()
126+
.map(|secret_class| secret_class.to_string())
127+
},
128+
),
128129
}
129130
}
130131

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

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
use std::str::FromStr;
2+
13
use serde::{Deserialize, Serialize};
2-
use stackable_operator::schemars::{self, JsonSchema};
4+
use stackable_operator::{
5+
schemars::{self, JsonSchema},
6+
v2::types::kubernetes::SecretClassName,
7+
};
38

49
const TLS_DEFAULT_SECRET_CLASS: &str = "tls";
510

@@ -14,7 +19,7 @@ pub struct DruidTls {
1419
// happens via the HTTPS port. Even if both HTTPS and HTTP port are enabled, Druid clients
1520
// will default to using TLS.
1621
#[serde(default = "tls_default", skip_serializing_if = "Option::is_none")]
17-
pub server_and_internal_secret_class: Option<String>,
22+
pub server_and_internal_secret_class: Option<SecretClassName>,
1823
}
1924

2025
/// Default TLS settings. Internal and server communication default to "tls" secret class.
@@ -25,14 +30,18 @@ pub fn default_druid_tls() -> Option<DruidTls> {
2530
}
2631

2732
/// Helper methods to provide defaults in the CRDs and tests
28-
pub fn tls_default() -> Option<String> {
29-
Some(TLS_DEFAULT_SECRET_CLASS.to_string())
33+
pub fn tls_default() -> Option<SecretClassName> {
34+
Some(SecretClassName::from_str(TLS_DEFAULT_SECRET_CLASS).expect("a valid secret class name"))
3035
}
3136

3237
#[cfg(test)]
3338
mod tests {
39+
use std::str::FromStr;
40+
3441
use indoc::formatdoc;
35-
use stackable_operator::utils::yaml_from_str_singleton_map;
42+
use stackable_operator::{
43+
utils::yaml_from_str_singleton_map, v2::types::kubernetes::SecretClassName,
44+
};
3645

3746
use crate::crd::{tls::DruidTls, v1alpha1::DruidClusterConfig};
3847

@@ -54,7 +63,9 @@ zookeeperConfigMapName: zk-config-map
5463
assert_eq!(
5564
druid_cluster_config.tls,
5665
Some(DruidTls {
57-
server_and_internal_secret_class: Some("tls".to_string())
66+
server_and_internal_secret_class: Some(
67+
SecretClassName::from_str("tls").expect("a valid secret class name")
68+
)
5869
}),
5970
);
6071
assert_eq!(druid_cluster_config.authentication, vec![]);
@@ -73,7 +84,10 @@ zookeeperConfigMapName: zk-config-map
7384
assert_eq!(
7485
druid_cluster_config.tls,
7586
Some(DruidTls {
76-
server_and_internal_secret_class: Some("druid-secret-class".to_string())
87+
server_and_internal_secret_class: Some(
88+
SecretClassName::from_str("druid-secret-class")
89+
.expect("a valid secret class name")
90+
)
7791
}),
7892
);
7993
assert_eq!(druid_cluster_config.authentication, vec![]);
@@ -126,7 +140,10 @@ zookeeperConfigMapName: zk-config-map
126140
assert_eq!(
127141
druid_cluster_config.tls,
128142
Some(DruidTls {
129-
server_and_internal_secret_class: Some("druid-secret-class".to_string())
143+
server_and_internal_secret_class: Some(
144+
SecretClassName::from_str("druid-secret-class")
145+
.expect("a valid secret class name")
146+
)
130147
}),
131148
);
132149
/*

rust/operator-binary/src/main.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,12 @@ fn references_config_map(
197197
return false;
198198
};
199199

200-
druid.spec.cluster_config.zookeeper_config_map_name == config_map.name_any()
200+
druid
201+
.spec
202+
.cluster_config
203+
.zookeeper_config_map_name
204+
.to_string()
205+
== config_map.name_any()
201206
|| match &druid.spec.cluster_config.authorization {
202207
Some(druid_authorization) => {
203208
druid_authorization.opa.config_map_name == config_map.name_any()
@@ -206,7 +211,7 @@ fn references_config_map(
206211
}
207212
|| match &druid.spec.cluster_config.deep_storage {
208213
crd::DeepStorageSpec::Hdfs(hdfs_spec) => {
209-
hdfs_spec.config_map_name == config_map.name_any()
214+
hdfs_spec.config_map_name.to_string() == config_map.name_any()
210215
}
211216
_ => false,
212217
}

0 commit comments

Comments
 (0)