Compare commits
	
		
			3 Commits
		
	
	
		
			49370af176
			...
			6e6f57e38c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6e6f57e38c | |||
| 6f55f79281 | |||
| 19f87fdaf7 | 
							
								
								
									
										69
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								README.md
									
									
									
									
									
								
							| @ -36,48 +36,59 @@ These principles surface as simple, ergonomic Rust APIs that let teams focus on | |||||||
| 
 | 
 | ||||||
| ## 2 · Quick Start | ## 2 · Quick Start | ||||||
| 
 | 
 | ||||||
| The snippet below spins up a complete **production-grade LAMP stack** with monitoring. Swap it for your own scores to deploy anything from microservices to machine-learning pipelines. | The snippet below spins up a complete **production-grade Rust + Leptos Webapp** with monitoring. Swap it for your own scores to deploy anything from microservices to machine-learning pipelines. | ||||||
| 
 | 
 | ||||||
| ```rust | ```rust | ||||||
| use harmony::{ | use harmony::{ | ||||||
|     data::Version, |  | ||||||
|     inventory::Inventory, |     inventory::Inventory, | ||||||
|     maestro::Maestro, |  | ||||||
|     modules::{ |     modules::{ | ||||||
|         lamp::{LAMPConfig, LAMPScore}, |         application::{ | ||||||
|         monitoring::monitoring_alerting::MonitoringAlertingStackScore, |             ApplicationScore, RustWebFramework, RustWebapp, | ||||||
|  |             features::{PackagingDeployment, rhob_monitoring::Monitoring}, | ||||||
|         }, |         }, | ||||||
|     topology::{K8sAnywhereTopology, Url}, |         monitoring::alert_channel::discord_alert_channel::DiscordWebhook, | ||||||
|  |     }, | ||||||
|  |     topology::K8sAnywhereTopology, | ||||||
| }; | }; | ||||||
|  | use harmony_macros::hurl; | ||||||
|  | use std::{path::PathBuf, sync::Arc}; | ||||||
| 
 | 
 | ||||||
