Skip to content

Commit 12bc737

Browse files
maltesanderclaude
andcommitted
refactor: extract ConfigMap building into controller/build/config_map
Moves rolegroup_config_map out of hdfs_controller into controller/build/config_map::build_rolegroup_config_map with its own Error enum, mirroring trino-operator. The function now takes the ValidatedCluster and looks up the role group's merged config and overrides internally instead of receiving them pre-destructured. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 34263a9 commit 12bc737

3 files changed

Lines changed: 169 additions & 132 deletions

File tree

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
//! Build the per-rolegroup `ConfigMap` for the HdfsCluster.
2+
3+
use std::str::FromStr;
4+
5+
use snafu::{OptionExt, ResultExt, Snafu};
6+
use stackable_operator::{
7+
builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder},
8+
k8s_openapi::api::core::v1::ConfigMap,
9+
kube::runtime::reflector::ObjectRef,
10+
role_utils::RoleGroupRef,
11+
utils::cluster_info::KubernetesClusterInfo,
12+
};
13+
14+
use crate::{
15+
config::writer::PropertiesWriterError,
16+
controller::build::properties::{
17+
ConfigFileName, core_site, hadoop_policy, hdfs_site, security_properties, ssl_client,
18+
ssl_server,
19+
},
20+
crd::{HdfsNodeRole, HdfsPodRef, v1alpha1},
21+
hdfs_controller::ValidatedCluster,
22+
product_logging::extend_role_group_config_map,
23+
};
24+
25+
#[derive(Snafu, Debug)]
26+
pub enum Error {
27+
#[snafu(display("object has no name"))]
28+
ObjectHasNoName {
29+
obj_ref: ObjectRef<v1alpha1::HdfsCluster>,
30+
},
31+
32+
#[snafu(display("could not parse HDFS role [{role}]"))]
33+
UnidentifiedHdfsRole {
34+
source: strum::ParseError,
35+
role: String,
36+
},
37+
38+
#[snafu(display("the validated cluster has no role group {role_group:?} for role {role:?}"))]
39+
MissingRoleGroup { role: String, role_group: String },
40+
41+
#[snafu(display("failed to build core-site.xml"))]
42+
BuildCoreSiteXml { source: core_site::Error },
43+
44+
#[snafu(display("failed to serialize {} for {rolegroup}", ConfigFileName::Security))]
45+
JvmSecurityProperties {
46+
source: PropertiesWriterError,
47+
rolegroup: String,
48+
},
49+
50+
#[snafu(display("failed to add the logging configuration to the ConfigMap {cm_name:?}"))]
51+
InvalidLoggingConfig {
52+
source: crate::product_logging::Error,
53+
cm_name: String,
54+
},
55+
56+
#[snafu(display("cannot build config map for role {role:?} and role group {role_group:?}"))]
57+
Assemble {
58+
source: stackable_operator::builder::configmap::Error,
59+
role: String,
60+
role_group: String,
61+
},
62+
}
63+
64+
type Result<T, E = Error> = std::result::Result<T, E>;
65+
66+
#[allow(clippy::too_many_arguments)]
67+
pub fn build_rolegroup_config_map(
68+
cluster: &ValidatedCluster,
69+
hdfs: &v1alpha1::HdfsCluster,
70+
cluster_info: &KubernetesClusterInfo,
71+
metadata: &ObjectMetaBuilder,
72+
rolegroup_ref: &RoleGroupRef<v1alpha1::HdfsCluster>,
73+
namenode_podrefs: &[HdfsPodRef],
74+
journalnode_podrefs: &[HdfsPodRef],
75+
) -> Result<ConfigMap> {
76+
tracing::info!("Setting up ConfigMap for {:?}", rolegroup_ref);
77+
78+
let role = HdfsNodeRole::from_str(&rolegroup_ref.role).with_context(|_| {
79+
UnidentifiedHdfsRoleSnafu {
80+
role: rolegroup_ref.role.clone(),
81+
}
82+
})?;
83+
let rolegroup_config = cluster
84+
.role_groups
85+
.get(&role)
86+
.and_then(|role_groups| role_groups.get(&rolegroup_ref.role_group))
87+
.with_context(|| MissingRoleGroupSnafu {
88+
role: rolegroup_ref.role.clone(),
89+
role_group: rolegroup_ref.role_group.clone(),
90+
})?;
91+
let merged_config = &rolegroup_config.merged_config;
92+
let config_overrides = &rolegroup_config.config_overrides;
93+
let hdfs_opa_config = cluster.hdfs_opa_config.as_ref();
94+
95+
let hdfs_name = hdfs
96+
.metadata
97+
.name
98+
.as_deref()
99+
.with_context(|| ObjectHasNoNameSnafu {
100+
obj_ref: ObjectRef::from_obj(hdfs),
101+
})?;
102+
103+
let hdfs_site_xml = hdfs_site::build(
104+
hdfs,
105+
hdfs_name,
106+
cluster_info,
107+
merged_config,
108+
namenode_podrefs,
109+
journalnode_podrefs,
110+
hdfs_opa_config,
111+
config_overrides.hdfs_site_xml.clone(),
112+
);
113+
let core_site_xml = core_site::build(
114+
hdfs,
115+
hdfs_name,
116+
role,
117+
cluster_info,
118+
hdfs_opa_config,
119+
config_overrides.core_site_xml.clone(),
120+
)
121+
.context(BuildCoreSiteXmlSnafu)?;
122+
let hadoop_policy_xml = hadoop_policy::build(config_overrides.hadoop_policy_xml.clone());
123+
let ssl_server_xml = ssl_server::build(
124+
hdfs.has_https_enabled(),
125+
config_overrides.ssl_server_xml.clone(),
126+
);
127+
let ssl_client_xml = ssl_client::build(
128+
hdfs.has_https_enabled(),
129+
config_overrides.ssl_client_xml.clone(),
130+
);
131+
132+
let mut builder = ConfigMapBuilder::new();
133+
builder
134+
.metadata(metadata.build())
135+
.add_data(ConfigFileName::CoreSite.to_string(), core_site_xml)
136+
.add_data(ConfigFileName::HdfsSite.to_string(), hdfs_site_xml)
137+
.add_data(ConfigFileName::HadoopPolicy.to_string(), hadoop_policy_xml)
138+
.add_data(ConfigFileName::SslServer.to_string(), ssl_server_xml)
139+
.add_data(ConfigFileName::SslClient.to_string(), ssl_client_xml)
140+
.add_data(
141+
ConfigFileName::Security.to_string(),
142+
security_properties::build(config_overrides.security_properties.clone()).with_context(
143+
|_| JvmSecurityPropertiesSnafu {
144+
rolegroup: rolegroup_ref.role_group.clone(),
145+
},
146+
)?,
147+
);
148+
149+
extend_role_group_config_map(rolegroup_ref, merged_config, &mut builder).context(
150+
InvalidLoggingConfigSnafu {
151+
cm_name: rolegroup_ref.object_name(),
152+
},
153+
)?;
154+
155+
builder.build().with_context(|_| AssembleSnafu {
156+
role: rolegroup_ref.role.clone(),
157+
role_group: rolegroup_ref.role_group.clone(),
158+
})
159+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
pub mod config_map;
12
pub mod properties;

rust/operator-binary/src/hdfs_controller.rs

Lines changed: 9 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
use std::{collections::BTreeMap, str::FromStr, sync::Arc};
1+
use std::{collections::BTreeMap, sync::Arc};
22

33
use const_format::concatcp;
4-
use snafu::{OptionExt, ResultExt, Snafu};
4+
use snafu::{ResultExt, Snafu};
55
use stackable_operator::{
66
builder::{
7-
configmap::ConfigMapBuilder,
87
meta::ObjectMetaBuilder,
98
pod::{PodBuilder, security::PodSecurityContextBuilder},
109
},
@@ -17,7 +16,7 @@ use stackable_operator::{
1716
DeepMerge,
1817
api::{
1918
apps::v1::{StatefulSet, StatefulSetSpec},
20-
core::v1::{ConfigMap, ServiceAccount},
19+
core::v1::ServiceAccount,
2120
},
2221
apimachinery::pkg::apis::meta::v1::LabelSelector,
2322
},
@@ -44,12 +43,7 @@ use strum::{EnumDiscriminants, IntoEnumIterator, IntoStaticStr};
4443

4544
use crate::{
4645
OPERATOR_NAME, build_recommended_labels,
47-
config::writer::PropertiesWriterError,
4846
container::{self, ContainerConfig},
49-
controller::build::properties::{
50-
ConfigFileName, core_site, hadoop_policy, hdfs_site, security_properties, ssl_client,
51-
ssl_server,
52-
},
5347
crd::{
5448
AnyNodeConfig, HdfsClusterStatus, HdfsNodeRole, HdfsPodRef, UpgradeState,
5549
UpgradeStateError, constants::*, v1alpha1,
@@ -60,7 +54,6 @@ use crate::{
6054
graceful_shutdown::{self, add_graceful_shutdown_config},
6155
pdb::add_pdbs,
6256
},
63-
product_logging::extend_role_group_config_map,
6457
security::opa::HdfsOpaConfig,
6558
service::{self, rolegroup_headless_service, rolegroup_metrics_service},
6659
};
@@ -144,16 +137,9 @@ pub enum Error {
144137
obj_ref: ObjectRef<v1alpha1::HdfsCluster>,
145138
},
146139

147-
#[snafu(display("object has no name"))]
148-
ObjectHasNoName {
149-
obj_ref: ObjectRef<v1alpha1::HdfsCluster>,
150-
},
151-
152-
#[snafu(display("cannot build config map for role {role:?} and role group {role_group:?}"))]
140+
#[snafu(display("failed to build the role group ConfigMap"))]
153141
BuildRoleGroupConfigMap {
154-
source: stackable_operator::builder::configmap::Error,
155-
role: String,
156-
role_group: String,
142+
source: crate::controller::build::config_map::Error,
157143
},
158144

159145
#[snafu(display("cannot collect discovery configuration"))]
@@ -185,12 +171,6 @@ pub enum Error {
185171
#[snafu(display("failed to create pod references"))]
186172
CreatePodReferences { source: crate::crd::Error },
187173

188-
#[snafu(display("failed to add the logging configuration to the ConfigMap {cm_name:?}"))]
189-
InvalidLoggingConfig {
190-
source: crate::product_logging::Error,
191-
cm_name: String,
192-
},
193-
194174
#[snafu(display("failed to create cluster event"))]
195175
FailedToCreateClusterEvent { source: crate::event::Error },
196176

@@ -212,18 +192,6 @@ pub enum Error {
212192
source: stackable_operator::commons::rbac::Error,
213193
},
214194

215-
#[snafu(display("failed to serialize {} for {rolegroup}", ConfigFileName::Security))]
216-
JvmSecurityProperties {
217-
source: PropertiesWriterError,
218-
rolegroup: String,
219-
},
220-
221-
#[snafu(display("could not parse HDFS role [{role}]"))]
222-
UnidentifiedHdfsRole {
223-
source: strum::ParseError,
224-
role: String,
225-
},
226-
227195
#[snafu(display("failed to configure graceful shutdown"))]
228196
GracefulShutdown { source: graceful_shutdown::Error },
229197

@@ -241,9 +209,6 @@ pub enum Error {
241209
source: stackable_operator::builder::meta::Error,
242210
},
243211

244-
#[snafu(display("failed to build core-site.xml"))]
245-
BuildCoreSiteXml { source: core_site::Error },
246-
247212
#[snafu(display("HdfsCluster object is invalid"))]
248213
InvalidHdfsCluster {
249214
source: error_boundary::InvalidObject,
@@ -402,17 +367,16 @@ pub async fn reconcile_hdfs(
402367
))
403368
.context(ObjectMetaSnafu)?;
404369

405-
let rg_configmap = rolegroup_config_map(
370+
let rg_configmap = crate::controller::build::config_map::build_rolegroup_config_map(
371+
&validated,
406372
hdfs,
407373
&client.kubernetes_cluster_info,
408374
metadata,
409375
&rolegroup_ref,
410-
&validated_rg_config.config_overrides,
411376
&namenode_podrefs,
412377
&journalnode_podrefs,
413-
merged_config,
414-
&validated.hdfs_opa_config,
415-
)?;
378+
)
379+
.context(BuildRoleGroupConfigMapSnafu)?;
416380

417381
let rg_statefulset = rolegroup_statefulset(
418382
hdfs,
@@ -564,93 +528,6 @@ pub async fn reconcile_hdfs(
564528
Ok(Action::await_change())
565529
}
566530

567-
#[allow(clippy::too_many_arguments)]
568-
fn rolegroup_config_map(
569-
hdfs: &v1alpha1::HdfsCluster,
570-
cluster_info: &KubernetesClusterInfo,
571-
metadata: &ObjectMetaBuilder,
572-
rolegroup_ref: &RoleGroupRef<v1alpha1::HdfsCluster>,
573-
config_overrides: &v1alpha1::HdfsConfigOverrides,
574-
namenode_podrefs: &[HdfsPodRef],
575-
journalnode_podrefs: &[HdfsPodRef],
576-
merged_config: &AnyNodeConfig,
577-
hdfs_opa_config: &Option<HdfsOpaConfig>,
578-
) -> HdfsOperatorResult<ConfigMap> {
579-
tracing::info!("Setting up ConfigMap for {:?}", rolegroup_ref);
580-
581-
let role = HdfsNodeRole::from_str(&rolegroup_ref.role).with_context(|_| {
582-
UnidentifiedHdfsRoleSnafu {
583-
role: rolegroup_ref.role.clone(),
584-
}
585-
})?;
586-
let hdfs_name = hdfs
587-
.metadata
588-
.name
589-
.as_deref()
590-
.with_context(|| ObjectHasNoNameSnafu {
591-
obj_ref: ObjectRef::from_obj(hdfs),
592-
})?;
593-
594-
let hdfs_site_xml = hdfs_site::build(
595-
hdfs,
596-
hdfs_name,
597-
cluster_info,
598-
merged_config,
599-
namenode_podrefs,
600-
journalnode_podrefs,
601-
hdfs_opa_config.as_ref(),
602-
config_overrides.hdfs_site_xml.clone(),
603-
);
604-
let core_site_xml = core_site::build(
605-
hdfs,
606-
hdfs_name,
607-
role,
608-
cluster_info,
609-
hdfs_opa_config.as_ref(),
610-
config_overrides.core_site_xml.clone(),
611-
)
612-
.context(BuildCoreSiteXmlSnafu)?;
613-
let hadoop_policy_xml = hadoop_policy::build(config_overrides.hadoop_policy_xml.clone());
614-
let ssl_server_xml = ssl_server::build(
615-
hdfs.has_https_enabled(),
616-
config_overrides.ssl_server_xml.clone(),
617-
);
618-
let ssl_client_xml = ssl_client::build(
619-
hdfs.has_https_enabled(),
620-
config_overrides.ssl_client_xml.clone(),
621-
);
622-
623-
let mut builder = ConfigMapBuilder::new();
624-
builder
625-
.metadata(metadata.build())
626-
.add_data(ConfigFileName::CoreSite.to_string(), core_site_xml)
627-
.add_data(ConfigFileName::HdfsSite.to_string(), hdfs_site_xml)
628-
.add_data(ConfigFileName::HadoopPolicy.to_string(), hadoop_policy_xml)
629-
.add_data(ConfigFileName::SslServer.to_string(), ssl_server_xml)
630-
.add_data(ConfigFileName::SslClient.to_string(), ssl_client_xml)
631-
.add_data(
632-
ConfigFileName::Security.to_string(),
633-
security_properties::build(config_overrides.security_properties.clone()).with_context(
634-
|_| JvmSecurityPropertiesSnafu {
635-
rolegroup: rolegroup_ref.role_group.clone(),
636-
},
637-
)?,
638-
);
639-
640-
extend_role_group_config_map(rolegroup_ref, merged_config, &mut builder).context(
641-
InvalidLoggingConfigSnafu {
642-
cm_name: rolegroup_ref.object_name(),
643-
},
644-
)?;
645-
646-
builder
647-
.build()
648-
.with_context(|_| BuildRoleGroupConfigMapSnafu {
649-
role: rolegroup_ref.role.clone(),
650-
role_group: rolegroup_ref.role_group.clone(),
651-
})
652-
}
653-
654531
#[allow(clippy::too_many_arguments)]
655532
fn rolegroup_statefulset(
656533
hdfs: &v1alpha1::HdfsCluster,

0 commit comments

Comments
 (0)