Skip to content

Commit a4057fa

Browse files
committed
refactor: add hdfssite to ConfigFileName, clean up constants, share object_meta builder
1 parent e23aa70 commit a4057fa

11 files changed

Lines changed: 176 additions & 97 deletions

File tree

rust/operator-binary/src/controller.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,31 @@ impl ValidatedCluster {
289289
pub fn role_listener_name(&self, hive_role: &HiveRole) -> String {
290290
format!("{name}-{role}", name = self.name, role = hive_role)
291291
}
292+
293+
/// Returns an [`ObjectMetaBuilder`] pre-filled with the namespace, an owner reference back to
294+
/// this cluster, and the recommended labels for a resource named `name` in `role_group_name`.
295+
///
296+
/// Consolidates the metadata chain repeated by the child-resource builders. Call sites that
297+
/// need extra labels/annotations chain them onto the returned builder.
298+
pub(crate) fn object_meta(
299+
&self,
300+
name: impl Into<String>,
301+
role_group_name: &RoleGroupName,
302+
) -> stackable_operator::builder::meta::ObjectMetaBuilder {
303+
let mut builder = stackable_operator::builder::meta::ObjectMetaBuilder::new();
304+
builder
305+
.name_and_namespace(self)
306+
.name(name)
307+
.ownerreference(
308+
stackable_operator::v2::builder::meta::ownerreference_from_resource(
309+
self,
310+
None,
311+
Some(true),
312+
),
313+
)
314+
.with_labels(self.recommended_labels(role_group_name));
315+
builder
316+
}
292317
}
293318

294319
/// Lets [`ValidatedCluster`] stand in for the raw [`v1alpha1::HiveCluster`] when building owner
@@ -623,3 +648,43 @@ pub(crate) mod test_support {
623648
.expect("validate should succeed for the test fixture")
624649
}
625650
}
651+
652+
#[cfg(test)]
653+
mod tests {
654+
use std::str::FromStr;
655+
656+
use super::{RoleGroupName, test_support::*};
657+
658+
const DERBY_YAML: &str = r#"
659+
apiVersion: hive.stackable.tech/v1alpha1
660+
kind: HiveCluster
661+
metadata:
662+
name: simple-hive
663+
namespace: default
664+
uid: 12345678-1234-1234-1234-123456789012
665+
spec:
666+
image:
667+
productVersion: 4.2.0
668+
clusterConfig:
669+
metadataDatabase:
670+
derby: {}
671+
metastore:
672+
roleGroups:
673+
default:
674+
replicas: 1
675+
"#;
676+
677+
#[test]
678+
fn object_meta_sets_namespace_owner_and_recommended_labels() {
679+
let hive = minimal_hive(DERBY_YAML);
680+
let cluster = validated_cluster(&hive);
681+
let role_group_name = RoleGroupName::from_str("default").expect("valid role group name");
682+
683+
let meta = cluster.object_meta("test-name", &role_group_name).build();
684+
685+
assert_eq!(meta.name.as_deref(), Some("test-name"));
686+
assert_eq!(meta.namespace.as_deref(), Some(cluster.namespace.as_ref()));
687+
assert!(meta.owner_references.is_some());
688+
assert!(meta.labels.is_some());
689+
}
690+
}

rust/operator-binary/src/controller/build/command.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use stackable_operator::crd::s3;
22

