feat: Application module architecture and placeholder features #70
| @ -0,0 +1,37 @@ | |||||||
|  | /// ContinuousDelivery in Harmony provides this functionality :
 | ||||||
|  | ///
 | ||||||
|  | /// - **Package** the application
 | ||||||
|  | /// - **Push** to an artifact registry
 | ||||||
|  | /// - **Deploy** to a testing environment
 | ||||||
|  | /// - **Deploy** to a production environment
 | ||||||
|  | ///
 | ||||||
|  | /// It is intended to be used as an application feature passed down to an ApplicationInterpret. For
 | ||||||
|  | /// example :
 | ||||||
|  | ///
 | ||||||
|  | /// ```rust
 | ||||||
|  | /// let app = RustApplicationScore {
 | ||||||
|  | ///     name: "My Rust App".to_string(),
 | ||||||
|  | ///     features: vec![ContinuousDelivery::default()],
 | ||||||
|  | /// };
 | ||||||
|  | /// ```
 | ||||||
|  | ///
 | ||||||
|  | /// *Note :*
 | ||||||
|  | ///
 | ||||||
|  | /// By default, the Harmony Opinionated Pipeline is built using these technologies :
 | ||||||
|  | ///
 | ||||||
|  | /// - Gitea Action (executes pipeline steps)
 | ||||||
|  | /// - Docker to build an OCI container image
 | ||||||
|  | /// - Helm chart to package Kubernetes resources
 | ||||||
|  | /// - Harbor as artifact registru
 | ||||||
|  | /// - ArgoCD to install/upgrade/rollback/inspect k8s resources
 | ||||||
|  | /// - Kubernetes for runtime orchestration
 | ||||||
|  | #[derive(Debug, Default)] | ||||||
|  | pub struct ContinuousDelivery {} | ||||||
|  | 
 | ||||||
