From 3e60002734d17048c46a4ceb88a946852b6a70bb Mon Sep 17 00:00:00 2001 From: Andrew Kenworthy Date: Mon, 20 Jul 2026 12:46:39 +0200 Subject: [PATCH 1/5] factor: add infallible rbac functions --- Cargo.lock | 11 +-- Cargo.toml | 2 +- rust/operator-binary/src/controller.rs | 67 +++++---------- .../src/controller/build/mod.rs | 83 ++++++++++++++----- .../src/controller/build/resource/mod.rs | 1 + .../src/controller/build/resource/pdb.rs | 2 +- .../src/controller/build/resource/rbac.rs | 42 ++++++++++ .../controller/build/resource/statefulset.rs | 15 ++-- .../src/controller/validate.rs | 68 +++++++++++---- rust/operator-binary/src/crd/mod.rs | 8 +- 10 files changed, 189 insertions(+), 110 deletions(-) create mode 100644 rust/operator-binary/src/controller/build/resource/rbac.rs diff --git a/Cargo.lock b/Cargo.lock index 462b0563..cd08a141 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1622,7 +1622,6 @@ dependencies = [ [[package]] name = "k8s-version" version = "0.1.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#013bbf43f7006a4ddfc08a147f68441ed88b462b" dependencies = [ "darling", "regex", @@ -3068,7 +3067,6 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stackable-certs" version = "0.4.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#013bbf43f7006a4ddfc08a147f68441ed88b462b" dependencies = [ "const-oid", "ecdsa", @@ -3117,8 +3115,7 @@ dependencies = [ [[package]] name = "stackable-operator" -version = "0.113.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#013bbf43f7006a4ddfc08a147f68441ed88b462b" +version = "0.113.4" dependencies = [ "base64", "clap", @@ -3163,7 +3160,6 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#013bbf43f7006a4ddfc08a147f68441ed88b462b" dependencies = [ "darling", "proc-macro2", @@ -3174,7 +3170,6 @@ dependencies = [ [[package]] name = "stackable-shared" version = "0.1.2" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#013bbf43f7006a4ddfc08a147f68441ed88b462b" dependencies = [ "jiff", "k8s-openapi", @@ -3191,7 +3186,6 @@ dependencies = [ [[package]] name = "stackable-telemetry" version = "0.6.5" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#013bbf43f7006a4ddfc08a147f68441ed88b462b" dependencies = [ "axum", "clap", @@ -3215,7 +3209,6 @@ dependencies = [ [[package]] name = "stackable-versioned" version = "0.11.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#013bbf43f7006a4ddfc08a147f68441ed88b462b" dependencies = [ "kube", "schemars", @@ -3229,7 +3222,6 @@ dependencies = [ [[package]] name = "stackable-versioned-macros" version = "0.11.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#013bbf43f7006a4ddfc08a147f68441ed88b462b" dependencies = [ "convert_case", "convert_case_extras", @@ -3247,7 +3239,6 @@ dependencies = [ [[package]] name = "stackable-webhook" version = "0.9.2" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#013bbf43f7006a4ddfc08a147f68441ed88b462b" dependencies = [ "arc-swap", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index ae2da32a..90e13a4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,5 +33,5 @@ tracing = "0.1" uuid = "1.23" [patch."https://github.com/stackabletech/operator-rs.git"] -# stackable-operator = { path = "../operator-rs/crates/stackable-operator" } +stackable-operator = { path = "../operator-rs/crates/stackable-operator" } # stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index ed5aef14..642a31bb 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -8,19 +8,17 @@ use snafu::{ResultExt, Snafu}; use stackable_operator::{ cli::OperatorEnvironmentOptions, cluster_resources::ClusterResourceApplyStrategy, - commons::rbac::build_rbac_resources, crd::listener::v1alpha1::Listener, k8s_openapi::api::{ apps::v1::StatefulSet, - core::v1::{ConfigMap, Service}, + core::v1::{ConfigMap, Service, ServiceAccount}, policy::v1::PodDisruptionBudget, + rbac::v1::RoleBinding, }, kube::{ - ResourceExt, core::{DeserializeGuard, error_boundary}, runtime::controller::Action, }, - kvp::{KeyValuePairError, LabelValueError}, logging::controller::ReconcilerError, shared::time::Duration, status::condition::{ @@ -83,6 +81,8 @@ pub struct KubernetesResources { pub listeners: Vec, pub config_maps: Vec, pub pod_disruption_budgets: Vec, + pub service_accounts: Vec, + pub role_bindings: Vec, } #[derive(Snafu, Debug, EnumDiscriminants)] @@ -122,26 +122,6 @@ pub enum Error { source: crate::internal_secret::Error, }, - #[snafu(display("failed to create RBAC service account"))] - ApplyServiceAccount { - source: stackable_operator::cluster_resources::Error, - }, - - #[snafu(display("failed to create RBAC role binding"))] - ApplyRoleBinding { - source: stackable_operator::cluster_resources::Error, - }, - - #[snafu(display("failed to build RBAC resources"))] - BuildRbacResources { - source: stackable_operator::commons::rbac::Error, - }, - - #[snafu(display("failed to get required labels"))] - GetRequiredLabels { - source: KeyValuePairError, - }, - #[snafu(display("DruidCluster object is invalid"))] InvalidDruidCluster { source: error_boundary::InvalidObject, @@ -196,39 +176,30 @@ pub async fn reconcile_druid( &druid.spec.object_overrides, ); - let (rbac_sa, rbac_rolebinding) = build_rbac_resources( - druid, - APP_NAME, - cluster_resources - .get_required_labels() - .context(GetRequiredLabelsSnafu)?, - ) - .context(BuildRbacResourcesSnafu)?; - - // The ServiceAccount name is deterministic on the built object, so the StatefulSet builder only - // needs the name and does not depend on the applied ServiceAccount. - let service_account_name = rbac_sa.name_any(); - - cluster_resources - .add(client, rbac_sa) - .await - .context(ApplyServiceAccountSnafu)?; - cluster_resources - .add(client, rbac_rolebinding) - .await - .context(ApplyRoleBindingSnafu)?; - // The internal secret is shared across all roles and role groups, so it only needs to be // created once per reconcile rather than inside the role loop below. create_shared_internal_secret(&validated_cluster, client, DRUID_CONTROLLER_NAME) .await .context(FailedInternalSecretCreationSnafu)?; - let resources = - build::build(&validated_cluster, &service_account_name).context(BuildResourcesSnafu)?; + let resources = build::build(&validated_cluster).context(BuildResourcesSnafu)?; let mut ss_cond_builder = StatefulSetConditionBuilder::default(); + for service_account in resources.service_accounts { + cluster_resources + .add(client, service_account) + .await + .context(ApplyResourceSnafu)?; + } + + for role_binding in resources.role_bindings { + cluster_resources + .add(client, role_binding) + .await + .context(ApplyResourceSnafu)?; + } + // Apply order: everything a Pod mounts (ConfigMaps) must exist before the StatefulSets, so the // StatefulSets are applied last to prevent unnecessary Pod restarts. // See https://github.com/stackabletech/commons-operator/issues/111 for details. diff --git a/rust/operator-binary/src/controller/build/mod.rs b/rust/operator-binary/src/controller/build/mod.rs index ceeada95..d545b435 100644 --- a/rust/operator-binary/src/controller/build/mod.rs +++ b/rust/operator-binary/src/controller/build/mod.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use snafu::{ResultExt, Snafu}; -use stackable_operator::v2::types::operator::{ProductVersion, RoleGroupName}; +use stackable_operator::v2::types::operator::RoleGroupName; use crate::{ controller::{ @@ -12,6 +12,7 @@ use crate::{ config_map::build_rolegroup_config_map, listener::{build_group_listener, group_listener_name}, pdb::build_pdb, + rbac::{build_role_binding, build_service_account}, service::{build_rolegroup_headless_service, build_rolegroup_metrics_service}, statefulset::build_rolegroup_statefulset, }, @@ -28,10 +29,6 @@ stackable_operator::constant!(pub(crate) PLACEHOLDER_DISCOVERY_ROLE_GROUP: RoleG // (which is not tied to a single role group). stackable_operator::constant!(pub(crate) PLACEHOLDER_LISTENER_ROLE_GROUP: RoleGroupName = "none"); -// Placeholder product version used for labels on PVC templates, which cannot be modified once -// deployed. A constant value keeps the labels stable across version upgrades. -stackable_operator::constant!(pub(crate) UNVERSIONED_PRODUCT_VERSION: ProductVersion = "none"); - pub mod authentication; pub mod graceful_shutdown; pub mod jvm; @@ -66,10 +63,7 @@ pub enum Error { /// The Router group `Listener` and the discovery `ConfigMap`s are not built here: the discovery /// `ConfigMap` derives from the *applied* Router listener's ingress address, so both are built and /// applied in the reconcile step instead. -pub fn build( - cluster: &ValidatedCluster, - service_account_name: &str, -) -> Result { +pub fn build(cluster: &ValidatedCluster) -> Result { let mut stateful_sets = vec![]; let mut services = vec![]; let mut listeners = vec![]; @@ -116,16 +110,11 @@ pub fn build( )?, ); stateful_sets.push( - build_rolegroup_statefulset( - cluster, - druid_role, - role_group_name, - rg, - service_account_name, - ) - .context(StatefulSetSnafu { - role_group: role_group_name.clone(), - })?, + build_rolegroup_statefulset(cluster, druid_role, role_group_name, rg).context( + StatefulSetSnafu { + role_group: role_group_name.clone(), + }, + )?, ); } } @@ -136,11 +125,15 @@ pub fn build( listeners, config_maps, pod_disruption_budgets, + service_accounts: vec![build_service_account(cluster)], + role_bindings: vec![build_role_binding(cluster)], }) } #[cfg(test)] mod tests { + use std::collections::BTreeMap; + use stackable_operator::kube::Resource; use super::build; @@ -161,7 +154,7 @@ mod tests { fn build_produces_expected_resource_names() { let druid = druid_from_yaml(MINIMAL_DRUID_YAML); let cluster = validated_cluster(&druid); - let resources = build(&cluster, "simple-druid-serviceaccount").expect("build succeeds"); + let resources = build(&cluster).expect("build succeeds"); // One StatefulSet and one ConfigMap per role group (one role group per role). let expected_role_group_names = [ @@ -188,4 +181,54 @@ mod tests { ["simple-druid-broker", "simple-druid-coordinator"] ); } + + /// Locks the RBAC resource names, the roleRef, and the recommended label set against + /// accidental drift. The fixture's cluster name deliberately differs from the product name so + /// that swapped `name`/`instance` label values cannot pass unnoticed. + #[test] + fn build_produces_rbac() { + let druid = druid_from_yaml(MINIMAL_DRUID_YAML); + let cluster = validated_cluster(&druid); + let resources = build(&cluster).expect("build succeeds"); + + assert_eq!( + sorted_names(&resources.service_accounts), + ["simple-druid-serviceaccount"] + ); + assert_eq!( + sorted_names(&resources.role_bindings), + ["simple-druid-rolebinding"] + ); + + let expected_labels = BTreeMap::from( + [ + ("app.kubernetes.io/component", "none"), + ("app.kubernetes.io/instance", "simple-druid"), + ( + "app.kubernetes.io/managed-by", + "druid.stackable.tech_druidcluster", + ), + ("app.kubernetes.io/name", "druid"), + ("app.kubernetes.io/role-group", "none"), + ("app.kubernetes.io/version", "30.0.0-stackable0.0.0-dev"), + ("stackable.tech/vendor", "Stackable"), + ] + .map(|(key, value)| (key.to_string(), value.to_string())), + ); + let service_account = resources + .service_accounts + .first() + .expect("a ServiceAccount is built"); + assert_eq!( + service_account.metadata.labels, + Some(expected_labels.clone()) + ); + + let role_binding = resources + .role_bindings + .first() + .expect("a RoleBinding is built"); + assert_eq!(role_binding.metadata.labels, Some(expected_labels)); + assert_eq!(role_binding.role_ref.name, "druid-clusterrole"); + } } diff --git a/rust/operator-binary/src/controller/build/resource/mod.rs b/rust/operator-binary/src/controller/build/resource/mod.rs index d7fba99e..ecdc6cfe 100644 --- a/rust/operator-binary/src/controller/build/resource/mod.rs +++ b/rust/operator-binary/src/controller/build/resource/mod.rs @@ -4,5 +4,6 @@ pub mod config_map; pub mod discovery; pub mod listener; pub mod pdb; +pub mod rbac; pub mod service; pub mod statefulset; diff --git a/rust/operator-binary/src/controller/build/resource/pdb.rs b/rust/operator-binary/src/controller/build/resource/pdb.rs index e7de455b..79bfd963 100644 --- a/rust/operator-binary/src/controller/build/resource/pdb.rs +++ b/rust/operator-binary/src/controller/build/resource/pdb.rs @@ -27,7 +27,7 @@ pub fn build_pdb( let pdb = pod_disruption_budget_builder_with_role( cluster, &product_name(), - &role.to_role_name(), + &ValidatedCluster::role_name(role), &operator_name(), &controller_name(), ) diff --git a/rust/operator-binary/src/controller/build/resource/rbac.rs b/rust/operator-binary/src/controller/build/resource/rbac.rs new file mode 100644 index 00000000..4e89fdb7 --- /dev/null +++ b/rust/operator-binary/src/controller/build/resource/rbac.rs @@ -0,0 +1,42 @@ +//! Builds the RBAC resources (ServiceAccount + RoleBinding) shared by all role groups. + +use std::str::FromStr; + +use stackable_operator::{ + k8s_openapi::api::{core::v1::ServiceAccount, rbac::v1::RoleBinding}, + kvp::Labels, + v2::{ + rbac, + types::operator::{RoleGroupName, RoleName}, + }, +}; + +use crate::controller::validate::ValidatedCluster; + +stackable_operator::constant!(NONE_ROLE_NAME: RoleName = "none"); +stackable_operator::constant!(NONE_ROLE_GROUP_NAME: RoleGroupName = "none"); + +/// Builds the [`ServiceAccount`] that all role-group Pods run under. +pub fn build_service_account(cluster: &ValidatedCluster) -> ServiceAccount { + rbac::build_service_account( + cluster, + &cluster.rbac_resource_names(), + rbac_labels(cluster), + ) +} + +/// Builds the [`RoleBinding`] that binds the [`ServiceAccount`] from [`build_service_account`] to +/// the operator-deployed ClusterRole. +pub fn build_role_binding(cluster: &ValidatedCluster) -> RoleBinding { + rbac::build_role_binding( + cluster, + &cluster.rbac_resource_names(), + rbac_labels(cluster), + ) +} + +/// Both resources are shared by the whole cluster rather than tied to a role or role group, so +/// the recommended labels carry `none` for both values. +fn rbac_labels(cluster: &ValidatedCluster) -> Labels { + cluster.recommended_labels_for(&NONE_ROLE_NAME, &NONE_ROLE_GROUP_NAME) +} diff --git a/rust/operator-binary/src/controller/build/resource/statefulset.rs b/rust/operator-binary/src/controller/build/resource/statefulset.rs index 54a478fe..cbb0e46e 100644 --- a/rust/operator-binary/src/controller/build/resource/statefulset.rs +++ b/rust/operator-binary/src/controller/build/resource/statefulset.rs @@ -34,7 +34,7 @@ use stackable_operator::{ use crate::{ controller::{ build::{ - UNVERSIONED_PRODUCT_VERSION, authentication, + authentication, graceful_shutdown::add_graceful_shutdown_config, properties::product_logging::MAX_DRUID_LOG_FILES_SIZE, resource::listener::{ @@ -113,7 +113,6 @@ pub fn build_rolegroup_statefulset( role: &DruidRole, role_group_name: &RoleGroupName, rg: &DruidRoleGroupConfig, - service_account_name: &str, ) -> Result { let merged_rolegroup_config = &rg.config; let resource_names = cluster.resource_names(role, role_group_name); @@ -301,11 +300,8 @@ pub fn build_rolegroup_statefulset( .add_volume_mount(&*LISTENER_VOLUME_NAME, LISTENER_VOLUME_DIR) .context(AddVolumeMountSnafu)?; - // Used for PVC templates that cannot be modified once they are deployed - // A version value is required, and we do want to use the "recommended" format for the - // other desired labels, hence the unversioned product version. let unversioned_recommended_labels = - cluster.recommended_labels_for(role, &UNVERSIONED_PRODUCT_VERSION, role_group_name); + cluster.unversioned_recommended_labels(role, role_group_name); pvcs = Some(vec![build_group_listener_pvc( &group_listener_name, @@ -321,7 +317,12 @@ pub fn build_rolegroup_statefulset( .add_init_container(cb_prepare.build()) .add_container(cb_druid.build()) .metadata(metadata) - .service_account_name(service_account_name) + .service_account_name( + cluster + .rbac_resource_names() + .service_account_name() + .to_string(), + ) .security_context(PodSecurityContextBuilder::new().fs_group(1000).build()); // The Vector agent reads the static `vector.yaml` (added to the rolegroup ConfigMap) from the diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index bc268437..d0296bb9 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -28,9 +28,10 @@ use stackable_operator::{ controller_utils::{get_cluster_name, get_namespace, get_uid}, kvp::label::{recommended_labels, role_group_selector}, role_group_utils::ResourceNames, + role_utils, types::{ kubernetes::{ListenerClassName, NamespaceName, Uid}, - operator::{ClusterName, ProductVersion, RoleGroupName}, + operator::{ClusterName, ProductVersion, RoleGroupName, RoleName}, }, }, }; @@ -91,6 +92,9 @@ type Result = std::result::Result; /// re-exported here for the build step. pub use crate::crd::DruidRoleGroupConfig; +// Placeholder version label value for resources whose labels must not change after deployment. +stackable_operator::constant!(UNVERSIONED_PRODUCT_VERSION: ProductVersion = "none"); + /// Cluster-wide resolved fields that are not role/rolegroup specific. pub struct ValidatedClusterConfig { pub zookeeper_connection_string: String, @@ -193,14 +197,16 @@ impl ValidatedCluster { .expect("every DruidRole has a validated role config") } - /// Recommended labels for a role-group resource, using the given product version. - /// - /// Kept separate so the listener PVC templates (which require an immutable, version-independent - /// label set) can pass the unversioned product version. - pub(crate) fn recommended_labels_for( + /// The type-safe role name for a Druid role. + pub(crate) fn role_name(role: &DruidRole) -> RoleName { + RoleName::from_str(&role.to_string()) + .expect("a DruidRole always serializes to a valid role name") + } + + fn recommended_labels_with( &self, - role: &DruidRole, product_version: &ProductVersion, + role_name: &RoleName, role_group_name: &RoleGroupName, ) -> Labels { recommended_labels( @@ -209,27 +215,48 @@ impl ValidatedCluster { product_version, &operator_name(), &controller_name(), - &role.to_role_name(), + role_name, role_group_name, ) } - /// Recommended labels for a role-group resource. - pub(crate) fn recommended_labels( + /// Recommended labels for a resource that is not tied to a concrete [`DruidRole`] (e.g. the + /// cluster-shared RBAC resources), using a free-form role/role-group label value. + pub fn recommended_labels_for( &self, - role: &DruidRole, + role_name: &RoleName, role_group_name: &RoleGroupName, ) -> Labels { - self.recommended_labels_for(role, &self.product_version, role_group_name) + self.recommended_labels_with(&self.product_version, role_name, role_group_name) } - /// Selector labels matching the pods of a role group. - pub(crate) fn role_group_selector( + /// Recommended labels for a role-group resource. + pub fn recommended_labels(&self, role: &DruidRole, role_group_name: &RoleGroupName) -> Labels { + self.recommended_labels_for(&Self::role_name(role), role_group_name) + } + + /// Recommended labels with the constant [`UNVERSIONED_PRODUCT_VERSION`], for PVC templates + /// that cannot be modified after deployment (keeps the labels stable across version upgrades). + pub fn unversioned_recommended_labels( &self, role: &DruidRole, role_group_name: &RoleGroupName, ) -> Labels { - role_group_selector(self, &product_name(), &role.to_role_name(), role_group_name) + self.recommended_labels_with( + &UNVERSIONED_PRODUCT_VERSION, + &Self::role_name(role), + role_group_name, + ) + } + + /// Selector labels matching the pods of a role group. + pub fn role_group_selector(&self, role: &DruidRole, role_group_name: &RoleGroupName) -> Labels { + role_group_selector( + self, + &product_name(), + &Self::role_name(role), + role_group_name, + ) } /// Returns an [`ObjectMetaBuilder`] pre-filled with the namespace, an owner reference back to @@ -252,6 +279,15 @@ impl ValidatedCluster { builder } + /// Type-safe names for the per-cluster RBAC resources: the ServiceAccount shared by all + /// Pods, its (namespaced) RoleBinding, and the operator-deployed ClusterRole it binds. + pub fn rbac_resource_names(&self) -> role_utils::ResourceNames { + role_utils::ResourceNames { + cluster_name: self.name.clone(), + product_name: product_name(), + } + } + /// Type-safe names for the resources of the given role's role group. pub(crate) fn resource_names( &self, @@ -260,7 +296,7 @@ impl ValidatedCluster { ) -> ResourceNames { ResourceNames { cluster_name: self.name.clone(), - role_name: role.to_role_name(), + role_name: Self::role_name(role), role_group_name: role_group_name.clone(), } } diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index d7f572ee..2bacae3a 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -46,7 +46,7 @@ use stackable_operator::{ types::{ common::Port, kubernetes::{ConfigMapName, ContainerName, ListenerClassName}, - operator::{RoleGroupName, RoleName}, + operator::RoleGroupName, }, }, versioned::versioned, @@ -631,12 +631,6 @@ pub enum DruidRole { } impl DruidRole { - /// Returns the typed role name used for Kubernetes labels and selectors. - pub fn to_role_name(&self) -> RoleName { - RoleName::from_str(&self.to_string()) - .expect("a DruidRole always serializes to a valid role name") - } - /// Returns the name of the internal druid process name associated with the role. /// These strings are used by druid internally to identify processes. fn get_process_name(&self) -> &str { From f7a3db963db25f08298009a5dd666de884ec7c5d Mon Sep 17 00:00:00 2001 From: Andrew Kenworthy Date: Tue, 21 Jul 2026 18:10:10 +0200 Subject: [PATCH 2/5] reference op-rs remote branch not local one --- CHANGELOG.md | 3 +++ Cargo.lock | 9 ++++++++ Cargo.nix | 56 +++++++++++++++++++++++------------------------ Cargo.toml | 4 ++-- crate-hashes.json | 18 +++++++-------- 5 files changed, 51 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6c4a50c..eaa5b552 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,11 @@ All notable changes to this project will be documented in this file. - Internal operator refactoring: introduce a build() step in the reconciler that assembles all relevant Kubernetes resources before anything is applied ([#841]). +- The RBAC ServiceAccount and RoleBinding are now built with the operator-rs `v2::rbac` + functions and carry the full set of recommended labels ([#846]). [#841]: https://github.com/stackabletech/druid-operator/pull/841 +[#846]: https://github.com/stackabletech/druid-operator/pull/846 ## [26.7.0] - 2026-07-21 diff --git a/Cargo.lock b/Cargo.lock index cd08a141..d73b2d82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1622,6 +1622,7 @@ dependencies = [ [[package]] name = "k8s-version" version = "0.1.3" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" dependencies = [ "darling", "regex", @@ -3067,6 +3068,7 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stackable-certs" version = "0.4.1" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" dependencies = [ "const-oid", "ecdsa", @@ -3116,6 +3118,7 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.113.4" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" dependencies = [ "base64", "clap", @@ -3160,6 +3163,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" dependencies = [ "darling", "proc-macro2", @@ -3170,6 +3174,7 @@ dependencies = [ [[package]] name = "stackable-shared" version = "0.1.2" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" dependencies = [ "jiff", "k8s-openapi", @@ -3186,6 +3191,7 @@ dependencies = [ [[package]] name = "stackable-telemetry" version = "0.6.5" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" dependencies = [ "axum", "clap", @@ -3209,6 +3215,7 @@ dependencies = [ [[package]] name = "stackable-versioned" version = "0.11.1" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" dependencies = [ "kube", "schemars", @@ -3222,6 +3229,7 @@ dependencies = [ [[package]] name = "stackable-versioned-macros" version = "0.11.1" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" dependencies = [ "convert_case", "convert_case_extras", @@ -3239,6 +3247,7 @@ dependencies = [ [[package]] name = "stackable-webhook" version = "0.9.2" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" dependencies = [ "arc-swap", "async-trait", diff --git a/Cargo.nix b/Cargo.nix index 0a32c103..e98e77cd 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -5135,9 +5135,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "013bbf43f7006a4ddfc08a147f68441ed88b462b"; - sha256 = "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; + sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; }; libName = "k8s_version"; authors = [ @@ -10035,9 +10035,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "013bbf43f7006a4ddfc08a147f68441ed88b462b"; - sha256 = "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; + sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; }; libName = "stackable_certs"; authors = [ @@ -10243,13 +10243,13 @@ rec { }; "stackable-operator" = rec { crateName = "stackable-operator"; - version = "0.113.3"; + version = "0.113.4"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "013bbf43f7006a4ddfc08a147f68441ed88b462b"; - sha256 = "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; + sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; }; libName = "stackable_operator"; authors = [ @@ -10446,9 +10446,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "013bbf43f7006a4ddfc08a147f68441ed88b462b"; - sha256 = "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; + sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; }; procMacro = true; libName = "stackable_operator_derive"; @@ -10481,9 +10481,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "013bbf43f7006a4ddfc08a147f68441ed88b462b"; - sha256 = "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; + sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; }; libName = "stackable_shared"; authors = [ @@ -10562,9 +10562,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "013bbf43f7006a4ddfc08a147f68441ed88b462b"; - sha256 = "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; + sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; }; libName = "stackable_telemetry"; authors = [ @@ -10672,9 +10672,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "013bbf43f7006a4ddfc08a147f68441ed88b462b"; - sha256 = "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; + sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; }; libName = "stackable_versioned"; authors = [ @@ -10722,9 +10722,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "013bbf43f7006a4ddfc08a147f68441ed88b462b"; - sha256 = "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; + sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; }; procMacro = true; libName = "stackable_versioned_macros"; @@ -10790,9 +10790,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "013bbf43f7006a4ddfc08a147f68441ed88b462b"; - sha256 = "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; + sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; }; libName = "stackable_webhook"; authors = [ diff --git a/Cargo.toml b/Cargo.toml index 90e13a4a..971f9ea8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,5 +33,5 @@ tracing = "0.1" uuid = "1.23" [patch."https://github.com/stackabletech/operator-rs.git"] -stackable-operator = { path = "../operator-rs/crates/stackable-operator" } -# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } +# stackable-operator = { path = "../operator-rs/crates/stackable-operator" } +stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "feat/smooth-operator/build-rbac" } diff --git a/crate-hashes.json b/crate-hashes.json index cd3917c3..a733adf9 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,12 +1,12 @@ { - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#k8s-version@0.1.3": "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#stackable-certs@0.4.1": "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#stackable-operator-derive@0.3.1": "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#stackable-operator@0.113.3": "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#stackable-shared@0.1.2": "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#stackable-telemetry@0.6.5": "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#stackable-versioned-macros@0.11.1": "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#stackable-versioned@0.11.1": "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.113.3#stackable-webhook@0.9.2": "054p2mcinq3x4iykmc72nhga7kapc8ihkx9mnzqq3qdm2bk2qcps", + "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#k8s-version@0.1.3": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", + "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-certs@0.4.1": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", + "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-operator-derive@0.3.1": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", + "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-operator@0.113.4": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", + "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-shared@0.1.2": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", + "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-telemetry@0.6.5": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", + "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-versioned-macros@0.11.1": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", + "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-versioned@0.11.1": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", + "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-webhook@0.9.2": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", "git+https://github.com/stackabletech/product-config.git?tag=0.8.0#product-config@0.8.0": "1dz70kapm2wdqcr7ndyjji0lhsl98bsq95gnb2lw487wf6yr7987" } \ No newline at end of file From ed92cb438a21c7a2600661fd65eb9d47b4801134 Mon Sep 17 00:00:00 2001 From: Andrew Kenworthy Date: Wed, 22 Jul 2026 17:21:54 +0200 Subject: [PATCH 3/5] bump op-rs to 0.114.0 --- Cargo.lock | 84 ++-------- Cargo.nix | 263 ++++--------------------------- Cargo.toml | 4 +- crate-hashes.json | 19 ++- rust/operator-binary/src/main.rs | 1 - 5 files changed, 50 insertions(+), 321 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d73b2d82..44837fee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,21 +265,6 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - [[package]] name = "bitflags" version = "1.3.2" @@ -835,17 +820,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fancy-regex" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f" -dependencies = [ - "bit-set", - "regex-automata", - "regex-syntax", -] - [[package]] name = "fastrand" version = "2.4.1" @@ -1622,7 +1596,7 @@ dependencies = [ [[package]] name = "k8s-version" version = "0.1.3" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#ee66b8d66fe10c216acfed0f81070b362604b392" dependencies = [ "darling", "regex", @@ -2319,22 +2293,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "product-config" -version = "0.8.0" -source = "git+https://github.com/stackabletech/product-config.git?tag=0.8.0#678fb7cf30af7d7b516c9a46698a1b661120d54a" -dependencies = [ - "fancy-regex", - "java-properties", - "schemars", - "semver", - "serde", - "serde_json", - "serde_yaml", - "snafu 0.8.9", - "xml", -] - [[package]] name = "prost" version = "0.14.4" @@ -2980,15 +2938,6 @@ dependencies = [ "snafu-derive 0.6.10", ] -[[package]] -name = "snafu" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e84b3f4eacbf3a1ce05eac6763b4d629d60cbc94d632e4092c54ade71f1e1a2" -dependencies = [ - "snafu-derive 0.8.9", -] - [[package]] name = "snafu" version = "0.9.1" @@ -3009,18 +2958,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "snafu-derive" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.118", -] - [[package]] name = "snafu-derive" version = "0.9.1" @@ -3068,7 +3005,7 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stackable-certs" version = "0.4.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#ee66b8d66fe10c216acfed0f81070b362604b392" dependencies = [ "const-oid", "ecdsa", @@ -3117,8 +3054,8 @@ dependencies = [ [[package]] name = "stackable-operator" -version = "0.113.4" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" +version = "0.114.0" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#ee66b8d66fe10c216acfed0f81070b362604b392" dependencies = [ "base64", "clap", @@ -3135,7 +3072,6 @@ dependencies = [ "json-patch", "k8s-openapi", "kube", - "product-config", "rand 0.9.4", "regex", "schemars", @@ -3163,7 +3099,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#ee66b8d66fe10c216acfed0f81070b362604b392" dependencies = [ "darling", "proc-macro2", @@ -3174,7 +3110,7 @@ dependencies = [ [[package]] name = "stackable-shared" version = "0.1.2" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#ee66b8d66fe10c216acfed0f81070b362604b392" dependencies = [ "jiff", "k8s-openapi", @@ -3191,7 +3127,7 @@ dependencies = [ [[package]] name = "stackable-telemetry" version = "0.6.5" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#ee66b8d66fe10c216acfed0f81070b362604b392" dependencies = [ "axum", "clap", @@ -3215,7 +3151,7 @@ dependencies = [ [[package]] name = "stackable-versioned" version = "0.11.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#ee66b8d66fe10c216acfed0f81070b362604b392" dependencies = [ "kube", "schemars", @@ -3229,7 +3165,7 @@ dependencies = [ [[package]] name = "stackable-versioned-macros" version = "0.11.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#ee66b8d66fe10c216acfed0f81070b362604b392" dependencies = [ "convert_case", "convert_case_extras", @@ -3247,7 +3183,7 @@ dependencies = [ [[package]] name = "stackable-webhook" version = "0.9.2" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#633404488f2d62b0178bc7f11a6f7ab3576f6796" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#ee66b8d66fe10c216acfed0f81070b362604b392" dependencies = [ "arc-swap", "async-trait", diff --git a/Cargo.nix b/Cargo.nix index e98e77cd..68ca33c3 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -862,50 +862,6 @@ rec { }; resolvedDefaultFeatures = [ "alloc" ]; }; - "bit-set" = rec { - crateName = "bit-set"; - version = "0.8.0"; - edition = "2015"; - sha256 = "18riaa10s6n59n39vix0cr7l2dgwdhcpbcm97x1xbyfp1q47x008"; - libName = "bit_set"; - authors = [ - "Alexis Beingessner " - ]; - dependencies = [ - { - name = "bit-vec"; - packageId = "bit-vec"; - usesDefaultFeatures = false; - } - ]; - features = { - "default" = [ "std" ]; - "serde" = [ "dep:serde" "bit-vec/serde" ]; - "std" = [ "bit-vec/std" ]; - }; - resolvedDefaultFeatures = [ "std" ]; - }; - "bit-vec" = rec { - crateName = "bit-vec"; - version = "0.8.0"; - edition = "2015"; - sha256 = "1xxa1s2cj291r7k1whbxq840jxvmdsq9xgh7bvrxl46m80fllxjy"; - libName = "bit_vec"; - authors = [ - "Alexis Beingessner " - ]; - features = { - "borsh" = [ "dep:borsh" ]; - "borsh_std" = [ "borsh/std" ]; - "default" = [ "std" ]; - "miniserde" = [ "dep:miniserde" ]; - "nanoserde" = [ "dep:nanoserde" ]; - "serde" = [ "dep:serde" ]; - "serde_no_std" = [ "serde/alloc" ]; - "serde_std" = [ "std" "serde/std" ]; - }; - resolvedDefaultFeatures = [ "std" ]; - }; "bitflags 1.3.2" = rec { crateName = "bitflags"; version = "1.3.2"; @@ -2555,43 +2511,6 @@ rec { }; resolvedDefaultFeatures = [ "default" "std" ]; }; - "fancy-regex" = rec { - crateName = "fancy-regex"; - version = "0.16.2"; - edition = "2018"; - sha256 = "0vy4c012f82xcg3gs068mq110zhsrnajh58fmq1jxr7vaijhb2wr"; - libName = "fancy_regex"; - authors = [ - "Raph Levien " - "Robin Stocker " - "Keith Hall " - ]; - dependencies = [ - { - name = "bit-set"; - packageId = "bit-set"; - usesDefaultFeatures = false; - } - { - name = "regex-automata"; - packageId = "regex-automata"; - usesDefaultFeatures = false; - features = [ "alloc" "syntax" "meta" "nfa" "dfa" "hybrid" ]; - } - { - name = "regex-syntax"; - packageId = "regex-syntax"; - usesDefaultFeatures = false; - } - ]; - features = { - "default" = [ "unicode" "perf" "std" ]; - "perf" = [ "regex-automata/perf" ]; - "std" = [ "regex-automata/std" "regex-syntax/std" "bit-set/std" ]; - "unicode" = [ "regex-automata/unicode" "regex-syntax/unicode" ]; - }; - resolvedDefaultFeatures = [ "default" "perf" "std" "unicode" ]; - }; "fastrand" = rec { crateName = "fastrand"; version = "2.4.1"; @@ -5135,9 +5054,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech//operator-rs.git"; - rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; - sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; + url = "https://github.com/stackabletech/operator-rs.git"; + rev = "ee66b8d66fe10c216acfed0f81070b362604b392"; + sha256 = "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj"; }; libName = "k8s_version"; authors = [ @@ -7562,61 +7481,6 @@ rec { }; resolvedDefaultFeatures = [ "default" "proc-macro" ]; }; - "product-config" = rec { - crateName = "product-config"; - version = "0.8.0"; - edition = "2021"; - workspace_member = null; - src = pkgs.fetchgit { - url = "https://github.com/stackabletech/product-config.git"; - rev = "678fb7cf30af7d7b516c9a46698a1b661120d54a"; - sha256 = "1dz70kapm2wdqcr7ndyjji0lhsl98bsq95gnb2lw487wf6yr7987"; - }; - libName = "product_config"; - authors = [ - "Malte Sander " - ]; - dependencies = [ - { - name = "fancy-regex"; - packageId = "fancy-regex"; - } - { - name = "java-properties"; - packageId = "java-properties"; - } - { - name = "schemars"; - packageId = "schemars"; - } - { - name = "semver"; - packageId = "semver"; - } - { - name = "serde"; - packageId = "serde"; - features = [ "derive" ]; - } - { - name = "serde_json"; - packageId = "serde_json"; - } - { - name = "serde_yaml"; - packageId = "serde_yaml"; - } - { - name = "snafu"; - packageId = "snafu 0.8.9"; - } - { - name = "xml"; - packageId = "xml"; - } - ]; - - }; "prost" = rec { crateName = "prost"; version = "0.14.4"; @@ -8117,7 +7981,7 @@ rec { "unicode-script" = [ "regex-syntax?/unicode-script" ]; "unicode-segment" = [ "regex-syntax?/unicode-segment" ]; }; - resolvedDefaultFeatures = [ "alloc" "dfa" "dfa-build" "dfa-onepass" "dfa-search" "hybrid" "meta" "nfa" "nfa-backtrack" "nfa-pikevm" "nfa-thompson" "perf" "perf-inline" "perf-literal" "perf-literal-multisubstring" "perf-literal-substring" "std" "syntax" "unicode" "unicode-age" "unicode-bool" "unicode-case" "unicode-gencat" "unicode-perl" "unicode-script" "unicode-segment" "unicode-word-boundary" ]; + resolvedDefaultFeatures = [ "alloc" "dfa-build" "dfa-onepass" "dfa-search" "hybrid" "meta" "nfa-backtrack" "nfa-pikevm" "nfa-thompson" "perf-inline" "perf-literal" "perf-literal-multisubstring" "perf-literal-substring" "std" "syntax" "unicode" "unicode-age" "unicode-bool" "unicode-case" "unicode-gencat" "unicode-perl" "unicode-script" "unicode-segment" "unicode-word-boundary" ]; }; "regex-syntax" = rec { crateName = "regex-syntax"; @@ -9780,37 +9644,6 @@ rec { }; resolvedDefaultFeatures = [ "default" "guide" "std" ]; }; - "snafu 0.8.9" = rec { - crateName = "snafu"; - version = "0.8.9"; - edition = "2018"; - sha256 = "18p1y5qxwjn5j902wqsdr75n17b29lxpdipa0p7a3wybxbsb713f"; - authors = [ - "Jake Goulding " - ]; - dependencies = [ - { - name = "snafu-derive"; - packageId = "snafu-derive 0.8.9"; - } - ]; - features = { - "backtrace" = [ "dep:backtrace" ]; - "backtraces-impl-backtrace-crate" = [ "backtrace" ]; - "default" = [ "std" "rust_1_65" ]; - "futures" = [ "futures-core-crate" "pin-project" ]; - "futures-core-crate" = [ "dep:futures-core-crate" ]; - "futures-crate" = [ "dep:futures-crate" ]; - "internal-dev-dependencies" = [ "futures-crate" ]; - "pin-project" = [ "dep:pin-project" ]; - "rust_1_61" = [ "snafu-derive/rust_1_61" ]; - "rust_1_65" = [ "rust_1_61" ]; - "rust_1_81" = [ "rust_1_65" ]; - "std" = [ "alloc" ]; - "unstable-provider-api" = [ "snafu-derive/unstable-provider-api" ]; - }; - resolvedDefaultFeatures = [ "alloc" "default" "rust_1_61" "rust_1_65" "std" ]; - }; "snafu 0.9.1" = rec { crateName = "snafu"; version = "0.9.1"; @@ -9863,40 +9696,6 @@ rec { features = { }; }; - "snafu-derive 0.8.9" = rec { - crateName = "snafu-derive"; - version = "0.8.9"; - edition = "2018"; - sha256 = "0lg4s58jzx6w48ig4qp8jasrrs886pifqqd58k5b2jzlvd3pgjf1"; - procMacro = true; - libName = "snafu_derive"; - authors = [ - "Jake Goulding " - ]; - dependencies = [ - { - name = "heck"; - packageId = "heck"; - usesDefaultFeatures = false; - } - { - name = "proc-macro2"; - packageId = "proc-macro2"; - } - { - name = "quote"; - packageId = "quote"; - } - { - name = "syn"; - packageId = "syn 2.0.118"; - features = [ "full" ]; - } - ]; - features = { - }; - resolvedDefaultFeatures = [ "rust_1_61" ]; - }; "snafu-derive 0.9.1" = rec { crateName = "snafu-derive"; version = "0.9.1"; @@ -10035,9 +9834,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech//operator-rs.git"; - rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; - sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; + url = "https://github.com/stackabletech/operator-rs.git"; + rev = "ee66b8d66fe10c216acfed0f81070b362604b392"; + sha256 = "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj"; }; libName = "stackable_certs"; authors = [ @@ -10243,13 +10042,13 @@ rec { }; "stackable-operator" = rec { crateName = "stackable-operator"; - version = "0.113.4"; + version = "0.114.0"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech//operator-rs.git"; - rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; - sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; + url = "https://github.com/stackabletech/operator-rs.git"; + rev = "ee66b8d66fe10c216acfed0f81070b362604b392"; + sha256 = "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj"; }; libName = "stackable_operator"; authors = [ @@ -10324,10 +10123,6 @@ rec { usesDefaultFeatures = false; features = [ "client" "jsonpatch" "runtime" "derive" "admission" "rustls-tls" "ring" ]; } - { - name = "product-config"; - packageId = "product-config"; - } { name = "rand"; packageId = "rand 0.9.4"; @@ -10446,9 +10241,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech//operator-rs.git"; - rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; - sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; + url = "https://github.com/stackabletech/operator-rs.git"; + rev = "ee66b8d66fe10c216acfed0f81070b362604b392"; + sha256 = "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj"; }; procMacro = true; libName = "stackable_operator_derive"; @@ -10481,9 +10276,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech//operator-rs.git"; - rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; - sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; + url = "https://github.com/stackabletech/operator-rs.git"; + rev = "ee66b8d66fe10c216acfed0f81070b362604b392"; + sha256 = "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj"; }; libName = "stackable_shared"; authors = [ @@ -10562,9 +10357,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech//operator-rs.git"; - rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; - sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; + url = "https://github.com/stackabletech/operator-rs.git"; + rev = "ee66b8d66fe10c216acfed0f81070b362604b392"; + sha256 = "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj"; }; libName = "stackable_telemetry"; authors = [ @@ -10672,9 +10467,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech//operator-rs.git"; - rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; - sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; + url = "https://github.com/stackabletech/operator-rs.git"; + rev = "ee66b8d66fe10c216acfed0f81070b362604b392"; + sha256 = "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj"; }; libName = "stackable_versioned"; authors = [ @@ -10722,9 +10517,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech//operator-rs.git"; - rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; - sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; + url = "https://github.com/stackabletech/operator-rs.git"; + rev = "ee66b8d66fe10c216acfed0f81070b362604b392"; + sha256 = "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj"; }; procMacro = true; libName = "stackable_versioned_macros"; @@ -10790,9 +10585,9 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech//operator-rs.git"; - rev = "633404488f2d62b0178bc7f11a6f7ab3576f6796"; - sha256 = "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s"; + url = "https://github.com/stackabletech/operator-rs.git"; + rev = "ee66b8d66fe10c216acfed0f81070b362604b392"; + sha256 = "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj"; }; libName = "stackable_webhook"; authors = [ diff --git a/Cargo.toml b/Cargo.toml index 971f9ea8..53b34833 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ edition = "2024" repository = "https://github.com/stackabletech/druid-operator" [workspace.dependencies] -stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.113.3", features = ["crds", "webhook"] } +stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.114.0", features = ["crds", "webhook"] } anyhow = "1.0.103" built = { version = "0.8", features = ["chrono", "git2"] } @@ -34,4 +34,4 @@ uuid = "1.23" [patch."https://github.com/stackabletech/operator-rs.git"] # stackable-operator = { path = "../operator-rs/crates/stackable-operator" } -stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "feat/smooth-operator/build-rbac" } +# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } diff --git a/crate-hashes.json b/crate-hashes.json index a733adf9..04979b96 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,12 +1,11 @@ { - "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#k8s-version@0.1.3": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", - "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-certs@0.4.1": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", - "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-operator-derive@0.3.1": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", - "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-operator@0.113.4": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", - "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-shared@0.1.2": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", - "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-telemetry@0.6.5": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", - "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-versioned-macros@0.11.1": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", - "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-versioned@0.11.1": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", - "git+https://github.com/stackabletech//operator-rs.git?branch=feat%2Fsmooth-operator%2Fbuild-rbac#stackable-webhook@0.9.2": "1ci8lal5q1i5jbjavlxknl6xvd6pjflk9n39mim47168rs046c6s", - "git+https://github.com/stackabletech/product-config.git?tag=0.8.0#product-config@0.8.0": "1dz70kapm2wdqcr7ndyjji0lhsl98bsq95gnb2lw487wf6yr7987" + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#k8s-version@0.1.3": "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#stackable-certs@0.4.1": "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#stackable-operator-derive@0.3.1": "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#stackable-operator@0.114.0": "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#stackable-shared@0.1.2": "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#stackable-telemetry@0.6.5": "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#stackable-versioned-macros@0.11.1": "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#stackable-versioned@0.11.1": "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.114.0#stackable-webhook@0.9.2": "1v6slybgc0xqsmh3bxyid6xjvmz8ps41nfmmc6csgyzqs2v0wzxj" } \ No newline at end of file diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 7ce7bc57..98c3bc66 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -63,7 +63,6 @@ async fn main() -> anyhow::Result<()> { Command::Run(RunArguments { operator_environment, watch_namespace, - product_config: _, maintenance, common, }) => { From 178fdad402ee555dcd7a60d8ec88b4a46f987929 Mon Sep 17 00:00:00 2001 From: Andrew Kenworthy Date: Wed, 22 Jul 2026 17:31:47 +0200 Subject: [PATCH 4/5] rename resource names functions --- rust/operator-binary/src/controller/build/mod.rs | 2 +- .../src/controller/build/resource/config_map.rs | 2 +- .../src/controller/build/resource/listener.rs | 4 ++-- .../src/controller/build/resource/rbac.rs | 4 ++-- .../src/controller/build/resource/service.rs | 4 ++-- .../src/controller/build/resource/statefulset.rs | 4 ++-- rust/operator-binary/src/controller/validate.rs | 15 ++++++++++++--- 7 files changed, 22 insertions(+), 13 deletions(-) diff --git a/rust/operator-binary/src/controller/build/mod.rs b/rust/operator-binary/src/controller/build/mod.rs index d545b435..03132fcf 100644 --- a/rust/operator-binary/src/controller/build/mod.rs +++ b/rust/operator-binary/src/controller/build/mod.rs @@ -27,7 +27,7 @@ stackable_operator::constant!(pub(crate) PLACEHOLDER_DISCOVERY_ROLE_GROUP: RoleG // Placeholder role-group name used for the recommended labels of the role-level `Listener` // (which is not tied to a single role group). -stackable_operator::constant!(pub(crate) PLACEHOLDER_LISTENER_ROLE_GROUP: RoleGroupName = "none"); +stackable_operator::constant!(pub(crate) NONE_ROLE_GROUP_NAME: RoleGroupName = "none"); pub mod authentication; pub mod graceful_shutdown; diff --git a/rust/operator-binary/src/controller/build/resource/config_map.rs b/rust/operator-binary/src/controller/build/resource/config_map.rs index ee8805e6..6e3c0357 100644 --- a/rust/operator-binary/src/controller/build/resource/config_map.rs +++ b/rust/operator-binary/src/controller/build/resource/config_map.rs @@ -151,7 +151,7 @@ pub fn build_rolegroup_config_map( role_group_name: &RoleGroupName, rg: &DruidRoleGroupConfig, ) -> Result { - let resource_names = cluster.resource_names(role, role_group_name); + let resource_names = cluster.role_group_resource_names(role, role_group_name); let cluster_config = &cluster.cluster_config; let druid_tls_security = &cluster_config.druid_tls_security; let druid_auth_config = &cluster_config.druid_auth_config; diff --git a/rust/operator-binary/src/controller/build/resource/listener.rs b/rust/operator-binary/src/controller/build/resource/listener.rs index a154cce6..78845d01 100644 --- a/rust/operator-binary/src/controller/build/resource/listener.rs +++ b/rust/operator-binary/src/controller/build/resource/listener.rs @@ -15,7 +15,7 @@ use stackable_operator::{ use crate::{ controller::{ - build::{PLACEHOLDER_LISTENER_ROLE_GROUP, security::listener_ports}, + build::{NONE_ROLE_GROUP_NAME, security::listener_ports}, validate::ValidatedCluster, }, crd::{ @@ -52,7 +52,7 @@ pub fn build_group_listener( .object_meta( listener_group_name.to_string(), druid_role, - &PLACEHOLDER_LISTENER_ROLE_GROUP, + &NONE_ROLE_GROUP_NAME, ) .build(), spec: listener::v1alpha1::ListenerSpec { diff --git a/rust/operator-binary/src/controller/build/resource/rbac.rs b/rust/operator-binary/src/controller/build/resource/rbac.rs index 4e89fdb7..77495b11 100644 --- a/rust/operator-binary/src/controller/build/resource/rbac.rs +++ b/rust/operator-binary/src/controller/build/resource/rbac.rs @@ -20,7 +20,7 @@ stackable_operator::constant!(NONE_ROLE_GROUP_NAME: RoleGroupName = "none"); pub fn build_service_account(cluster: &ValidatedCluster) -> ServiceAccount { rbac::build_service_account( cluster, - &cluster.rbac_resource_names(), + &cluster.cluster_resource_names(), rbac_labels(cluster), ) } @@ -30,7 +30,7 @@ pub fn build_service_account(cluster: &ValidatedCluster) -> ServiceAccount { pub fn build_role_binding(cluster: &ValidatedCluster) -> RoleBinding { rbac::build_role_binding( cluster, - &cluster.rbac_resource_names(), + &cluster.cluster_resource_names(), rbac_labels(cluster), ) } diff --git a/rust/operator-binary/src/controller/build/resource/service.rs b/rust/operator-binary/src/controller/build/resource/service.rs index eb914248..f8bfb5c9 100644 --- a/rust/operator-binary/src/controller/build/resource/service.rs +++ b/rust/operator-binary/src/controller/build/resource/service.rs @@ -22,7 +22,7 @@ pub fn build_rolegroup_headless_service( metadata: cluster .object_meta( cluster - .resource_names(druid_role, role_group_name) + .role_group_resource_names(druid_role, role_group_name) .headless_service_name() .to_string(), druid_role, @@ -59,7 +59,7 @@ pub fn build_rolegroup_metrics_service( metadata: cluster .object_meta( cluster - .resource_names(druid_role, role_group_name) + .role_group_resource_names(druid_role, role_group_name) .metrics_service_name() .to_string(), druid_role, diff --git a/rust/operator-binary/src/controller/build/resource/statefulset.rs b/rust/operator-binary/src/controller/build/resource/statefulset.rs index cbb0e46e..7c267d63 100644 --- a/rust/operator-binary/src/controller/build/resource/statefulset.rs +++ b/rust/operator-binary/src/controller/build/resource/statefulset.rs @@ -115,7 +115,7 @@ pub fn build_rolegroup_statefulset( rg: &DruidRoleGroupConfig, ) -> Result { let merged_rolegroup_config = &rg.config; - let resource_names = cluster.resource_names(role, role_group_name); + let resource_names = cluster.role_group_resource_names(role, role_group_name); // Everything below used to be threaded in as separate parameters; it all lives on the // `ValidatedCluster` now. let resolved_product_image = &cluster.image; @@ -319,7 +319,7 @@ pub fn build_rolegroup_statefulset( .metadata(metadata) .service_account_name( cluster - .rbac_resource_names() + .cluster_resource_names() .service_account_name() .to_string(), ) diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index d0296bb9..db975c51 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -281,7 +281,7 @@ impl ValidatedCluster { /// Type-safe names for the per-cluster RBAC resources: the ServiceAccount shared by all /// Pods, its (namespaced) RoleBinding, and the operator-deployed ClusterRole it binds. - pub fn rbac_resource_names(&self) -> role_utils::ResourceNames { + pub fn cluster_resource_names(&self) -> role_utils::ResourceNames { role_utils::ResourceNames { cluster_name: self.name.clone(), product_name: product_name(), @@ -289,7 +289,7 @@ impl ValidatedCluster { } /// Type-safe names for the resources of the given role's role group. - pub(crate) fn resource_names( + pub(crate) fn role_group_resource_names( &self, role: &DruidRole, role_group_name: &RoleGroupName, @@ -614,7 +614,7 @@ mod tests { use strum::IntoEnumIterator; use super::{ - Error, + Error, ValidatedCluster, test_support::{MINIMAL_DRUID_YAML, druid_from_yaml}, validate, }; @@ -718,4 +718,13 @@ mod tests { "expected a ClusterIdentity error when the cluster has no uid" ); } + + /// Locks the invariant behind the `expect` in [`ValidatedCluster::role_name`]: every + /// `DruidRole` variant (present and future) must serialise to a valid `RoleName`. + #[test] + fn every_druid_role_serialises_to_a_valid_role_name() { + for role in DruidRole::iter() { + ValidatedCluster::role_name(&role); + } + } } From 7132255ca9a66c02de107de0fa5a39859f735060 Mon Sep 17 00:00:00 2001 From: Andrew Kenworthy Date: Thu, 23 Jul 2026 17:24:53 +0200 Subject: [PATCH 5/5] review feedback --- .../src/controller/build/mod.rs | 4 +-- .../src/controller/build/resource/pdb.rs | 2 +- .../src/controller/validate.rs | 34 ++++++------------- rust/operator-binary/src/crd/mod.rs | 16 ++++++++- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/rust/operator-binary/src/controller/build/mod.rs b/rust/operator-binary/src/controller/build/mod.rs index 03132fcf..c690c507 100644 --- a/rust/operator-binary/src/controller/build/mod.rs +++ b/rust/operator-binary/src/controller/build/mod.rs @@ -54,8 +54,8 @@ pub enum Error { /// Builds the Kubernetes resources for the given validated cluster. /// /// Does not need a Kubernetes client: every reference to another Kubernetes resource is already -/// dereferenced and validated by this point. The remaining errors are resource-assembly failures -/// only. +/// dereferenced and validated by this point. +/// The remaining errors are resource-assembly failures only. /// /// `service_account_name` is the name of the RBAC `ServiceAccount` the role-group Pods run under /// (RBAC resources are built and applied separately, in the reconcile step). diff --git a/rust/operator-binary/src/controller/build/resource/pdb.rs b/rust/operator-binary/src/controller/build/resource/pdb.rs index 79bfd963..33ab8e9b 100644 --- a/rust/operator-binary/src/controller/build/resource/pdb.rs +++ b/rust/operator-binary/src/controller/build/resource/pdb.rs @@ -27,7 +27,7 @@ pub fn build_pdb( let pdb = pod_disruption_budget_builder_with_role( cluster, &product_name(), - &ValidatedCluster::role_name(role), + &role.into(), &operator_name(), &controller_name(), ) diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index db975c51..140a0512 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -197,12 +197,6 @@ impl ValidatedCluster { .expect("every DruidRole has a validated role config") } - /// The type-safe role name for a Druid role. - pub(crate) fn role_name(role: &DruidRole) -> RoleName { - RoleName::from_str(&role.to_string()) - .expect("a DruidRole always serializes to a valid role name") - } - fn recommended_labels_with( &self, product_version: &ProductVersion, @@ -232,7 +226,7 @@ impl ValidatedCluster { /// Recommended labels for a role-group resource. pub fn recommended_labels(&self, role: &DruidRole, role_group_name: &RoleGroupName) -> Labels { - self.recommended_labels_for(&Self::role_name(role), role_group_name) + self.recommended_labels_for(&role.into(), role_group_name) } /// Recommended labels with the constant [`UNVERSIONED_PRODUCT_VERSION`], for PVC templates @@ -242,21 +236,12 @@ impl ValidatedCluster { role: &DruidRole, role_group_name: &RoleGroupName, ) -> Labels { - self.recommended_labels_with( - &UNVERSIONED_PRODUCT_VERSION, - &Self::role_name(role), - role_group_name, - ) + self.recommended_labels_with(&UNVERSIONED_PRODUCT_VERSION, &role.into(), role_group_name) } /// Selector labels matching the pods of a role group. pub fn role_group_selector(&self, role: &DruidRole, role_group_name: &RoleGroupName) -> Labels { - role_group_selector( - self, - &product_name(), - &Self::role_name(role), - role_group_name, - ) + role_group_selector(self, &product_name(), &role.into(), role_group_name) } /// Returns an [`ObjectMetaBuilder`] pre-filled with the namespace, an owner reference back to @@ -296,7 +281,7 @@ impl ValidatedCluster { ) -> ResourceNames { ResourceNames { cluster_name: self.name.clone(), - role_name: Self::role_name(role), + role_name: role.into(), role_group_name: role_group_name.clone(), } } @@ -610,11 +595,11 @@ spec: #[cfg(test)] mod tests { - use stackable_operator::cli::OperatorEnvironmentOptions; + use stackable_operator::{cli::OperatorEnvironmentOptions, v2::types::operator::RoleName}; use strum::IntoEnumIterator; use super::{ - Error, ValidatedCluster, + Error, test_support::{MINIMAL_DRUID_YAML, druid_from_yaml}, validate, }; @@ -719,12 +704,13 @@ mod tests { ); } - /// Locks the invariant behind the `expect` in [`ValidatedCluster::role_name`]: every - /// `DruidRole` variant (present and future) must serialise to a valid `RoleName`. + /// Locks the invariant behind the `expect` in the `From for RoleName` impls: + /// every `DruidRole` variant (present and future) must serialise to a valid `RoleName`. #[test] fn every_druid_role_serialises_to_a_valid_role_name() { for role in DruidRole::iter() { - ValidatedCluster::role_name(&role); + let _: RoleName = (&role).into(); + let _: RoleName = role.into(); } } } diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index 2bacae3a..dbd2f360 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -46,7 +46,7 @@ use stackable_operator::{ types::{ common::Port, kubernetes::{ConfigMapName, ContainerName, ListenerClassName}, - operator::RoleGroupName, + operator::{RoleGroupName, RoleName}, }, }, versioned::versioned, @@ -630,6 +630,20 @@ pub enum DruidRole { Router, } +impl From for RoleName { + fn from(value: DruidRole) -> Self { + RoleName::from_str(&value.to_string()) + .expect("a DruidRole always serializes to a valid role name") + } +} + +impl From<&DruidRole> for RoleName { + fn from(value: &DruidRole) -> Self { + RoleName::from_str(&value.to_string()) + .expect("a DruidRole always serializes to a valid role name") + } +} + impl DruidRole { /// Returns the name of the internal druid process name associated with the role. /// These strings are used by druid internally to identify processes.