Merge pull request 'fix: added routes to domain name for prometheus, grafana, alertmanageradded argo cd to the reporting after successfull build' (#155) from fix/add_routes_to_domain into master
All checks were successful
Run Check Script / check (push) Successful in 59s
Compile and package harmony_composer / package_harmony_composer (push) Successful in 6m27s

Reviewed-on: https://git.nationtech.io/NationTech/harmony/pulls/155
This commit is contained in:
johnride 2025-09-10 19:44:53 +00:00
commit 6e6f57e38c
7 changed files with 120 additions and 81 deletions

View File

@ -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

View File

@ -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)

View File

@ -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,
) )

View File

@ -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 {

View File

@ -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)],
}; };