1- use std:: {
2- collections:: { BTreeMap , HashMap } ,
3- str:: FromStr ,
4- } ;
1+ use std:: collections:: BTreeMap ;
52
6- use product_config:: { ProductConfigManager , types:: PropertyNameKind } ;
73use snafu:: { ResultExt , Snafu } ;
84use stackable_operator:: {
95 commons:: product_image_selection:: { self , ResolvedProductImage } ,
10- product_config_utils:: { transform_all_roles_to_config, validate_all_roles_and_groups_config} ,
116 role_utils:: RoleGroupRef ,
127} ;
138use strum:: IntoEnumIterator ;
149
15- use crate :: crd:: { AIRFLOW_CONFIG_FILENAME , AirflowConfig , AirflowExecutor , AirflowRole , v1alpha2} ;
10+ use super :: dereference:: DereferencedObjects ;
11+ use crate :: crd:: {
12+ AirflowConfig , AirflowExecutor , AirflowRole , MergedOverrides ,
13+ authentication:: AirflowClientAuthenticationDetailsResolved ,
14+ authorization:: AirflowAuthorizationResolved , v1alpha2,
15+ } ;
1616
1717#[ derive( Snafu , Debug ) ]
1818pub enum Error {
@@ -21,24 +21,8 @@ pub enum Error {
2121 source : product_image_selection:: Error ,
2222 } ,
2323
24- #[ snafu( display( "invalid product config" ) ) ]
25- InvalidProductConfig {
26- source : stackable_operator:: product_config_utils:: Error ,
27- } ,
28-
29- #[ snafu( display( "failed to generate product config" ) ) ]
30- GenerateProductConfig {
31- source : stackable_operator:: product_config_utils:: Error ,
32- } ,
33-
3424 #[ snafu( display( "failed to resolve and merge config for role and role group" ) ) ]
3525 FailedToResolveConfig { source : crate :: crd:: Error } ,
36-
37- #[ snafu( display( "could not parse Airflow role [{role}]" ) ) ]
38- UnidentifiedAirflowRole {
39- source : strum:: ParseError ,
40- role : String ,
41- } ,
4226}
4327
4428/// Per-role configuration extracted during validation.
@@ -49,115 +33,99 @@ pub struct ValidatedRoleConfig {
4933 pub group_listener_name : Option < String > ,
5034}
5135
52- /// Per-rolegroup configuration: the merged CRD config plus the product-config properties .
36+ /// Per-rolegroup configuration: the merged CRD config plus overrides .
5337#[ derive( Clone , Debug ) ]
5438pub struct ValidatedRoleGroupConfig {
5539 pub merged_config : AirflowConfig ,
56- pub product_config_properties : HashMap < PropertyNameKind , BTreeMap < String , String > > ,
40+ pub overrides : MergedOverrides ,
5741}
5842
59- /// The validated cluster: proves that product-config validation and config merging
60- /// succeeded for every role and role group before any resources are created.
43+ /// The validated cluster: proves that config merging succeeded for every role and
44+ /// role group before any resources are created. It also carries the dereferenced
45+ /// external references, so every downstream build step reads them from here.
6146#[ derive( Clone , Debug ) ]
6247pub struct ValidatedAirflowCluster {
6348 pub image : ResolvedProductImage ,
6449 pub role_groups : BTreeMap < AirflowRole , BTreeMap < String , ValidatedRoleGroupConfig > > ,
6550 pub role_configs : BTreeMap < AirflowRole , ValidatedRoleConfig > ,
6651 pub executor : AirflowExecutor ,
52+ pub authentication_config : AirflowClientAuthenticationDetailsResolved ,
53+ pub authorization_config : AirflowAuthorizationResolved ,
6754}
6855
6956pub fn validate_cluster (
7057 airflow : & v1alpha2:: AirflowCluster ,
7158 image_base_name : & str ,
7259 image_repository : & str ,
7360 pkg_version : & str ,
74- product_config_manager : & ProductConfigManager ,
61+ dereferenced : DereferencedObjects ,
7562) -> Result < ValidatedAirflowCluster , Error > {
7663 let resolved_product_image = airflow
7764 . spec
7865 . image
7966 . resolve ( image_base_name, image_repository, pkg_version)
8067 . context ( ResolveProductImageSnafu ) ?;
8168
82- let mut roles = HashMap :: new ( ) ;
69+ let mut role_groups = BTreeMap :: new ( ) ;
70+ let mut role_configs = BTreeMap :: new ( ) ;
8371
8472 // if the kubernetes executor is specified there will be no worker role as the pods
8573 // are provisioned by airflow as defined by the task (default: one pod per task)
8674 for role in AirflowRole :: iter ( ) {
87- if let Some ( resolved_role) = airflow. get_role ( & role) {
88- roles. insert (
89- role. to_string ( ) ,
90- (
91- vec ! [
92- PropertyNameKind :: Env ,
93- PropertyNameKind :: File ( AIRFLOW_CONFIG_FILENAME . into( ) ) ,
94- ] ,
95- resolved_role. clone ( ) ,
96- ) ,
97- ) ;
98- }
99- }
100-
101- let role_config = transform_all_roles_to_config ( airflow, & roles) ;
102- let validated_role_config = validate_all_roles_and_groups_config (
103- & resolved_product_image. product_version ,
104- & role_config. context ( GenerateProductConfigSnafu ) ?,
105- product_config_manager,
106- false ,
107- false ,
108- )
109- . context ( InvalidProductConfigSnafu ) ?;
110-
111- let mut role_groups = BTreeMap :: new ( ) ;
112- let mut role_configs = BTreeMap :: new ( ) ;
113-
114- for ( role_name, rolegroup_configs) in validated_role_config. iter ( ) {
115- let airflow_role =
116- AirflowRole :: from_str ( role_name) . context ( UnidentifiedAirflowRoleSnafu {
117- role : role_name. to_string ( ) ,
118- } ) ?;
75+ let Some ( resolved_role) = airflow. get_role ( & role) else {
76+ continue ;
77+ } ;
11978
12079 role_configs. insert (
121- airflow_role . clone ( ) ,
80+ role . clone ( ) ,
12281 ValidatedRoleConfig {
12382 pdb : airflow
124- . role_config ( & airflow_role )
83+ . role_config ( & role )
12584 . map ( |rc| rc. pod_disruption_budget ) ,
126- listener_class : airflow_role
127- . listener_class_name ( airflow)
128- . map ( |s| s. to_string ( ) ) ,
129- group_listener_name : airflow. group_listener_name ( & airflow_role) ,
85+ listener_class : role. listener_class_name ( airflow) . map ( |s| s. to_string ( ) ) ,
86+ group_listener_name : airflow. group_listener_name ( & role) ,
13087 } ,
13188 ) ;
13289
13390 let mut group_configs = BTreeMap :: new ( ) ;
134- for ( rolegroup_name, rolegroup_config ) in rolegroup_configs . iter ( ) {
91+ for rolegroup_name in resolved_role . role_groups . keys ( ) {
13592 let rolegroup_ref = RoleGroupRef {
13693 cluster : stackable_operator:: kube:: runtime:: reflector:: ObjectRef :: from_obj ( airflow) ,
137- role : role_name . into ( ) ,
94+ role : role . to_string ( ) ,
13895 role_group : rolegroup_name. into ( ) ,
13996 } ;
14097
14198 let merged_config = airflow
142- . merged_config ( & airflow_role, & rolegroup_ref)
99+ . merged_config ( & role, & rolegroup_ref)
100+ . context ( FailedToResolveConfigSnafu ) ?;
101+
102+ let overrides = airflow
103+ . merged_overrides ( & role, rolegroup_name)
143104 . context ( FailedToResolveConfigSnafu ) ?;
144105
145106 group_configs. insert (
146107 rolegroup_name. clone ( ) ,
147108 ValidatedRoleGroupConfig {
148109 merged_config,
149- product_config_properties : rolegroup_config . clone ( ) ,
110+ overrides ,
150111 } ,
151112 ) ;
152113 }
153114
154- role_groups. insert ( airflow_role , group_configs) ;
115+ role_groups. insert ( role , group_configs) ;
155116 }
156117
118+ let DereferencedObjects {
119+ authentication_config,
120+ authorization_config,
121+ } = dereferenced;
122+
157123 Ok ( ValidatedAirflowCluster {
158124 image : resolved_product_image,
159125 role_groups,
160126 role_configs,
161127 executor : airflow. spec . executor . clone ( ) ,
128+ authentication_config,
129+ authorization_config,
162130 } )
163131}
0 commit comments