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 = "ErgoNetwork", namespaced, status = "ErgoNetworkStatus", shortname = "ergo", printcolumn = r#"{"name":"Hostname", "type":"string", "jsonPath":".spec.hostname"}"#, printcolumn = r#"{"name":"Network", "type":"string", "jsonPath":".spec.networkName"}"#, printcolumn = r#"{"name":"Ready", "type":"string", "jsonPath":".status.conditions[?(@.type==\"Ready\")].status"}"# )] pub struct ErgoNetworkSpec { pub hostname: String, #[serde(default, rename = "networkName")] pub network_name: Option, #[serde(default, rename = "operCredentials")] pub oper_credentials: Option, #[serde(default)] pub listeners: Vec, #[serde(default)] pub tls: Option, #[serde(default)] pub route: Option, #[serde(default)] pub resources: Option, #[serde(default)] pub storage: Option, #[serde(default)] pub oauth2: Option, #[serde(default)] pub cloaking: Option, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct OperCredentials { #[serde(rename = "secretName")] pub secret_name: String, } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct StorageSpec { #[serde(default = "default_storage_size")] pub size: String, #[serde(default, rename = "storageClassName")] pub storage_class_name: Option, } fn default_storage_size() -> String { "1Gi".to_string() } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct Listener { pub address: String, #[serde(default)] pub tls: 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 OAuth2Spec { pub introspection_url: String, pub secret_ref: String, #[serde(default = "default_true")] pub autocreate: bool, } fn default_true() -> bool { true } #[derive(Serialize, Deserialize, Default, Debug, Clone, JsonSchema)] pub struct CloakingSpec { pub netname: 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 ErgoNetworkStatus { #[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 = ErgoNetwork::crd(); let name = crd.metadata.name.unwrap(); assert_eq!(name, "ergonetworks.irc.josie.cloud"); } #[test] fn default_spec_has_sane_values() { let spec = ErgoNetworkSpec::default(); assert!(spec.listeners.is_empty()); assert!(spec.tls.is_none()); assert!(spec.route.is_none()); assert!(spec.resources.is_none()); assert!(spec.storage.is_none()); assert!(spec.oper_credentials.is_none()); assert!(spec.network_name.is_none()); } #[test] fn default_spec_has_no_oauth2() { let spec = ErgoNetworkSpec::default(); assert!(spec.oauth2.is_none()); } }