Skip to content

Commit d510d11

Browse files
adwk67claude
andcommitted
refactor: move secret creation from dereference to reconciler
Secret creation is a side effect that should not happen before the cluster spec has been validated. Moved it to the reconciler, after validate_cluster succeeds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e7c5e13 commit d510d11

2 files changed

Lines changed: 50 additions & 45 deletions

File tree

rust/operator-binary/src/airflow_controller.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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,

rust/operator-binary/src/controller/dereference.rs

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
use snafu::{ResultExt, Snafu};
2-
use stackable_operator::commons::random_secret_creation;
32

43
use crate::crd::{
54
authentication::AirflowClientAuthenticationDetailsResolved,
6-
authorization::AirflowAuthorizationResolved,
7-
internal_secret::{FERNET_KEY_SECRET_KEY, INTERNAL_SECRET_SECRET_KEY, JWT_SECRET_SECRET_KEY},
8-
v1alpha2,
5+
authorization::AirflowAuthorizationResolved, v1alpha2,
96
};
107

118
#[derive(Snafu, Debug)]
@@ -19,11 +16,6 @@ pub enum Error {
1916
AuthorizationConfig {
2017
source: stackable_operator::commons::opa::Error,
2118
},
22-
23-
#[snafu(display("failed to create internal secret"))]
24-
InternalSecret {
25-
source: random_secret_creation::Error,
26-
},
2719
}
2820

2921
/// External references resolved during the dereference step.
@@ -51,40 +43,6 @@ pub async fn dereference(
5143
.await
5244
.context(AuthorizationConfigSnafu)?;
5345

54-
random_secret_creation::create_random_secret_if_not_exists(
55-
&airflow.shared_internal_secret_secret_name(),
56-
INTERNAL_SECRET_SECRET_KEY,
57-
256,
58-
airflow,
59-
client,
60-
)
61-
.await
62-
.context(InternalSecretSnafu)?;
63-
64-
random_secret_creation::create_random_secret_if_not_exists(
65-
&airflow.shared_jwt_secret_secret_name(),
66-
JWT_SECRET_SECRET_KEY,
67-
256,
68-
airflow,
69-
client,
70-
)
71-
.await
72-
.context(InternalSecretSnafu)?;
73-
74-
// https://airflow.apache.org/docs/apache-airflow/stable/security/secrets/fernet.html#security-fernet
75-
// does not document how long the fernet key should be, but recommends using
76-
// python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
77-
// which returns `jUm21LuA76YZmrIa9u4eXRg0h0P24MDC9IDOmDvJbfw=`, which has 44 characters, which makes 32 bytes.
78-
random_secret_creation::create_random_secret_if_not_exists(
79-
&airflow.shared_fernet_key_secret_name(),
80-
FERNET_KEY_SECRET_KEY,
81-
32,
82-
airflow,
83-
client,
84-
)
85-
.await
86-
.context(InternalSecretSnafu)?;
87-
8846
Ok(DereferencedObjects {
8947
authentication_config,
9048
authorization_config,

0 commit comments

Comments
 (0)