feat: Introduce Application trait, not too sure how it will evolve but it makes sense, at the very least to identify the Application, also some minor refactoring
Some checks failed
Run Check Script / check (pull_request) Failing after -38s

This commit is contained in:
Jean-Gabriel Gill-Couture 2025-07-02 07:53:14 -04:00
parent 8ae0d6b548
commit c74c51090a
5 changed files with 45 additions and 39 deletions

View File

@ -39,4 +39,7 @@ impl<T: Topology + 'static> ApplicationFeature<T> for ContinuousDelivery {
info!("Installing ContinuousDelivery feature"); info!("Installing ContinuousDelivery feature");
todo!() todo!()
} }
fn name(&self) -> String {
"ContinuousDelivery".to_string()
}
} }

View File

@ -36,4 +36,7 @@ impl<T: Topology + K8sclient + 'static> ApplicationFeature<T> for PublicEndpoint
); );
todo!() todo!()
} }
fn name(&self) -> String {
"PublicEndpoint".to_string()
}
} }

View File

@ -15,4 +15,7 @@ impl<T: Topology + HelmCommand + 'static> ApplicationFeature<T> for Monitoring {
info!("Ensuring monitoring is available for application"); info!("Ensuring monitoring is available for application");
todo!("create and execute k8s prometheus score, depends on Will's work") todo!("create and execute k8s prometheus score, depends on Will's work")
} }
fn name(&self) -> String {
"Monitoring".to_string()
}
} }

View File

@ -1,9 +1,11 @@
mod feature;
pub mod features; pub mod features;
mod rust; mod rust;
pub use feature::*;
use log::info;
pub use rust::*; pub use rust::*;
use async_trait::async_trait; use async_trait::async_trait;
use serde::Serialize;
use crate::{ use crate::{
data::{Id, Version}, data::{Id, Version},
@ -12,9 +14,14 @@ use crate::{
topology::Topology, topology::Topology,
}; };
pub trait Application: std::fmt::Debug + Send + Sync {
fn name(&self) -> String;
}
#[derive(Debug)] #[derive(Debug)]
pub struct ApplicationInterpret<T: Topology + std::fmt::Debug> { pub struct ApplicationInterpret<T: Topology + std::fmt::Debug> {
features: Vec<Box<dyn ApplicationFeature<T>>>, features: Vec<Box<dyn ApplicationFeature<T>>>,
application: Box<dyn Application>,
} }
#[async_trait] #[async_trait]
@ -24,7 +31,20 @@ impl<T: Topology + std::fmt::Debug> Interpret<T> for ApplicationInterpret<T> {
_inventory: &Inventory, _inventory: &Inventory,
topology: &T, topology: &T,
) -> Result<Outcome, InterpretError> { ) -> Result<Outcome, InterpretError> {
let app_name = self.application.name();
info!(
"Preparing features {} for application {app_name}",
self.features
.iter()
.map(|f| f.name())
.collect::<Vec<String>>()
.join(", ")
);
for feature in self.features.iter() { for feature in self.features.iter() {
info!(
"Installing feature {} for application {app_name}",
feature.name()
);
let _ = match feature.ensure_installed(topology).await { let _ = match feature.ensure_installed(topology).await {
Ok(()) => (), Ok(()) => (),
Err(msg) => { Err(msg) => {
@ -53,40 +73,3 @@ impl<T: Topology + std::fmt::Debug> Interpret<T> for ApplicationInterpret<T> {
todo!() todo!()
} }
} }
/// An ApplicationFeature provided by harmony, such as Backups, Monitoring, MultisiteAvailability,
/// ContinuousIntegration, ContinuousDelivery
#[async_trait]
pub trait ApplicationFeature<T: Topology>:
std::fmt::Debug + Send + Sync + ApplicationFeatureClone<T>
{
async fn ensure_installed(&self, topology: &T) -> Result<(), String>;
}
trait ApplicationFeatureClone<T: Topology> {
fn clone_box(&self) -> Box<dyn ApplicationFeature<T>>;
}
impl<A, T: Topology> ApplicationFeatureClone<T> for A
where
A: ApplicationFeature<T> + Clone + 'static,
{
fn clone_box(&self) -> Box<dyn ApplicationFeature<T>> {
Box::new(self.clone())
}
}
impl<T: Topology> Serialize for Box<dyn ApplicationFeature<T>> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
todo!()
}
}
impl<T: Topology> Clone for Box<dyn ApplicationFeature<T>> {
fn clone(&self) -> Self {
self.clone_box()
}
}

View File

@ -5,7 +5,7 @@ use crate::{
topology::{Topology, Url}, topology::{Topology, Url},
}; };
use super::{ApplicationFeature, ApplicationInterpret, features::ContinuousDelivery}; use super::{Application, ApplicationFeature, ApplicationInterpret};
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
pub struct RustWebappScore<T: Topology + Clone + Serialize> { pub struct RustWebappScore<T: Topology + Clone + Serialize> {
@ -18,6 +18,9 @@ impl<T: Topology + std::fmt::Debug + Clone + Serialize + 'static> Score<T> for R
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> { fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
Box::new(ApplicationInterpret { Box::new(ApplicationInterpret {
features: self.features.clone(), features: self.features.clone(),
application: Box::new(RustWebapp {
name: self.name.clone(),
}),
}) })
} }
@ -25,3 +28,14 @@ impl<T: Topology + std::fmt::Debug + Clone + Serialize + 'static> Score<T> for R
format!("{}-RustWebapp", self.name) format!("{}-RustWebapp", self.name)
} }
} }
#[derive(Debug)]
struct RustWebapp {
name: String,
}
impl Application for RustWebapp {
fn name(&self) -> String {
self.name.clone()
}
}