From 4baa3ae707f5a7901a176d07a89846b313407d09 Mon Sep 17 00:00:00 2001 From: Willem Date: Wed, 2 Jul 2025 14:06:08 -0400 Subject: [PATCH 1/2] feat: added default resource limit and request to k8s tenant --- harmony/src/domain/topology/tenant/k8s.rs | 43 ++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/harmony/src/domain/topology/tenant/k8s.rs b/harmony/src/domain/topology/tenant/k8s.rs index 705b0c4..3f94caa 100644 --- a/harmony/src/domain/topology/tenant/k8s.rs +++ b/harmony/src/domain/topology/tenant/k8s.rs @@ -8,7 +8,7 @@ use async_trait::async_trait; use derive_new::new; use k8s_openapi::{ api::{ - core::v1::{Namespace, ResourceQuota}, + core::v1::{LimitRange, Namespace, ResourceQuota}, networking::v1::{ NetworkPolicy, NetworkPolicyEgressRule, NetworkPolicyIngressRule, NetworkPolicyPort, }, @@ -132,6 +132,43 @@ impl K8sTenantManager { }) } + fn build_limit_range(&self, config: &TenantConfig) -> Result { + let limit_range = json!({ + "apiVersion": "v1", + "kind": "LimitRange", + "metadata": { + "name": format!("{}-defaults", config.name), + "labels": { + "harmony.nationtech.io/tenant.id": config.id.to_string(), + "harmony.nationtech.io/tenant.name": config.name, + }, + "namespace": self.get_namespace_name(config), + }, + "spec": { + "limits": [ + { + "type": "Container", + "default": { + "cpu": "500m", + "memory": "500Mi" + }, + "defaultRequest": { + "cpu": "100m", + "memory": "100Mi" + }, + } + ] + } + }); + + serde_json::from_value(limit_range).map_err(|e| { + ExecutorError::ConfigurationError(format!( + "Could not build TenantManager LimitRange. {}", + e + )) + }) + } + fn build_network_policy(&self, config: &TenantConfig) -> Result { let network_policy = json!({ "apiVersion": "networking.k8s.io/v1", @@ -328,6 +365,7 @@ impl TenantManager for K8sTenantManager { let namespace = self.build_namespace(config)?; let resource_quota = self.build_resource_quota(config)?; let network_policy = self.build_network_policy(config)?; + let resource_limit_range = self.build_limit_range(config)?; self.ensure_constraints(&namespace)?; @@ -337,6 +375,9 @@ impl TenantManager for K8sTenantManager { debug!("Creating resource_quota for tenant {}", config.name); self.apply_resource(resource_quota, config).await?; + debug!("Creating limit_range for tenant {}", config.name); + self.apply_resource(resource_limit_range, config).await?; + debug!("Creating network_policy for tenant {}", config.name); self.apply_resource(network_policy, config).await?; From e50c01c0b3345eba37966d162279072d59605d40 Mon Sep 17 00:00:00 2001 From: Jean-Gabriel Gill-Couture Date: Wed, 2 Jul 2025 15:11:03 -0400 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20Forgotten=20file=20=F0=9F=99=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- harmony/src/modules/application/feature.rs | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 harmony/src/modules/application/feature.rs diff --git a/harmony/src/modules/application/feature.rs b/harmony/src/modules/application/feature.rs new file mode 100644 index 0000000..9c12553 --- /dev/null +++ b/harmony/src/modules/application/feature.rs @@ -0,0 +1,41 @@ +use async_trait::async_trait; +use serde::Serialize; + +use crate::topology::Topology; +/// An ApplicationFeature provided by harmony, such as Backups, Monitoring, MultisiteAvailability, +/// ContinuousIntegration, ContinuousDelivery +#[async_trait] +pub trait ApplicationFeature: + std::fmt::Debug + Send + Sync + ApplicationFeatureClone +{ + async fn ensure_installed(&self, topology: &T) -> Result<(), String>; + fn name(&self) -> String; +} + +trait ApplicationFeatureClone { + fn clone_box(&self) -> Box>; +} + +impl ApplicationFeatureClone for A +where + A: ApplicationFeature + Clone + 'static, +{ + fn clone_box(&self) -> Box> { + Box::new(self.clone()) + } +} + +impl Serialize for Box> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + todo!() + } +} + +impl Clone for Box> { + fn clone(&self) -> Self { + self.clone_box() + } +}