|  | #[async_trait] | ||||||
|  | impl <T: Topology + 'static> ApplicationFeature<T> for ContinuousDelivery { | ||||||
|  |     async fn ensure_installed(&self, _topology: &T) -> Result<(), String> { | ||||||
|  |         info!("Installing ContinuousDelivery feature"); | ||||||
|  |         todo!() | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,7 +1,10 @@ | |||||||
| use async_trait::async_trait; | use async_trait::async_trait; | ||||||
| use log::info; | use log::info; | ||||||
| 
 | 
 | ||||||
| use crate::{modules::application::{Application, ApplicationFeature}, topology::{K8sclient, Topology}}; | use crate::{ | ||||||
|  |     modules::application::ApplicationFeature, | ||||||
|  |     topology::{K8sclient, Topology}, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct PublicEndpoint { | pub struct PublicEndpoint { | ||||||
| @ -25,17 +28,12 @@ impl Default for PublicEndpoint { | |||||||
| 
 | 
 | ||||||
| /// For now we only suport K8s ingress, but we will support more stuff at some point
 | /// For now we only suport K8s ingress, but we will support more stuff at some point
 | ||||||
| #[async_trait] | #[async_trait] | ||||||
| impl <T: Topology + K8sclient + 'static> ApplicationFeature<T> for PublicEndpoint { | impl<T: Topology + K8sclient + 'static> ApplicationFeature<T> for PublicEndpoint { | ||||||
|     async fn ensure_installed(&self, _topology: &T) -> Result<(), String> { |     async fn ensure_installed(&self, _topology: &T) -> Result<(), String> { | ||||||
|         info!("Making sure public endpoint is installed for port {}", self.application_port); |         info!( | ||||||
|         todo!() |             "Making sure public endpoint is installed for port {}", | ||||||
|     } |             self.application_port | ||||||
| 
 |         ); | ||||||
|     async fn is_installed(&self) -> Result<bool, String> { |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     async fn uninstall(&self) -> Result<(), String> { |  | ||||||
|         todo!() |         todo!() | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,102 +1,6 @@ | |||||||
| mod endpoint; | mod endpoint; | ||||||
| use async_trait::async_trait; |  | ||||||
| pub use endpoint::*; | pub use endpoint::*; | ||||||
| use log::info; | mod monitoring; | ||||||
| 
 | pub use monitoring::*; | ||||||
| use crate::topology::{HelmCommand, Topology}; | mod continuous_delivery; | ||||||
| 
 | pub use endpoint::*; | ||||||
| use super::ApplicationFeature; |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, Default)] |  | ||||||
| pub struct SoftwareQualityChecks {} |  | ||||||
| 
 |  | ||||||
| #[async_trait] |  | ||||||
| impl<T: Topology + 'static>  ApplicationFeature<T> for SoftwareQualityChecks { |  | ||||||
|     // Either allow ApplicationFeature to self-install, which means passing Topology and Inventory
 |  | ||||||
|     // here. This would be a very easy thing to be done reliably by the ApplicationInterpret.
 |  | ||||||
|     // However, I feel like this would probably better be a list of Scores (or some sort of
 |  | ||||||
|     // executable) to be orchestrated by the maestro. We will soon have to manage more complex
 |  | ||||||
|     // lifecycles, dependencies, parallelism, etc.
 |  | ||||||
|     //
 |  | ||||||
|     //
 |  | ||||||
|     // Or change the ApplicationFeature trait to a Score trait.
 |  | ||||||
|     //
 |  | ||||||
|     // For now I'll go with the first option
 |  | ||||||
|     async fn ensure_installed(&self, _topology: &T) -> Result<(), String> { |  | ||||||
|         info!("Ensuring SoftwareQualityChecks are installed for application"); |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     async fn is_installed(&self) -> Result<bool, String> { |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     async fn uninstall(&self) -> Result<(), String> { |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// ContinuousDelivery in Harmony provides this functionality :
 |  | ||||||
| ///
 |  | ||||||
| /// - **Package** the application
 |  | ||||||
| /// - **Push** to an artifact registry
 |  | ||||||
| /// - **Deploy** to a testing environment
 |  | ||||||
| /// - **Deploy** to a production environment
 |  | ||||||
| ///
 |  | ||||||
| /// It is intended to be used as an application feature passed down to an ApplicationInterpret. For
 |  | ||||||
| /// example :
 |  | ||||||
| ///
 |  | ||||||
| /// ```rust
 |  | ||||||
| /// let app = RustApplicationScore {
 |  | ||||||
| ///     name: "My Rust App".to_string(),
 |  | ||||||
| ///     features: vec![ContinuousDelivery::default()],
 |  | ||||||
| /// };
 |  | ||||||
| /// ```
 |  | ||||||
| ///
 |  | ||||||
| /// *Note :*
 |  | ||||||
| ///
 |  | ||||||
| /// By default, the Harmony Opinionated Pipeline is built using these technologies :
 |  | ||||||
| ///
 |  | ||||||
| /// - Gitea Action (executes pipeline steps)
 |  | ||||||
| /// - Docker to build an OCI container image
 |  | ||||||
| /// - Helm chart to package Kubernetes resources
 |  | ||||||
| /// - Harbor as artifact registru
 |  | ||||||
| /// - ArgoCD to install/upgrade/rollback/inspect k8s resources
 |  | ||||||
| /// - Kubernetes for runtime orchestration
 |  | ||||||
| #[derive(Debug, Default)] |  | ||||||
| pub struct ContinuousDelivery {} |  | ||||||
| 
 |  | ||||||
| #[async_trait] |  | ||||||
| impl <T: Topology + 'static> ApplicationFeature<T> for ContinuousDelivery { |  | ||||||
|     async fn ensure_installed(&self, _topology: &T) -> Result<(), String> { |  | ||||||
|         info!("Installing ContinuousDelivery feature"); |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     async fn is_installed(&self) -> Result<bool, String> { |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     async fn uninstall(&self) -> Result<(), String> { |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, Default)] |  | ||||||
| pub struct Monitoring {} |  | ||||||
| 
 |  | ||||||
| #[async_trait] |  | ||||||
| impl <T: Topology + HelmCommand + 'static> ApplicationFeature<T> for Monitoring { |  | ||||||
|     async fn ensure_installed(&self, _topology: &T) -> Result<(), String> { |  | ||||||
|         info!("Ensuring monitoring is available for application"); |  | ||||||
|         todo!("create and execute k8s prometheus score, depends on Will's work") |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     async fn is_installed(&self) -> Result<bool, String> { |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     async fn uninstall(&self) -> Result<(), String> { |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								harmony/src/modules/application/features/monitoring.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								harmony/src/modules/application/features/monitoring.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | #[derive(Debug, Default)] | ||||||
|  | pub struct Monitoring {} | ||||||
|  | 
 | ||||||
|  | #[async_trait] | ||||||
|  | impl <T: Topology + HelmCommand + 'static> ApplicationFeature<T> for Monitoring { | ||||||
|  |     async fn ensure_installed(&self, _topology: &T) -> Result<(), String> { | ||||||
|  |         info!("Ensuring monitoring is available for application"); | ||||||
|  |         todo!("create and execute k8s prometheus score, depends on Will's work") | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -70,8 +70,6 @@ trait Application {} | |||||||
| #[async_trait] | #[async_trait] | ||||||
| pub trait ApplicationFeature<T: Topology>: std::fmt::Debug + Send + Sync { | pub trait ApplicationFeature<T: Topology>: std::fmt::Debug + Send + Sync { | ||||||
|     async fn ensure_installed(&self, topology: &T) -> Result<(), String>; |     async fn ensure_installed(&self, topology: &T) -> Result<(), String>; | ||||||
| 
					
					letian marked this conversation as resolved
					
						
						
							Outdated
						
					
				 | |||||||
|     async fn is_installed(&self) -> Result<bool, String>; |  | ||||||
|     async fn uninstall(&self) -> Result<(), String>; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
					
					letian marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						letian
						commented  
 `is_installed` and `uninstall` seem unnecessary for now | |||||||
| impl<T: Topology> Serialize for Box<dyn ApplicationFeature<T>> { | impl<T: Topology> Serialize for Box<dyn ApplicationFeature<T>> { | ||||||
| @ -97,12 +95,4 @@ impl <T: Topology > ApplicationFeature<T> for BackupFeature { | |||||||
|     async fn ensure_installed(&self, _topology: &T) -> Result<(), String> { |     async fn ensure_installed(&self, _topology: &T) -> Result<(), String> { | ||||||
|         todo!() |         todo!() | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     async fn is_installed(&self) -> Result<bool, String> { |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     async fn uninstall(&self) -> Result<(), String> { |  | ||||||
|         todo!() |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	
naming could be revisited, but good enough for now