fix: added create_issuer fn to trait and its implementation is k8sanywhere
All checks were successful
Run Check Script / check (pull_request) Successful in 1m43s

This commit is contained in:
2026-01-14 14:39:05 -05:00
parent dc421fa099
commit 25c5cd84fe
8 changed files with 88 additions and 64 deletions

View File

@@ -18,7 +18,7 @@ use crate::{
inventory::Inventory, inventory::Inventory,
modules::{ modules::{
cert_manager::{ cert_manager::{
capability::{CertificateManagement, CertificateManagementConfig, Issuer}, capability::{CertificateManagement, CertificateManagementConfig},
crd::{score_certificate::CertificateScore, score_issuer::IssuerScore}, crd::{score_certificate::CertificateScore, score_issuer::IssuerScore},
operator::CertManagerOperatorScore, operator::CertManagerOperatorScore,
}, },
@@ -376,6 +376,7 @@ impl CertificateManagement for K8sAnywhereTopology {
.interpret(&Inventory::empty(), self) .interpret(&Inventory::empty(), self)
.await .await
.map_err(|e| PreparationError { msg: e.to_string() })?; .map_err(|e| PreparationError { msg: e.to_string() })?;
Ok(PreparationOutcome::Success { Ok(PreparationOutcome::Success {
details: format!( details: format!(
"Installed cert-manager into ns: {}", "Installed cert-manager into ns: {}",
@@ -388,31 +389,52 @@ impl CertificateManagement for K8sAnywhereTopology {
&self, &self,
config: &CertificateManagementConfig, config: &CertificateManagementConfig,
) -> Result<PreparationOutcome, PreparationError> { ) -> Result<PreparationOutcome, PreparationError> {
self.certificate_issuer_ready(Issuer::Issuer, config) todo!()
.await?; }
async fn create_issuer(
&self,
issuer_name: String,
config: &CertificateManagementConfig,
) -> Result<PreparationOutcome, PreparationError> {
let issuer_score = IssuerScore {
config: config.clone(),
};
issuer_score
.interpret(&Inventory::empty(), self)
.await
.map_err(|e| PreparationError { msg: e.to_string() })?;
Ok(PreparationOutcome::Success { Ok(PreparationOutcome::Success {
details: "issuer ready".to_string(), details: format!("issuer of kind {} is ready", issuer_name),
}) })
} }
async fn create_certificate( async fn create_certificate(
&self, &self,
cert_name: String, cert_name: String,
issuer_name: String,
config: &CertificateManagementConfig, config: &CertificateManagementConfig,
) -> Result<PreparationOutcome, PreparationError> { ) -> Result<PreparationOutcome, PreparationError> {
self.certificate_issuer_ready(
issuer_name.clone(),
self.k8s_client().await.unwrap(),
config,
)
.await?;
let cert = CertificateScore { let cert = CertificateScore {
name: cert_name, cert_name: cert_name,
config: config.clone(), config: config.clone(),
issuer_name,
}; };
cert.interpret(&Inventory::empty(), self) cert.interpret(&Inventory::empty(), self)
.await .await
.map_err(|e| PreparationError { msg: e.to_string() })?; .map_err(|e| PreparationError { msg: e.to_string() })?;
Ok(PreparationOutcome::Success { Ok(PreparationOutcome::Success {
details: format!( details: format!("Created cert into ns: {:#?}", config.namespace.clone()),
"Created cert into ns: {:#?}",
config.namespace.clone()
),
}) })
} }
} }
@@ -436,6 +458,35 @@ impl K8sAnywhereTopology {
} }
} }
pub async fn certificate_issuer_ready(
&self,
issuer_name: String,
k8s_client: Arc<K8sClient>,
config: &CertificateManagementConfig,
) -> Result<PreparationOutcome, PreparationError> {
let ns = config.namespace.clone().ok_or_else(|| PreparationError {
msg: "namespace is required".to_string(),
})?;
let gvk = GroupVersionKind {
group: "cert-manager.io".to_string(),
version: "v1".to_string(),
kind: "Issuer".to_string(),
};
match k8s_client
.get_resource_json_value(&issuer_name, Some(&ns), &gvk)
.await
{
Ok(_cert_issuer) => Ok(PreparationOutcome::Success {
details: format!("issuer of kind {} is ready", issuer_name),
}),
Err(e) => Err(PreparationError {
msg: format!("{} issuer {} not present", e.to_string(), issuer_name),
}),
}
}
pub async fn get_k8s_distribution(&self) -> Result<&KubernetesDistribution, PreparationError> { pub async fn get_k8s_distribution(&self) -> Result<&KubernetesDistribution, PreparationError> {
self.k8s_distribution self.k8s_distribution
.get_or_try_init(async || { .get_or_try_init(async || {
@@ -968,29 +1019,6 @@ impl K8sAnywhereTopology {
), ),
}) })
} }
async fn certificate_issuer_ready(
&self,
issuer: Issuer,
config: &CertificateManagementConfig,
) -> Result<PreparationOutcome, PreparationError> {
match issuer {
Issuer::ClusterIssuer => todo!(),
Issuer::Issuer => {
let issuer_score = IssuerScore {
config: config.clone(),
};
issuer_score
.interpret(&Inventory::empty(), self)
.await
.map_err(|e| PreparationError { msg: e.to_string() })?;
Ok(PreparationOutcome::Success {
details: format!("issuer of kind {} is ready", issuer.to_string()),
})
}
}
}
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

View File

@@ -1,8 +1,12 @@
use async_trait::async_trait; use async_trait::async_trait;
use serde::Serialize; use serde::Serialize;
use crate::{modules::cert_manager::crd::{AcmeIssuer, CaIssuer}, topology::{PreparationError, PreparationOutcome}}; use crate::{
modules::cert_manager::crd::{AcmeIssuer, CaIssuer},
topology::{PreparationError, PreparationOutcome},
};
///TODO rust doc explaining issuer, certificate etc
#[async_trait] #[async_trait]
pub trait CertificateManagement: Send + Sync { pub trait CertificateManagement: Send + Sync {
async fn install( async fn install(
@@ -15,9 +19,16 @@ pub trait CertificateManagement: Send + Sync {
config: &CertificateManagementConfig, config: &CertificateManagementConfig,
) -> Result<PreparationOutcome, PreparationError>; ) -> Result<PreparationOutcome, PreparationError>;
async fn create_issuer(
&self,
issuer_name: String,
config: &CertificateManagementConfig,
) -> Result<PreparationOutcome, PreparationError>;
async fn create_certificate( async fn create_certificate(
&self, &self,
cert_name: String, cert_name: String,
issuer_name: String,
config: &CertificateManagementConfig, config: &CertificateManagementConfig,
) -> Result<PreparationOutcome, PreparationError>; ) -> Result<PreparationOutcome, PreparationError>;
} }
@@ -30,19 +41,3 @@ pub struct CertificateManagementConfig {
pub ca_issuer: Option<CaIssuer>, pub ca_issuer: Option<CaIssuer>,
pub self_signed: bool, pub self_signed: bool,
} }
#[derive(Serialize)]
pub enum Issuer {
ClusterIssuer,
Issuer,
}
impl std::fmt::Display for Issuer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Issuer::Issuer => f.write_str("Issuer"),
Issuer::ClusterIssuer => f.write_str("ClusterIssuer"),
}
}
}

