Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/stackable-operator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ All notable changes to this project will be documented in this file.
### Removed

- BREAKING: Removed `last_update_time` from CRD ClusterCondition status ([#1054]).
- BREAKING: Removed role binding to legacy service accounts ([#1060]).

[#1049]: https://github.com/stackabletech/operator-rs/pull/1049
[#1054]: https://github.com/stackabletech/operator-rs/pull/1054
[#1058]: https://github.com/stackabletech/operator-rs/pull/1058
[#1060]: https://github.com/stackabletech/operator-rs/pull/1060

## [0.93.2] - 2025-05-26

Expand Down
40 changes: 12 additions & 28 deletions crates/stackable-operator/src/commons/rbac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,18 @@ pub enum Error {
}

/// Build RBAC objects for the product workloads.
/// The `product_name` is meant to be the product name, for example: zookeeper, airflow, etc.
/// and it is a assumed that a ClusterRole named `{product_name}-clusterrole` exists.
/// The names of the service account and role binding match the following templates:
/// - `{resource_name}-serviceaccount`
/// - `{resource_name}-rolebinding`
///
/// The service account is bound to a cluster role named `{product_name}-clusterrole` which
/// must already exist.
pub fn build_rbac_resources<T: Clone + Resource<DynamicType = ()>>(
resource: &T,
// 'product_name' is not used to build the names of the serviceAccount and roleBinding objects,
// as this caused problems with multiple clusters of the same product within the same namespace
// see <https://stackable.atlassian.net/browse/SUP-148> for more details.
// Instead the names for these objects are created by reading the name from the cluster object
// and appending [-rolebinding|-serviceaccount] to create unique names instead of using the
// same objects for multiple clusters.
product_name: &str,
labels: Labels,
) -> Result<(ServiceAccount, RoleBinding)> {
let sa_name = service_account_name(&resource.name_any());
// We add the legacy serviceAccount name to the binding here for at least one
// release cycle, so that the switchover during the upgrade can be smoother.
// To be removed in v24.3+1.
let legacy_sa_name = service_account_name(product_name);
let service_account = ServiceAccount {
metadata: ObjectMetaBuilder::new()
.name_and_namespace(resource)
Expand Down Expand Up @@ -74,22 +68,12 @@ pub fn build_rbac_resources<T: Clone + Resource<DynamicType = ()>>(
name: format!("{product_name}-clusterrole"),
api_group: "rbac.authorization.k8s.io".to_string(),
},
subjects: Some(vec![
Subject {
kind: "ServiceAccount".to_string(),
name: sa_name,
namespace: resource.namespace(),
..Subject::default()
},
// We add the legacy serviceAccount name to the binding here for at least one
// release cycle, so that the switchover during the upgrade can be smoother.
Subject {
kind: "ServiceAccount".to_string(),
name: legacy_sa_name,
namespace: resource.namespace(),
..Subject::default()
},
]),
subjects: Some(vec![Subject {
kind: "ServiceAccount".to_string(),
name: sa_name,
namespace: resource.namespace(),
..Subject::default()
}]),
};

Ok((service_account, role_binding))
Expand Down