fix: unjank the demo #85
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -2,3 +2,7 @@ target | ||||
| private_repos | ||||
| log/ | ||||
| *.tgz | ||||
| examples/rust/examples/rust/webapp/helm/ | ||||
|  | ||||
| examples/rust/examples/rust/webapp/Dockerfile.harmony | ||||
| examples/rust/webapp/helm/harmony-example-rust-webapp-chart/ | ||||
| .gitignore | ||||
|  | ||||
							
								
								
									
										1
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -1726,6 +1726,7 @@ name = "harmony" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "async-trait", | ||||
|  "bollard", | ||||
|  "chrono", | ||||
|  "cidr", | ||||
|  "convert_case", | ||||
|  | ||||
| @ -53,3 +53,4 @@ chrono = "0.4" | ||||
| similar = "2" | ||||
| uuid = { version = "1.11", features = ["v4", "fast-rng", "macro-diagnostics"] } | ||||
| pretty_assertions = "1.4.1" | ||||
| bollard = "0.19.1" | ||||
|  | ||||
| @ -1,18 +1,41 @@ | ||||
| use std::{path::PathBuf, sync::Arc}; | ||||
| 
 | ||||
| use harmony::{ | ||||
|     data::Id, | ||||
|     inventory::Inventory, | ||||
|     maestro::Maestro, | ||||
|     modules::application::{ | ||||
|         ApplicationScore, RustWebFramework, RustWebapp, | ||||
|         features::{ContinuousDelivery, Monitoring}, | ||||
|     modules::{ | ||||
|         application::{ | ||||
|             ApplicationScore, RustWebFramework, RustWebapp, | ||||
|             features::{ContinuousDelivery, Monitoring}, | ||||
|         }, | ||||
|         tenant::TenantScore, | ||||
|     }, | ||||
|     topology::{ | ||||
|         K8sAnywhereTopology, Url, | ||||
|         tenant::{ResourceLimits, TenantConfig, TenantNetworkPolicy}, | ||||
|     }, | ||||
|     topology::{K8sAnywhereTopology, Url}, | ||||
| }; | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main() { | ||||
|     env_logger::init(); | ||||
| 
 | ||||
|     let tenant = TenantScore { | ||||
|         config: TenantConfig { | ||||
|             id: Id::from_string("1234".to_string()), | ||||
|             name: "harmonydemo-staging".to_string(), | ||||
|             resource_limits: ResourceLimits { | ||||
|                 cpu_request_cores: 6.0, | ||||
|                 cpu_limit_cores: 4.0, | ||||
|                 memory_request_gb: 4.0, | ||||
|                 memory_limit_gb: 4.0, | ||||
|                 storage_total_gb: 10.0, | ||||
|             }, | ||||
|             network_policy: TenantNetworkPolicy::default(), | ||||
|         }, | ||||
|     }; | ||||
| 
 | ||||
|     let application = Arc::new(RustWebapp { | ||||
|         name: "harmony-example-rust-webapp".to_string(), | ||||
|         domain: Url::Url(url::Url::parse("https://rustapp.harmony.example.com").unwrap()), | ||||
| @ -35,6 +58,6 @@ async fn main() { | ||||
|     let mut maestro = Maestro::initialize(Inventory::autoload(), topology) | ||||
|         .await | ||||
|         .unwrap(); | ||||
|     maestro.register_all(vec![Box::new(app)]); | ||||
|     maestro.register_all(vec![Box::new(tenant), Box::new(app)]); | ||||
|     harmony_cli::init(maestro, None).await.unwrap(); | ||||
| } | ||||
|  | ||||
| @ -59,6 +59,7 @@ tokio-util = "0.7.15" | ||||
| strum = { version = "0.27.1", features = ["derive"] } | ||||
| tempfile = "3.20.0" | ||||
| serde_with = "3.14.0" | ||||
| bollard.workspace = true | ||||
| 
 | ||||
| [dev-dependencies] | ||||
| pretty_assertions.workspace = true | ||||
|  | ||||
| @ -1,6 +1,3 @@ | ||||
| use std::{backtrace, collections::HashMap}; | ||||
| 
 | ||||
| use k8s_openapi::{Metadata, NamespaceResourceScope, Resource}; | ||||
| use log::debug; | ||||
| use serde::Serialize; | ||||
| use serde_with::skip_serializing_none; | ||||
| @ -34,10 +31,11 @@ pub struct Helm { | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub struct Source { | ||||
|     #[serde(rename = "repoURL")] | ||||
|     pub repo_url: Url, | ||||
|     pub repo_url: String, | ||||
|     pub target_revision: Option<String>, | ||||
|     pub chart: String, | ||||
|     pub helm: Helm, | ||||
|     pub path: String, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, Serialize)] | ||||
| @ -90,7 +88,7 @@ impl Default for ArgoApplication { | ||||
|             namespace: Default::default(), | ||||
|             project: Default::default(), | ||||
|             source: Source { | ||||
|                 repo_url: Url::parse("http://asdf").expect("Couldn't parse to URL"), | ||||
|                 repo_url: "http://asdf".to_string(), | ||||
|                 target_revision: None, | ||||
|                 chart: "".to_string(), | ||||
|                 helm: Helm { | ||||
| @ -109,6 +107,7 @@ impl Default for ArgoApplication { | ||||
|                     api_versions: vec![], | ||||
|                     namespace: None, | ||||
|                 }, | ||||
|                 path: "".to_string(), | ||||
|             }, | ||||
|             sync_policy: SyncPolicy { | ||||
|                 automated: Automated { | ||||
| @ -138,10 +137,10 @@ impl From<CDApplicationConfig> for ArgoApplication { | ||||
|             namespace: Some(value.namespace), | ||||
|             project: "default".to_string(), | ||||
|             source: Source { | ||||
|                 repo_url: Url::parse(value.helm_chart_repo_url.to_string().as_str()) | ||||
|                     .expect("couldn't convert to URL"), | ||||
|                 repo_url: value.helm_chart_repo_url, | ||||
|                 target_revision: Some(value.version.to_string()), | ||||
|                 chart: value.helm_chart_name, | ||||
|                 chart: value.helm_chart_name.clone(), | ||||
|                 path: value.helm_chart_name, | ||||
|                 helm: Helm { | ||||
|                     pass_credentials: None, | ||||
|                     parameters: vec![], | ||||
| @ -218,7 +217,7 @@ spec: | ||||
|         let mut yaml_value: Value = | ||||
|             serde_yaml::from_str(yaml_str.as_str()).expect("couldn't parse string to YAML"); | ||||
| 
 | ||||
|         let mut spec = yaml_value | ||||
|         let spec = yaml_value | ||||
|             .get_mut("spec") | ||||
|             .expect("couldn't get spec from yaml") | ||||
|             .as_mapping_mut() | ||||
| @ -271,7 +270,7 @@ mod tests { | ||||
|             namespace: Some("test-ns".to_string()), | ||||
|             project: "test-project".to_string(), | ||||
|             source: Source { | ||||
|                 repo_url: Url::parse("http://test").unwrap(), | ||||
|                 repo_url: "http://test".to_string(), | ||||
|                 target_revision: None, | ||||
|                 chart: "test-chart".to_string(), | ||||
|                 helm: Helm { | ||||
| @ -290,6 +289,7 @@ mod tests { | ||||
|                     api_versions: vec![], | ||||
|                     namespace: None, | ||||
|                 }, | ||||
|                 path: "".to_string(), | ||||
|             }, | ||||
|             sync_policy: SyncPolicy { | ||||
|                 automated: Automated { | ||||
|  | ||||
| @ -9,12 +9,9 @@ use crate::{ | ||||
|     config::HARMONY_DATA_DIR, | ||||
|     data::Version, | ||||
|     inventory::Inventory, | ||||
|     modules::{ | ||||
|         application::{ | ||||
|             Application, ApplicationFeature, HelmPackage, OCICompliant, | ||||
|             features::{ArgoApplication, ArgoHelmScore}, | ||||
|         }, | ||||
|         helm::chart::HelmChartScore, | ||||
|     modules::application::{ | ||||
|         Application, ApplicationFeature, HelmPackage, OCICompliant, | ||||
|         features::{ArgoApplication, ArgoHelmScore}, | ||||
|     }, | ||||
|     score::Score, | ||||
|     topology::{DeploymentTarget, HelmCommand, K8sclient, MultiTargetTopology, Topology, Url}, | ||||
| @ -162,7 +159,7 @@ impl< | ||||
|         info!("Pushed new helm chart {helm_chart}"); | ||||
| 
 | ||||
|         error!("TODO Make building image configurable/skippable"); | ||||
|         let image = self.application.build_push_oci_image().await?; | ||||
|         // let image = self.application.build_push_oci_image().await?;
 | ||||
|         info!("Pushed new docker image {image}"); | ||||
| 
 | ||||
|         info!("Installing ContinuousDelivery feature"); | ||||
| @ -188,12 +185,12 @@ impl< | ||||
|                 info!("Deploying to target {target:?}"); | ||||
|                 let score = ArgoHelmScore { | ||||
|                     namespace: "harmonydemo-staging".to_string(), | ||||
|                     openshift: true, | ||||
|                     openshift: false, | ||||
|                     domain: "argo.harmonydemo.apps.st.mcd".to_string(), | ||||
|                     argo_apps: vec![ArgoApplication::from(CDApplicationConfig { | ||||
|                         // helm pull oci://hub.nationtech.io/harmony/harmony-example-rust-webapp-chart/harmony-example-rust-webapp-chart --version 0.1.0
 | ||||
|                         // helm pull oci://hub.nationtech.io/harmony/harmony-example-rust-webapp-chart --version 0.1.0
 | ||||
|                         version: Version::from("0.1.0").unwrap(), | ||||
|                         helm_chart_repo_url: Url::Url(url::Url::parse("oci://hub.nationtech.io/harmony/harmony-example-rust-webapp-chart/harmony-example-rust-webapp-chart").unwrap()), | ||||
|                         helm_chart_repo_url: "hub.nationtech.io/harmony".to_string(), | ||||
|                         helm_chart_name: "harmony-example-rust-webapp-chart".to_string(), | ||||
|                         values_overrides: None, | ||||
|                         name: "harmony-demo-rust-webapp".to_string(), | ||||
| @ -225,7 +222,7 @@ impl< | ||||
| /// more CD systems
 | ||||
| pub struct CDApplicationConfig { | ||||
|     pub version: Version, | ||||
|     pub helm_chart_repo_url: Url, | ||||
|     pub helm_chart_repo_url: String, | ||||
|     pub helm_chart_name: String, | ||||
|     pub values_overrides: Option<Value>, | ||||
|     pub name: String, | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| use async_trait::async_trait; | ||||
| use k8s_openapi::Resource; | ||||
| use log::error; | ||||
| use non_blank_string_rs::NonBlankString; | ||||
| use serde::Serialize; | ||||
| @ -647,7 +646,7 @@ server: | ||||
|   # Argo CD server ingress configuration | ||||
|   ingress: | ||||
|     # -- Enable an ingress resource for the Argo CD server | ||||
|     enabled: false | ||||
|     enabled: true | ||||
|     # -- Specific implementation for ingress controller. One of `generic`, `aws` or `gke` | ||||
|     ## Additional configuration might be required in related configuration sections | ||||
|     controller: generic | ||||
|  | ||||
| @ -4,13 +4,10 @@ use log::info; | ||||
| use crate::{ | ||||
|     inventory::Inventory, | ||||
|     modules::{ | ||||
|         application::{Application, ApplicationFeature}, | ||||
|         application::ApplicationFeature, | ||||
|         monitoring::{ | ||||
|             application_monitoring::k8s_application_monitoring_score::ApplicationPrometheusMonitoringScore, | ||||
|             kube_prometheus::{ | ||||
|                 helm_prometheus_alert_score::HelmPrometheusAlertingScore, | ||||
|                 types::{NamespaceSelector, ServiceMonitor}, | ||||
|             }, | ||||
|             kube_prometheus::types::{NamespaceSelector, ServiceMonitor}, | ||||
|         }, | ||||
|     }, | ||||
|     score::Score, | ||||
|  | ||||
| @ -416,7 +416,7 @@ ingress: | ||||
| Expand the name of the chart. | ||||
| */}} | ||||
| {{- define "chart.name" -}} | ||||
| {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} | ||||
| {{- default .Chart.Name $.Values.nameOverride | trunc 63 | trimSuffix "-" }} | ||||
| {{- end }} | ||||
| 
 | ||||
| {{/* | ||||
| @ -424,7 +424,7 @@ Create a default fully qualified app name. | ||||
| We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). | ||||
| */}} | ||||
| {{- define "chart.fullname" -}} | ||||
| {{- $name := default .Chart.Name .Values.nameOverride }} | ||||
| {{- $name := default .Chart.Name $.Values.nameOverride }} | ||||
| {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} | ||||
| {{- end }} | ||||
| "#;
 | ||||
| @ -437,12 +437,12 @@ kind: Service | ||||
| metadata: | ||||
|   name: {{ include "chart.fullname" . }} | ||||
| spec: | ||||
|   type: {{ .Values.service.type }} | ||||
|   type: {{ $.Values.service.type }} | ||||
|   ports: | ||||
|     - port: {{ .Values.service.port }} | ||||
|       targetPort: 3000 | ||||
|     - name: main | ||||
|       port: {{ $.Values.service.port | default 3000 }} | ||||
|       targetPort: {{ $.Values.service.port | default 3000 }} | ||||
|       protocol: TCP | ||||
|       name: http | ||||
|   selector: | ||||
|     app: {{ include "chart.name" . }} | ||||
| "#;
 | ||||
| @ -455,7 +455,7 @@ kind: Deployment | ||||
| metadata: | ||||
| 
				
					
						johnride
						commented  Thanks for fixing my demo hardcoding crap 😅 Thanks for fixing my demo hardcoding crap 😅 | ||||
|   name: {{ include "chart.fullname" . }} | ||||
| spec: | ||||
|   replicas: {{ .Values.replicaCount }} | ||||
|   replicas: {{ $.Values.replicaCount }} | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app: {{ include "chart.name" . }} | ||||
| @ -466,28 +466,28 @@ spec: | ||||
|     spec: | ||||
|       containers: | ||||
|         - name: {{ .Chart.Name }} | ||||
|           image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" | ||||
|           imagePullPolicy: {{ .Values.image.pullPolicy }} | ||||
|           image: "{{ $.Values.image.repository }}:{{ $.Values.image.tag | default .Chart.AppVersion }}" | ||||
|           imagePullPolicy: {{ $.Values.image.pullPolicy }} | ||||
|           ports: | ||||
|             - name: http | ||||
|               containerPort: 3000 | ||||
|             - name: main | ||||
|               containerPort: {{ $.Values.service.port | default 3000 }} | ||||
|               protocol: TCP | ||||
| "#;
 | ||||
|         fs::write(templates_dir.join("deployment.yaml"), deployment_yaml)?; | ||||
| 
 | ||||
|         // Create templates/ingress.yaml
 | ||||
|         let ingress_yaml = r#" | ||||
| {{- if .Values.ingress.enabled -}} | ||||
| {{- if $.Values.ingress.enabled -}} | ||||
| apiVersion: networking.k8s.io/v1 | ||||
| kind: Ingress | ||||
| metadata: | ||||
|   name: {{ include "chart.fullname" . }} | ||||
|   annotations: | ||||
|     {{- toYaml .Values.ingress.annotations | nindent 4 }} | ||||
|     {{- toYaml $.Values.ingress.annotations | nindent 4 }} | ||||
| spec: | ||||
|   {{- if .Values.ingress.tls }} | ||||
|   {{- if $.Values.ingress.tls }} | ||||
|   tls: | ||||
|     {{- range .Values.ingress.tls }} | ||||
|     {{- range $.Values.ingress.tls }} | ||||
|     - hosts: | ||||
|         {{- range .hosts }} | ||||
|         - {{ . | quote }} | ||||
| @ -496,7 +496,7 @@ spec: | ||||
|     {{- end }} | ||||
|   {{- end }} | ||||
|   rules: | ||||
|     {{- range .Values.ingress.hosts }} | ||||
|     {{- range $.Values.ingress.hosts }} | ||||
|     - host: {{ .host | quote }} | ||||
|       http: | ||||
|         paths: | ||||
| @ -507,7 +507,7 @@ spec: | ||||
|               service: | ||||
|                 name: {{ include "chart.fullname" $ }} | ||||
|                 port: | ||||
|                   number: 3000 | ||||
|                   number: {{ $.Values.service.port | default 3000 }} | ||||
|           {{- end }} | ||||
|     {{- end }} | ||||
| {{- end }} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	
These would be better in the examples's own gitignore file
examples/rust/.gitignore. Eventually we may have hundreds of examples, we don't want thousands of lines in this file.But thinking a bit further, this points towards a problem on the way we manage these generated files. They should probably end up in a harmony specific directory that we can then ignore in a single line for all examples. Maybe
harmony_generatedorharmony_build?