View File

@@ -110,4 +110,3 @@ pub struct PrivateKey {
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub rotation_policy: Option<String>, pub rotation_policy: Option<String>,
} }

View File

@@ -42,4 +42,3 @@ impl Default for ClusterIssuerSpec {
} }
} }
} }

View File

@@ -1,12 +1,11 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub mod certificate; pub mod certificate;
pub mod issuer;
pub mod cluster_issuer; pub mod cluster_issuer;
pub mod issuer;
//pub mod score_cluster_issuer; //pub mod score_cluster_issuer;
pub mod score_issuer;
pub mod score_certificate; pub mod score_certificate;
pub mod score_issuer;
#[derive(Deserialize, Serialize, Clone, Debug)] #[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]

View File

@@ -16,7 +16,8 @@ use crate::{
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct CertificateScore { pub struct CertificateScore {
pub name: String, pub cert_name: String,
pub issuer_name: String,
pub config: CertificateManagementConfig, pub config: CertificateManagementConfig,
} }
@@ -28,14 +29,14 @@ impl<T: Topology + K8sclient> Score<T> for CertificateScore {
fn create_interpret(&self) -> Box<dyn Interpret<T>> { fn create_interpret(&self) -> Box<dyn Interpret<T>> {
let cert = Certificate { let cert = Certificate {
metadata: ObjectMeta { metadata: ObjectMeta {
name: Some(self.name.clone()), name: Some(self.cert_name.clone()),
namespace: self.config.namespace.clone(), namespace: self.config.namespace.clone(),
..Default::default() ..Default::default()
}, },
spec: CertificateSpec { spec: CertificateSpec {
secret_name: format!("{}-tls", self.name.clone()), secret_name: format!("{}-tls", self.cert_name.clone()),
issuer_ref: IssuerRef { issuer_ref: IssuerRef {
name: self.config.name.clone(), name: self.issuer_name.clone(),
kind: Some("Issuer".into()), kind: Some("Issuer".into()),
group: Some("cert-manager.io".into()), group: Some("cert-manager.io".into()),
}, },

View File

@@ -4,10 +4,13 @@ use serde::Serialize;
use crate::{ use crate::{
interpret::Interpret, interpret::Interpret,
modules::{ modules::{
cert_manager::{capability::CertificateManagementConfig, crd::{ cert_manager::{
AcmeIssuer, CaIssuer, SelfSignedIssuer, capability::CertificateManagementConfig,
issuer::{Issuer, IssuerSpec}, crd::{
}}, SelfSignedIssuer,
issuer::{Issuer, IssuerSpec},
},
},
k8s::resource::K8sResourceScore, k8s::resource::K8sResourceScore,
}, },
score::Score, score::Score,
@@ -26,7 +29,7 @@ impl<T: Topology + K8sclient> Score<T> for IssuerScore {
fn create_interpret(&self) -> Box<dyn Interpret<T>> { fn create_interpret(&self) -> Box<dyn Interpret<T>> {
let metadata = ObjectMeta { let metadata = ObjectMeta {
name: Some(self.config.name.clone()), name: Some(format!("{}-issuer", self.config.namespace.clone().unwrap())),
namespace: self.config.namespace.clone(), namespace: self.config.namespace.clone(),
..ObjectMeta::default() ..ObjectMeta::default()
}; };

View File

@@ -1,7 +1,7 @@
pub mod capability; pub mod capability;
pub mod cluster_issuer; pub mod cluster_issuer;
pub mod crd;
mod helm; mod helm;
pub mod operator; pub mod operator;
pub mod score_k8s; pub mod score_k8s;
pub mod crd;
pub use helm::*; pub use helm::*;