@@ -38,8 +38,9 @@ use stackable_operator::{
38
38
api:: {
39
39
apps:: v1:: { DaemonSet , DaemonSetSpec } ,
40
40
core:: v1:: {
41
- ConfigMap , EmptyDirVolumeSource , EnvVar , HTTPGetAction , Probe , SecretVolumeSource ,
42
- Service , ServiceAccount , ServicePort , ServiceSpec ,
41
+ ConfigMap , EmptyDirVolumeSource , EnvVar , EnvVarSource , HTTPGetAction ,
42
+ ObjectFieldSelector , Probe , SecretVolumeSource , Service , ServiceAccount ,
43
+ ServicePort , ServiceSpec ,
43
44
} ,
44
45
} ,
45
46
apimachinery:: pkg:: { apis:: meta:: v1:: LabelSelector , util:: intstr:: IntOrString } ,
@@ -69,7 +70,7 @@ use stackable_operator::{
69
70
operations:: ClusterOperationsConditionBuilder ,
70
71
} ,
71
72
time:: Duration ,
72
- utils:: COMMON_BASH_TRAP_FUNCTIONS ,
73
+ utils:: { COMMON_BASH_TRAP_FUNCTIONS , cluster_info :: KubernetesClusterInfo } ,
73
74
} ;
74
75
use strum:: { EnumDiscriminants , IntoStaticStr } ;
75
76
@@ -104,6 +105,12 @@ const USER_INFO_FETCHER_KERBEROS_DIR: &str = "/stackable/kerberos";
104
105
105
106
const DOCKER_IMAGE_BASE_NAME : & str = "opa" ;
106
107
108
+ const CONSOLE_LOG_LEVEL_ENV : & str = "CONSOLE_LOG_LEVEL" ;
109
+ const FILE_LOG_LEVEL_ENV : & str = "FILE_LOG_LEVEL" ;
110
+ const FILE_LOG_DIRECTORY_ENV : & str = "FILE_LOG_DIRECTORY" ;
111
+ const KUBERNETES_NODE_NAME_ENV : & str = "KUBERNETES_NODE_NAME" ;
112
+ const KUBERNETES_CLUSTER_DOMAIN_ENV : & str = "KUBERNETES_CLUSTER_DOMAIN" ;
113
+
107
114
// logging defaults
108
115
const DEFAULT_DECISION_LOGGING_ENABLED : bool = false ;
109
116
const DEFAULT_FILE_LOG_LEVEL : LogLevel = LogLevel :: INFO ;
@@ -144,6 +151,7 @@ pub struct Ctx {
144
151
pub product_config : ProductConfigManager ,
145
152
pub opa_bundle_builder_image : String ,
146
153
pub user_info_fetcher_image : String ,
154
+ pub cluster_info : KubernetesClusterInfo ,
147
155
}
148
156
149
157
#[ derive( Snafu , Debug , EnumDiscriminants ) ]
@@ -492,6 +500,7 @@ pub async fn reconcile_opa(
492
500
& ctx. opa_bundle_builder_image ,
493
501
& ctx. user_info_fetcher_image ,
494
502
& rbac_sa,
503
+ & ctx. cluster_info ,
495
504
) ?;
496
505
497
506
cluster_resources
@@ -714,6 +723,44 @@ fn build_server_rolegroup_config_map(
714
723
} )
715
724
}
716
725
726
+ /// Env variables that are need to run stackable Rust binaries, such as
727
+ /// * opa-bundle-builder
728
+ /// * user-info-fetcher
729
+ fn add_stackable_rust_cli_env_vars (
730
+ container_builder : & mut ContainerBuilder ,
731
+ cluster_info : & KubernetesClusterInfo ,
732
+ log_level : impl Into < String > ,
733
+ container : & v1alpha1:: Container ,
734
+ ) {
735
+ let log_level = log_level. into ( ) ;
736
+ container_builder
737
+ . add_env_var ( CONSOLE_LOG_LEVEL_ENV , log_level. clone ( ) )
738
+ . add_env_var ( FILE_LOG_LEVEL_ENV , log_level)
739
+ . add_env_var (
740
+ FILE_LOG_DIRECTORY_ENV ,
741
+ format ! ( "{STACKABLE_LOG_DIR}/{container}" , ) ,
742
+ )
743
+ . add_env_var_from_source (
744
+ KUBERNETES_NODE_NAME_ENV ,
745
+ EnvVarSource {
746
+ field_ref : Some ( ObjectFieldSelector {
747
+ field_path : "spec.nodeName" . to_owned ( ) ,
748
+ ..Default :: default ( )
749
+ } ) ,
750
+ ..Default :: default ( )
751
+ } ,
752
+ )
753
+ // We set the cluster domain always explicitly, because the product Pods does not have the
754
+ // RBAC permission to get the `nodes/proxy` resource at cluster scope. This is likely
755
+ // because it only has a RoleBinding and no ClusterRoleBinding.
756
+ // By setting the cluster domain explicitly we avoid that the sidecars try to look it up
757
+ // based on some information coming from the node.
758
+ . add_env_var (
759
+ KUBERNETES_CLUSTER_DOMAIN_ENV ,
760
+ cluster_info. cluster_domain . to_string ( ) ,
761
+ ) ;
762
+ }
763
+
717
764
/// The rolegroup [`DaemonSet`] runs the rolegroup, as configured by the administrator.
718
765
///
719
766
/// The [`Pod`](`stackable_operator::k8s_openapi::api::core::v1::Pod`)s are accessible through the
@@ -732,6 +779,7 @@ fn build_server_rolegroup_daemonset(
732
779
opa_bundle_builder_image : & str ,
733
780
user_info_fetcher_image : & str ,
734
781
service_account : & ServiceAccount ,
782
+ cluster_info : & KubernetesClusterInfo ,
735
783
) -> Result < DaemonSet > {
736
784
let opa_name = opa. metadata . name . as_deref ( ) . context ( NoNameSnafu ) ?;
737
785
let role = opa. role ( opa_role) ;
@@ -782,8 +830,6 @@ fn build_server_rolegroup_daemonset(
782
830
. context ( AddVolumeMountSnafu ) ?
783
831
. resources ( merged_config. resources . to_owned ( ) . into ( ) ) ;
784
832
785
- let console_and_file_log_level = bundle_builder_log_level ( merged_config) ;
786
-
787
833
cb_bundle_builder
788
834
. image_from_product_image ( resolved_product_image) // inherit the pull policy and pull secrets, and then...
789
835
. image ( opa_bundle_builder_image) // ...override the image
@@ -799,12 +845,6 @@ fn build_server_rolegroup_daemonset(
799
845
& bundle_builder_container_name,
800
846
) ] )
801
847
. add_env_var_from_field_path ( "WATCH_NAMESPACE" , FieldPathEnvVar :: Namespace )
802
- . add_env_var ( "CONSOLE_LOG_LEVEL" , console_and_file_log_level. to_string ( ) )
803
- . add_env_var ( "FILE_LOG_LEVEL" , console_and_file_log_level. to_string ( ) )
804
- . add_env_var (
805
- "FILE_LOG_DIRECTORY" ,
806
- format ! ( "{STACKABLE_LOG_DIR}/{bundle_builder_container_name}" ) ,
807
- )
808
848
. add_volume_mount ( BUNDLES_VOLUME_NAME , BUNDLES_DIR )
809
849
. context ( AddVolumeMountSnafu ) ?
810
850
. add_volume_mount ( LOG_VOLUME_NAME , STACKABLE_LOG_DIR )
@@ -838,6 +878,12 @@ fn build_server_rolegroup_daemonset(
838
878
} ) ,
839
879
..Probe :: default ( )
840
880
} ) ;
881
+ add_stackable_rust_cli_env_vars (
882
+ & mut cb_bundle_builder,
883
+ cluster_info,
884
+ sidecar_container_log_level ( merged_config, & v1alpha1:: Container :: BundleBuilder ) . to_string ( ) ,
885
+ & v1alpha1:: Container :: BundleBuilder ,
886
+ ) ;
841
887
842
888
cb_opa
843
889
. image_from_product_image ( resolved_product_image)
@@ -949,6 +995,13 @@ fn build_server_rolegroup_daemonset(
949
995
. with_memory_limit ( "128Mi" )
950
996
. build ( ) ,
951
997
) ;
998
+ add_stackable_rust_cli_env_vars (
999
+ & mut cb_user_info_fetcher,
1000
+ cluster_info,
1001
+ sidecar_container_log_level ( merged_config, & v1alpha1:: Container :: UserInfoFetcher )
1002
+ . to_string ( ) ,
1003
+ & v1alpha1:: Container :: UserInfoFetcher ,
1004
+ ) ;
952
1005
953
1006
match & user_info. backend {
954
1007
user_info_fetcher:: v1alpha1:: Backend :: None { } => { }
@@ -1257,13 +1310,42 @@ fn build_bundle_builder_start_command(
1257
1310
}
1258
1311
}
1259
1312
1260
- fn bundle_builder_log_level ( merged_config : & v1alpha1:: OpaConfig ) -> BundleBuilderLogLevel {
1313
+ /// TODO: *Technically* this function would need to be way more complex.
1314
+ /// For now it's a good-enough approximation, this is fine :D
1315
+ ///
1316
+ /// The following config
1317
+ ///
1318
+ /// ```
1319
+ /// containers:
1320
+ /// opa-bundle-builder:
1321
+ /// console:
1322
+ /// level: DEBUG
1323
+ /// file:
1324
+ /// level: INFO
1325
+ /// loggers:
1326
+ /// ROOT:
1327
+ /// level: INFO
1328
+ /// my.module:
1329
+ /// level: DEBUG
1330
+ /// some.chatty.module:
1331
+ /// level: NONE
1332
+ /// ```
1333
+ ///
1334
+ /// should result in
1335
+ /// `CONSOLE_LOG_LEVEL=info,my.module=debug,some.chatty.module=none`
1336
+ /// and
1337
+ /// `FILE_LOG_LEVEL=info,my.module=info,some.chatty.module=none`.
1338
+ /// Note that `my.module` is `info` instead of `debug`, because it's clamped by the global file log
1339
+ /// level.
1340
+ ///
1341
+ /// Context: https://docs.stackable.tech/home/stable/concepts/logging/
1342
+ fn sidecar_container_log_level (
1343
+ merged_config : & v1alpha1:: OpaConfig ,
1344
+ sidecar_container : & v1alpha1:: Container ,
1345
+ ) -> BundleBuilderLogLevel {
1261
1346
if let Some ( ContainerLogConfig {
1262
1347
choice : Some ( ContainerLogConfigChoice :: Automatic ( log_config) ) ,
1263
- } ) = merged_config
1264
- . logging
1265
- . containers
1266
- . get ( & v1alpha1:: Container :: BundleBuilder )
1348
+ } ) = merged_config. logging . containers . get ( sidecar_container)
1267
1349
{
1268
1350
if let Some ( logger) = log_config
1269
1351
. loggers
0 commit comments