Skip to content

Commit d0bcb3b

Browse files
committed
feat: Add conversion webhook
1 parent 7633210 commit d0bcb3b

9 files changed

Lines changed: 2281 additions & 127 deletions

File tree

Cargo.lock

Lines changed: 466 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.nix

Lines changed: 1721 additions & 87 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ edition = "2024"
1010
repository = "https://github.com/stackabletech/opensearch-operator"
1111

1212
[workspace.dependencies]
13-
stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.105.0", features = ["telemetry", "versioned"] }
13+
stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.105.0", features = ["telemetry", "versioned", "webhook"] }
1414

1515
built = { version = "0.8.0", features = ["chrono", "git2"] }
1616
clap = "4.5"

Tiltfile

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@ custom_build(
1717
outputs_image_ref_to='result/ref',
1818
)
1919

20-
# Load the latest CRDs from Nix
21-
watch_file('result')
22-
if os.path.exists('result'):
23-
k8s_yaml('result/crds.yaml')
24-
2520
# We need to set the correct image annotation on the operator Deployment to use e.g.
2621
# oci.stackable.tech/sandbox/opa-operator:7y19m3d8clwxlv34v5q2x4p7v536s00g instead of
2722
# oci.stackable.tech/sandbox/opa-operator:0.0.0-dev (which does not exist)
@@ -35,18 +30,12 @@ helm_values = settings.get('helm_values', None)
3530

3631
helm_override_image_repository = 'image.repository=' + registry + '/' + operator_name
3732

38-
# Exclude stale CRDs from Helm chart, and apply the rest
39-
helm_crds, helm_non_crds = filter_yaml(
40-
helm(
41-
'deploy/helm/' + operator_name,
42-
name=operator_name,
43-
namespace="stackable-operators",
44-
set=[
45-
helm_override_image_repository,
46-
],
47-
values=helm_values,
48-
),
49-
api_version = "^apiextensions\\.k8s\\.io/.*$",
50-
kind = "^CustomResourceDefinition$",
51-
)
52-
k8s_yaml(helm_non_crds)
33+
k8s_yaml(helm(
34+
'deploy/helm/' + operator_name,
35+
name=operator_name,
36+
namespace="stackable-operators",
37+
set=[
38+
helm_override_image_repository,
39+
],
40+
values=helm_values,
41+
))

crate-hashes.json

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/operator-binary/src/controller.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub const HTTP_PORT_NAME: &str = "http";
5757
pub const HTTP_PORT: Port = Port(9200);
5858
pub const TRANSPORT_PORT_NAME: &str = "transport";
5959
pub const TRANSPORT_PORT: Port = Port(9300);
60+
pub const FIELD_MANAGER: &str = "opensearch-operator";
6061

6162
/// Names in the controller context which are passed to the submodules of the controller
6263
///

rust/operator-binary/src/main.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use strum::{EnumDiscriminants, IntoStaticStr};
3434
mod controller;
3535
mod crd;
3636
mod framework;
37+
mod webhooks;
3738

3839
mod built_info {
3940
include!(concat!(env!("OUT_DIR"), "/built.rs"));
@@ -74,6 +75,18 @@ pub enum Error {
7475
CreateSignalWatcher {
7576
source: stackable_operator::utils::signal::SignalError,
7677
},
78+
79+
#[snafu(display("failed to create webhook server"))]
80+
CreateWebhook { source: webhooks::conversion::Error },
81+
82+
// No context selector is being generated here so that we can run the webhook
83+
// as is, without the need to map the error to this variant. The ? operator
84+
// used after the futures::try_join function automatically converts the
85+
// underlying error to this variant.
86+
#[snafu(display("failed to run webhook server"), context(false))]
87+
RunWebhook {
88+
source: stackable_operator::webhook::WebhookServerError,
89+
},
7790
}
7891

7992
#[derive(clap::Parser)]
@@ -95,7 +108,7 @@ async fn main() -> Result<()> {
95108
.context(SerializeCrdSnafu)?;
96109
}
97110
Command::Run(RunArguments {
98-
operator_environment: _,
111+
operator_environment,
99112
product_config: _,
100113
watch_namespace,
101114
maintenance,
@@ -135,6 +148,16 @@ async fn main() -> Result<()> {
135148
.await
136149
.context(CreateClientSnafu)?;
137150

151+
let webhook_server = webhooks::conversion::create_webhook_server(
152+
&operator_environment,
153+
maintenance.disable_crd_maintenance,
154+
client.as_kube_client(),
155+
)
156+
.await
157+
.context(CreateWebhookSnafu)?;
158+
159+
let webhook_server = webhook_server.run(sigterm_watcher.handle());
160+
138161
let controller_context = controller::Context::new(client.clone(), operator_name);
139162
let full_controller_name = controller_context.full_controller_name();
140163

@@ -203,7 +226,7 @@ async fn main() -> Result<()> {
203226
)
204227
.map(Ok);
205228

206-
futures::try_join!(controller, eos_checker)?;
229+
futures::try_join!(controller, eos_checker, webhook_server)?;
207230
}
208231
}
209232

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use snafu::{ResultExt, Snafu};
2+
use stackable_operator::{
3+
cli::OperatorEnvironmentOptions,
4+
kube::{Client, core::crd::MergeError},
5+
webhook::{
6+
WebhookServer, WebhookServerError, WebhookServerOptions,
7+
webhooks::{ConversionWebhook, ConversionWebhookOptions},
8+
},
9+
};
10+
11+
use crate::{
12+
controller::FIELD_MANAGER,
13+
crd::{OpenSearchCluster, OpenSearchClusterVersion},
14+
};
15+
16+
/// Contains errors which can be encountered when creating the conversion webhook server and the
17+
/// CRD maintainer.
18+
#[derive(Debug, Snafu)]
19+
pub enum Error {
20+
#[snafu(display("failed to merge CRD"))]
21+
MergeCrd { source: MergeError },
22+
23+
#[snafu(display("failed to create conversion webhook server"))]
24+
CreateWebhook { source: WebhookServerError },
25+
}
26+
27+
/// Creates and returns a [`WebhookServer`].
28+
pub async fn create_webhook_server(
29+
operator_environment: &OperatorEnvironmentOptions,
30+
disable_crd_maintenance: bool,
31+
client: Client,
32+
) -> Result<WebhookServer, Error> {
33+
let crds_and_handlers = vec![(
34+
OpenSearchCluster::merged_crd(OpenSearchClusterVersion::V1Alpha1).context(MergeCrdSnafu)?,
35+
OpenSearchCluster::try_convert,
36+
)];
37+
38+
let conversion_webhook_options = ConversionWebhookOptions {
39+
disable_crd_maintenance,
40+
field_manager: FIELD_MANAGER.to_owned(),
41+
};
42+
43+
let (conversion_webhook, _initial_reconcile_rx) =
44+
ConversionWebhook::new(crds_and_handlers, client, conversion_webhook_options);
45+
46+
let webhook_server_options = WebhookServerOptions {
47+
socket_addr: WebhookServer::DEFAULT_SOCKET_ADDRESS,
48+
webhook_namespace: operator_environment.operator_namespace.to_owned(),
49+
webhook_service_name: operator_environment.operator_service_name.to_owned(),
50+
};
51+
52+
WebhookServer::new(vec![Box::new(conversion_webhook)], webhook_server_options)
53+
.await
54+
.context(CreateWebhookSnafu)
55+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod conversion;

0 commit comments

Comments
 (0)