From b0ad7bb4c42bda545c0db2f7ecd3754d03cf9f74 Mon Sep 17 00:00:00 2001 From: Jean-Gabriel Gill-Couture Date: Tue, 14 Oct 2025 15:19:12 -0400 Subject: [PATCH] feat(application): Webapp feature with production dns --- harmony/src/domain/topology/mod.rs | 2 +- .../application/features/helm_argocd_score.rs | 3 ++- .../features/packaging_deployment.rs | 20 +++++++++++-------- harmony/src/modules/application/mod.rs | 1 + harmony/src/modules/application/rust.rs | 12 ++++++++++- harmony/src/modules/application/webapp.rs | 7 +++++++ 6 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 harmony/src/modules/application/webapp.rs diff --git a/harmony/src/domain/topology/mod.rs b/harmony/src/domain/topology/mod.rs index 85e57d7..bf99a42 100644 --- a/harmony/src/domain/topology/mod.rs +++ b/harmony/src/domain/topology/mod.rs @@ -186,7 +186,7 @@ impl TopologyState { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum DeploymentTarget { LocalDev, Staging, diff --git a/harmony/src/modules/application/features/helm_argocd_score.rs b/harmony/src/modules/application/features/helm_argocd_score.rs index ea53691..de08fd0 100644 --- a/harmony/src/modules/application/features/helm_argocd_score.rs +++ b/harmony/src/modules/application/features/helm_argocd_score.rs @@ -57,8 +57,9 @@ impl Interpret for ArgoInter let k8s_client = topology.k8s_client().await?; let svc = format!("argo-{}", self.score.namespace.clone()); let domain = topology.get_domain(&svc).await?; + // FIXME we now have a way to know if we're running on openshift family 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); helm_score.interpret(inventory, topology).await?; diff --git a/harmony/src/modules/application/features/packaging_deployment.rs b/harmony/src/modules/application/features/packaging_deployment.rs index 4fafbf0..0da3393 100644 --- a/harmony/src/modules/application/features/packaging_deployment.rs +++ b/harmony/src/modules/application/features/packaging_deployment.rs @@ -10,12 +10,11 @@ use crate::{ data::Version, inventory::Inventory, modules::application::{ - ApplicationFeature, HelmPackage, InstallationError, InstallationOutcome, OCICompliant, - features::{ArgoApplication, ArgoHelmScore}, + features::{ArgoApplication, ArgoHelmScore}, webapp::Webapp, ApplicationFeature, HelmPackage, InstallationError, InstallationOutcome, OCICompliant }, score::Score, topology::{ - DeploymentTarget, HelmCommand, K8sclient, MultiTargetTopology, Topology, ingress::Ingress, + ingress::Ingress, DeploymentTarget, HelmCommand, K8sclient, MultiTargetTopology, Topology }, }; @@ -47,11 +46,11 @@ use crate::{ /// - ArgoCD to install/upgrade/rollback/inspect k8s resources /// - Kubernetes for runtime orchestration #[derive(Debug, Default, Clone)] -pub struct PackagingDeployment { +pub struct PackagingDeployment { pub application: Arc, } -impl PackagingDeployment { +impl PackagingDeployment { async fn deploy_to_local_k3d( &self, app_name: String, @@ -137,7 +136,7 @@ impl PackagingDeployment { #[async_trait] impl< - A: OCICompliant + HelmPackage + Clone + 'static, + A: OCICompliant + HelmPackage + Webapp + Clone + 'static, T: Topology + HelmCommand + MultiTargetTopology + K8sclient + Ingress + 'static, > ApplicationFeature for PackagingDeployment { @@ -146,10 +145,15 @@ impl< topology: &T, ) -> Result { let image = self.application.image_name(); - let domain = topology + + let domain = if topology.current_target() == DeploymentTarget::Production { + self.application.dns() + } else { + topology .get_domain(&self.application.name()) .await - .map_err(|e| e.to_string())?; + .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 diff --git a/harmony/src/modules/application/mod.rs b/harmony/src/modules/application/mod.rs index b7bb973..03965e3 100644 --- a/harmony/src/modules/application/mod.rs +++ b/harmony/src/modules/application/mod.rs @@ -2,6 +2,7 @@ mod feature; pub mod features; pub mod oci; mod rust; +mod webapp; use std::sync::Arc; pub use feature::*; diff --git a/harmony/src/modules/application/rust.rs b/harmony/src/modules/application/rust.rs index 4874798..4cd0739 100644 --- a/harmony/src/modules/application/rust.rs +++ b/harmony/src/modules/application/rust.rs @@ -16,6 +16,7 @@ use tar::{Builder, Header}; use walkdir::WalkDir; use crate::config::{REGISTRY_PROJECT, REGISTRY_URL}; +use crate::modules::application::webapp::Webapp; use crate::{score::Score, topology::Topology}; use super::{Application, ApplicationFeature, ApplicationInterpret, HelmPackage, OCICompliant}; @@ -60,6 +61,10 @@ pub struct RustWebapp { pub project_root: PathBuf, pub service_port: u32, pub framework: Option, + /// Host name that will be used in production environment. + /// + /// This is the place to put the public host name if this is a public facing webapp. + pub dns: String, } impl Application for RustWebapp { @@ -68,6 +73,12 @@ impl Application for RustWebapp { } } +impl Webapp for RustWebapp { + fn dns(&self) -> String { + self.dns.clone() + } +} + #[async_trait] impl HelmPackage for RustWebapp { async fn build_push_helm_package( @@ -257,7 +268,6 @@ impl RustWebapp { ".harmony_generated", "harmony", "node_modules", - "Dockerfile.harmony", ]; let mut entries: Vec<_> = WalkDir::new(project_root) .into_iter() diff --git a/harmony/src/modules/application/webapp.rs b/harmony/src/modules/application/webapp.rs new file mode 100644 index 0000000..1e17d70 --- /dev/null +++ b/harmony/src/modules/application/webapp.rs @@ -0,0 +1,7 @@ +use super::Application; +use async_trait::async_trait; + +#[async_trait] +pub trait Webapp: Application { + fn dns(&self) -> String; +}