Compare commits
	
		
			3 Commits
		
	
	
		
			2f6a11ead7
			...
			2ff3f4afa9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2ff3f4afa9 | |||
| 6e884cff3a | |||
| c74c51090a | 
@ -21,6 +21,7 @@ pub enum InterpretName {
 | 
				
			|||||||
    OPNSense,
 | 
					    OPNSense,
 | 
				
			||||||
    K3dInstallation,
 | 
					    K3dInstallation,
 | 
				
			||||||
    TenantInterpret,
 | 
					    TenantInterpret,
 | 
				
			||||||
 | 
					    Application,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl std::fmt::Display for InterpretName {
 | 
					impl std::fmt::Display for InterpretName {
 | 
				
			||||||
@ -37,6 +38,7 @@ impl std::fmt::Display for InterpretName {
 | 
				
			|||||||
            InterpretName::OPNSense => f.write_str("OPNSense"),
 | 
					            InterpretName::OPNSense => f.write_str("OPNSense"),
 | 
				
			||||||
            InterpretName::K3dInstallation => f.write_str("K3dInstallation"),
 | 
					            InterpretName::K3dInstallation => f.write_str("K3dInstallation"),
 | 
				
			||||||
            InterpretName::TenantInterpret => f.write_str("Tenant"),
 | 
					            InterpretName::TenantInterpret => f.write_str("Tenant"),
 | 
				
			||||||
 | 
					            InterpretName::Application => f.write_str("Application"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,17 @@ pub struct Inventory {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Inventory {
 | 
					impl Inventory {
 | 
				
			||||||
 | 
					    pub fn empty() -> Self {
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            location: Location::new("Empty".to_string(), "location".to_string()),
 | 
				
			||||||
 | 
					            switch: vec![],
 | 
				
			||||||
 | 
					            firewall: vec![],
 | 
				
			||||||
 | 
					            worker_host: vec![],
 | 
				
			||||||
 | 
					            storage_host: vec![],
 | 
				
			||||||
 | 
					            control_plane_host: vec![],
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn autoload() -> Self {
 | 
					    pub fn autoload() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            location: Location::test_building(),
 | 
					            location: Location::test_building(),
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,14 @@
 | 
				
			|||||||
use async_trait::async_trait;
 | 
					use async_trait::async_trait;
 | 
				
			||||||
use log::info;
 | 
					use log::info;
 | 
				
			||||||
 | 
					use serde_json::Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{modules::application::ApplicationFeature, topology::Topology};
 | 
					use crate::{
 | 
				
			||||||
 | 
					    data::Version,
 | 
				
			||||||
 | 
					    inventory::Inventory,
 | 
				
			||||||
 | 
					    modules::{application::ApplicationFeature, helm::chart::HelmChartScore},
 | 
				
			||||||
 | 
					    score::Score,
 | 
				
			||||||
 | 
					    topology::{HelmCommand, Topology, Url},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// ContinuousDelivery in Harmony provides this functionality :
 | 
					/// ContinuousDelivery in Harmony provides this functionality :
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
@ -34,9 +41,44 @@ use crate::{modules::application::ApplicationFeature, topology::Topology};
 | 
				
			|||||||
pub struct ContinuousDelivery {}
 | 
					pub struct ContinuousDelivery {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[async_trait]
 | 
					#[async_trait]
 | 
				
			||||||
impl<T: Topology + 'static> ApplicationFeature<T> for ContinuousDelivery {
 | 
					impl<T: Topology + HelmCommand + 'static> ApplicationFeature<T> for ContinuousDelivery {
 | 
				
			||||||
    async fn ensure_installed(&self, _topology: &T) -> Result<(), String> {
 | 
					    async fn ensure_installed(&self, topology: &T) -> Result<(), String> {
 | 
				
			||||||
        info!("Installing ContinuousDelivery feature");
 | 
					        info!("Installing ContinuousDelivery feature");
 | 
				
			||||||
        todo!()
 | 
					        let cd_server = HelmChartScore {
 | 
				
			||||||
 | 
					            namespace: todo!(
 | 
				
			||||||
 | 
					                "ArgoCD Helm chart with proper understanding of Tenant, see how Will did it for Monitoring for now"
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            release_name: todo!("argocd helm chart whatever"),
 | 
				
			||||||
 | 
					            chart_name: todo!(),
 | 
				
			||||||
 | 
					            chart_version: todo!(),
 | 
				
			||||||
 | 
					            values_overrides: todo!(),
 | 
				
			||||||
 | 
					            values_yaml: todo!(),
 | 
				
			||||||
 | 
					            create_namespace: todo!(),
 | 
				
			||||||
 | 
					            install_only: todo!(),
 | 
				
			||||||
 | 
					            repository: todo!(),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        let interpret = cd_server.create_interpret();
 | 
				
			||||||
 | 
					        interpret.execute(&Inventory::empty(), topology);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        todo!("1. Create ArgoCD score that installs argo using helm chart, see if Taha's already done it
 | 
				
			||||||
 | 
					            2. Package app (docker image, helm chart)
 | 
				
			||||||
 | 
					            3. Push to registry if staging or prod
 | 
				
			||||||
 | 
					            4. Poke Argo
 | 
				
			||||||
 | 
					            5. Ensure app is up")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn name(&self) -> String {
 | 
				
			||||||
 | 
					        "ContinuousDelivery".to_string()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// For now this is entirely bound to K8s / ArgoCD, will have to be revisited when we support
 | 
				
			||||||
 | 
					/// more CD systems
 | 
				
			||||||
 | 
					pub struct CDApplicationConfig {
 | 
				
			||||||
 | 
					    version: Version,
 | 
				
			||||||
 | 
					    helm_chart_url: Url,
 | 
				
			||||||
 | 
					    values_overrides: Value,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub trait ContinuousDeliveryApplication {
 | 
				
			||||||
 | 
					    fn get_config(&self) -> CDApplicationConfig;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -36,4 +36,7 @@ impl<T: Topology + K8sclient + 'static> ApplicationFeature<T> for PublicEndpoint
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
        todo!()
 | 
					        todo!()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    fn name(&self) -> String {
 | 
				
			||||||
 | 
					        "PublicEndpoint".to_string()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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,21 @@ 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.len(),
 | 
				
			||||||
 | 
					            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) => {
 | 
				
			||||||
@ -34,15 +55,17 @@ impl<T: Topology + std::fmt::Debug> Interpret<T> for ApplicationInterpret<T> {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        todo!("Do I need to do anything more than this here??")
 | 
					        todo!(
 | 
				
			||||||
 | 
					            "Do I need to do anything more than this here?? I feel like the Application trait itself should expose something like ensure_ready but its becoming redundant. We'll see as this evolves."
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn get_name(&self) -> InterpretName {
 | 
					    fn get_name(&self) -> InterpretName {
 | 
				
			||||||
        todo!()
 | 
					        InterpretName::Application
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn get_version(&self) -> Version {
 | 
					    fn get_version(&self) -> Version {
 | 
				
			||||||
        todo!()
 | 
					        Version::from("1.0.0").unwrap()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn get_status(&self) -> InterpretStatus {
 | 
					    fn get_status(&self) -> InterpretStatus {
 | 
				
			||||||
@ -53,40 +76,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()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -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()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user