From 19f87fdaf700f36be49269a681ab5618bc4db26f Mon Sep 17 00:00:00 2001 From: Willem Date: Wed, 10 Sep 2025 15:08:13 -0400 Subject: [PATCH 1/2] fix: added routes to domain name for prometheus, grafana, alertmanageradded argo cd to the reporting after successfull build --- .../application/features/helm_argocd_score.rs | 22 +++++++++++-------- harmony/src/modules/k8s/ingress.rs | 5 ++++- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/harmony/src/modules/application/features/helm_argocd_score.rs b/harmony/src/modules/application/features/helm_argocd_score.rs index 84aff9a..26767e1 100644 --- a/harmony/src/modules/application/features/helm_argocd_score.rs +++ b/harmony/src/modules/application/features/helm_argocd_score.rs @@ -55,7 +55,8 @@ impl Interpret for ArgoInter topology: &T, ) -> Result { 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 = argo_helm_chart_score(&self.score.namespace, self.score.openshift, &domain); @@ -66,14 +67,17 @@ impl Interpret for ArgoInter .await .unwrap(); - Ok(Outcome::success(format!( - "ArgoCD installed with {} {}", - self.argo_apps.len(), - match self.argo_apps.len() { - 1 => "application", - _ => "applications", - } - ))) + Ok(Outcome::success_with_details( + format!( + "ArgoCD {} {}", + self.argo_apps.len(), + match self.argo_apps.len() { + 1 => "application", + _ => "applications", + } + ), + vec![format!("argo application: http://{}", domain)], + )) } fn get_name(&self) -> InterpretName { diff --git a/harmony/src/modules/k8s/ingress.rs b/harmony/src/modules/k8s/ingress.rs index d94a1aa..045f1f8 100644 --- a/harmony/src/modules/k8s/ingress.rs +++ b/harmony/src/modules/k8s/ingress.rs @@ -141,7 +141,10 @@ impl Interpret for K8sIngressInterpret { InterpretStatus::SUCCESS => { let details = match &self.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)], }; -- 2.39.5 From 6f55f79281e28f8af1450779f8e8ff803d677e5e Mon Sep 17 00:00:00 2001 From: Jean-Gabriel Gill-Couture Date: Wed, 10 Sep 2025 15:21:33 -0400 Subject: [PATCH 2/2] feat: Update readme with newer UX/DX Rust Leptos app, update slides and misc stuff --- README.md | 69 +++++++++------- .../qrcode_gitea_nationtech.png | Bin 0 -> 8449 bytes .../slides.html | 75 ++++++++++-------- .../slides.md | 14 ++++ examples/try_rust_webapp/src/main.rs | 16 ++-- 5 files changed, 103 insertions(+), 71 deletions(-) create mode 100644 demos/cncf-k8s-quebec-meetup-september-2025/qrcode_gitea_nationtech.png diff --git a/README.md b/README.md index e77718e..4ccdae7 100644 --- a/README.md +++ b/README.md @@ -36,48 +36,59 @@ These principles surface as simple, ergonomic Rust APIs that let teams focus on ## 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 use harmony::{ - data::Version, inventory::Inventory, - maestro::Maestro, modules::{ - lamp::{LAMPConfig, LAMPScore}, - monitoring::monitoring_alerting::MonitoringAlertingStackScore, + application::{ + ApplicationScore, RustWebFramework, RustWebapp, + features::{PackagingDeployment, rhob_monitoring::Monitoring}, + }, + monitoring::alert_channel::discord_alert_channel::DiscordWebhook, }, - topology::{K8sAnywhereTopology, Url}, + topology::K8sAnywhereTopology, }; +use harmony_macros::hurl; +use std::{path::PathBuf, sync::Arc}; #[tokio::main] async fn main() { - // 1. Describe what you want - let lamp_stack = LAMPScore { - name: "harmony-lamp-demo".into(), - domain: Url::Url(url::Url::parse("https://lampdemo.example.com").unwrap()), - php_version: Version::from("8.3.0").unwrap(), - config: LAMPConfig { - project_root: "./php".into(), - database_size: "4Gi".into(), - ..Default::default() - }, + let application = Arc::new(RustWebapp { + name: "harmony-example-leptos".to_string(), + project_root: PathBuf::from(".."), // <== Your project root, usually .. if you use the standard `/harmony` folder + framework: Some(RustWebFramework::Leptos), + service_port: 8080, + }); + + // Define your Application deployment and the features you want + 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( - Inventory::autoload(), // auto-detect hardware / kube-config - K8sAnywhereTopology::from_env(), // local k3d, CI, staging, prod… - vec![ - Box::new(lamp_stack), - Box::new(monitoring) - ], - None - ).await.unwrap(); + Inventory::autoload(), + K8sAnywhereTopology::from_env(), // <== Deploy to local automatically provisioned local k3d by default or connect to any kubernetes cluster + vec![Box::new(app)], + None, + ) + .await + .unwrap(); } ``` diff --git a/demos/cncf-k8s-quebec-meetup-september-2025/qrcode_gitea_nationtech.png b/demos/cncf-k8s-quebec-meetup-september-2025/qrcode_gitea_nationtech.png new file mode 100644 index 0000000000000000000000000000000000000000..4ad8de542236e3fb0dd8ebafbfec82302f6d55d6 GIT binary patch literal 8449 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 l'histoire de Petit Poisson
+

