feat: add more to the tenantmanager k8s impl #46
| @ -15,9 +15,7 @@ use crate::{ | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use super::{ | use super::{ | ||||||
|     HelmCommand, K8sclient, Topology, |     k8s::K8sClient, tenant::{k8s::K8sTenantManager, ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy}, HelmCommand, K8sclient, Topology | ||||||
|     k8s::K8sClient, |  | ||||||
|     tenant::{ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy}, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct K8sState { | struct K8sState { | ||||||
| @ -34,8 +32,10 @@ enum K8sSource { | |||||||
| 
 | 
 | ||||||
| pub struct K8sAnywhereTopology { | pub struct K8sAnywhereTopology { | ||||||
|     k8s_state: OnceCell<Option<K8sState>>, |     k8s_state: OnceCell<Option<K8sState>>, | ||||||
|  |     tenant_manager: K8sTenantManager, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| #[async_trait] | #[async_trait] | ||||||
| impl K8sclient for K8sAnywhereTopology { | impl K8sclient for K8sAnywhereTopology { | ||||||
|     async fn k8s_client(&self) -> Result<Arc<K8sClient>, String> { |     async fn k8s_client(&self) -> Result<Arc<K8sClient>, String> { | ||||||
| @ -216,80 +216,29 @@ impl Topology for K8sAnywhereTopology { | |||||||
| 
 | 
 | ||||||
| impl HelmCommand for K8sAnywhereTopology {} | impl HelmCommand for K8sAnywhereTopology {} | ||||||
| 
 | 
 | ||||||
|  | #[async_trait] | ||||||
| impl TenantManager for K8sAnywhereTopology { | impl TenantManager for K8sAnywhereTopology { | ||||||
|     fn provision_tenant<'life0, 'life1, 'async_trait>( |     async fn provision_tenant(&self, config: &TenantConfig) -> Result<(), ExecutorError> { | ||||||
|         &'life0 self, |         self.tenant_manager.provision_tenant(config).await | ||||||
|         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!() |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn update_tenant_resource_limits<'life0, 'life1, 'life2, 'async_trait>( |     async fn update_tenant_resource_limits( | ||||||
|         &'life0 self, |         &self, | ||||||
|         tenant_name: &'life1 str, |         tenant_name: &str, | ||||||
|         new_limits: &'life2 ResourceLimits, |         new_limits: &ResourceLimits, | ||||||
|     ) -> ::core::pin::Pin< |     ) -> Result<(), ExecutorError> { | ||||||
|         Box< |         self.tenant_manager.update_tenant_resource_limits(tenant_name, new_limits).await | ||||||
|             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!() |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn update_tenant_network_policy<'life0, 'life1, 'life2, 'async_trait>( |     async fn update_tenant_network_policy( | ||||||
|         &'life0 self, |         &self, | ||||||
|         tenant_name: &'life1 str, |         tenant_name: &str, | ||||||
|         new_policy: &'life2 TenantNetworkPolicy, |         new_policy: &TenantNetworkPolicy, | ||||||
|     ) -> ::core::pin::Pin< |     ) -> Result<(), ExecutorError> { | ||||||
|         Box< |         self.tenant_manager.update_tenant_network_policy(tenant_name, new_policy).await | ||||||
|             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!() |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn deprovision_tenant<'life0, 'life1, 'async_trait>( |     async fn deprovision_tenant(&self, tenant_name: &str) -> Result<(), ExecutorError> { | ||||||
|         &'life0 self, |         self.tenant_manager.deprovision_tenant(tenant_name).await | ||||||
|         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!() |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										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; | mod manager; | ||||||
|  | pub mod k8s; | ||||||
| pub use manager::*; | pub use manager::*; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| 
 | 
 | ||||||
| @ -29,17 +30,17 @@ pub struct TenantConfig { | |||||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] | #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] | ||||||
| pub struct ResourceLimits { | pub struct ResourceLimits { | ||||||
|     /// Requested/guaranteed CPU cores (e.g., 2.0).
 |     /// 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).
 |     /// 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).
 |     /// 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).
 |     /// 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.
 |     /// 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)] | #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user