11//! Ensures that `Pod`s are configured and running for each [`v1alpha2::AirflowCluster`]
22use std:: {
33 collections:: { BTreeMap , BTreeSet , HashMap } ,
4+ str:: FromStr ,
45 sync:: Arc ,
56} ;
67
@@ -37,12 +38,12 @@ use stackable_operator::{
3738 } ,
3839 } ,
3940 k8s_openapi:: {
40- self , DeepMerge ,
41+ DeepMerge ,
4142 api:: {
4243 apps:: v1:: { StatefulSet , StatefulSetSpec } ,
4344 core:: v1:: {
44- ConfigMap , EnvVar , PersistentVolumeClaim , PodTemplateSpec , Probe , ServiceAccount ,
45- TCPSocketAction ,
45+ ConfigMap , Container as K8sContainer , EnvVar , PersistentVolumeClaim ,
46+ PodTemplateSpec , Probe , ServiceAccount , TCPSocketAction ,
4647 } ,
4748 } ,
4849 apimachinery:: pkg:: { apis:: meta:: v1:: LabelSelector , util:: intstr:: IntOrString } ,
@@ -55,7 +56,6 @@ use stackable_operator::{
5556 } ,
5657 kvp:: { Annotation , Label , LabelError } ,
5758 logging:: controller:: ReconcilerError ,
58- product_logging:: { self , framework:: LoggingError , spec:: ContainerLogConfig } ,
5959 role_utils:: RoleGroupRef ,
6060 shared:: time:: Duration ,
6161 status:: condition:: {
@@ -64,14 +64,21 @@ use stackable_operator::{
6464 } ,
6565 utils:: COMMON_BASH_TRAP_FUNCTIONS ,
6666 v2:: {
67- builder:: meta:: ownerreference_from_resource,
68- types:: operator:: { RoleGroupName , RoleName } ,
67+ builder:: { meta:: ownerreference_from_resource, pod:: container:: EnvVarSet } ,
68+ product_logging:: framework:: { VectorContainerLogConfig , vector_container} ,
69+ role_group_utils:: ResourceNames ,
70+ types:: {
71+ kubernetes:: { ContainerName , VolumeName } ,
72+ operator:: { RoleGroupName , RoleName } ,
73+ } ,
6974 } ,
7075} ;
7176use strum:: { EnumDiscriminants , IntoStaticStr } ;
7277
7378use crate :: {
74- controller:: { AirflowRoleGroupConfig , ValidatedCluster , build:: config_map} ,
79+ controller:: {
80+ AirflowRoleGroupConfig , ValidatedCluster , ValidatedLogging , build:: config_map, validate,
81+ } ,
7582 controller_commons:: { self , CONFIG_VOLUME_NAME , LOG_CONFIG_VOLUME_NAME , LOG_VOLUME_NAME } ,
7683 crd:: {
7784 self , APP_NAME , AirflowClusterStatus , AirflowConfigOverrides , AirflowExecutor ,
@@ -199,9 +206,6 @@ pub enum Error {
199206 source : stackable_operator:: cluster_resources:: Error ,
200207 } ,
201208
202- #[ snafu( display( "vector agent is enabled but vector aggregator ConfigMap is missing" ) ) ]
203- VectorAggregatorConfigMapMissing ,
204-
205209 #[ snafu( display( "failed to update status" ) ) ]
206210 ApplyStatus {
207211 source : stackable_operator:: client:: Error ,
@@ -253,9 +257,6 @@ pub enum Error {
253257 source : stackable_operator:: builder:: meta:: Error ,
254258 } ,
255259
256- #[ snafu( display( "failed to configure logging" ) ) ]
257- ConfigureLogging { source : LoggingError } ,
258-
259260 #[ snafu( display( "failed to add needed volume" ) ) ]
260261 AddVolume { source : builder:: pod:: Error } ,
261262
@@ -476,7 +477,10 @@ pub async fn reconcile_airflow(
476477 }
477478 }
478479
479- for ( rolegroup_name, validated_rg_config) in role_group_configs {
480+ for ( rolegroup_name, validated_rg) in role_group_configs {
481+ let validated_rg_config = & validated_rg. config ;
482+ let logging = & validated_rg. logging ;
483+
480484 let rolegroup = RoleGroupRef {
481485 cluster : ObjectRef :: from_obj ( airflow) ,
482486 role : role_name. clone ( ) ,
@@ -540,6 +544,7 @@ pub async fn reconcile_airflow(
540544 airflow_role,
541545 & rolegroup,
542546 validated_rg_config,
547+ logging,
543548 & metadata_database_connection_details,
544549 & celery_database_connection_details,
545550 & rbac_sa,
@@ -707,6 +712,7 @@ fn build_server_rolegroup_statefulset(
707712 airflow_role : & AirflowRole ,
708713 rolegroup_ref : & RoleGroupRef < v1alpha2:: AirflowCluster > ,
709714 validated_rg_config : & AirflowRoleGroupConfig ,
715+ logging : & ValidatedLogging ,
710716 metadata_database_connection_details : & SqlAlchemyDatabaseConnectionDetails ,
711717 celery_database_connection_details : & Option < (
712718 CeleryDatabaseConnectionDetails ,
@@ -936,26 +942,12 @@ fn build_server_rolegroup_statefulset(
936942 . context ( AddVolumeSnafu ) ?;
937943 }
938944
939- if merged_airflow_config. logging . enable_vector_agent {
940- match & airflow
941- . spec
942- . cluster_config
943- . vector_aggregator_config_map_name
944- {
945- Some ( vector_aggregator_config_map_name) => {
946- pb. add_container ( build_logging_container (
947- resolved_product_image,
948- merged_airflow_config
949- . logging
950- . containers
951- . get ( & Container :: Vector ) ,
952- vector_aggregator_config_map_name,
953- ) ?) ;
954- }
955- None => {
956- VectorAggregatorConfigMapMissingSnafu . fail ( ) ?;
957- }
958- }
945+ if let Some ( vector_log_config) = & logging. vector_container {
946+ pb. add_container ( build_logging_container (
947+ resolved_product_image,
948+ vector_log_config,
949+ & resource_names,
950+ ) ) ;
959951 }
960952 let mut pod_template = pb. build_template ( ) ;
961953 pod_template. merge_from ( validated_rg_config. pod_overrides . clone ( ) ) ;
@@ -1005,25 +997,30 @@ fn build_server_rolegroup_statefulset(
1005997 } )
1006998}
1007999
1000+ stackable_operator:: constant!( VECTOR_CONTAINER_NAME : ContainerName = "vector" ) ;
1001+ // Typed volume names required by the v2 `vector_container`. Their values match the `&str`
1002+ // constants in `controller_commons` used elsewhere to build the same volumes.
1003+ stackable_operator:: constant!( CONFIG_VOLUME_NAME_TYPED : VolumeName = "config" ) ;
1004+ stackable_operator:: constant!( LOG_VOLUME_NAME_TYPED : VolumeName = "log" ) ;
1005+
1006+ /// Builds the Vector log-collection sidecar container from the up-front-validated logging config.
1007+ ///
1008+ /// The vector container's resource limits are set inside the v2 `vector_container` helper (to the
1009+ /// same values previously hard-coded here), so this is behaviour-preserving.
10081010fn build_logging_container (
10091011 resolved_product_image : & ResolvedProductImage ,
1010- log_config : Option < & ContainerLogConfig > ,
1011- vector_aggregator_config_map_name : & str ,
1012- ) -> Result < k8s_openapi:: api:: core:: v1:: Container > {
1013- product_logging:: framework:: vector_container (
1012+ vector_log_config : & VectorContainerLogConfig ,
1013+ resource_names : & ResourceNames ,
1014+ ) -> K8sContainer {
1015+ vector_container (
1016+ & VECTOR_CONTAINER_NAME ,
10141017 resolved_product_image,
1015- CONFIG_VOLUME_NAME ,
1016- LOG_VOLUME_NAME ,
1017- log_config,
1018- ResourceRequirementsBuilder :: new ( )
1019- . with_cpu_request ( "250m" )
1020- . with_cpu_limit ( "500m" )
1021- . with_memory_request ( "128Mi" )
1022- . with_memory_limit ( "128Mi" )
1023- . build ( ) ,
1024- vector_aggregator_config_map_name,
1018+ vector_log_config,
1019+ resource_names,
1020+ & CONFIG_VOLUME_NAME_TYPED ,
1021+ & LOG_VOLUME_NAME_TYPED ,
1022+ EnvVarSet :: new ( ) ,
10251023 )
1026- . context ( ConfigureLoggingSnafu )
10271024}
10281025
10291026#[ allow( clippy:: too_many_arguments) ]
@@ -1112,26 +1109,22 @@ fn build_executor_template_config_map(
11121109 ) )
11131110 . context ( AddVolumeSnafu ) ?;
11141111
1115- if merged_executor_config. logging . enable_vector_agent {
1116- match & airflow
1117- . spec
1118- . cluster_config
1119- . vector_aggregator_config_map_name
1120- {
1121- Some ( vector_aggregator_config_map_name) => {
1122- pb. add_container ( build_logging_container (
1123- resolved_product_image,
1124- merged_executor_config
1125- . logging
1126- . containers
1127- . get ( & Container :: Vector ) ,
1128- vector_aggregator_config_map_name,
1129- ) ?) ;
1130- }
1131- None => {
1132- VectorAggregatorConfigMapMissingSnafu . fail ( ) ?;
1133- }
1134- }
1112+ // The Kubernetes executor pod template is not an `AirflowRole` with role groups, so its logging
1113+ // is validated here (at build time) via the shared `validate_logging`, mirroring the role-group
1114+ // path in `validate`.
1115+ let executor_aggregator_config_map_name =
1116+ validate:: parse_vector_aggregator_config_map_name ( airflow) . context ( ValidateSnafu ) ?;
1117+ let executor_logging = validate:: validate_logging (
1118+ & merged_executor_config. logging ,
1119+ & executor_aggregator_config_map_name,
1120+ )
1121+ . context ( ValidateSnafu ) ?;
1122+ if let Some ( vector_log_config) = & executor_logging. vector_container {
1123+ pb. add_container ( build_logging_container (
1124+ resolved_product_image,
1125+ vector_log_config,
1126+ & cluster. resource_names ( & executor_role_name ( ) , & executor_template_role_group_name ( ) ) ,
1127+ ) ) ;
11351128 }
11361129
11371130 let mut pod_template = pb. build_template ( ) ;
0 commit comments