22//! `smooth-operator` branch, with simplifications appropriate for hive-operator.
33//!
44//! Differences from upstream:
5- //! - `env_overrides` is `BTreeMap<String, String>` instead of `EnvVarSet`.
65//! - No `cli_overrides_to_vec` helper, `ResourceNames`, or service-account helpers.
76//! - The `CommonConfig` (a.k.a. `product_specific_common_config`) does NOT need to
87//! implement `Merge`. Hive uses `JavaCommonConfig`, which intentionally does not
1312//! Replace with `stackable_operator::v2::role_utils::*` once upstream relaxes the
1413//! `Merge` bound.
1514
16- use std:: collections:: BTreeMap ;
15+ use std:: {
16+ collections:: { BTreeMap , HashMap } ,
17+ str:: FromStr ,
18+ } ;
1719
1820use serde:: Serialize ;
21+ use snafu:: { ResultExt , Snafu } ;
1922use stackable_operator:: {
2023 config:: {
2124 fragment:: { self , FromFragment } ,
@@ -24,15 +27,25 @@ use stackable_operator::{
2427 k8s_openapi:: { DeepMerge , api:: core:: v1:: PodTemplateSpec } ,
2528 role_utils:: { Role , RoleGroup } ,
2629 schemars:: JsonSchema ,
30+ v2:: builder:: pod:: container:: { self , EnvVarName , EnvVarSet } ,
2731} ;
2832
33+ #[ derive( Snafu , Debug ) ]
34+ pub enum Error {
35+ #[ snafu( display( "failed to validate the role group config" ) ) ]
36+ ValidateConfig { source : fragment:: ValidationError } ,
37+
38+ #[ snafu( display( "invalid environment variable override name" ) ) ]
39+ ParseEnvVarName { source : container:: Error } ,
40+ }
41+
2942/// Hive-friendly view of a validated, merged `RoleGroup`.
3043#[ derive( Clone , Debug , PartialEq ) ]
3144pub struct RoleGroupConfig < Config , CommonConfig , ConfigOverrides > {
3245 pub replicas : u16 ,
3346 pub config : Config ,
3447 pub config_overrides : ConfigOverrides ,
35- pub env_overrides : BTreeMap < String , String > ,
48+ pub env_overrides : EnvVarSet ,
3649 pub cli_overrides : BTreeMap < String , String > ,
3750 pub pod_overrides : PodTemplateSpec ,
3851 pub product_specific_common_config : CommonConfig ,
@@ -43,18 +56,16 @@ pub fn with_validated_config<ValidatedConfig, CommonConfig, Config, RoleConfig,
4356 role_group : & RoleGroup < Config , CommonConfig , ConfigOverrides > ,
4457 role : & Role < Config , ConfigOverrides , RoleConfig , CommonConfig > ,
4558 default_config : & Config ,
46- ) -> Result <
47- RoleGroupConfig < ValidatedConfig , CommonConfig , ConfigOverrides > ,
48- fragment:: ValidationError ,
49- >
59+ ) -> Result < RoleGroupConfig < ValidatedConfig , CommonConfig , ConfigOverrides > , Error >
5060where
5161 ValidatedConfig : FromFragment < Fragment = Config > ,
5262 CommonConfig : Clone + Default + JsonSchema + Serialize ,
5363 Config : Clone + Merge ,
5464 RoleConfig : Default + JsonSchema + Serialize ,
5565 ConfigOverrides : Clone + Default + JsonSchema + Merge + Serialize ,
5666{
57- let validated_config = validate_config ( role_group, role, default_config) ?;
67+ let validated_config =
68+ validate_config ( role_group, role, default_config) . context ( ValidateConfigSnafu ) ?;
5869 Ok ( RoleGroupConfig {
5970 replicas : role_group. replicas . unwrap_or ( 1 ) ,
6071 config : validated_config,
6374 role_group. config . config_overrides . clone ( ) ,
6475 ) ,
6576 env_overrides : merged_env_overrides (
66- role. config
67- . env_overrides
68- . iter ( )
69- . map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) )
70- . collect ( ) ,
71- role_group
72- . config
73- . env_overrides
74- . iter ( )
75- . map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) )
76- . collect ( ) ,
77- ) ,
77+ & role. config . env_overrides ,
78+ & role_group. config . env_overrides ,
79+ ) ?,
7880 cli_overrides : merged_cli_overrides (
7981 role. config . cli_overrides . clone ( ) ,
8082 role_group. config . cli_overrides . clone ( ) ,
@@ -113,12 +115,22 @@ where
113115}
114116
115117fn merged_env_overrides (
116- role_env_overrides : BTreeMap < String , String > ,
117- role_group_env_overrides : BTreeMap < String , String > ,
118- ) -> BTreeMap < String , String > {
119- let mut merged = role_env_overrides;
120- merged. extend ( role_group_env_overrides) ;
121- merged
118+ role_env_overrides : & HashMap < String , String > ,
119+ role_group_env_overrides : & HashMap < String , String > ,
120+ ) -> Result < EnvVarSet , Error > {
121+ // Process the role first, then the role group, so that role-group overrides win on key
122+ // collisions (`EnvVarSet::with_value` overrides earlier entries with the same name).
123+ let mut env_overrides = EnvVarSet :: new ( ) ;
124+ for ( name, value) in role_env_overrides
125+ . iter ( )
126+ . chain ( role_group_env_overrides. iter ( ) )
127+ {
128+ env_overrides = env_overrides. with_value (
129+ & EnvVarName :: from_str ( name) . context ( ParseEnvVarNameSnafu ) ?,
130+ value. clone ( ) ,
131+ ) ;
132+ }
133+ Ok ( env_overrides)
122134}
123135
124136fn merged_cli_overrides (
0 commit comments