@@ -15,17 +15,17 @@ use stackable_operator::{
1515 affinity:: StackableAffinity ,
1616 product_image_selection:: ResolvedProductImage ,
1717 random_secret_creation:: { self , create_random_secret_if_not_exists} ,
18- rbac:: build_rbac_resources,
1918 resources:: { NoRuntimeLimits , Resources } ,
2019 } ,
2120 crd:: listener,
2221 k8s_openapi:: api:: {
2322 apps:: v1:: { Deployment , StatefulSet } ,
24- core:: v1:: { ConfigMap , Secret , Service } ,
23+ core:: v1:: { ConfigMap , Secret , Service , ServiceAccount } ,
2524 policy:: v1:: PodDisruptionBudget ,
25+ rbac:: v1:: RoleBinding ,
2626 } ,
2727 kube:: {
28- Resource , ResourceExt ,
28+ Resource ,
2929 api:: ObjectMeta ,
3030 core:: { DeserializeGuard , error_boundary} ,
3131 runtime:: controller:: Action ,
@@ -44,7 +44,7 @@ use stackable_operator::{
4444 kvp:: label:: { recommended_labels, role_group_selector} ,
4545 product_logging:: framework:: { ValidatedContainerLogConfigChoice , VectorContainerLogConfig } ,
4646 role_group_utils:: ResourceNames ,
47- role_utils:: { GenericCommonConfig , RoleGroupConfig } ,
47+ role_utils:: { self , GenericCommonConfig , RoleGroupConfig } ,
4848 types:: {
4949 kubernetes:: { ListenerClassName , ListenerName , NamespaceName , Uid } ,
5050 operator:: {
@@ -94,6 +94,8 @@ pub struct KubernetesResources {
9494 pub listeners : Vec < listener:: v1alpha1:: Listener > ,
9595 pub config_maps : Vec < ConfigMap > ,
9696 pub pod_disruption_budgets : Vec < PodDisruptionBudget > ,
97+ pub service_accounts : Vec < ServiceAccount > ,
98+ pub role_bindings : Vec < RoleBinding > ,
9799}
98100
99101/// Per-role configuration extracted during validation.
@@ -238,6 +240,15 @@ impl ValidatedCluster {
238240 }
239241 }
240242
243+ /// Type-safe names for the per-cluster RBAC resources: the ServiceAccount shared by all
244+ /// Pods, its (namespaced) RoleBinding, and the operator-deployed ClusterRole it binds.
245+ pub fn rbac_resource_names ( & self ) -> role_utils:: ResourceNames {
246+ role_utils:: ResourceNames {
247+ cluster_name : self . name . clone ( ) ,
248+ product_name : product_name ( ) ,
249+ }
250+ }
251+
241252 pub fn recommended_labels (
242253 & self ,
243254 role : & SupersetRole ,
@@ -409,27 +420,6 @@ pub enum Error {
409420 source : stackable_operator:: client:: Error ,
410421 } ,
411422
412- #[ snafu( display( "failed to patch service account" ) ) ]
413- ApplyServiceAccount {
414- source : stackable_operator:: cluster_resources:: Error ,
415- } ,
416-
417- #[ snafu( display( "failed to patch role binding" ) ) ]
418- ApplyRoleBinding {
419- source : stackable_operator:: cluster_resources:: Error ,
420- } ,
421-
422- #[ snafu( display( "failed to build RBAC objects" ) ) ]
423- BuildRBACObjects {
424- source : stackable_operator:: commons:: rbac:: Error ,
425- } ,
426-
427- #[ snafu( display( "failed to get required Labels" ) ) ]
428- GetRequiredLabels {
429- source :
430- stackable_operator:: kvp:: KeyValuePairError < stackable_operator:: kvp:: LabelValueError > ,
431- } ,
432-
433423 #[ snafu( display( "SupersetCluster object is invalid" ) ) ]
434424 InvalidSupersetCluster {
435425 source : error_boundary:: InvalidObject ,
@@ -504,24 +494,6 @@ pub async fn reconcile_superset(
504494 & superset. spec . object_overrides ,
505495 ) ;
506496
507- let ( rbac_sa, rbac_rolebinding) = build_rbac_resources (
508- superset,
509- APP_NAME ,
510- cluster_resources
511- . get_required_labels ( )
512- . context ( GetRequiredLabelsSnafu ) ?,
513- )
514- . context ( BuildRBACObjectsSnafu ) ?;
515-
516- let rbac_sa = cluster_resources
517- . add ( client, rbac_sa)
518- . await
519- . context ( ApplyServiceAccountSnafu ) ?;
520- cluster_resources
521- . add ( client, rbac_rolebinding)
522- . await
523- . context ( ApplyRoleBindingSnafu ) ?;
524-
525497 // TODO: Can be removed after SDP 26.7 is released (it's only a migration from 26.3 - 26.7)
526498 // (don't forget about the snafu Error variants).
527499 // Removal is tracked in https://github.com/stackabletech/superset-operator/issues/755
@@ -536,14 +508,26 @@ pub async fn reconcile_superset(
536508 . await
537509 . context ( CreateSecretKeySecretSnafu ) ?;
538510
539- let resources = build:: build ( & validated, & rbac_sa . name_any ( ) ) . context ( BuildResourcesSnafu ) ?;
511+ let resources = build:: build ( & validated) . context ( BuildResourcesSnafu ) ?;
540512
541513 let mut statefulset_cond_builder = StatefulSetConditionBuilder :: default ( ) ;
542514 let mut deployment_cond_builder = DeploymentConditionBuilder :: default ( ) ;
543515
544516 // The StatefulSets/Deployments are applied last, so every ConfigMap and Secret they mount
545517 // already exists — otherwise a changed mount would restart the Pods.
546518 // See https://github.com/stackabletech/commons-operator/issues/111 for details.
519+ for service_account in resources. service_accounts {
520+ cluster_resources
521+ . add ( client, service_account)
522+ . await
523+ . context ( ApplyResourceSnafu ) ?;
524+ }
525+ for role_binding in resources. role_bindings {
526+ cluster_resources
527+ . add ( client, role_binding)
528+ . await
529+ . context ( ApplyResourceSnafu ) ?;
530+ }
547531 for service in resources. services {
548532 cluster_resources
549533 . add ( client, service)
0 commit comments