diff --git a/harmony/src/modules/cert_manager/crd/certificate.rs b/harmony/src/modules/cert_manager/crd/certificate.rs new file mode 100644 index 0000000..7c0866b --- /dev/null +++ b/harmony/src/modules/cert_manager/crd/certificate.rs @@ -0,0 +1,113 @@ +use kube::{CustomResource, api::ObjectMeta}; +use serde::{Deserialize, Serialize}; + +#[derive(CustomResource, Deserialize, Serialize, Clone, Debug)] +#[kube( + group = "cert-manager.io", + version = "v1", + kind = "Certificate", + plural = "certificates", + namespaced = true, + schema = "disabled" +)] +#[serde(rename_all = "camelCase")] +pub struct CertificateSpec { + /// Name of the Secret where the certificate will be stored + pub secret_name: String, + + /// Common Name (optional but often discouraged in favor of SANs) + #[serde(skip_serializing_if = "Option::is_none")] + pub common_name: Option, + + /// DNS Subject Alternative Names + #[serde(skip_serializing_if = "Option::is_none")] + pub dns_names: Option>, + + /// IP Subject Alternative Names + #[serde(skip_serializing_if = "Option::is_none")] + pub ip_addresses: Option>, + + /// Certificate duration (e.g. "2160h") + #[serde(skip_serializing_if = "Option::is_none")] + pub duration: Option, + + /// How long before expiry cert-manager should renew + #[serde(skip_serializing_if = "Option::is_none")] + pub renew_before: Option, + + /// Reference to the Issuer or ClusterIssuer + pub issuer_ref: IssuerRef, + + /// Is this a CA certificate + #[serde(skip_serializing_if = "Option::is_none")] + pub is_ca: Option, + + /// Private key configuration + #[serde(skip_serializing_if = "Option::is_none")] + pub private_key: Option, +} + +impl Default for Certificate { + fn default() -> Self { + Certificate { + metadata: ObjectMeta::default(), + spec: CertificateSpec::default(), + } + } +} + +impl Default for CertificateSpec { + fn default() -> Self { + Self { + secret_name: String::new(), + common_name: None, + dns_names: None, + ip_addresses: None, + duration: None, + renew_before: None, + issuer_ref: IssuerRef::default(), + is_ca: None, + private_key: None, + } + } +} + +#[derive(Deserialize, Serialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct IssuerRef { + pub name: String, + + /// Either "Issuer" or "ClusterIssuer" + #[serde(skip_serializing_if = "Option::is_none")] + pub kind: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub group: Option, +} + +impl Default for IssuerRef { + fn default() -> Self { + Self { + name: String::new(), + kind: None, + group: None, + } + } +} + +#[derive(Deserialize, Serialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PrivateKey { + /// RSA or ECDSA + #[serde(skip_serializing_if = "Option::is_none")] + pub algorithm: Option, + + /// Key size (e.g. 2048, 4096) + #[serde(skip_serializing_if = "Option::is_none")] + pub size: Option, + + /// Rotation policy: "Never" or "Always" + #[serde(skip_serializing_if = "Option::is_none")] + pub rotation_policy: Option, +} + diff --git a/harmony/src/modules/cert_manager/crd/cluster_issuer.rs b/harmony/src/modules/cert_manager/crd/cluster_issuer.rs new file mode 100644 index 0000000..4939548 --- /dev/null +++ b/harmony/src/modules/cert_manager/crd/cluster_issuer.rs @@ -0,0 +1,45 @@ +use kube::{CustomResource, api::ObjectMeta}; +use serde::{Deserialize, Serialize}; + +use crate::modules::cert_manager::crd::{AcmeIssuer, CaIssuer, SelfSignedIssuer}; + +#[derive(CustomResource, Deserialize, Serialize, Clone, Debug)] +#[kube( + group = "cert-manager.io", + version = "v1", + kind = "ClusterIssuer", + plural = "clusterissuers", + namespaced = false, + schema = "disabled" +)] +#[serde(rename_all = "camelCase")] +pub struct ClusterIssuerSpec { + #[serde(skip_serializing_if = "Option::is_none")] + pub self_signed: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub ca: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub acme: Option, +} + +impl Default for ClusterIssuer { + fn default() -> Self { + ClusterIssuer { + metadata: ObjectMeta::default(), + spec: ClusterIssuerSpec::default(), + } + } +} + +impl Default for ClusterIssuerSpec { + fn default() -> Self { + Self { + self_signed: None, + ca: None, + acme: None, + } + } +} + diff --git a/harmony/src/modules/cert_manager/crd/issuer.rs b/harmony/src/modules/cert_manager/crd/issuer.rs new file mode 100644 index 0000000..e4d57d3 --- /dev/null +++ b/harmony/src/modules/cert_manager/crd/issuer.rs @@ -0,0 +1,44 @@ +use kube::{CustomResource, api::ObjectMeta}; +use serde::{Deserialize, Serialize}; + +use crate::modules::cert_manager::crd::{AcmeIssuer, CaIssuer, SelfSignedIssuer}; + +#[derive(CustomResource, Deserialize, Serialize, Clone, Debug)] +#[kube( + group = "cert-manager.io", + version = "v1", + kind = "Issuer", + plural = "issuers", + namespaced = true, + schema = "disabled" +)] +#[serde(rename_all = "camelCase")] +pub struct IssuerSpec { + #[serde(skip_serializing_if = "Option::is_none")] + pub self_signed: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub ca: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub acme: Option, +} + +impl Default for Issuer { + fn default() -> Self { + Issuer { + metadata: ObjectMeta::default(), + spec: IssuerSpec::default(), + } + } +} + +impl Default for IssuerSpec { + fn default() -> Self { + Self { + self_signed: None, + ca: None, + acme: None, + } + } +} diff --git a/harmony/src/modules/cert_manager/crd/mod.rs b/harmony/src/modules/cert_manager/crd/mod.rs new file mode 100644 index 0000000..c9050b7 --- /dev/null +++ b/harmony/src/modules/cert_manager/crd/mod.rs @@ -0,0 +1,63 @@ +use serde::{Deserialize, Serialize}; + + +pub mod certificate; +pub mod issuer; +pub mod cluster_issuer; + +#[derive(Deserialize, Serialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct CaIssuer { + /// Secret containing `tls.crt` and `tls.key` + pub secret_name: String, +} + +#[derive(Deserialize, Serialize, Clone, Debug, Default)] +#[serde(rename_all = "camelCase")] +pub struct SelfSignedIssuer {} + +#[derive(Deserialize, Serialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct AcmeIssuer { + pub server: String, + pub email: String, + + /// Secret used to store the ACME account private key + pub private_key_secret_ref: SecretKeySelector, + + pub solvers: Vec, +} + +#[derive(Deserialize, Serialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SecretKeySelector { + pub name: String, + pub key: String, +} + +#[derive(Deserialize, Serialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct AcmeSolver { + #[serde(skip_serializing_if = "Option::is_none")] + pub http01: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub dns01: Option, +} + +#[derive(Deserialize, Serialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct Dns01Solver {} + +#[derive(Deserialize, Serialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct Http01Solver { + pub ingress: IngressSolver, +} + +#[derive(Deserialize, Serialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct IngressSolver { + #[serde(skip_serializing_if = "Option::is_none")] + pub class: Option, +} diff --git a/harmony/src/modules/cert_manager/mod.rs b/harmony/src/modules/cert_manager/mod.rs index 3e4da4f..430252d 100644 --- a/harmony/src/modules/cert_manager/mod.rs +++ b/harmony/src/modules/cert_manager/mod.rs @@ -3,4 +3,5 @@ pub mod cluster_issuer; mod helm; pub mod operator; pub mod score_k8s; +pub mod crd; pub use helm::*;