use kube::CustomResource; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #[derive(CustomResource, Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] #[kube( group = "irc.josie.cloud", version = "v1alpha1", kind = "SojuBouncer", namespaced, status = "SojuBouncerStatus", shortname = "soju", printcolumn = r#"{"name":"Hostname", "type":"string", "jsonPath":".spec.hostname"}"#, printcolumn = r#"{"name":"Ready", "type":"string", "jsonPath":".status.conditions[?(@.type==\"Ready\")].status"}"# )] pub struct SojuBouncerSpec { pub hostname: String, #[serde(default)] pub hostname_cloak: Option, #[serde(default)] pub title: Option, #[serde(default)] pub listeners: Vec, #[serde(default)] pub tls: Option, #[serde(default)] pub route: Option, #[serde(default)] pub resources: Option, #[serde(default)] pub auth: Option, } #[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)] pub struct AuthSpec { pub oauth2_url: String, #[serde(default)] pub secret_ref: Option, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct Listener { pub address: String, #[serde(default)] pub tls: bool, #[serde(default)] pub websocket: bool, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct TlsSpec { pub issuer_ref: IssuerRef, pub dns_names: Vec, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct IssuerRef { pub name: String, pub kind: String, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct RouteSpec { pub host: String, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct ResourceRequirements { #[serde(default)] pub requests: Option, #[serde(default)] pub limits: Option, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct ResourceList { #[serde(default)] pub memory: Option, #[serde(default)] pub cpu: Option, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct SojuBouncerStatus { #[serde(default)] pub conditions: Vec, #[serde(default)] pub observed_generation: Option, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct Condition { #[serde(rename = "type")] pub type_: String, pub status: String, pub reason: String, pub message: String, pub last_transition_time: String, } #[cfg(test)] mod tests { use super::*; use kube::CustomResourceExt; #[test] fn crd_generates_valid_schema() { let crd = SojuBouncer::crd(); let name = crd.metadata.name.unwrap(); assert_eq!(name, "sojubouncers.irc.josie.cloud"); } #[test] fn default_spec_has_sane_values() { let spec = SojuBouncerSpec::default(); assert!(spec.listeners.is_empty()); assert!(spec.tls.is_none()); assert!(spec.route.is_none()); assert!(spec.resources.is_none()); } }