@@ -30,7 +30,10 @@ use stackable_operator::{
3030 } ,
3131 cli:: OperatorEnvironmentOptions ,
3232 cluster_resources:: { ClusterResourceApplyStrategy , ClusterResources } ,
33- commons:: { product_image_selection:: ResolvedProductImage , rbac:: build_rbac_resources} ,
33+ commons:: {
34+ product_image_selection:: ResolvedProductImage , random_secret_creation,
35+ rbac:: build_rbac_resources,
36+ } ,
3437 crd:: { authentication:: ldap, git_sync, listener} ,
3538 database_connections:: {
3639 TemplatingMechanism ,
@@ -90,7 +93,11 @@ use crate::{
9093 AirflowAuthenticationClassResolved , AirflowClientAuthenticationDetailsResolved ,
9194 } ,
9295 authorization:: AirflowAuthorizationResolved ,
93- build_recommended_labels, v1alpha2,
96+ build_recommended_labels,
97+ internal_secret:: {
98+ FERNET_KEY_SECRET_KEY , INTERNAL_SECRET_SECRET_KEY , JWT_SECRET_SECRET_KEY ,
99+ } ,
100+ v1alpha2,
94101 } ,
95102 env_vars:: { self , build_airflow_template_envs} ,
96103 operations:: {
@@ -208,6 +215,11 @@ pub enum Error {
208215 source : stackable_operator:: client:: Error ,
209216 } ,
210217
218+ #[ snafu( display( "failed to create internal secret" ) ) ]
219+ InternalSecret {
220+ source : random_secret_creation:: Error ,
221+ } ,
222+
211223 #[ snafu( display( "failed to dereference cluster resources" ) ) ]
212224 Dereference {
213225 source : crate :: controller:: dereference:: Error ,
@@ -378,6 +390,41 @@ pub async fn reconcile_airflow(
378390 )
379391 . context ( ValidateSnafu ) ?;
380392
393+ // TODO: Move secret creation to a dedicated apply step once it exists.
394+ random_secret_creation:: create_random_secret_if_not_exists (
395+ & airflow. shared_internal_secret_secret_name ( ) ,
396+ INTERNAL_SECRET_SECRET_KEY ,
397+ 256 ,
398+ airflow,
399+ client,
400+ )
401+ . await
402+ . context ( InternalSecretSnafu ) ?;
403+
404+ random_secret_creation:: create_random_secret_if_not_exists (
405+ & airflow. shared_jwt_secret_secret_name ( ) ,
406+ JWT_SECRET_SECRET_KEY ,
407+ 256 ,
408+ airflow,
409+ client,
410+ )
411+ . await
412+ . context ( InternalSecretSnafu ) ?;
413+
414+ // https://airflow.apache.org/docs/apache-airflow/stable/security/secrets/fernet.html#security-fernet
415+ // does not document how long the fernet key should be, but recommends using
416+ // python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
417+ // which returns `jUm21LuA76YZmrIa9u4eXRg0h0P24MDC9IDOmDvJbfw=`, which has 44 characters, which makes 32 bytes.
418+ random_secret_creation:: create_random_secret_if_not_exists (
419+ & airflow. shared_fernet_key_secret_name ( ) ,
420+ FERNET_KEY_SECRET_KEY ,
421+ 32 ,
422+ airflow,
423+ client,
424+ )
425+ . await
426+ . context ( InternalSecretSnafu ) ?;
427+
381428 let mut cluster_resources = ClusterResources :: new (
382429 APP_NAME ,
383430 OPERATOR_NAME ,
0 commit comments