diff --git a/harmony/src/domain/topology/tenant/k8s.rs b/harmony/src/domain/topology/tenant/k8s.rs index f3a7cb2..36cf9f0 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", @@ -362,6 +399,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)?; @@ -371,6 +409,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?; 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() + } +}