forked from NationTech/harmony
use topology domain to build & push helm package for continuous deliery
This commit is contained in:
parent
54803c40a2
commit
3bf5cb0526
@ -27,7 +27,6 @@ async fn main() {
|
||||
};
|
||||
let application = Arc::new(RustWebapp {
|
||||
name: "example-monitoring".to_string(),
|
||||
domain: Url::Url(url::Url::parse("https://rustapp.harmony.example.com").unwrap()),
|
||||
project_root: PathBuf::from("./examples/rust/webapp"),
|
||||
framework: Some(RustWebFramework::Leptos),
|
||||
service_port: 3000,
|
||||
|
@ -17,7 +17,6 @@ use harmony_types::net::Url;
|
||||
async fn main() {
|
||||
let application = Arc::new(RustWebapp {
|
||||
name: "test-rhob-monitoring".to_string(),
|
||||
domain: Url::Url(url::Url::parse("htps://some-fake-url").unwrap()),
|
||||
project_root: PathBuf::from("./webapp"), // Relative from 'harmony-path' param
|
||||
framework: Some(RustWebFramework::Leptos),
|
||||
service_port: 3000,
|
||||
|
@ -19,7 +19,6 @@ use harmony_macros::hurl;
|
||||
async fn main() {
|
||||
let application = Arc::new(RustWebapp {
|
||||
name: "harmony-example-rust-webapp".to_string(),
|
||||
domain: hurl!("https://rustapp.harmony.example.com"),
|
||||
project_root: PathBuf::from("./webapp"),
|
||||
framework: Some(RustWebFramework::Leptos),
|
||||
service_port: 3000,
|
||||
|
@ -17,7 +17,6 @@ use harmony_types::net::Url;
|
||||
async fn main() {
|
||||
let application = Arc::new(RustWebapp {
|
||||
name: "harmony-example-tryrust".to_string(),
|
||||
domain: Url::Url(url::Url::parse("https://tryrust.harmony.example.com").unwrap()),
|
||||
project_root: PathBuf::from("./tryrust.org"),
|
||||
framework: Some(RustWebFramework::Leptos),
|
||||
service_port: 8080,
|
||||
|
@ -1,8 +1,7 @@
|
||||
use crate::topology::{PreparationError, k8s::K8sClient};
|
||||
use crate::topology::PreparationError;
|
||||
use async_trait::async_trait;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[async_trait]
|
||||
pub trait Ingress {
|
||||
async fn get_domain(&self, client: Arc<K8sClient>) -> Result<String, PreparationError>;
|
||||
async fn get_domain(&self) -> Result<String, PreparationError>;
|
||||
}
|
||||
|
@ -576,7 +576,9 @@ impl TenantManager for K8sAnywhereTopology {
|
||||
#[async_trait]
|
||||
impl Ingress for K8sAnywhereTopology {
|
||||
//TODO this is specifically for openshift/okd which violates the k8sanywhere idea
|
||||
async fn get_domain(&self, client: Arc<K8sClient>) -> Result<String, PreparationError> {
|
||||
async fn get_domain(&self) -> Result<String, PreparationError> {
|
||||
let client = self.k8s_client().await?;
|
||||
|
||||
if let Some(Some(k8s_state)) = self.k8s_state.get() {
|
||||
match k8s_state.source {
|
||||
K8sSource::LocalK3d => Ok("localhost".to_string()),
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{io::Write, process::Command, sync::Arc};
|
||||
use std::{io::Write, marker::PhantomData, process::Command, sync::Arc};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use log::info;
|
||||
@ -10,10 +10,13 @@ use crate::{
|
||||
data::Version,
|
||||
inventory::Inventory,
|
||||
modules::application::{
|
||||
features::{ArgoApplication, ArgoHelmScore}, ApplicationFeature, HelmPackage, OCICompliant
|
||||
ApplicationFeature, HelmPackage, OCICompliant,
|
||||
features::{ArgoApplication, ArgoHelmScore},
|
||||
},
|
||||
score::Score,
|
||||
topology::{ingress::Ingress, DeploymentTarget, HelmCommand, K8sclient, MultiTargetTopology, Topology},
|
||||
topology::{
|
||||
DeploymentTarget, HelmCommand, K8sclient, MultiTargetTopology, Topology, ingress::Ingress,
|
||||
},
|
||||
};
|
||||
|
||||
/// ContinuousDelivery in Harmony provides this functionality :
|
||||
@ -140,13 +143,17 @@ 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())?;
|
||||
|
||||
// TODO Write CI/CD workflow files
|
||||
// we can autotedect the CI type using the remote url (default to github action for github
|
||||
// url, etc..)
|
||||
// Or ask for it when unknown
|
||||
|
||||
let helm_chart = self.application.build_push_helm_package(&image).await?;
|
||||
let helm_chart = self
|
||||
.application
|
||||
.build_push_helm_package(&image, &domain_host)
|
||||
.await?;
|
||||
|
||||
// TODO: Make building image configurable/skippable if image already exists (prompt)")
|
||||
// https://git.nationtech.io/NationTech/harmony/issues/104
|
||||
|
@ -55,7 +55,7 @@ impl<T: Topology + K8sclient + HelmCommand + Ingress> Interpret<T> for ArgoInter
|
||||
topology: &T,
|
||||
) -> Result<Outcome, InterpretError> {
|
||||
let k8s_client = topology.k8s_client().await?;
|
||||
let domain = topology.get_domain(k8s_client.clone()).await?;
|
||||
let domain = topology.get_domain().await?;
|
||||
let domain = format!("argo.{domain}");
|
||||
let helm_score =
|
||||
argo_helm_chart_score(&self.score.namespace, self.score.openshift, &domain);
|
||||
|
@ -1,6 +1,5 @@
|
||||
use async_trait::async_trait;
|
||||
|
||||
use super::Application;
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait]
|
||||
pub trait OCICompliant: Application {
|
||||
@ -17,5 +16,9 @@ pub trait HelmPackage: Application {
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `image_url` - The full URL of the OCI container image to be used in the Deployment.
|
||||
async fn build_push_helm_package(&self, image_url: &str) -> Result<String, String>;
|
||||
async fn build_push_helm_package(
|
||||
&self,
|
||||
image_url: &str,
|
||||
domain_host: &str,
|
||||
) -> Result<String, String>;
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::fs::{self, File};
|
||||
use std::io::Read;
|
||||
use std::fs::{self};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use std::sync::Arc;
|
||||
@ -13,12 +12,11 @@ use dockerfile_builder::instruction_builder::CopyBuilder;
|
||||
use futures_util::StreamExt;
|
||||
use log::{debug, info, log_enabled};
|
||||
use serde::Serialize;
|
||||
use tar::{Archive, Builder, Header};
|
||||
use tar::{Builder, Header};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::config::{REGISTRY_PROJECT, REGISTRY_URL};
|
||||
use crate::{score::Score, topology::Topology};
|
||||
use harmony_types::net::Url;
|
||||
|
||||
use super::{Application, ApplicationFeature, ApplicationInterpret, HelmPackage, OCICompliant};
|
||||
|
||||
@ -58,7 +56,6 @@ pub enum RustWebFramework {
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct RustWebapp {
|
||||
pub name: String,
|
||||
pub domain: Url,
|
||||
/// The path to the root of the Rust project to be containerized.
|
||||
pub project_root: PathBuf,
|
||||
pub service_port: u32,
|
||||
@ -73,12 +70,17 @@ impl Application for RustWebapp {
|
||||
|
||||
#[async_trait]
|
||||
impl HelmPackage for RustWebapp {
|
||||
async fn build_push_helm_package(&self, image_url: &str) -> Result<String, String> {
|
||||
async fn build_push_helm_package(
|
||||
&self,
|
||||
image_url: &str,
|
||||
domain_host: &str,
|
||||
) -> Result<String, String> {
|
||||
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)
|
||||
.create_helm_chart_files(image_url, domain_host)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to create Helm chart files: {}", e))?;
|
||||
info!("Successfully created Helm chart files in {:?}", chart_dir);
|
||||
|
||||
@ -408,10 +410,10 @@ impl RustWebapp {
|
||||
}
|
||||
|
||||
/// Creates all necessary files for a basic Helm chart.
|
||||
fn create_helm_chart_files(
|
||||
async fn create_helm_chart_files(
|
||||
&self,
|
||||
image_url: &str,
|
||||
topology: &T,
|
||||
domain_host: &str,
|
||||
) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
||||
let chart_name = format!("{}-chart", self.name);
|
||||
let chart_dir = self
|
||||
@ -423,9 +425,9 @@ 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 = topology.get_domain(client.clone()).await?;
|
||||
let domain = format!("{}.{domain_host}", self.name);
|
||||
|
||||
// Create Chart.yaml
|
||||
let chart_yaml = format!(
|
||||
@ -478,7 +480,7 @@ ingress:
|
||||
- {}
|
||||
|
||||
"#,
|
||||
chart_name, image_repo, image_tag, self.service_port, domain, self.name
|
||||
chart_name, image_repo, image_tag, self.service_port, domain, self.name, domain
|
||||
);
|
||||
fs::write(chart_dir.join("values.yaml"), values_yaml)?;
|
||||
|
||||
|
@ -275,7 +275,7 @@ impl RHOBAlertingInterpret {
|
||||
.await
|
||||
.map_err(|e| InterpretError::new(e.to_string()))?;
|
||||
|
||||
let domain = topology.get_domain(client.clone()).await?;
|
||||
let domain = topology.get_domain().await?;
|
||||
let name = format!("{}-alert-manager", self.sender.namespace.clone());
|
||||
let backend_service = format!("{}-alert-manager", self.sender.namespace.clone());
|
||||
let namespace = self.sender.namespace.clone();
|
||||
@ -510,7 +510,7 @@ impl RHOBAlertingInterpret {
|
||||
.apply(&grafana, Some(&self.sender.namespace.clone()))
|
||||
.await
|
||||
.map_err(|e| InterpretError::new(e.to_string()))?;
|
||||
let domain = topology.get_domain(client.clone()).await?;
|
||||
let domain = topology.get_domain().await?;
|
||||
let name = format!("{}-grafana", self.sender.namespace.clone());
|
||||
let backend_service = format!("{}-grafana", self.sender.namespace.clone());
|
||||
let grafana_ingress = K8sIngressScore {
|
||||
|
Loading…
Reference in New Issue
Block a user