3-
use super::{opa::HiveOpaConfig, properties::ConfigFileName};
3+
use super::{opa::HiveOpaConfig, properties::ConfigFileName, statefulset::HDFS_CONFIG_MOUNT_DIR};
44
use crate::crd::{
55
STACKABLE_CONFIG_DIR, STACKABLE_CONFIG_MOUNT_DIR, STACKABLE_LOG_CONFIG_MOUNT_DIR,
66
STACKABLE_TRUST_STORE, STACKABLE_TRUST_STORE_PASSWORD, v1alpha1,
@@ -13,6 +13,7 @@ pub fn build_container_command_args(
1313
hive_opa_config: Option<&HiveOpaConfig>,
1414
) -> Vec<String> {
1515
let log4j2_properties = ConfigFileName::Log4j2;
16+
let core_site = ConfigFileName::CoreSite;
1617
let mut args = vec![
1718
// copy config files to a writeable empty folder in order to set s3 access and secret keys
1819
format!("echo copying {STACKABLE_CONFIG_MOUNT_DIR} to {STACKABLE_CONFIG_DIR}"),
@@ -26,7 +27,7 @@ pub fn build_container_command_args(
2627
),
2728
// Template config files
2829
format!(
29-
"if test -f {STACKABLE_CONFIG_DIR}/core-site.xml; then config-utils template {STACKABLE_CONFIG_DIR}/core-site.xml; fi"
30+
"if test -f {STACKABLE_CONFIG_DIR}/{core_site}; then config-utils template {STACKABLE_CONFIG_DIR}/{core_site}; fi"
3031
),
3132
format!(
3233
"if test -f {STACKABLE_CONFIG_DIR}/hive-site.xml; then config-utils template {STACKABLE_CONFIG_DIR}/hive-site.xml; fi"
@@ -39,8 +40,8 @@ pub fn build_container_command_args(
3940

4041
if hive.spec.cluster_config.hdfs.is_some() {
4142
args.extend([
42-
format!("echo copying /stackable/mount/hdfs-config to {STACKABLE_CONFIG_DIR}"),
43-
format!("cp -RL /stackable/mount/hdfs-config/* {STACKABLE_CONFIG_DIR}"),
43+
format!("echo copying {HDFS_CONFIG_MOUNT_DIR} to {STACKABLE_CONFIG_DIR}"),
44+
format!("cp -RL {HDFS_CONFIG_MOUNT_DIR}/* {STACKABLE_CONFIG_DIR}"),
4445
]);
4546
}
4647

rust/operator-binary/src/controller/build/config_map.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@
22
33
use snafu::{ResultExt, Snafu};
44
use stackable_operator::{
5-
builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder},
5+
builder::configmap::ConfigMapBuilder,
66
k8s_openapi::api::core::v1::ConfigMap,
77
product_logging::framework::VECTOR_CONFIG_FILE,
8-
v2::{
9-
builder::meta::ownerreference_from_resource,
10-
config_file_writer::{PropertiesWriterError, to_hadoop_xml, to_java_properties_string},
11-
},
8+
v2::config_file_writer::{PropertiesWriterError, to_hadoop_xml, to_java_properties_string},
129
};
1310

1411
use crate::controller::{
@@ -63,16 +60,14 @@ pub fn build_metastore_rolegroup_config_map(
6360
let mut cm_builder = ConfigMapBuilder::new();
6461
cm_builder
6562
.metadata(
66-
ObjectMetaBuilder::new()
67-
.name_and_namespace(cluster)
68-
.name(
63+
cluster
64+
.object_meta(
6965
cluster
7066
.resource_names(role_group_name)
7167
.role_group_config_map()
7268
.to_string(),
69+
role_group_name,
7370
)
74-
.ownerreference(ownerreference_from_resource(cluster, None, Some(true)))
75-
.with_labels(cluster.recommended_labels(role_group_name))
7671
.build(),
7772
)
7873
.add_data(

rust/operator-binary/src/controller/build/discovery.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
1-
use std::str::FromStr;
2-
31
use snafu::{ResultExt, Snafu};
42
use stackable_operator::{
5-
builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder},
6-
crd::listener::v1alpha1::Listener,
7-
k8s_openapi::api::core::v1::ConfigMap,
8-
kube::runtime::reflector::ObjectRef,
9-
v2::builder::meta::ownerreference_from_resource,
3+
builder::configmap::ConfigMapBuilder, crd::listener::v1alpha1::Listener,
4+
k8s_openapi::api::core::v1::ConfigMap, kube::runtime::reflector::ObjectRef,
105
};
116

127
use crate::{
138
controller::{
14-
RoleGroupName, ValidatedCluster, build::listener::build_listener_connection_string,
9+
ValidatedCluster,
10+
build::{PLACEHOLDER_DISCOVERY_ROLE_GROUP, listener::build_listener_connection_string},
1511
},
1612
crd::{HiveRole, v1alpha1},
1713
};
@@ -64,17 +60,11 @@ fn build_discovery_configmap(
6460
let mut discovery_configmap = ConfigMapBuilder::new();
6561

6662
discovery_configmap.metadata(
67-
ObjectMetaBuilder::new()
68-
.name_and_namespace(cluster)
69-
.ownerreference(ownerreference_from_resource(cluster, None, Some(true)))
70-
// Discovery is a role-level object; "discovery" is used as a placeholder role-group
71-
// name for the recommended labels.
72-
.with_labels(
73-
cluster.recommended_labels(
74-
&RoleGroupName::from_str("discovery")
75-
.expect("'discovery' is a valid role group name"),
76-
),
77-
)
63+
cluster
64+
// Discovery is a role-level object; the cluster name is used as the resource name
65+
// (matching `name_and_namespace`) and "discovery" as a placeholder role-group name
66+
// for the recommended labels.
67+
.object_meta(cluster.name.to_string(), &PLACEHOLDER_DISCOVERY_ROLE_GROUP)
7868
.build(),
7969
);
8070

rust/operator-binary/src/controller/build/jvm.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use snafu::{OptionExt, ResultExt, Snafu};
22
use stackable_operator::memory::{BinaryMultiple, MemoryQuantity};
33

4-
use super::properties::ConfigFileName;
4+
use super::{kerberos::STACKABLE_KERBEROS_DIR, properties::ConfigFileName};
55
use crate::{
66
controller::HiveRoleGroupConfig,
77
crd::{
@@ -37,7 +37,9 @@ fn construct_jvm_args(hive: &HiveCluster, rg: &HiveRoleGroupConfig) -> Vec<Strin
3737
];
3838

3939
if hive.has_kerberos_enabled() {
40-
jvm_args.push("-Djava.security.krb5.conf=/stackable/kerberos/krb5.conf".to_owned());
40+
jvm_args.push(format!(
41+
"-Djava.security.krb5.conf={STACKABLE_KERBEROS_DIR}/krb5.conf"
42+
));
4143
}
4244

4345
// Apply the already-merged (role + role group) JVM argument overrides on top of the
@@ -123,11 +125,13 @@ mod tests {
123125

124126
assert_eq!(
125127
non_heap_jvm_args,
126-
"-Djava.security.properties=/stackable/config/security.properties \
127-
-javaagent:/stackable/jmx/jmx_prometheus_javaagent.jar=9084:/stackable/jmx/jmx_hive_config.yaml \
128-
-Djavax.net.ssl.trustStore=/stackable/truststore.p12 \
129-
-Djavax.net.ssl.trustStorePassword=changeit \
128+
format!(
129+
"-Djava.security.properties={STACKABLE_CONFIG_DIR}/security.properties \
130+
-javaagent:/stackable/jmx/jmx_prometheus_javaagent.jar={METRICS_PORT}:/stackable/jmx/jmx_hive_config.yaml \
131+
-Djavax.net.ssl.trustStore={STACKABLE_TRUST_STORE} \
132+
-Djavax.net.ssl.trustStorePassword={STACKABLE_TRUST_STORE_PASSWORD} \
130133
-Djavax.net.ssl.trustStoreType=pkcs12"
134+
)
131135
);
132136
assert_eq!(hadoop_heapsize_env, "614");
133137
}
@@ -176,14 +180,16 @@ mod tests {
176180

177181
assert_eq!(
178182
non_heap_jvm_args,
179-
"-Djava.security.properties=/stackable/config/security.properties \
180-
-javaagent:/stackable/jmx/jmx_prometheus_javaagent.jar=9084:/stackable/jmx/jmx_hive_config.yaml \
181-
-Djavax.net.ssl.trustStore=/stackable/truststore.p12 \
182-
-Djavax.net.ssl.trustStorePassword=changeit \
183+
format!(
184+
"-Djava.security.properties={STACKABLE_CONFIG_DIR}/security.properties \
185+
-javaagent:/stackable/jmx/jmx_prometheus_javaagent.jar={METRICS_PORT}:/stackable/jmx/jmx_hive_config.yaml \
186+
-Djavax.net.ssl.trustStore={STACKABLE_TRUST_STORE} \
187+
-Djavax.net.ssl.trustStorePassword={STACKABLE_TRUST_STORE_PASSWORD} \
183188
-Djavax.net.ssl.trustStoreType=pkcs12 \
184189
-Dhttps.proxyHost=proxy.my.corp \
185190
-Djava.net.preferIPv4Stack=true \
186191
-Dhttps.proxyPort=1234"
192+
)
187193
);
188194
assert_eq!(hadoop_heapsize_env, "34406");
189195
}

rust/operator-binary/src/controller/build/kerberos.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::BTreeMap;
1+
use std::{collections::BTreeMap, str::FromStr};
22

33
use indoc::formatdoc;
44
use snafu::{ResultExt, Snafu};
@@ -17,11 +17,20 @@ use stackable_operator::{
1717
commons::secret_class::SecretClassVolumeProvisionParts,
1818
kube::ResourceExt,
1919
utils::cluster_info::KubernetesClusterInfo,
20+
v2::types::kubernetes::VolumeName,
2021
};
2122

2223
use super::properties::ConfigFileName;
2324
use crate::crd::{HiveRole, STACKABLE_CONFIG_DIR, v1alpha1};
2425

26+
// Typed name for the Kerberos secret-operator volume, reusing the existing `"kerberos"` string
27+
// value so the produced volume/mount name is unchanged.
28+
stackable_operator::constant!(pub(crate) KERBEROS_VOLUME_NAME: VolumeName = "kerberos");
29+
30+
/// The directory the Kerberos secret-operator volume is mounted at. `krb5.conf` and `keytab`
31+
/// sub-paths are derived from this.
32+
pub(crate) const STACKABLE_KERBEROS_DIR: &str = "/stackable/kerberos";
33+
2534
#[derive(Snafu, Debug)]
2635
#[allow(clippy::enum_variant_names)] // all variants have the same prefix: `Add`
2736
pub enum Error {
@@ -57,16 +66,16 @@ pub fn add_kerberos_pod_config(
5766
.build()
5867
.context(AddKerberosSecretVolumeSnafu)?;
5968
pb.add_volume(
60-
VolumeBuilder::new("kerberos")
69+
VolumeBuilder::new(&*KERBEROS_VOLUME_NAME)
6170
.ephemeral(kerberos_secret_operator_volume)
6271
.build(),
6372
)
6473
.context(AddVolumeSnafu)?;
65-
cb.add_volume_mount("kerberos", "/stackable/kerberos")
74+
cb.add_volume_mount(&*KERBEROS_VOLUME_NAME, STACKABLE_KERBEROS_DIR)
6675
.context(AddVolumeMountSnafu)?;
6776

6877
// Needed env vars
69-
cb.add_env_var("KRB5_CONFIG", "/stackable/kerberos/krb5.conf");
78+
cb.add_env_var("KRB5_CONFIG", format!("{STACKABLE_KERBEROS_DIR}/krb5.conf"));
7079
}
7180

7281
Ok(())
@@ -97,7 +106,7 @@ pub fn kerberos_config_properties(
97106
),
98107
(
99108
"hive.metastore.kerberos.keytab.file".to_string(),
100-
"/stackable/kerberos/keytab".to_string(),
109+
format!("{STACKABLE_KERBEROS_DIR}/keytab"),
101110
),
102111
(
103112
"hive.metastore.sasl.enabled".to_string(),
@@ -113,15 +122,17 @@ pub fn kerberos_container_start_commands(hive: &v1alpha1::HiveCluster) -> String
113122

114123
let hive_site_xml = ConfigFileName::HiveSite;
115124
let mut args = vec![formatdoc! {"
116-
export KERBEROS_REALM=$(grep -oP 'default_realm = \\K.*' /stackable/kerberos/krb5.conf)
125+
export KERBEROS_REALM=$(grep -oP 'default_realm = \\K.*' {STACKABLE_KERBEROS_DIR}/krb5.conf)
117126
sed -i -e 's/${{env.KERBEROS_REALM}}/'\"$KERBEROS_REALM/g\" {STACKABLE_CONFIG_DIR}/{hive_site_xml}",
118127
}];
119128

120129
if hive.spec.cluster_config.hdfs.is_some() {
130+
let core_site_xml = ConfigFileName::CoreSite;
131+
let hdfs_site_xml = ConfigFileName::HdfsSite;
121132
args.extend([
122133
formatdoc! {"
123-
sed -i -e 's/${{env.KERBEROS_REALM}}/'\"$KERBEROS_REALM/g\" {STACKABLE_CONFIG_DIR}/core-site.xml
124-
sed -i -e 's/${{env.KERBEROS_REALM}}/'\"$KERBEROS_REALM/g\" {STACKABLE_CONFIG_DIR}/hdfs-site.xml",
134+
sed -i -e 's/${{env.KERBEROS_REALM}}/'\"$KERBEROS_REALM/g\" {STACKABLE_CONFIG_DIR}/{core_site_xml}
135+
sed -i -e 's/${{env.KERBEROS_REALM}}/'\"$KERBEROS_REALM/g\" {STACKABLE_CONFIG_DIR}/{hdfs_site_xml}",
125136
}
126137
]);
127138
}

rust/operator-binary/src/controller/build/listener.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
use std::str::FromStr;
2-
31
use snafu::{OptionExt, Snafu};
4-
use stackable_operator::{
5-
builder::meta::ObjectMetaBuilder,
6-
crd::listener::v1alpha1::{Listener, ListenerPort, ListenerSpec},
7-
v2::builder::meta::ownerreference_from_resource,
8-
};
2+
use stackable_operator::crd::listener::v1alpha1::{Listener, ListenerPort, ListenerSpec};
93

104
use crate::{
11-
controller::{RoleGroupName, ValidatedCluster},
5+
controller::{ValidatedCluster, build::PLACEHOLDER_LISTENER_ROLE_GROUP},
126
crd::{HIVE_PORT, HIVE_PORT_NAME, HiveRole},
137
};
148

@@ -63,13 +57,11 @@ pub fn build_role_listener(
6357
) -> Listener {
6458
// The role listener is a role-level (not role-group-level) object, so there is no real
6559
// role-group name; "none" is used as a placeholder for the recommended labels.
66-
let metadata = ObjectMetaBuilder::new()
67-
.name_and_namespace(cluster)
68-
.name(cluster.role_listener_name(hive_role))
69-
.ownerreference(ownerreference_from_resource(cluster, None, Some(true)))
70-
.with_labels(cluster.recommended_labels(
71-
&RoleGroupName::from_str("none").expect("'none' is a valid role group name"),
72-
))
60+
let metadata = cluster
61+
.object_meta(
62+
cluster.role_listener_name(hive_role),
63+
&PLACEHOLDER_LISTENER_ROLE_GROUP,
64+
)
7365
.build();
7466

7567
let spec = ListenerSpec {

rust/operator-binary/src/controller/build/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
//! Builders that turn a `ValidatedCluster` into Kubernetes resources.
22
3+
use std::str::FromStr;
4+
5+
use stackable_operator::v2::types::operator::{ProductVersion, RoleGroupName};
6+
7+
// Placeholder role-group name used for the recommended labels of the role-level discovery
8+
// `ConfigMap` (which is not tied to a single role group).
9+
stackable_operator::constant!(pub(crate) PLACEHOLDER_DISCOVERY_ROLE_GROUP: RoleGroupName = "discovery");
10+
11+
// Placeholder role-group name used for the recommended labels of the role-level `Listener`
12+
// (which is not tied to a single role group).
13+
stackable_operator::constant!(pub(crate) PLACEHOLDER_LISTENER_ROLE_GROUP: RoleGroupName = "none");
14+
15+
// Placeholder product version used for labels on PVC templates, which cannot be modified once
16+
// deployed. A constant value keeps the labels stable across version upgrades.
17+
stackable_operator::constant!(pub(crate) UNVERSIONED_PRODUCT_VERSION: ProductVersion = "none");
18+
319
pub mod command;
420
pub mod config_map;
521
pub mod discovery;

0 commit comments

Comments
 (0)