feat: add more to the tenantmanager k8s impl #46
| @ -15,9 +15,7 @@ use crate::{ | ||||
| }; | ||||
| 
 | ||||
| use super::{ | ||||
|     HelmCommand, K8sclient, Topology, | ||||
|     k8s::K8sClient, | ||||
|     tenant::{ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy}, | ||||
|     k8s::K8sClient, tenant::{k8s::K8sTenantManager, ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy}, HelmCommand, K8sclient, Topology | ||||
| }; | ||||
| 
 | ||||
| struct K8sState { | ||||
| @ -34,8 +32,10 @@ enum K8sSource { | ||||
| 
 | ||||
| pub struct K8sAnywhereTopology { | ||||
|     k8s_state: OnceCell<Option<K8sState>>, | ||||
|     tenant_manager: K8sTenantManager, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[async_trait] | ||||
| impl K8sclient for K8sAnywhereTopology { | ||||
|     async fn k8s_client(&self) -> Result<Arc<K8sClient>, String> { | ||||
| @ -216,80 +216,29 @@ impl Topology for K8sAnywhereTopology { | ||||
| 
 | ||||
| impl HelmCommand for K8sAnywhereTopology {} | ||||
| 
 | ||||
| #[async_trait] | ||||
| impl TenantManager for K8sAnywhereTopology { | ||||
|     fn provision_tenant<'life0, 'life1, 'async_trait>( | ||||
|         &'life0 self, | ||||
|         config: &'life1 TenantConfig, | ||||
|     ) -> ::core::pin::Pin< | ||||
|         Box< | ||||
|             dyn ::core::future::Future<Output = Result<(), ExecutorError>> | ||||
|                 + ::core::marker::Send | ||||
|                 + 'async_trait, | ||||
|         >, | ||||
|     > | ||||
|     where | ||||
|         'life0: 'async_trait, | ||||
|         'life1: 'async_trait, | ||||
|         Self: 'async_trait, | ||||
|     { | ||||
|         todo!() | ||||
|     async fn provision_tenant(&self, config: &TenantConfig) -> Result<(), ExecutorError> { | ||||
|         self.tenant_manager.provision_tenant(config).await | ||||
|     } | ||||
| 
 | ||||
|     fn update_tenant_resource_limits<'life0, 'life1, 'life2, 'async_trait>( | ||||
|         &'life0 self, | ||||
|         tenant_name: &'life1 str, | ||||
|         new_limits: &'life2 ResourceLimits, | ||||
|     ) -> ::core::pin::Pin< | ||||
|         Box< | ||||
|             dyn ::core::future::Future<Output = Result<(), ExecutorError>> | ||||
|                 + ::core::marker::Send | ||||
|                 + 'async_trait, | ||||
|         >, | ||||
|     > | ||||
|     where | ||||
|         'life0: 'async_trait, | ||||
|         'life1: 'async_trait, | ||||
|         'life2: 'async_trait, | ||||
|         Self: 'async_trait, | ||||
|     { | ||||
|         todo!() | ||||
|     async fn update_tenant_resource_limits( | ||||
|         &self, | ||||
|         tenant_name: &str, | ||||
|         new_limits: &ResourceLimits, | ||||
|     ) -> Result<(), ExecutorError> { | ||||
|         self.tenant_manager.update_tenant_resource_limits(tenant_name, new_limits).await | ||||
|     } | ||||
| 
 | ||||
|     fn update_tenant_network_policy<'life0, 'life1, 'life2, 'async_trait>( | ||||
|         &'life0 self, | ||||
|         tenant_name: &'life1 str, | ||||
|         new_policy: &'life2 TenantNetworkPolicy, | ||||
|     ) -> ::core::pin::Pin< | ||||
|         Box< | ||||
|             dyn ::core::future::Future<Output = Result<(), ExecutorError>> | ||||
|                 + ::core::marker::Send | ||||
|                 + 'async_trait, | ||||
|         >, | ||||
|     > | ||||
|     where | ||||
|         'life0: 'async_trait, | ||||
|         'life1: 'async_trait, | ||||
|         'life2: 'async_trait, | ||||
|         Self: 'async_trait, | ||||
|     { | ||||
|         todo!() | ||||
|     async fn update_tenant_network_policy( | ||||
|         &self, | ||||
|         tenant_name: &str, | ||||
|         new_policy: &TenantNetworkPolicy, | ||||
|     ) -> Result<(), ExecutorError> { | ||||
|         self.tenant_manager.update_tenant_network_policy(tenant_name, new_policy).await | ||||
|     } | ||||
| 
 | ||||
|     fn deprovision_tenant<'life0, 'life1, 'async_trait>( | ||||
|         &'life0 self, | ||||
|         tenant_name: &'life1 str, | ||||
|     ) -> ::core::pin::Pin< | ||||
|         Box< | ||||
|             dyn ::core::future::Future<Output = Result<(), ExecutorError>> | ||||
|                 + ::core::marker::Send | ||||
|                 + 'async_trait, | ||||
|         >, | ||||
|     > | ||||
|     where | ||||
|         'life0: 'async_trait, | ||||
|         'life1: 'async_trait, | ||||
|         Self: 'async_trait, | ||||
|     { | ||||
|         todo!() | ||||
|     async fn deprovision_tenant(&self, tenant_name: &str) -> Result<(), ExecutorError> { | ||||
|         self.tenant_manager.deprovision_tenant(tenant_name).await | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										88
									
								
								harmony/src/domain/topology/tenant/k8s.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								harmony/src/domain/topology/tenant/k8s.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| use crate::{executors::ExecutorError, topology::k8s::K8sClient}; | ||||
| use async_trait::async_trait; | ||||
| use k8s_openapi::api::core::v1::Namespace; | ||||
| use serde_json::json; | ||||
| 
 | ||||
| use super::{ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy}; | ||||
| 
 | ||||
| pub struct K8sTenantManager { | ||||
|     k8s_client: Arc<K8sClient>, | ||||
| } | ||||
| 
 | ||||
| #[async_trait] | ||||
| impl TenantManager for K8sTenantManager { | ||||
|     async fn provision_tenant(&self, config: &TenantConfig) -> Result<(), ExecutorError> { | ||||
|         let namespace = json!( | ||||
|             { | ||||
|                 "apiVersion": "v1", | ||||
|                 "kind": "Namespace", | ||||
|                 "metadata": { | ||||
|                     "labels": { | ||||
|                         "harmony.nationtech.io/tenant.id": config.id, | ||||
|                         "name": config.name, | ||||
| 
 | ||||
|                     }, | ||||
|                 "name": config.name, | ||||
|                 }, | ||||
|             } | ||||
|         ); | ||||
|        todo!("Validate that when tenant already exists (by id) that name has not changed"); 
 | ||||
| 
 | ||||
|        let namespace: Namespace = serde_json::from_value(namespace).unwrap(); | ||||
| 
 | ||||
| 
 | ||||
|        let resource_quota = json!( | ||||
|             { | ||||
|               "apiVersion": "v1", | ||||
|               "kind": "List", | ||||
|               "items": [ | ||||
|                 { | ||||
|                   "apiVersion": "v1", | ||||
|                   "kind": "ResourceQuota", | ||||
|                   "metadata": { | ||||
|                     "name": config.name | ||||
|                   }, | ||||
|                   "spec": { | ||||
|                     "hard": { | ||||
|                       "cpu": config.resource_limits.cpu_limit_cores, | ||||
|                       "memory": format!("{:.3}Gi", config.resource_limits.memory_limit_gb), | ||||
|                     }, | ||||
|                     "scopeSelector": { | ||||
|                       "matchExpressions": [ | ||||
|                         { | ||||
|                           "operator": "In", | ||||
|                           "scopeName": "PriorityClass", | ||||
|                           "values": ["high"] | ||||
|                         } | ||||
|                       ] | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               ] | ||||
|             } | ||||
| 
 | ||||
|            ); | ||||
|     } | ||||
| 
 | ||||
|     async fn update_tenant_resource_limits( | ||||
|         &self, | ||||
|         tenant_name: &str, | ||||
|         new_limits: &ResourceLimits, | ||||
|     ) -> Result<(), ExecutorError> { | ||||
|         todo!() | ||||
|     } | ||||
| 
 | ||||
|     async fn update_tenant_network_policy( | ||||
|         &self, | ||||
|         tenant_name: &str, | ||||
|         new_policy: &TenantNetworkPolicy, | ||||
|     ) -> Result<(), ExecutorError> { | ||||
|         todo!() | ||||
|     } | ||||
| 
 | ||||
|     async fn deprovision_tenant(&self, tenant_name: &str) -> Result<(), ExecutorError> { | ||||
|         todo!() | ||||
|     } | ||||
| } | ||||
| @ -1,4 +1,5 @@ | ||||
| mod manager; | ||||
| pub mod k8s; | ||||
| pub use manager::*; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| 
 | ||||
| @ -29,17 +30,17 @@ pub struct TenantConfig { | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] | ||||
| pub struct ResourceLimits { | ||||
|     /// Requested/guaranteed CPU cores (e.g., 2.0).
 | ||||
|     pub cpu_request_cores: Option<f32>, | ||||
|     pub cpu_request_cores: f32, | ||||
|     /// Maximum CPU cores the tenant can burst to (e.g., 4.0).
 | ||||
|     pub cpu_limit_cores: Option<f32>, | ||||
|     pub cpu_limit_cores: f32, | ||||
| 
 | ||||
|     /// Requested/guaranteed memory in Gigabytes (e.g., 8.0).
 | ||||
|     pub memory_request_gb: Option<f32>, | ||||
|     pub memory_request_gb: f32, | ||||
|     /// Maximum memory in Gigabytes tenant can burst to (e.g., 16.0).
 | ||||
|     pub memory_limit_gb: Option<f32>, | ||||
|     pub memory_limit_gb: f32, | ||||
| 
 | ||||
|     /// Total persistent storage allocation in Gigabytes across all volumes.
 | ||||
|     pub storage_total_gb: Option<f32>, | ||||
|     pub storage_total_gb: f32, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user