Skip to content

Commit 48f8aad

Browse files
sbernauerTechassi
andauthored
feat!: Add a new CLI flag/env to disabling CRD maintenance (#1085)
* feat!: Add a new CLI flag/env to disabling CRD maintenance * changelog * Update docs * Update crates/stackable-operator/src/cli.rs Co-authored-by: Techassi <git@techassi.dev> * Update crates/stackable-webhook/src/servers/conversion.rs Co-authored-by: Techassi <git@techassi.dev> * collapse ifs * Move maintain_crds into ConversionWebhookOptions * Update crates/stackable-webhook/CHANGELOG.md Co-authored-by: Techassi <git@techassi.dev> --------- Co-authored-by: Techassi <git@techassi.dev>
1 parent 89f484c commit 48f8aad

File tree

4 files changed

+65
-23
lines changed

4 files changed

+65
-23
lines changed

crates/stackable-operator/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Added
8+
9+
- BREAKING: Add a new CLI flag/env to disabling CRD maintenance: `--disable-crd-maintenance` ([#1085]).
10+
11+
[#1085]: https://github.com/stackabletech/operator-rs/pull/1085
12+
713
## [0.96.0] - 2025-08-25
814

915
### Added

crates/stackable-operator/src/cli.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ pub enum Command<Run: Args = ProductOperatorRun> {
208208
/// operator_namespace: "stackable-operators".to_string(),
209209
/// operator_service_name: "foo-operator".to_string(),
210210
/// },
211+
/// disable_crd_maintenance: false,
211212
/// },
212213
/// }));
213214
/// ```
@@ -245,6 +246,17 @@ pub struct ProductOperatorRun {
245246
/// Provides a specific namespace to watch (instead of watching all namespaces)
246247
#[arg(long, env, default_value = "")]
247248
pub watch_namespace: WatchNamespace,
249+
250+
/// Don't maintain the CustomResourceDefinitions (CRDs) the operator is responsible for.
251+
///
252+
/// Maintenance includes creating the CRD initially, adding new versions and keeping the TLS
253+
/// certificate of webhooks up to date. Turning this off can be desirable to reduce the RBAC
254+
/// permissions of the operator.
255+
///
256+
/// WARNING: If you disable CRD maintenance you are responsible for maintaining it, including,
257+
/// but not limited to, the points above.
258+
#[arg(long, env)]
259+
pub disable_crd_maintenance: bool,
248260
}
249261

250262
/// All the CLI arguments that all (or at least most) Stackable applications use.

crates/stackable-webhook/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Added
8+
9+
- BREAKING: Support disabling CRD maintenance using a new boolean flag in `ConversionWebhookOptions` ([#1085]).
10+
11+
[#1085]: https://github.com/stackabletech/operator-rs/pull/1085
12+
713
## [0.5.0] - 2025-08-21
814

915
### Changed

crates/stackable-webhook/src/servers/conversion.rs

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ pub struct ConversionWebhookOptions {
7878
/// The name of the Kubernetes service which points to the operator/webhook.
7979
pub service_name: String,
8080

81+
/// If the CRDs should be maintained automatically. Use the (negated) value from
82+
/// `stackable_operator::cli::ProductOperatorRun::disable_crd_maintenance`
83+
/// for this.
84+
// # Because of https://github.com/rust-lang/cargo/issues/3475 we can not use a real link here
85+
pub maintain_crds: bool,
86+
8187
/// The field manager used to apply Kubernetes objects, typically the operator name, e.g.
8288
/// `airflow-operator`.
8389
pub field_manager: String,
@@ -97,11 +103,12 @@ impl ConversionWebhookServer {
97103
/// Creates a new conversion webhook server, which expects POST requests being made to the
98104
/// `/convert/{crd name}` endpoint.
99105
///
100-
/// You need to provide two things for every CRD passed in via the `crds_and_handlers` argument:
106+
/// You need to provide a few things for every CRD passed in via the `crds_and_handlers` argument:
101107
///
102108
/// 1. The CRD
103109
/// 2. A conversion function to convert between CRD versions. Typically you would use the
104-
/// the auto-generated `try_convert` function on CRD spec definition structs for this.
110+
/// the auto-generated `try_convert` function on CRD spec definition structs for this.
111+
/// 3. A [`kube::Client`] used to create/update the CRDs.
105112
///
106113
/// The [`ConversionWebhookServer`] takes care of reconciling the CRDs into the Kubernetes
107114
/// cluster and takes care of adding itself as conversion webhook. This includes TLS
@@ -119,14 +126,18 @@ impl ConversionWebhookServer {
119126
/// use stackable_operator::{
120127
/// kube::Client,
121128
/// crd::s3::{S3Connection, S3ConnectionVersion},
122-
/// cli::OperatorEnvironmentOptions,
129+
/// cli::ProductOperatorRun,
123130
/// };
124131
///
125132
/// # async fn test() {
126133
/// // Things that should already be in you operator:
127134
/// const OPERATOR_NAME: &str = "product-operator";
128135
/// let client = Client::try_default().await.expect("failed to create Kubernetes client");
129-
/// let operator_environment = OperatorEnvironmentOptions::parse();
136+
/// let ProductOperatorRun {
137+
/// operator_environment,
138+
/// disable_crd_maintenance,
139+
/// ..
140+
/// } = ProductOperatorRun::parse();
130141
///
131142
/// let crds_and_handlers = [
132143
/// (
@@ -140,9 +151,10 @@ impl ConversionWebhookServer {
140151
/// socket_addr: format!("0.0.0.0:{CONVERSION_WEBHOOK_HTTPS_PORT}")
141152
/// .parse()
142153
/// .expect("static address is always valid"),
143-
/// field_manager: OPERATOR_NAME.to_owned(),
144154
/// namespace: operator_environment.operator_namespace,
145155
/// service_name: operator_environment.operator_service_name,
156+
/// maintain_crds: !disable_crd_maintenance,
157+
/// field_manager: OPERATOR_NAME.to_owned(),
146158
/// };
147159
///
148160
/// // Construct the conversion webhook server
@@ -205,9 +217,10 @@ impl ConversionWebhookServer {
205217

206218
let ConversionWebhookOptions {
207219
socket_addr,
208-
field_manager,
209220
namespace: operator_namespace,
210221
service_name: operator_service_name,
222+
maintain_crds,
223+
field_manager,
211224
} = &options;
212225

213226
// This is how Kubernetes calls us, so it decides about the naming.
@@ -233,28 +246,33 @@ impl ConversionWebhookServer {
233246
.recv()
234247
.await
235248
.context(ReceiveCertificateFromChannelSnafu)?;
236-
Self::reconcile_crds(
237-
&client,
238-
field_manager,
239-
&crds,
240-
operator_namespace,
241-
operator_service_name,
242-
current_cert,
243-
)
244-
.await
245-
.context(ReconcileCrdsSnafu)?;
246-
247-
try_join!(
248-
Self::run_webhook_server(server),
249-
Self::run_crd_reconciliation_loop(
250-
cert_rx,
249+
250+
if *maintain_crds {
251+
Self::reconcile_crds(
251252
&client,
252253
field_manager,
253254
&crds,
254255
operator_namespace,
255256
operator_service_name,
256-
),
257-
)?;
257+
current_cert,
258+
)
259+
.await
260+
.context(ReconcileCrdsSnafu)?;
261+
262+
try_join!(
263+
Self::run_webhook_server(server),
264+
Self::run_crd_reconciliation_loop(
265+
cert_rx,
266+
&client,
267+
field_manager,
268+
&crds,
269+
operator_namespace,
270+
operator_service_name,
271+
),
272+
)?;
273+
} else {
274+
Self::run_webhook_server(server).await?;
275+
};
258276

259277
Ok(())
260278
}

0 commit comments

Comments
 (0)