diff --git a/harmony/Cargo.toml b/harmony/Cargo.toml index 391628b..ad57db1 100644 --- a/harmony/Cargo.toml +++ b/harmony/Cargo.toml @@ -10,7 +10,11 @@ testing = [] [dependencies] hex = "0.4" -reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features = false } +reqwest = { version = "0.11", features = [ + "blocking", + "json", + "rustls-tls", +], default-features = false } russh = "0.45.0" rust-ipmi = "0.1.1" semver = "1.0.23" diff --git a/harmony/src/modules/application/features/continuous_delivery.rs b/harmony/src/modules/application/features/continuous_delivery.rs index 33c03eb..d6b65db 100644 --- a/harmony/src/modules/application/features/continuous_delivery.rs +++ b/harmony/src/modules/application/features/continuous_delivery.rs @@ -1,4 +1,4 @@ -use std::{io::Write, marker::PhantomData, process::Command, sync::Arc}; +use std::{io::Write, process::Command, sync::Arc}; use async_trait::async_trait; use log::info; @@ -143,7 +143,7 @@ impl< { async fn ensure_installed(&self, topology: &T) -> Result<(), String> { let image = self.application.image_name(); - let domain_host = topology.get_domain().await.map_err(|e| e.to_string())?; + let domain = topology.get_domain().await.map_err(|e| e.to_string())?; // TODO Write CI/CD workflow files // we can autotedect the CI type using the remote url (default to github action for github @@ -152,7 +152,7 @@ impl< let helm_chart = self .application - .build_push_helm_package(&image, &domain_host) + .build_push_helm_package(&image, &domain) .await?; // TODO: Make building image configurable/skippable if image already exists (prompt)") diff --git a/harmony/src/modules/application/features/monitoring.rs b/harmony/src/modules/application/features/monitoring.rs index 1c1c00b..fa3a6a3 100644 --- a/harmony/src/modules/application/features/monitoring.rs +++ b/harmony/src/modules/application/features/monitoring.rs @@ -1,10 +1,8 @@ -use std::sync::Arc; - use crate::modules::application::{Application, ApplicationFeature}; use crate::modules::monitoring::application_monitoring::application_monitoring_score::ApplicationMonitoringScore; use crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::CRDPrometheus; - use crate::topology::MultiTargetTopology; +use crate::topology::ingress::Ingress; use crate::{ inventory::Inventory, modules::monitoring::{ @@ -19,8 +17,12 @@ use crate::{ }; use async_trait::async_trait; use base64::{Engine as _, engine::general_purpose}; +use harmony_secret::SecretManager; +use harmony_secret_derive::Secret; use harmony_types::net::Url; use log::{debug, info}; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; #[derive(Debug, Clone)] pub struct Monitoring { @@ -36,8 +38,9 @@ impl< + TenantManager + K8sclient + MultiTargetTopology - + std::fmt::Debug - + PrometheusApplicationMonitoring, + + PrometheusApplicationMonitoring + + Ingress + + std::fmt::Debug, > ApplicationFeature for Monitoring { async fn ensure_installed(&self, topology: &T) -> Result<(), String> { @@ -47,6 +50,7 @@ impl< .await .map(|ns| ns.name.clone()) .unwrap_or_else(|| self.application.name()); + let domain = topology.get_domain().await.unwrap(); let mut alerting_score = ApplicationMonitoringScore { sender: CRDPrometheus { @@ -58,19 +62,17 @@ impl< }; let ntfy = NtfyScore { namespace: namespace.clone(), - host: "ntfy.harmonydemo.apps.ncd0.harmony.mcd".to_string(), + host: format!("ntfy.{domain}"), }; ntfy.interpret(&Inventory::empty(), topology) .await .map_err(|e| e.to_string())?; - let ntfy_default_auth_username = "harmony"; - let ntfy_default_auth_password = "harmony"; + let config = SecretManager::get_or_prompt::().await.unwrap(); + let ntfy_default_auth_header = format!( "Basic {}", - general_purpose::STANDARD.encode(format!( - "{ntfy_default_auth_username}:{ntfy_default_auth_password}" - )) + general_purpose::STANDARD.encode(format!("{}:{}", config.username, config.password)) ); debug!("ntfy_default_auth_header: {ntfy_default_auth_header}"); @@ -100,9 +102,17 @@ impl< .interpret(&Inventory::empty(), topology) .await .map_err(|e| e.to_string())?; + Ok(()) } + fn name(&self) -> String { "Monitoring".to_string() } } + +#[derive(Secret, Serialize, Deserialize, Clone, Debug)] +struct NtfyAuth { + username: String, + password: String, +} diff --git a/harmony/src/modules/application/oci.rs b/harmony/src/modules/application/oci.rs index 4085aa0..8b1585c 100644 --- a/harmony/src/modules/application/oci.rs +++ b/harmony/src/modules/application/oci.rs @@ -16,9 +16,10 @@ pub trait HelmPackage: Application { /// /// # Arguments /// * `image_url` - The full URL of the OCI container image to be used in the Deployment. + /// * `domain` - The domain where the application is hosted. async fn build_push_helm_package( &self, image_url: &str, - domain_host: &str, + domain: &str, ) -> Result; } diff --git a/harmony/src/modules/application/rust.rs b/harmony/src/modules/application/rust.rs index b56ac94..c16d665 100644 --- a/harmony/src/modules/application/rust.rs +++ b/harmony/src/modules/application/rust.rs @@ -73,13 +73,13 @@ impl HelmPackage for RustWebapp { async fn build_push_helm_package( &self, image_url: &str, - domain_host: &str, + domain: &str, ) -> Result { info!("Starting Helm chart build and push for '{}'", self.name); // 1. Create the Helm chart files on disk. let chart_dir = self - .create_helm_chart_files(image_url, domain_host) + .create_helm_chart_files(image_url, domain) .await .map_err(|e| format!("Failed to create Helm chart files: {}", e))?; info!("Successfully created Helm chart files in {:?}", chart_dir); @@ -413,7 +413,7 @@ impl RustWebapp { async fn create_helm_chart_files( &self, image_url: &str, - domain_host: &str, + domain: &str, ) -> Result> { let chart_name = format!("{}-chart", self.name); let chart_dir = self @@ -425,9 +425,7 @@ impl RustWebapp { fs::create_dir_all(&templates_dir)?; let (image_repo, image_tag) = image_url.rsplit_once(':').unwrap_or((image_url, "latest")); - - //TODO need to find a way to use topology to get the domain - let domain = format!("{}.{domain_host}", self.name); + let domain = format!("{}.{domain}", self.name); // Create Chart.yaml let chart_yaml = format!(