11//! Builds the rolegroup [`DaemonSet`] that runs OPA (plus its bundle-builder, optional
22//! user-info-fetcher, and Vector sidecars) on every node.
33
4- use std:: collections:: BTreeMap ;
4+ use std:: { collections:: BTreeMap , str :: FromStr } ;
55
66use indoc:: formatdoc;
77use snafu:: { ResultExt , Snafu } ;
@@ -49,7 +49,7 @@ use stackable_operator::{
4949 } ,
5050 } ,
5151 utils:: { COMMON_BASH_TRAP_FUNCTIONS , cluster_info:: KubernetesClusterInfo } ,
52- v2:: builder:: meta:: ownerreference_from_resource,
52+ v2:: { builder:: meta:: ownerreference_from_resource, types :: kubernetes :: VolumeName } ,
5353} ;
5454
5555use super :: service:: { self , APP_PORT , APP_PORT_NAME } ;
@@ -68,19 +68,27 @@ pub const BUNDLES_INCOMING_DIR: &str = "/bundles/incoming";
6868pub const BUNDLES_TMP_DIR : & str = "/bundles/tmp" ;
6969pub const BUNDLE_BUILDER_PORT : i32 = 3030 ;
7070
71- const CONFIG_VOLUME_NAME : & str = "config" ;
71+ stackable_operator :: constant! ( CONFIG_VOLUME_NAME : VolumeName = "config" ) ;
7272const CONFIG_DIR : & str = "/stackable/config" ;
73- const LOG_VOLUME_NAME : & str = "log" ;
73+ stackable_operator :: constant! ( LOG_VOLUME_NAME : VolumeName = "log" ) ;
7474const STACKABLE_LOG_DIR : & str = "/stackable/log" ;
75- const BUNDLES_VOLUME_NAME : & str = "bundles" ;
75+ stackable_operator :: constant! ( BUNDLES_VOLUME_NAME : VolumeName = "bundles" ) ;
7676const BUNDLES_DIR : & str = "/bundles" ;
77- const USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME : & str = "credentials" ;
77+ stackable_operator :: constant! ( USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME : VolumeName = "credentials" ) ;
7878const USER_INFO_FETCHER_CREDENTIALS_DIR : & str = "/stackable/credentials" ;
79- const USER_INFO_FETCHER_KERBEROS_VOLUME_NAME : & str = "kerberos" ;
79+ stackable_operator :: constant! ( USER_INFO_FETCHER_KERBEROS_VOLUME_NAME : VolumeName = "kerberos" ) ;
8080const USER_INFO_FETCHER_KERBEROS_DIR : & str = "/stackable/kerberos" ;
81- const TLS_VOLUME_NAME : & str = "tls" ;
81+ stackable_operator :: constant! ( TLS_VOLUME_NAME : VolumeName = "tls" ) ;
8282const TLS_STORE_DIR : & str = "/stackable/tls" ;
8383
84+ // HTTP probe configuration shared by the bundle-builder and OPA containers. Both expose a
85+ // `/status` endpoint; only the port (and, for OPA, the URI scheme) differ.
86+ const PROBE_PATH : & str = "/status" ;
87+ const PROBE_PERIOD_SECONDS : i32 = 10 ;
88+ const READINESS_PROBE_INITIAL_DELAY_SECONDS : i32 = 5 ;
89+ const READINESS_PROBE_FAILURE_THRESHOLD : i32 = 5 ;
90+ const LIVENESS_PROBE_INITIAL_DELAY_SECONDS : i32 = 30 ;
91+
8492const CONSOLE_LOG_LEVEL_ENV : & str = "CONSOLE_LOG_LEVEL" ;
8593const FILE_LOG_LEVEL_ENV : & str = "FILE_LOG_LEVEL" ;
8694const FILE_LOG_DIRECTORY_ENV : & str = "FILE_LOG_DIRECTORY" ;
@@ -175,6 +183,46 @@ pub enum Error {
175183
176184type Result < T , E = Error > = std:: result:: Result < T , E > ;
177185
186+ /// The strict-mode `bash` entrypoint shared by the prepare, bundle-builder, and OPA containers.
187+ /// The actual script is passed via `.args(...)`.
188+ fn bash_entrypoint_command ( ) -> Vec < String > {
189+ [ "/bin/bash" , "-x" , "-euo" , "pipefail" , "-c" ]
190+ . iter ( )
191+ . map ( |arg| arg. to_string ( ) )
192+ . collect ( )
193+ }
194+
195+ /// An HTTP readiness [`Probe`] against the `/status` endpoint on the given `port`/`scheme`.
196+ fn http_status_readiness_probe ( port : IntOrString , scheme : Option < String > ) -> Probe {
197+ Probe {
198+ initial_delay_seconds : Some ( READINESS_PROBE_INITIAL_DELAY_SECONDS ) ,
199+ period_seconds : Some ( PROBE_PERIOD_SECONDS ) ,
200+ failure_threshold : Some ( READINESS_PROBE_FAILURE_THRESHOLD ) ,
201+ http_get : Some ( HTTPGetAction {
202+ port,
203+ path : Some ( PROBE_PATH . to_string ( ) ) ,
204+ scheme,
205+ ..HTTPGetAction :: default ( )
206+ } ) ,
207+ ..Probe :: default ( )
208+ }
209+ }
210+
211+ /// An HTTP liveness [`Probe`] against the `/status` endpoint on the given `port`/`scheme`.
212+ fn http_status_liveness_probe ( port : IntOrString , scheme : Option < String > ) -> Probe {
213+ Probe {
214+ initial_delay_seconds : Some ( LIVENESS_PROBE_INITIAL_DELAY_SECONDS ) ,
215+ period_seconds : Some ( PROBE_PERIOD_SECONDS ) ,
216+ http_get : Some ( HTTPGetAction {
217+ port,
218+ path : Some ( PROBE_PATH . to_string ( ) ) ,
219+ scheme,
220+ ..HTTPGetAction :: default ( )
221+ } ) ,
222+ ..Probe :: default ( )
223+ }
224+ }
225+
178226/// The rolegroup [`DaemonSet`] runs the rolegroup, as configured by the administrator.
179227///
180228/// The [`Pod`](`stackable_operator::k8s_openapi::api::core::v1::Pod`)s are accessible through the
@@ -214,40 +262,28 @@ pub fn build_server_rolegroup_daemonset(
214262
215263 cb_prepare
216264 . image_from_product_image ( resolved_product_image)
217- . command ( vec ! [
218- "/bin/bash" . to_string( ) ,
219- "-x" . to_string( ) ,
220- "-euo" . to_string( ) ,
221- "pipefail" . to_string( ) ,
222- "-c" . to_string( ) ,
223- ] )
265+ . command ( bash_entrypoint_command ( ) )
224266 . args ( vec ! [
225267 build_prepare_start_command( merged_config, & prepare_container_name) . join( " && " ) ,
226268 ] )
227- . add_volume_mount ( BUNDLES_VOLUME_NAME , BUNDLES_DIR )
269+ . add_volume_mount ( BUNDLES_VOLUME_NAME . as_ref ( ) , BUNDLES_DIR )
228270 . context ( AddVolumeMountSnafu ) ?
229- . add_volume_mount ( LOG_VOLUME_NAME , STACKABLE_LOG_DIR )
271+ . add_volume_mount ( LOG_VOLUME_NAME . as_ref ( ) , STACKABLE_LOG_DIR )
230272 . context ( AddVolumeMountSnafu ) ?
231273 . resources ( merged_config. resources . to_owned ( ) . into ( ) ) ;
232274
233275 cb_bundle_builder
234276 . image_from_product_image ( resolved_product_image) // inherit the pull policy and pull secrets, and then...
235277 . image ( opa_bundle_builder_image) // ...override the image
236- . command ( vec ! [
237- "/bin/bash" . to_string( ) ,
238- "-x" . to_string( ) ,
239- "-euo" . to_string( ) ,
240- "pipefail" . to_string( ) ,
241- "-c" . to_string( ) ,
242- ] )
278+ . command ( bash_entrypoint_command ( ) )
243279 . args ( vec ! [ build_bundle_builder_start_command(
244280 merged_config,
245281 & bundle_builder_container_name,
246282 ) ] )
247283 . add_env_var_from_field_path ( "WATCH_NAMESPACE" , & FieldPathEnvVar :: Namespace )
248- . add_volume_mount ( BUNDLES_VOLUME_NAME , BUNDLES_DIR )
284+ . add_volume_mount ( BUNDLES_VOLUME_NAME . as_ref ( ) , BUNDLES_DIR )
249285 . context ( AddVolumeMountSnafu ) ?
250- . add_volume_mount ( LOG_VOLUME_NAME , STACKABLE_LOG_DIR )
286+ . add_volume_mount ( LOG_VOLUME_NAME . as_ref ( ) , STACKABLE_LOG_DIR )
251287 . context ( AddVolumeMountSnafu ) ?
252288 . resources (
253289 ResourceRequirementsBuilder :: new ( )
@@ -257,27 +293,14 @@ pub fn build_server_rolegroup_daemonset(
257293 . with_memory_limit ( "128Mi" )
258294 . build ( ) ,
259295 )
260- . readiness_probe ( Probe {
261- initial_delay_seconds : Some ( 5 ) ,
262- period_seconds : Some ( 10 ) ,
263- failure_threshold : Some ( 5 ) ,
264- http_get : Some ( HTTPGetAction {
265- port : IntOrString :: Int ( BUNDLE_BUILDER_PORT ) ,
266- path : Some ( "/status" . to_string ( ) ) ,
267- ..HTTPGetAction :: default ( )
268- } ) ,
269- ..Probe :: default ( )
270- } )
271- . liveness_probe ( Probe {
272- initial_delay_seconds : Some ( 30 ) ,
273- period_seconds : Some ( 10 ) ,
274- http_get : Some ( HTTPGetAction {
275- port : IntOrString :: Int ( BUNDLE_BUILDER_PORT ) ,
276- path : Some ( "/status" . to_string ( ) ) ,
277- ..HTTPGetAction :: default ( )
278- } ) ,
279- ..Probe :: default ( )
280- } ) ;
296+ . readiness_probe ( http_status_readiness_probe (
297+ IntOrString :: Int ( BUNDLE_BUILDER_PORT ) ,
298+ None ,
299+ ) )
300+ . liveness_probe ( http_status_liveness_probe (
301+ IntOrString :: Int ( BUNDLE_BUILDER_PORT ) ,
302+ None ,
303+ ) ) ;
281304 add_stackable_rust_cli_env_vars (
282305 & mut cb_bundle_builder,
283306 cluster_info,
@@ -287,13 +310,7 @@ pub fn build_server_rolegroup_daemonset(
287310
288311 cb_opa
289312 . image_from_product_image ( resolved_product_image)
290- . command ( vec ! [
291- "/bin/bash" . to_string( ) ,
292- "-x" . to_string( ) ,
293- "-euo" . to_string( ) ,
294- "pipefail" . to_string( ) ,
295- "-c" . to_string( ) ,
296- ] )
313+ . command ( bash_entrypoint_command ( ) )
297314 . args ( vec ! [ build_opa_start_command(
298315 merged_config,
299316 & opa_container_name,
@@ -315,16 +332,16 @@ pub fn build_server_rolegroup_daemonset(
315332 if opa. spec . cluster_config . tls_enabled ( ) {
316333 cb_opa. add_container_port ( service:: APP_TLS_PORT_NAME , service:: APP_TLS_PORT . into ( ) ) ;
317334 cb_opa
318- . add_volume_mount ( TLS_VOLUME_NAME , TLS_STORE_DIR )
335+ . add_volume_mount ( TLS_VOLUME_NAME . as_ref ( ) , TLS_STORE_DIR )
319336 . context ( AddVolumeMountSnafu ) ?;
320337 } else {
321338 cb_opa. add_container_port ( APP_PORT_NAME , APP_PORT . into ( ) ) ;
322339 }
323340
324341 cb_opa
325- . add_volume_mount ( CONFIG_VOLUME_NAME , CONFIG_DIR )
342+ . add_volume_mount ( CONFIG_VOLUME_NAME . as_ref ( ) , CONFIG_DIR )
326343 . context ( AddVolumeMountSnafu ) ?
327- . add_volume_mount ( LOG_VOLUME_NAME , STACKABLE_LOG_DIR )
344+ . add_volume_mount ( LOG_VOLUME_NAME . as_ref ( ) , STACKABLE_LOG_DIR )
328345 . context ( AddVolumeMountSnafu ) ?
329346 . resources ( merged_config. resources . to_owned ( ) . into ( ) ) ;
330347
@@ -335,27 +352,14 @@ pub fn build_server_rolegroup_daemonset(
335352 } ;
336353
337354 cb_opa
338- . readiness_probe ( Probe {
339- initial_delay_seconds : Some ( 5 ) ,
340- period_seconds : Some ( 10 ) ,
341- failure_threshold : Some ( 5 ) ,
342- http_get : Some ( HTTPGetAction {
343- port : IntOrString :: String ( probe_port_name. to_string ( ) ) ,
344- scheme : probe_scheme. clone ( ) ,
345- ..HTTPGetAction :: default ( )
346- } ) ,
347- ..Probe :: default ( )
348- } )
349- . liveness_probe ( Probe {
350- initial_delay_seconds : Some ( 30 ) ,
351- period_seconds : Some ( 10 ) ,
352- http_get : Some ( HTTPGetAction {
353- port : IntOrString :: String ( probe_port_name. to_string ( ) ) ,
354- scheme : probe_scheme,
355- ..HTTPGetAction :: default ( )
356- } ) ,
357- ..Probe :: default ( )
358- } ) ;
355+ . readiness_probe ( http_status_readiness_probe (
356+ IntOrString :: String ( probe_port_name. to_string ( ) ) ,
357+ probe_scheme. clone ( ) ,
358+ ) )
359+ . liveness_probe ( http_status_liveness_probe (
360+ IntOrString :: String ( probe_port_name. to_string ( ) ) ,
361+ probe_scheme,
362+ ) ) ;
359363
360364 let pb_metadata = ObjectMetaBuilder :: new ( )
361365 . with_labels ( cluster. recommended_labels ( role_group_name) )
@@ -368,7 +372,7 @@ pub fn build_server_rolegroup_daemonset(
368372 . image_pull_secrets_from_product_image ( resolved_product_image)
369373 . affinity ( & merged_config. affinity )
370374 . add_volume (
371- VolumeBuilder :: new ( CONFIG_VOLUME_NAME )
375+ VolumeBuilder :: new ( CONFIG_VOLUME_NAME . as_ref ( ) )
372376 . with_config_map (
373377 cluster
374378 . resource_names ( role_group_name)
@@ -379,13 +383,13 @@ pub fn build_server_rolegroup_daemonset(
379383 )
380384 . context ( AddVolumeSnafu ) ?
381385 . add_volume (
382- VolumeBuilder :: new ( BUNDLES_VOLUME_NAME )
386+ VolumeBuilder :: new ( BUNDLES_VOLUME_NAME . as_ref ( ) )
383387 . with_empty_dir ( None :: < String > , None )
384388 . build ( ) ,
385389 )
386390 . context ( AddVolumeSnafu ) ?
387391 . add_volume (
388- VolumeBuilder :: new ( LOG_VOLUME_NAME )
392+ VolumeBuilder :: new ( LOG_VOLUME_NAME . as_ref ( ) )
389393 . empty_dir ( EmptyDirVolumeSource {
390394 medium : None ,
391395 size_limit : Some ( product_logging:: framework:: calculate_log_volume_size_limit (
@@ -404,7 +408,7 @@ pub fn build_server_rolegroup_daemonset(
404408
405409 if let Some ( tls) = & opa. spec . cluster_config . tls {
406410 pb. add_volume (
407- VolumeBuilder :: new ( TLS_VOLUME_NAME )
411+ VolumeBuilder :: new ( TLS_VOLUME_NAME . as_ref ( ) )
408412 . ephemeral (
409413 SecretOperatorVolumeSourceBuilder :: new (
410414 & tls. server_secret_class ,
@@ -437,7 +441,7 @@ pub fn build_server_rolegroup_daemonset(
437441 . command ( vec ! [ "stackable-opa-user-info-fetcher" . to_string( ) ] )
438442 . add_env_var ( "CONFIG" , format ! ( "{CONFIG_DIR}/user-info-fetcher.json" ) )
439443 . add_env_var ( "CREDENTIALS_DIR" , USER_INFO_FETCHER_CREDENTIALS_DIR )
440- . add_volume_mount ( CONFIG_VOLUME_NAME , CONFIG_DIR )
444+ . add_volume_mount ( CONFIG_VOLUME_NAME . as_ref ( ) , CONFIG_DIR )
441445 . context ( AddVolumeMountSnafu ) ?
442446 . resources (
443447 ResourceRequirementsBuilder :: new ( )
@@ -469,7 +473,7 @@ pub fn build_server_rolegroup_daemonset(
469473 } ) ,
470474 )
471475 . to_volume (
472- USER_INFO_FETCHER_KERBEROS_VOLUME_NAME ,
476+ USER_INFO_FETCHER_KERBEROS_VOLUME_NAME . as_ref ( ) ,
473477 // The user-info-fetcher needs both the keytab (private) and the Kerberos config (public).
474478 SecretClassVolumeProvisionParts :: PublicPrivate ,
475479 )
@@ -478,7 +482,7 @@ pub fn build_server_rolegroup_daemonset(
478482 . context ( UserInfoFetcherKerberosVolumeSnafu ) ?;
479483 cb_user_info_fetcher
480484 . add_volume_mount (
481- USER_INFO_FETCHER_KERBEROS_VOLUME_NAME ,
485+ USER_INFO_FETCHER_KERBEROS_VOLUME_NAME . as_ref ( ) ,
482486 USER_INFO_FETCHER_KERBEROS_DIR ,
483487 )
484488 . context ( UserInfoFetcherKerberosVolumeMountSnafu ) ?;
@@ -497,7 +501,7 @@ pub fn build_server_rolegroup_daemonset(
497501 }
498502 user_info_fetcher:: v1alpha2:: Backend :: Keycloak ( keycloak) => {
499503 pb. add_volume (
500- VolumeBuilder :: new ( USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME )
504+ VolumeBuilder :: new ( USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME . as_ref ( ) )
501505 . secret ( SecretVolumeSource {
502506 secret_name : Some ( keycloak. client_credentials_secret . clone ( ) ) ,
503507 ..Default :: default ( )
@@ -507,7 +511,7 @@ pub fn build_server_rolegroup_daemonset(
507511 . context ( AddVolumeSnafu ) ?;
508512 cb_user_info_fetcher
509513 . add_volume_mount (
510- USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME ,
514+ USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME . as_ref ( ) ,
511515 USER_INFO_FETCHER_CREDENTIALS_DIR ,
512516 )
513517 . context ( AddVolumeMountSnafu ) ?;
@@ -518,7 +522,7 @@ pub fn build_server_rolegroup_daemonset(
518522 }
519523 user_info_fetcher:: v1alpha2:: Backend :: Entra ( entra) => {
520524 pb. add_volume (
521- VolumeBuilder :: new ( USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME )
525+ VolumeBuilder :: new ( USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME . as_ref ( ) )
522526 . secret ( SecretVolumeSource {
523527 secret_name : Some ( entra. client_credentials_secret . clone ( ) ) ,
524528 ..Default :: default ( )
@@ -528,7 +532,7 @@ pub fn build_server_rolegroup_daemonset(
528532 . context ( AddVolumeSnafu ) ?;
529533 cb_user_info_fetcher
530534 . add_volume_mount (
531- USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME ,
535+ USER_INFO_FETCHER_CREDENTIALS_VOLUME_NAME . as_ref ( ) ,
532536 USER_INFO_FETCHER_CREDENTIALS_DIR ,
533537 )
534538 . context ( AddVolumeMountSnafu ) ?;
@@ -558,8 +562,8 @@ pub fn build_server_rolegroup_daemonset(
558562 pb. add_container (
559563 product_logging:: framework:: vector_container (
560564 resolved_product_image,
561- CONFIG_VOLUME_NAME ,
562- LOG_VOLUME_NAME ,
565+ CONFIG_VOLUME_NAME . as_ref ( ) ,
566+ LOG_VOLUME_NAME . as_ref ( ) ,
563567 merged_config. logging . containers . get ( & Container :: Vector ) ,
564568 ResourceRequirementsBuilder :: new ( )
565569 . with_cpu_request ( "250m" )
0 commit comments