Skip to content

Commit 5925935

Browse files
committed
refactor: use v2 RoleGroupConfig and optional replicas
1 parent 1f1cd7a commit 5925935

6 files changed

Lines changed: 60 additions & 42 deletions

File tree

rust/operator-binary/src/controller.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,9 @@ impl ValidatedCluster {
197197
let resource_names = self.resource_names(role, role_group_name);
198198
let role_group_statefulset_name = resource_names.stateful_set_name();
199199
let role_group_service_name = resource_names.headless_service_name();
200-
for replica in 0..validated_rg.replicas {
200+
// Pods must be predicted from a concrete count (e.g. for KRaft quorum
201+
// voters), so an unset replica count falls back to 1.
202+
for replica in 0..validated_rg.replicas.unwrap_or(1) {
201203
pod_descriptors.push(KafkaPodDescriptor {
202204
namespace: self.namespace.clone(),
203205
role_group_service_name: role_group_service_name.clone(),
@@ -409,27 +411,21 @@ impl Resource for ValidatedCluster {
409411
}
410412
}
411413

412-
/// A validated, merged Kafka role-group config.
413-
///
414-
/// The merged config fragment is wrapped in [`AnyConfig`] and the merged
415-
/// `configOverrides` in [`AnyConfigOverrides`], so a single role-agnostic type carries
416-
/// both broker and controller role groups. Produced from the upstream
417-
/// [`stackable_operator::v2::role_utils::with_validated_config`] result in
418-
/// [`validate`](crate::controller::validate). `jvm_argument_overrides` is already merged
419-
/// (role <- role group) at validation time and applied as-is during build.
414+
/// The validated, merged per-role-group product config.
420415
#[derive(Clone, Debug, PartialEq)]
421-
pub struct ValidatedRoleGroupConfig {
422-
pub replicas: u16,
416+
pub struct ValidatedKafkaConfig {
423417
pub config: AnyConfig,
424-
pub config_overrides: AnyConfigOverrides,
425-
pub env_overrides: stackable_operator::v2::builder::pod::container::EnvVarSet,
426-
pub pod_overrides: stackable_operator::k8s_openapi::api::core::v1::PodTemplateSpec,
427-
pub jvm_argument_overrides:
428-
stackable_operator::v2::jvm_argument_overrides::JvmArgumentOverrides,
429418
/// Validated logging configuration (derived from `config.logging` during validation).
430419
pub logging: validate::ValidatedLogging,
431420
}
432421

422+
/// A validated, merged Kafka role-group config.
423+
pub type ValidatedRoleGroupConfig = stackable_operator::v2::role_utils::RoleGroupConfig<
424+
ValidatedKafkaConfig,
425+
stackable_operator::v2::role_utils::JavaCommonConfig,
426+
AnyConfigOverrides,
427+
>;
428+
433429
pub struct Ctx {
434430
pub client: stackable_operator::client::Client,
435431
pub operator_environment: OperatorEnvironmentOptions,
@@ -621,6 +617,7 @@ pub async fn reconcile_kafka(
621617
// The Vector agent config is the static `vector.yaml`, added to the rolegroup
622618
// ConfigMap only when the Vector agent is enabled (resolved during validation).
623619
let vector_config = validated_rg
620+
.config
624621
.logging
625622
.vector_container
626623
.is_some()
@@ -672,7 +669,7 @@ pub async fn reconcile_kafka(
672669
.context(BuildStatefulsetSnafu)?,
673670
};
674671

675-
if let AnyConfig::Broker(broker_config) = &validated_rg.config {
672+
if let AnyConfig::Broker(broker_config) = &validated_rg.config.config {
676673
let rg_bootstrap_listener = build_broker_rolegroup_bootstrap_listener(
677674
&validated_cluster,
678675
kafka_role,

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ mod tests {
102102
.get(&KafkaRole::Broker)
103103
.and_then(|groups| groups.get(&"default".parse().unwrap()))
104104
.expect("broker default role group should exist");
105-
(rg.config.clone(), rg.jvm_argument_overrides.clone())
105+
(
106+
rg.config.config.clone(),
107+
rg.product_specific_common_config
108+
.jvm_argument_overrides
109+
.clone(),
110+
)
106111
}
107112

108113
#[test]

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ pub fn build_rolegroup_config_map(
7171
listener_config: &KafkaListenerConfig,
7272
vector_config: Option<String>,
7373
) -> Result<ConfigMap, Error> {
74-
let role = validated_rg.config.kafka_role();
74+
let role = validated_rg.config.config.kafka_role();
7575
let cluster_config = &validated_cluster.cluster_config;
7676
let kafka_security = &cluster_config.kafka_security;
7777
let resolved_product_image = &validated_cluster.image;
78-
let kafka_config_file_name = config_file_name(&validated_rg.config).to_string();
78+
let kafka_config_file_name = config_file_name(&validated_rg.config.config).to_string();
7979
let config_overrides = validated_rg
8080
.config_overrides
8181
.config_file_overrides()
@@ -90,7 +90,7 @@ pub fn build_rolegroup_config_map(
9090
return NoKraftControllersFoundSnafu.fail();
9191
}
9292

93-
let kafka_config = match &validated_rg.config {
93+
let kafka_config = match &validated_rg.config.config {
9494
AnyConfig::Broker(_) => crate::controller::build::properties::broker_properties::build(
9595
cluster_config,
9696
listener_config,
@@ -177,7 +177,7 @@ pub fn build_rolegroup_config_map(
177177

178178
let config_data = role_group_config_map_data(
179179
&resolved_product_image.product_version,
180-
&validated_rg.config,
180+
&validated_rg.config.config,
181181
);
182182
for (file_name, data) in config_data {
183183
if let Some(data) = data {

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

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ pub fn build_broker_rolegroup_statefulset(
146146
) -> Result<StatefulSet, Error> {
147147
let kafka_security = &validated_cluster.cluster_config.kafka_security;
148148
let resolved_product_image = &validated_cluster.image;
149-
let merged_config = &validated_rg.config;
149+
let merged_config = &validated_rg.config.config;
150150
let resource_names = validated_cluster.resource_names(kafka_role, role_group_name);
151151
let recommended_labels = validated_cluster.recommended_labels(kafka_role, role_group_name);
152152
// Used for PVC templates that cannot be modified once they are deployed
@@ -261,7 +261,9 @@ pub fn build_broker_rolegroup_statefulset(
261261
add_common_kafka_env(
262262
&mut cb_kafka,
263263
merged_config,
264-
&validated_rg.jvm_argument_overrides,
264+
&validated_rg
265+
.product_specific_common_config
266+
.jvm_argument_overrides,
265267
resolved_product_image,
266268
kafka_role,
267269
role_group_name,
@@ -334,7 +336,11 @@ pub fn build_broker_rolegroup_statefulset(
334336
..Probe::default()
335337
});
336338

337-
add_log_config_volume(&mut pod_builder, &validated_rg.logging, &resource_names)?;
339+
add_log_config_volume(
340+
&mut pod_builder,
341+
&validated_rg.config.logging,
342+
&resource_names,
343+
)?;
338344

339345
let metadata = ObjectMetaBuilder::new()
340346
.with_labels(recommended_labels.clone())
@@ -377,7 +383,7 @@ pub fn build_broker_rolegroup_statefulset(
377383

378384
add_vector_container(
379385
&mut pod_builder,
380-
&validated_rg.logging,
386+
&validated_rg.config.logging,
381387
resolved_product_image,
382388
&resource_names,
383389
);
@@ -407,7 +413,7 @@ pub fn build_broker_rolegroup_statefulset(
407413
.build(),
408414
spec: Some(StatefulSetSpec {
409415
pod_management_policy: Some("Parallel".to_string()),
410-
replicas: Some(i32::from(validated_rg.replicas)),
416+
replicas: validated_rg.replicas.map(i32::from),
411417
selector: LabelSelector {
412418
match_labels: Some(
413419
validated_cluster
@@ -435,7 +441,7 @@ pub fn build_controller_rolegroup_statefulset(
435441
) -> Result<StatefulSet, Error> {
436442
let kafka_security = &validated_cluster.cluster_config.kafka_security;
437443
let resolved_product_image = &validated_cluster.image;
438-
let merged_config = &validated_rg.config;
444+
let merged_config = &validated_rg.config.config;
439445
let resource_names = validated_cluster.resource_names(kafka_role, role_group_name);
440446
let recommended_labels = validated_cluster.recommended_labels(kafka_role, role_group_name);
441447

@@ -529,7 +535,9 @@ pub fn build_controller_rolegroup_statefulset(
529535
add_common_kafka_env(
530536
&mut cb_kafka,
531537
merged_config,
532-
&validated_rg.jvm_argument_overrides,
538+
&validated_rg
539+
.product_specific_common_config
540+
.jvm_argument_overrides,
533541
resolved_product_image,
534542
kafka_role,
535543
role_group_name,
@@ -569,7 +577,11 @@ pub fn build_controller_rolegroup_statefulset(
569577
..Probe::default()
570578
});
571579

572-
add_log_config_volume(&mut pod_builder, &validated_rg.logging, &resource_names)?;
580+
add_log_config_volume(
581+
&mut pod_builder,
582+
&validated_rg.config.logging,
583+
&resource_names,
584+
)?;
573585

574586
let metadata = ObjectMetaBuilder::new()
575587
.with_labels(recommended_labels.clone())
@@ -600,7 +612,7 @@ pub fn build_controller_rolegroup_statefulset(
600612

601613
add_vector_container(
602614
&mut pod_builder,
603-
&validated_rg.logging,
615+
&validated_rg.config.logging,
604616
resolved_product_image,
605617
&resource_names,
606618
);
@@ -630,7 +642,7 @@ pub fn build_controller_rolegroup_statefulset(
630642
type_: Some("RollingUpdate".to_string()),
631643
..StatefulSetUpdateStrategy::default()
632644
}),
633-
replicas: Some(i32::from(validated_rg.replicas)),
645+
replicas: validated_rg.replicas.map(i32::from),
634646
selector: LabelSelector {
635647
match_labels: Some(
636648
validated_cluster

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ use stackable_operator::{
2929

3030
use crate::{
3131
controller::{
32-
RoleGroupName, ValidatedCluster, ValidatedClusterConfig, ValidatedRoleConfig,
33-
ValidatedRoleGroupConfig,
32+
RoleGroupName, ValidatedCluster, ValidatedClusterConfig, ValidatedKafkaConfig,
33+
ValidatedRoleConfig, ValidatedRoleGroupConfig,
3434
dereference::DereferencedObjects,
3535
security::{self, ValidatedKafkaSecurity},
3636
},
@@ -363,16 +363,20 @@ where
363363
validate_logging(&merged.config.config, vector_aggregator_config_map_name)?;
364364

365365
let validated = ValidatedRoleGroupConfig {
366-
replicas: merged.replicas.unwrap_or(1),
367-
config: wrap_config(merged.config.config),
366+
// Passed through as-is (including `None`) so an unset replica count lets a
367+
// horizontal autoscaler own the StatefulSet's `.spec.replicas`.
368+
replicas: merged.replicas,
369+
config: ValidatedKafkaConfig {
370+
config: wrap_config(merged.config.config),
371+
logging,
372+
},
368373
config_overrides: wrap_overrides(merged.config.config_overrides),
369374
env_overrides,
375+
// Kafka does not use CLI overrides; the field is carried (and merged upstream)
376+
// but unused.
377+
cli_overrides: merged.config.cli_overrides,
370378
pod_overrides: merged.config.pod_overrides,
371-
jvm_argument_overrides: merged
372-
.config
373-
.product_specific_common_config
374-
.jvm_argument_overrides,
375-
logging,
379+
product_specific_common_config: merged.config.product_specific_common_config,
376380
};
377381
let role_group_name = RoleGroupName::from_str(role_group_name).with_context(|_| {
378382
ParseRoleGroupNameSnafu {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ mod tests {
6464
.role_group_configs
6565
.get(&role)
6666
.and_then(|groups| groups.get(&"default".parse().unwrap()))
67-
.map(|rg| &rg.config)
67+
.map(|rg| &rg.config.config)
6868
.expect("role group should exist");
6969

7070
assert_eq!(

0 commit comments

Comments
 (0)