feat: adding kubernetes implentation of tenant manager
Some checks failed
Run Check Script / check (push) Failing after 43s
Some checks failed
Run Check Script / check (push) Failing after 43s
This commit is contained in:
parent
624e4330bb
commit
97fba07f4e
@ -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