Skip to content

Commit

Permalink
feat: Add support for enabling observability via WasmCloudHostConfig
Browse files Browse the repository at this point in the history
  • Loading branch information
joonas committed Jun 30, 2024
1 parent 7dcb409 commit 8110957
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wasmcloud-operator-types"
version = "0.1.5"
version = "0.1.6"
edition = "2021"

[dependencies]
Expand Down
41 changes: 41 additions & 0 deletions crates/types/src/v1alpha1/wasmcloud_host_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ pub struct WasmCloudHostConfigSpec {
pub policy_service: Option<PolicyService>,
/// Kubernetes scheduling options for the wasmCloud host.
pub scheduling_options: Option<KubernetesSchedulingOptions>,
/// Observability options for configuring the OpenTelemetry integration
pub observability: Option<ObservabilityConfiguration>,
}

#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
Expand All @@ -101,6 +103,45 @@ pub struct KubernetesSchedulingOptions {
pub pod_template_additions: Option<PodSpec>,
}

#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct ObservabilityConfiguration {
#[serde(default)]
pub enable: bool,
pub endpoint: String,
pub protocol: Option<OtelProtocol>,
pub logs: Option<OtelSignalConfiguration>,
pub metrics: Option<OtelSignalConfiguration>,
pub traces: Option<OtelSignalConfiguration>,
}

#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub enum OtelProtocol {
Grpc,
Http,
}

impl std::fmt::Display for OtelProtocol {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
OtelProtocol::Grpc => "grpc",
OtelProtocol::Http => "http",
}
)
}
}

#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct OtelSignalConfiguration {
pub enable: Option<bool>,
pub endpoint: Option<String>,
}

/// This is a workaround for the fact that we can't override the PodSpec schema to make containers
/// an optional field. It generates the OpenAPI schema for the PodSpec type the same way that
/// kube.rs does while dropping any required fields.
Expand Down
51 changes: 50 additions & 1 deletion src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use std::sync::Arc;
use tokio::{sync::RwLock, time::Duration};
use tracing::{debug, info, warn};
use wasmcloud_operator_types::v1alpha1::{
AppStatus, WasmCloudHostConfig, WasmCloudHostConfigStatus,
AppStatus, WasmCloudHostConfig, WasmCloudHostConfigSpec, WasmCloudHostConfigStatus,
};

pub static CLUSTER_CONFIG_FINALIZER: &str = "operator.k8s.wasmcloud.dev/wasmcloud-host-config";
Expand Down Expand Up @@ -396,6 +396,8 @@ fn pod_template(config: &WasmCloudHostConfig, _ctx: Arc<Context>) -> PodTemplate
}
}

let wasmcloud_args = configure_observability(&config.spec);

let mut nats_resources: Option<k8s_openapi::api::core::v1::ResourceRequirements> = None;
let mut wasmcloud_resources: Option<k8s_openapi::api::core::v1::ResourceRequirements> = None;
if let Some(scheduling_options) = &config.spec.scheduling_options {
Expand Down Expand Up @@ -461,6 +463,8 @@ fn pod_template(config: &WasmCloudHostConfig, _ctx: Arc<Context>) -> PodTemplate
Container {
name: "wasmcloud-host".to_string(),
image: Some(image),
command: Some(vec!["wasmcloud".to_string()]),
args: Some(wasmcloud_args),
env: Some(wasmcloud_env),
resources: wasmcloud_resources,
..Default::default()
Expand Down Expand Up @@ -531,6 +535,51 @@ fn pod_template(config: &WasmCloudHostConfig, _ctx: Arc<Context>) -> PodTemplate
template
}

fn configure_observability(spec: &WasmCloudHostConfigSpec) -> Vec<String> {
let mut args = Vec::<String>::new();
if let Some(observability) = &spec.observability {
if observability.enable {
args.push("--enable-observability".to_string());
}
if !observability.endpoint.is_empty() {
args.push("--override-observability-endpoint".to_string());
args.push(observability.endpoint.clone());
}
if let Some(protocol) = &observability.protocol {
args.push("--observability-protocol".to_string());
args.push(protocol.to_string());
}
if let Some(traces) = &observability.traces {
if traces.enable.unwrap_or(false) {
args.push("--enable-traces".to_string())
}
if let Some(traces_endpoint) = &traces.endpoint {
args.push("--override-traces-endpoint".to_string());
args.push(traces_endpoint.to_owned());
}
}
if let Some(metrics) = &observability.metrics {
if metrics.enable.unwrap_or(false) {
args.push("--enable-metrics".to_string())
}
if let Some(metrics_endpoint) = &metrics.endpoint {
args.push("--override-metrics-endpoint".to_string());
args.push(metrics_endpoint.to_owned());
}
}
if let Some(logs) = &observability.logs {
if logs.enable.unwrap_or(false) {
args.push("--enable-logs".to_string())
}
if let Some(logs_endpoint) = &logs.endpoint {
args.push("--override-logs-endpoint".to_string());
args.push(logs_endpoint.to_owned());
}
}
}
args
}

fn deployment_spec(config: &WasmCloudHostConfig, ctx: Arc<Context>) -> DeploymentSpec {
let pod_template = pod_template(config, ctx);
let ls = LabelSelector {
Expand Down

0 comments on commit 8110957

Please sign in to comment.