TenantManager_impl_k8s_anywhere #47
@ -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