| #[tokio::main] | #[tokio::main] | ||||||
| async fn main() { | async fn main() { | ||||||
|     // 1. Describe what you want |     let application = Arc::new(RustWebapp { | ||||||
|     let lamp_stack = LAMPScore { |         name: "harmony-example-leptos".to_string(), | ||||||
|         name: "harmony-lamp-demo".into(), |         project_root: PathBuf::from(".."), // <== Your project root, usually .. if you use the standard `/harmony` folder | ||||||
|         domain: Url::Url(url::Url::parse("https://lampdemo.example.com").unwrap()), |         framework: Some(RustWebFramework::Leptos), | ||||||
|         php_version: Version::from("8.3.0").unwrap(), |         service_port: 8080, | ||||||
|         config: LAMPConfig { |     }); | ||||||
|             project_root: "./php".into(), | 
 | ||||||
|             database_size: "4Gi".into(), |     // Define your Application deployment and the features you want | ||||||
|             ..Default::default() |     let app = ApplicationScore { | ||||||
|         }, |         features: vec![ | ||||||
|  |             Box::new(PackagingDeployment { | ||||||
|  |                 application: application.clone(), | ||||||
|  |             }), | ||||||
|  |             Box::new(Monitoring { | ||||||
|  |                 application: application.clone(), | ||||||
|  |                 alert_receiver: vec![ | ||||||
|  |                     Box::new(DiscordWebhook { | ||||||
|  |                         name: "test-discord".to_string(), | ||||||
|  |                         url: hurl!("https://discord.doesnt.exist.com"), // <== Get your discord webhook url | ||||||
|  |                     }), | ||||||
|  |                 ], | ||||||
|  |             }), | ||||||
|  |         ], | ||||||
|  |         application, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     // 2. Enhance with extra scores (monitoring, CI/CD, …) |  | ||||||
|     let mut monitoring = MonitoringAlertingStackScore::new(); |  | ||||||
|     monitoring.namespace = Some(lamp_stack.config.namespace.clone()); |  | ||||||
| 
 |  | ||||||
|     // 3. Run your scores on the desired topology & inventory |  | ||||||
|     harmony_cli::run( |     harmony_cli::run( | ||||||
|         Inventory::autoload(),                // auto-detect hardware / kube-config |         Inventory::autoload(), | ||||||
|         K8sAnywhereTopology::from_env(),      // local k3d, CI, staging, prod… |         K8sAnywhereTopology::from_env(), // <== Deploy to local automatically provisioned local k3d by default or connect to any kubernetes cluster | ||||||
|         vec![ |         vec![Box::new(app)], | ||||||
|           Box::new(lamp_stack), |         None, | ||||||
|           Box::new(monitoring) |     ) | ||||||
|         ], |     .await | ||||||
|         None |     .unwrap(); | ||||||
|     ).await.unwrap(); |  | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | |||||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 8.3 KiB | 
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -225,3 +225,17 @@ Demo time | |||||||
| --- | --- | ||||||
| 
 | 
 | ||||||
| <img src="./Happy_swimmer.jpg" width="300"/> | <img src="./Happy_swimmer.jpg" width="300"/> | ||||||
|  | 
 | ||||||
|  | --- | ||||||
|  | 
 | ||||||
|  | # 🎼  | ||||||
|  | 
 | ||||||
|  | Harmony : [https://git.nationtech.io/nationtech/harmony](https://git.nationtech.io/nationtech/harmony) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |  <img src="./qrcode_gitea_nationtech.png" width="120"/> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | LinkedIn : [https://www.linkedin.com/in/jean-gabriel-gill-couture/](https://www.linkedin.com/in/jean-gabriel-gill-couture/) | ||||||
|  | 
 | ||||||
|  | Courriel : [jg@nationtech.io](mailto:jg@nationtech.io) | ||||||
|  | |||||||
| @ -16,16 +16,13 @@ use std::{path::PathBuf, sync::Arc}; | |||||||
| async fn main() { | async fn main() { | ||||||
|     let application = Arc::new(RustWebapp { |     let application = Arc::new(RustWebapp { | ||||||
|         name: "harmony-example-tryrust".to_string(), |         name: "harmony-example-tryrust".to_string(), | ||||||
|         project_root: PathBuf::from("./tryrust.org"), |         project_root: PathBuf::from("./tryrust.org"), // <== Project root, in this case it is a
 | ||||||
|  |         // submodule
 | ||||||
|         framework: Some(RustWebFramework::Leptos), |         framework: Some(RustWebFramework::Leptos), | ||||||
|         service_port: 8080, |         service_port: 8080, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     let discord_receiver = DiscordWebhook { |     // Define your Application deployment and the features you want
 | ||||||
|         name: "test-discord".to_string(), |  | ||||||
|         url: hurl!("https://discord.doesnt.exist.com"), |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     let app = ApplicationScore { |     let app = ApplicationScore { | ||||||
|         features: vec![ |         features: vec![ | ||||||
|             Box::new(PackagingDeployment { |             Box::new(PackagingDeployment { | ||||||
| @ -33,7 +30,10 @@ async fn main() { | |||||||
|             }), |             }), | ||||||
|             Box::new(Monitoring { |             Box::new(Monitoring { | ||||||
|                 application: application.clone(), |                 application: application.clone(), | ||||||
|                 alert_receiver: vec![Box::new(discord_receiver)], |                 alert_receiver: vec![Box::new(DiscordWebhook { | ||||||
|  |                     name: "test-discord".to_string(), | ||||||
|  |                     url: hurl!("https://discord.doesnt.exist.com"), | ||||||
|  |                 })], | ||||||
|             }), |             }), | ||||||
|         ], |         ], | ||||||
|         application, |         application, | ||||||
| @ -41,7 +41,7 @@ async fn main() { | |||||||
| 
 | 
 | ||||||
|     harmony_cli::run( |     harmony_cli::run( | ||||||
|         Inventory::autoload(), |         Inventory::autoload(), | ||||||
|         K8sAnywhereTopology::from_env(), |         K8sAnywhereTopology::from_env(), // <== Deploy to local automatically provisioned k3d by default or connect to any kubernetes cluster
 | ||||||
|         vec![Box::new(app)], |         vec![Box::new(app)], | ||||||
|         None, |         None, | ||||||
|     ) |     ) | ||||||
|  | |||||||
| @ -55,7 +55,8 @@ impl<T: Topology + K8sclient + HelmCommand + Ingress> Interpret<T> for ArgoInter | |||||||
|         topology: &T, |         topology: &T, | ||||||
|     ) -> Result<Outcome, InterpretError> { |     ) -> Result<Outcome, InterpretError> { | ||||||
|         let k8s_client = topology.k8s_client().await?; |         let k8s_client = topology.k8s_client().await?; | ||||||
|         let domain = topology.get_domain("argo").await?; |         let svc = format!("argo-{}", self.score.namespace.clone()); | ||||||
|  |         let domain = topology.get_domain(&svc).await?; | ||||||
|         let helm_score = |         let helm_score = | ||||||
|             argo_helm_chart_score(&self.score.namespace, self.score.openshift, &domain); |             argo_helm_chart_score(&self.score.namespace, self.score.openshift, &domain); | ||||||
| 
 | 
 | ||||||
| @ -66,14 +67,17 @@ impl<T: Topology + K8sclient + HelmCommand + Ingress> Interpret<T> for ArgoInter | |||||||
|             .await |             .await | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
| 
 | 
 | ||||||
|         Ok(Outcome::success(format!( |         Ok(Outcome::success_with_details( | ||||||
|             "ArgoCD installed with {} {}", |             format!( | ||||||
|  |                 "ArgoCD {} {}", | ||||||
|                 self.argo_apps.len(), |                 self.argo_apps.len(), | ||||||
|                 match self.argo_apps.len() { |                 match self.argo_apps.len() { | ||||||
|                     1 => "application", |                     1 => "application", | ||||||
|                     _ => "applications", |                     _ => "applications", | ||||||
|                 } |                 } | ||||||
|         ))) |             ), | ||||||
|  |             vec![format!("argo application: http://{}", domain)], | ||||||
|  |         )) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn get_name(&self) -> InterpretName { |     fn get_name(&self) -> InterpretName { | ||||||
|  | |||||||
| @ -141,7 +141,10 @@ impl<T: Topology + K8sclient> Interpret<T> for K8sIngressInterpret { | |||||||
|                 InterpretStatus::SUCCESS => { |                 InterpretStatus::SUCCESS => { | ||||||
|                     let details = match &self.namespace { |                     let details = match &self.namespace { | ||||||
|                         Some(namespace) => { |                         Some(namespace) => { | ||||||
|                             vec![format!("{} ({namespace}): {}", self.service, self.host)] |                             vec![format!( | ||||||
|  |                                 "{} ({namespace}): http://{}", | ||||||
|  |                                 self.service, self.host | ||||||
|  |                             )] | ||||||
|                         } |                         } | ||||||
|                         None => vec![format!("{}: {}", self.service, self.host)], |                         None => vec![format!("{}: {}", self.service, self.host)], | ||||||
|                     }; |                     }; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user