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");
todo!()
}
fn name(&self) -> String {
"ContinuousDelivery".to_string()
}
}

View File

@ -36,4 +36,7 @@ impl<T: Topology + K8sclient + 'static> ApplicationFeature<T> for PublicEndpoint
);
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");
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;
mod rust;
pub use feature::*;
use log::info;
pub use rust::*;
use async_trait::async_trait;
use serde::Serialize;
use crate::{
data::{Id, Version},
@ -12,9 +14,14 @@ use crate::{
topology::Topology,
};
pub trait Application: std::fmt::Debug + Send + Sync {
fn name(&self) -> String;
}
#[derive(Debug)]
pub struct ApplicationInterpret<T: Topology + std::fmt::Debug> {
features: Vec<Box<dyn ApplicationFeature<T>>>,
application: Box<dyn Application>,
}
#[async_trait]
@ -24,7 +31,20 @@ impl<T: Topology + std::fmt::Debug> Interpret<T> for ApplicationInterpret<T> {
_inventory: &Inventory,
topology: &T,
) -> 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() {
info!(
"Installing feature {} for application {app_name}",
feature.name()
);
let _ = match feature.ensure_installed(topology).await {
Ok(()) => (),
Err(msg) => {
@ -53,40 +73,3 @@ impl<T: Topology + std::fmt::Debug> Interpret<T> for ApplicationInterpret<T> {
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},
};
use super::{ApplicationFeature, ApplicationInterpret, features::ContinuousDelivery};
use super::{Application, ApplicationFeature, ApplicationInterpret};
#[derive(Debug, Serialize, Clone)]
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>> {
Box::new(ApplicationInterpret {
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)
}
}
#[derive(Debug)]
struct RustWebapp {
name: String,
}
impl Application for RustWebapp {
fn name(&self) -> String {
self.name.clone()
}
}