Voici l'histoire de Petit Poisson

-
+
-
+
-
+

https://tryrust.org

-
+
-
+
-
+
-
+
-
+

Demo time

-
+
-
+
-
+

Ansible❓

-
+
- name: Download wikipedia
   hosts: localhost
@@ -59,40 +59,40 @@
         mode: '0900'
 
-
+
ansible-lint download.yml
 
 Passed: 0 failure(s), 0 warning(s) on 1 files. Last profile that met the validation criteria was 'production'.
 
-
+
git push
 
-
+
-
+
-
+
-
+
-
+
-
+
-
+

Terraform❓❗

-
+
provider "docker" {}
@@ -106,7 +106,7 @@ resource "docker_network" "invalid_network" {
 }
 
-
+
terraform plan
@@ -136,14 +136,14 @@ Terraform will perform the following actions:
 Plan: 1 to add, 0 to change, 0 to destroy.
 
-
+

✅

-
+
terraform apply
 
-
+
Plan: 1 to add, 0 to change, 0 to destroy.
 
 Do you want to perform these actions?
@@ -153,7 +153,7 @@ Do you want to perform these actions?
   Enter a value: yes
 
-
+
docker_network.invalid_network: Creating...
 ╷
 │ Error: Unable to create network: Error response from daemon: invalid network config:
@@ -166,23 +166,30 @@ Do you want to perform these actions?
 ╵
 
-
+
-
+
-
+

Harmony❓❗

-
+

Demo time

-
+
+
+

🎼

+

Harmony : https://git.nationtech.io/nationtech/harmony

+ +

LinkedIn : https://www.linkedin.com/in/jean-gabriel-gill-couture/

+

Courriel : jg@nationtech.io

+
\ No newline at end of file diff --git a/demos/cncf-k8s-quebec-meetup-september-2025/slides.md b/demos/cncf-k8s-quebec-meetup-september-2025/slides.md index 3906755..2060883 100644 --- a/demos/cncf-k8s-quebec-meetup-september-2025/slides.md +++ b/demos/cncf-k8s-quebec-meetup-september-2025/slides.md @@ -225,3 +225,17 @@ Demo time --- + +--- + +# 🎼 + +Harmony : [https://git.nationtech.io/nationtech/harmony](https://git.nationtech.io/nationtech/harmony) + + + + + +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) diff --git a/examples/try_rust_webapp/src/main.rs b/examples/try_rust_webapp/src/main.rs index 977ca16..56a058d 100644 --- a/examples/try_rust_webapp/src/main.rs +++ b/examples/try_rust_webapp/src/main.rs @@ -16,16 +16,13 @@ use std::{path::PathBuf, sync::Arc}; async fn main() { let application = Arc::new(RustWebapp { 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), service_port: 8080, }); - let discord_receiver = DiscordWebhook { - name: "test-discord".to_string(), - url: hurl!("https://discord.doesnt.exist.com"), - }; - + // Define your Application deployment and the features you want let app = ApplicationScore { features: vec![ Box::new(PackagingDeployment { @@ -33,7 +30,10 @@ async fn main() { }), Box::new(Monitoring { 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, @@ -41,7 +41,7 @@ async fn main() { harmony_cli::run( 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)], None, ) -- 2.39.5