diff --git a/crates/stackable-certs/src/ca/mod.rs b/crates/stackable-certs/src/ca/mod.rs index c3bb57099..7f7160f09 100644 --- a/crates/stackable-certs/src/ca/mod.rs +++ b/crates/stackable-certs/src/ca/mod.rs @@ -247,7 +247,7 @@ where // // The root profile doesn't add the AuthorityKeyIdentifier extension. // We manually add it below by using the 160-bit SHA-1 hash of the - // subject pulic key. This conforms to one of the outlined methods for + // subject public key. This conforms to one of the outlined methods for // generating key identifiers outlined in RFC 5280, section 4.2.1.2. // // Prepare extensions so we can avoid clones. diff --git a/crates/stackable-webhook/CHANGELOG.md b/crates/stackable-webhook/CHANGELOG.md index e48c77b18..1265a2aa9 100644 --- a/crates/stackable-webhook/CHANGELOG.md +++ b/crates/stackable-webhook/CHANGELOG.md @@ -10,7 +10,12 @@ All notable changes to this project will be documented in this file. Both `WebhookServer::run` and `TlsServer::run` now require passing a shutdown signal, which is any `Future` ([#1144]). +### Changed + +- Improve certificate rotation instrumentation ([#1145]). + [#1144]: https://github.com/stackabletech/operator-rs/pull/1144 +[#1145]: https://github.com/stackabletech/operator-rs/pull/1145 ## [0.8.1] - 2026-01-07 diff --git a/crates/stackable-webhook/src/lib.rs b/crates/stackable-webhook/src/lib.rs index 00dfaba7c..4424d4a85 100644 --- a/crates/stackable-webhook/src/lib.rs +++ b/crates/stackable-webhook/src/lib.rs @@ -187,9 +187,21 @@ impl WebhookServer { // run associated function consumes self. This in turn means that when the receiver is // polled, it will return `Ok(Ready(None))`, which will cause this while loop to break // and the future to complete. - while let Some(cert) = cert_rx.recv().await { + while let Some(certificate) = cert_rx.recv().await { + // NOTE (@Techassi): There are currently NO semantic conventions for X509 certificates + // and as such, these are pretty much made up and potentially not ideal. + #[rustfmt::skip] + tracing::info!( + x509.not_before = certificate.tbs_certificate.validity.not_before.to_string(), + x509.not_after = certificate.tbs_certificate.validity.not_after.to_string(), + x509.serial_number = certificate.tbs_certificate.serial_number.to_string(), + x509.subject = certificate.tbs_certificate.subject.to_string(), + x509.issuer = certificate.tbs_certificate.issuer.to_string(), + "rotate certificate for registered webhooks" + ); + // The caBundle needs to be provided as a base64-encoded PEM envelope. - let ca_bundle = cert + let ca_bundle = certificate .to_pem(LineEnding::LF) .context(EncodeCertificateAuthorityAsPemSnafu)?; let ca_bundle = ByteString(ca_bundle.as_bytes().to_vec()); diff --git a/crates/stackable-webhook/src/webhooks/conversion_webhook.rs b/crates/stackable-webhook/src/webhooks/conversion_webhook.rs index f7870e41c..64cd58f2d 100644 --- a/crates/stackable-webhook/src/webhooks/conversion_webhook.rs +++ b/crates/stackable-webhook/src/webhooks/conversion_webhook.rs @@ -22,8 +22,7 @@ use snafu::{ResultExt, Snafu}; use tokio::sync::oneshot; use tracing::instrument; -use super::{Webhook, WebhookError}; -use crate::WebhookServerOptions; +use crate::{Webhook, WebhookError, WebhookServerOptions}; #[derive(Debug, Snafu)] pub enum ConversionWebhookError { @@ -138,7 +137,7 @@ impl ConversionWebhook { } #[instrument( - skip(self, crd, crd_api, new_ca_bundle), + skip(self, crd, crd_api, ca_bundle), fields( name = crd.name_any(), kind = &crd.spec.names.kind @@ -148,7 +147,7 @@ impl ConversionWebhook { &self, mut crd: CustomResourceDefinition, crd_api: &Api, - new_ca_bundle: &ByteString, + ca_bundle: ByteString, options: &WebhookServerOptions, ) -> Result<(), WebhookError> { let crd_kind = &crd.spec.names.kind; @@ -178,7 +177,7 @@ impl ConversionWebhook { port: Some(options.socket_addr.port().into()), }), // Here, ByteString takes care of encoding the provided content as base64. - ca_bundle: Some(new_ca_bundle.to_owned()), + ca_bundle: Some(ca_bundle), url: None, }), }), @@ -247,15 +246,15 @@ where self.options.disable_crd_maintenance } - #[instrument(skip(self, new_ca_bundle))] + #[instrument(skip(self, ca_bundle))] async fn handle_certificate_rotation( &mut self, - new_ca_bundle: &ByteString, + ca_bundle: &ByteString, options: &WebhookServerOptions, ) -> Result<(), WebhookError> { let crd_api: Api = Api::all(self.client.clone()); for (crd, _) in &self.crds_and_handlers { - self.reconcile_crd(crd.clone(), &crd_api, new_ca_bundle, options) + self.reconcile_crd(crd.clone(), &crd_api, ca_bundle.to_owned(), options) .await?; } diff --git a/crates/stackable-webhook/src/webhooks/mod.rs b/crates/stackable-webhook/src/webhooks/mod.rs index 23cbca7ef..ac165efac 100644 --- a/crates/stackable-webhook/src/webhooks/mod.rs +++ b/crates/stackable-webhook/src/webhooks/mod.rs @@ -48,7 +48,7 @@ pub trait Webhook { /// Webhooks are informed about new certificates by this function and can react accordingly. async fn handle_certificate_rotation( &mut self, - new_ca_bundle: &ByteString, + ca_bundle: &ByteString, options: &WebhookServerOptions, ) -> Result<(), WebhookError>; } diff --git a/crates/stackable-webhook/src/webhooks/mutating_webhook.rs b/crates/stackable-webhook/src/webhooks/mutating_webhook.rs index 67172fc80..9ff9192fd 100644 --- a/crates/stackable-webhook/src/webhooks/mutating_webhook.rs +++ b/crates/stackable-webhook/src/webhooks/mutating_webhook.rs @@ -12,8 +12,7 @@ use serde::{Serialize, de::DeserializeOwned}; use snafu::{ResultExt, Snafu}; use tracing::instrument; -use super::{Webhook, WebhookError}; -use crate::{WebhookServerOptions, webhooks::create_webhook_client_config}; +use crate::{Webhook, WebhookError, WebhookServerOptions, webhooks::create_webhook_client_config}; #[derive(Debug, Snafu)] pub enum MutatingWebhookError { @@ -209,14 +208,15 @@ where self.options.disable_mwc_maintenance } - #[instrument(skip(self, new_ca_bundle))] + #[instrument(skip(self, ca_bundle))] async fn handle_certificate_rotation( &mut self, - new_ca_bundle: &ByteString, + ca_bundle: &ByteString, options: &WebhookServerOptions, ) -> Result<(), WebhookError> { let mut mutating_webhook_configuration = self.mutating_webhook_configuration.clone(); let mwc_name = mutating_webhook_configuration.name_any(); + tracing::info!( k8s.mutatingwebhookconfiguration.name = mwc_name, "reconciling mutating webhook configurations" @@ -225,7 +225,7 @@ where for webhook in mutating_webhook_configuration.webhooks.iter_mut().flatten() { // We know how we can be called (and with what certificate), so we can always set that webhook.client_config = - create_webhook_client_config(options, new_ca_bundle.to_owned(), self.http_path()); + create_webhook_client_config(options, ca_bundle.to_owned(), self.http_path()); } let mwc_api: Api = Api::all(self.client.clone());