Implementing Kubernetes webhooks
Creating a new binary crate
Webhook servers are developed and deployed alongside the product operators.
This can be achieved by creating a new binary crate in the same repository, and adding it to the workspace.
In newer versions of cargo
the new workspace member is automatically added to the root Cargo.toml
file.
Follow along through the creation of such a binary, using the Airflow operator as an example.
Start by entering the airflow-operator
repository and creating a new binary crate using cargo
.
git clone https://github.com/stackabletech/airflow-operator.git
cd airflow-operator
cargo new rust/webhook-binary
Running this command created and adjusted multiple files.
The root Cargo.toml
file gained another workspace member and a new folder rust/webhook-binary
with default files was created.
Next, add stackable-webhook
and tokio
as dependencies.
All dependencies below used the latest version at the time of writing. Make sure to use the current latest version when following this guide. |
The root Cargo.toml
[workspace]
members = ["rust/crd", "rust/operator-binary", "rust/webhook-binary"]
resolver = "2"
[workspace.package]
version = "0.0.0-dev"
repository = "https://github.com/stackabletech/airflow-operator"
# ...
[workspace.dependencies]
stackable-webhook = { git = "https://github.com/stackabletech/operator-rs.git" }
tokio = { version = "1.29", features = ["full"] }
The new webhook crate’s Cargo.toml
[package]
name = "webhook-binary"
version.workspace = true
repository.workspace = true
# ...
[dependencies]
stackable-webhook.workspace = true
tokio.workspace = true
Before continuing, run cargo build
to ensure your development environment is configured correctly.
Now you are ready to write a custom webhook server.
Conversion webhook
In this example, you will develop a CRD conversion webhook.
The stackable-webhook
library provides a ready-to-use ConversionWebhookServer
, which already handles receiving and responding with the correct type.
The |
use stackable_webhook::{
servers::{ConversionReview, ConversionWebhookServer},
Options,
};
#[tokio::main]
async fn main() {
let server = ConversionWebhookServer::new(handler, Options::default());
server.run().await.unwrap()
}
fn handler(request: ConversionReview) -> ConversionReview {
// Add you CRD conversion here
todo!()
}
Mutating and validating webhooks
The stackable-webhook
library currently doesn’t provide ready-to-use webhook servers for mutating or validating webhooks like ConversionWebhookServer
above.
Instead, you can implement a completly custom Router
via the axum
crate.
use axum::{routing::post, Router};
use stackable_webhook::{Options, WebhookServer};
#[tokio::main]
async fn main() {
let router = Router::new()
.route("mutate", post(mutate))
.route("validate", post(validate));
let server = WebhookServer::new(router, Options::default());
server.run().await.unwrap();
}
async fn mutate() {}
async fn validate() {}