@@ -348,7 +348,7 @@ fn process_validation_result(
348
348
/// with the highest priority. The merge priority chain looks like this where '->' means
349
349
/// "overwrites if existing or adds":
350
350
///
351
- /// group overrides -> group config -> role overrides -> role config (TODO: -> common_config)
351
+ /// group overrides -> role overrides -> group config -> role config (TODO: -> common_config)
352
352
///
353
353
/// The output is a map where the [`crate::role_utils::RoleGroup] name points to another map of
354
354
/// [`product_config::types::PropertyValidationResult`] that points to the mapped configuration
@@ -371,24 +371,42 @@ where
371
371
{
372
372
let mut result = HashMap :: new ( ) ;
373
373
374
+ // Properties from the role have the lowest priority, so they are computed first...
374
375
let role_properties = parse_role_config ( resource, role_name, & role. config , property_kinds) ?;
376
+ let role_overrides = parse_role_overrides ( & role. config , property_kinds) ?;
375
377
376
378
// for each role group ...
377
379
for ( role_group_name, role_group) in & role. role_groups {
378
- // ... compute the group properties ...
380
+ let mut role_group_properties_merged = role_properties. clone ( ) ;
381
+
382
+ // ... compute the group properties and merge them into role properties.
379
383
let role_group_properties =
380
384
parse_role_config ( resource, role_name, & role_group. config , property_kinds) ?;
381
-
382
- // ... and merge them with the role properties.
383
- let mut role_properties_copy = role_properties. clone ( ) ;
384
385
for ( property_kind, properties) in role_group_properties {
385
- role_properties_copy
386
+ role_group_properties_merged
386
387
. entry ( property_kind)
387
388
. or_default ( )
388
389
. extend ( properties) ;
389
390
}
390
391
391
- result. insert ( role_group_name. clone ( ) , role_properties_copy) ;
392
+ // ... copy role overrides and merge them into `role_group_properties_merged`.
393
+ for ( property_kind, property_overrides) in role_overrides. clone ( ) {
394
+ role_group_properties_merged
395
+ . entry ( property_kind)
396
+ . or_default ( )
397
+ . extend ( property_overrides) ;
398
+ }
399
+
400
+ // ... compute the role group overrides and merge them into `role_group_properties_merged`.
401
+ let role_group_overrides = parse_role_overrides ( & role_group. config , property_kinds) ?;
402
+ for ( property_kind, property_overrides) in role_group_overrides {
403
+ role_group_properties_merged
404
+ . entry ( property_kind)
405
+ . or_default ( )
406
+ . extend ( property_overrides) ;
407
+ }
408
+
409
+ result. insert ( role_group_name. clone ( ) , role_group_properties_merged) ;
392
410
}
393
411
394
412
Ok ( result)
@@ -414,86 +432,80 @@ where
414
432
T : Configuration ,
415
433
{
416
434
let mut result = HashMap :: new ( ) ;
417
-
418
435
for property_kind in property_kinds {
419
436
match property_kind {
420
437
PropertyNameKind :: File ( file) => result. insert (
421
438
property_kind. clone ( ) ,
422
- parse_file_properties ( resource, role_name, config , file) ?,
439
+ config . config . compute_files ( resource, role_name, file) ?,
423
440
) ,
424
441
PropertyNameKind :: Env => result. insert (
425
442
property_kind. clone ( ) ,
426
- parse_env_properties ( resource, role_name, config ) ?,
443
+ config . config . compute_env ( resource, role_name) ?,
427
444
) ,
428
445
PropertyNameKind :: Cli => result. insert (
429
446
property_kind. clone ( ) ,
430
- parse_cli_properties ( resource, role_name, config ) ?,
447
+ config . config . compute_cli ( resource, role_name) ?,
431
448
) ,
432
449
} ;
433
450
}
434
451
435
452
Ok ( result)
436
453
}
437
454
438
- fn parse_cli_properties < T > (
439
- resource : & <T as Configuration >:: Configurable ,
440
- role_name : & str ,
441
- config : & CommonConfiguration < T > ,
442
- ) -> Result < BTreeMap < String , Option < String > > >
443
- where
444
- T : Configuration ,
445
- {
446
- // Properties from the role have the lowest priority, so they are computed and added first...
447
- let mut final_properties = config. config . compute_cli ( resource, role_name) ?;
448
-
449
- // ...followed by config_overrides from the role
450
- for ( key, value) in & config. cli_overrides {
451
- final_properties. insert ( key. clone ( ) , Some ( value. clone ( ) ) ) ;
452
- }
453
-
454
- Ok ( final_properties)
455
- }
456
-
457
- fn parse_env_properties < T > (
458
- resource : & <T as Configuration >:: Configurable ,
459
- role_name : & str ,
455
+ fn parse_role_overrides < T > (
460
456
config : & CommonConfiguration < T > ,
461
- ) -> Result < BTreeMap < String , Option < String > > >
457
+ property_kinds : & [ PropertyNameKind ] ,
458
+ ) -> Result < HashMap < PropertyNameKind , BTreeMap < String , Option < String > > > >
462
459
where
463
460
T : Configuration ,
464
461
{
465
- // Properties from the role have the lowest priority, so they are computed and added first...
466
- let mut final_properties = config. config . compute_env ( resource, role_name) ?;
467
-
468
- // ...followed by config_overrides from the role
469
- for ( key, value) in & config. env_overrides {
470
- final_properties. insert ( key. clone ( ) , Some ( value. clone ( ) ) ) ;
462
+ let mut result = HashMap :: new ( ) ;
463
+ for property_kind in property_kinds {
464
+ match property_kind {
465
+ PropertyNameKind :: File ( file) => {
466
+ result. insert ( property_kind. clone ( ) , parse_file_overrides ( config, file) ?)
467
+ }
468
+ PropertyNameKind :: Env => result. insert (
469
+ property_kind. clone ( ) ,
470
+ config
471
+ . env_overrides
472
+ . clone ( )
473
+ . into_iter ( )
474
+ . map ( |( k, v) | ( k, Some ( v) ) )
475
+ . collect ( ) ,
476
+ ) ,
477
+ PropertyNameKind :: Cli => result. insert (
478
+ property_kind. clone ( ) ,
479
+ config
480
+ . cli_overrides
481
+ . clone ( )
482
+ . into_iter ( )
483
+ . map ( |( k, v) | ( k, Some ( v) ) )
484
+ . collect ( ) ,
485
+ ) ,
486
+ } ;
471
487
}
472
488
473
- Ok ( final_properties )
489
+ Ok ( result )
474
490
}
475
491
476
- fn parse_file_properties < T > (
477
- resource : & <T as Configuration >:: Configurable ,
478
- role_name : & str ,
492
+ fn parse_file_overrides < T > (
479
493
config : & CommonConfiguration < T > ,
480
494
file : & str ,
481
495
) -> Result < BTreeMap < String , Option < String > > >
482
496
where
483
497
T : Configuration ,
484
498
{
485
- // Properties from the role have the lowest priority, so they are computed and added first...
486
- let mut final_properties = config. config . compute_files ( resource, role_name, file) ?;
499
+ let mut final_overrides: BTreeMap < String , Option < String > > = BTreeMap :: new ( ) ;
487
500
488
- // ...followed by config_overrides from the role
489
501
// For Conf files only process overrides that match our file name
490
502
if let Some ( config) = config. config_overrides . get ( file) {
491
503
for ( key, value) in config {
492
- final_properties . insert ( key. clone ( ) , Some ( value. clone ( ) ) ) ;
504
+ final_overrides . insert ( key. clone ( ) , Some ( value. clone ( ) ) ) ;
493
505
}
494
506
}
495
507
496
- Ok ( final_properties )
508
+ Ok ( final_overrides )
497
509
}
498
510
499
511
#[ cfg( test) ]
@@ -1049,6 +1061,136 @@ mod tests {
1049
1061
assert_eq ! ( config, expected) ;
1050
1062
}
1051
1063
1064
+ #[ rstest]
1065
+ #[ case(
1066
+ HashMap :: from( [
1067
+ ( "env" . to_string( ) , ROLE_ENV_OVERRIDE . to_string( ) ) ,
1068
+ ] ) ,
1069
+ HashMap :: from( [
1070
+ ( "env" . to_string( ) , GROUP_ENV_OVERRIDE . to_string( ) ) ,
1071
+ ] ) ,
1072
+ BTreeMap :: from( [
1073
+ ( "cli" . to_string( ) , ROLE_CLI_OVERRIDE . to_string( ) ) ,
1074
+ ] ) ,
1075
+ BTreeMap :: from( [
1076
+ ( "cli" . to_string( ) , GROUP_CLI_OVERRIDE . to_string( ) ) ,
1077
+ ] ) ,
1078
+ HashMap :: from( [
1079
+ ( "file" . to_string( ) , HashMap :: from( [
1080
+ ( "file" . to_string( ) , ROLE_CONF_OVERRIDE . to_string( ) )
1081
+ ] ) )
1082
+ ] ) ,
1083
+ HashMap :: from( [
1084
+ ( "file" . to_string( ) , HashMap :: from( [
1085
+ ( "file" . to_string( ) , GROUP_CONF_OVERRIDE . to_string( ) )
1086
+ ] ) )
1087
+ ] ) ,
1088
+ collection ! {
1089
+ ROLE_GROUP . to_string( ) => collection ! {
1090
+ PropertyNameKind :: Env => collection ! {
1091
+ "env" . to_string( ) => Some ( GROUP_ENV_OVERRIDE . to_string( ) ) ,
1092
+ } ,
1093
+ PropertyNameKind :: Cli => collection ! {
1094
+ "cli" . to_string( ) => Some ( GROUP_CLI_OVERRIDE . to_string( ) ) ,
1095
+ } ,
1096
+ PropertyNameKind :: File ( "file" . to_string( ) ) => collection ! {
1097
+ "file" . to_string( ) => Some ( GROUP_CONF_OVERRIDE . to_string( ) ) ,
1098
+ }
1099
+ }
1100
+ }
1101
+ ) ]
1102
+ #[ case(
1103
+ HashMap :: from( [
1104
+ ( "env" . to_string( ) , ROLE_ENV_OVERRIDE . to_string( ) ) ,
1105
+ ] ) ,
1106
+ HashMap :: from( [ ] ) ,
1107
+ BTreeMap :: from( [
1108
+ ( "cli" . to_string( ) , ROLE_CLI_OVERRIDE . to_string( ) ) ,
1109
+ ] ) ,
1110
+ BTreeMap :: from( [ ] ) ,
1111
+ HashMap :: from( [
1112
+ ( "file" . to_string( ) , HashMap :: from( [
1113
+ ( "file" . to_string( ) , ROLE_CONF_OVERRIDE . to_string( ) )
1114
+ ] ) )
1115
+ ] ) ,
1116
+ HashMap :: from( [ ] ) ,
1117
+ collection ! {
1118
+ ROLE_GROUP . to_string( ) => collection ! {
1119
+ PropertyNameKind :: Env => collection ! {
1120
+ "env" . to_string( ) => Some ( ROLE_ENV_OVERRIDE . to_string( ) ) ,
1121
+ } ,
1122
+ PropertyNameKind :: Cli => collection ! {
1123
+ "cli" . to_string( ) => Some ( ROLE_CLI_OVERRIDE . to_string( ) ) ,
1124
+ } ,
1125
+ PropertyNameKind :: File ( "file" . to_string( ) ) => collection ! {
1126
+ "file" . to_string( ) => Some ( ROLE_CONF_OVERRIDE . to_string( ) ) ,
1127
+ }
1128
+ }
1129
+ }
1130
+ ) ]
1131
+ #[ case(
1132
+ HashMap :: from( [ ] ) ,
1133
+ HashMap :: from( [ ] ) ,
1134
+ BTreeMap :: from( [ ] ) ,
1135
+ BTreeMap :: from( [ ] ) ,
1136
+ HashMap :: from( [ ] ) ,
1137
+ HashMap :: from( [ ] ) ,
1138
+ collection ! {
1139
+ ROLE_GROUP . to_string( ) => collection ! {
1140
+ PropertyNameKind :: Env => collection ! {
1141
+ "env" . to_string( ) => Some ( GROUP_ENV . to_string( ) ) ,
1142
+ } ,
1143
+ PropertyNameKind :: Cli => collection ! {
1144
+ "cli" . to_string( ) => Some ( GROUP_CLI . to_string( ) ) ,
1145
+ } ,
1146
+ PropertyNameKind :: File ( "file" . to_string( ) ) => collection ! {
1147
+ "file" . to_string( ) => Some ( GROUP_CONFIG . to_string( ) ) ,
1148
+ }
1149
+ }
1150
+ }
1151
+ ) ]
1152
+ fn test_order_in_transform_role_to_config (
1153
+ #[ case] role_env_override : HashMap < String , String > ,
1154
+ #[ case] group_env_override : HashMap < String , String > ,
1155
+ #[ case] role_cli_override : BTreeMap < String , String > ,
1156
+ #[ case] group_cli_override : BTreeMap < String , String > ,
1157
+ #[ case] role_conf_override : HashMap < String , HashMap < String , String > > ,
1158
+ #[ case] group_conf_override : HashMap < String , HashMap < String , String > > ,
1159
+ #[ case] expected : HashMap <
1160
+ String ,
1161
+ HashMap < PropertyNameKind , BTreeMap < String , Option < String > > > ,
1162
+ > ,
1163
+ ) {
1164
+ let role: Role < Box < TestConfig > , TestRoleConfig > = Role {
1165
+ config : build_common_config (
1166
+ build_test_config ( ROLE_CONFIG , ROLE_ENV , ROLE_CLI ) ,
1167
+ Some ( role_conf_override) ,
1168
+ Some ( role_env_override) ,
1169
+ Some ( role_cli_override) ,
1170
+ ) ,
1171
+ role_config : Default :: default ( ) ,
1172
+ role_groups : collection ! { "role_group" . to_string( ) => RoleGroup {
1173
+ replicas: Some ( 1 ) ,
1174
+ config: build_common_config(
1175
+ build_test_config( GROUP_CONFIG , GROUP_ENV , GROUP_CLI ) ,
1176
+ Some ( group_conf_override) ,
1177
+ Some ( group_env_override) ,
1178
+ Some ( group_cli_override) ) ,
1179
+ } } ,
1180
+ } ;
1181
+
1182
+ let property_kinds = vec ! [
1183
+ PropertyNameKind :: Env ,
1184
+ PropertyNameKind :: Cli ,
1185
+ PropertyNameKind :: File ( "file" . to_string( ) ) ,
1186
+ ] ;
1187
+
1188
+ let config =
1189
+ transform_role_to_config ( & String :: new ( ) , ROLE_GROUP , & role, & property_kinds) . unwrap ( ) ;
1190
+
1191
+ assert_eq ! ( config, expected) ;
1192
+ }
1193
+
1052
1194
#[ test]
1053
1195
fn test_transform_role_to_config_overrides ( ) {
1054
1196
let role_group = "role_group" ;
@@ -1088,7 +1230,7 @@ mod tests {
1088
1230
) ,
1089
1231
PropertyNameKind :: Cli =>
1090
1232
collection!(
1091
- "cli" . to_string( ) => Some ( GROUP_CLI . to_string( ) ) ,
1233
+ "cli" . to_string( ) => Some ( "cli" . to_string( ) ) ,
1092
1234
) ,
1093
1235
}
1094
1236
} ;
0 commit comments