forked from NationTech/harmony
		
	feat: Add initial Tenant traits and data structures
This commit is contained in:
		
							parent
							
								
									88d6af9815
								
							
						
					
					
						commit
						895fb02f4e
					
				
							
								
								
									
										186
									
								
								harmony/src/domain/topology/tenant/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								harmony/src/domain/topology/tenant/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,186 @@ | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] // Assuming serde for Scores
 | ||||
| pub struct TenantConfig { | ||||
|     /// A unique, human-readable name for the tenant (e.g., "client-alpha", "project-phoenix").
 | ||||
|     /// This will be used as the primary identifier for management operations.
 | ||||
|     pub name: String, | ||||
| 
 | ||||
|     /// An optional description for the tenant.
 | ||||
|     pub description: Option<String>, | ||||
| 
 | ||||
|     /// Desired resource allocations and limits for the tenant.
 | ||||
|     pub resource_limits: ResourceLimits, | ||||
| 
 | ||||
|     /// High-level network isolation policies for the tenant.
 | ||||
|     pub network_policy: TenantNetworkPolicy, | ||||
| 
 | ||||
|     /// Key-value pairs for provider-specific tagging, labeling, or metadata.
 | ||||
|     /// Useful for billing, organization, or filtering within the provider's console.
 | ||||
|     pub labels_or_tags: HashMap<String, String>, | ||||
|     // Note: User/group management for the tenant is deferred to a future ADR.
 | ||||
|     // For now, the TenantManager sets up the space; how it's accessed internally
 | ||||
|     // by the tenant's own users is a separate concern.
 | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||||
| pub struct TenantContext { | ||||
|     /// The provider-specific internal identifier for the tenant's primary isolation unit
 | ||||
|     /// (e.g., Kubernetes namespace name, OpenStack project ID, AWS Account ID).
 | ||||
|     pub provider_internal_id: String, | ||||
| 
 | ||||
|     /// The logical name of the tenant, matching `TenantConfig.name`.
 | ||||
|     pub name: String, | ||||
| 
 | ||||
|     /// Current operational status of the tenant.
 | ||||
|     pub status: TenantStatus, | ||||
| 
 | ||||
|     /// Effective resource limits currently applied to the tenant.
 | ||||
|     /// This might differ slightly from requested if the provider adjusted them.
 | ||||
|     pub effective_resource_limits: ResourceLimits, | ||||
| 
 | ||||
|     /// Effective network policy currently applied.
 | ||||
|     pub effective_network_policy: TenantNetworkPolicy, | ||||
| 
 | ||||
|     /// Additional provider-specific data or endpoints relevant to the tenant.
 | ||||
|     /// (e.g., K8s API server endpoint scoped to the namespace, if applicable).
 | ||||
|     pub provider_specific_data: HashMap<String, String>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||||
| pub enum TenantStatus { | ||||
|     Provisioning, | ||||
|     Active, | ||||
|     Updating, | ||||
|     Deleting, | ||||
|     Error(String), | ||||
|     Unknown, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] | ||||
| pub struct ResourceLimits { | ||||
|     /// Requested/guaranteed CPU cores (e.g., 2.0).
 | ||||
|     pub cpu_request_cores: Option<f32>, | ||||
|     /// Maximum CPU cores the tenant can burst to (e.g., 4.0).
 | ||||
|     pub cpu_limit_cores: Option<f32>, | ||||
| 
 | ||||
|     /// Requested/guaranteed memory in Gigabytes (e.g., 8.0).
 | ||||
|     pub memory_request_gb: Option<f32>, | ||||
|     /// Maximum memory in Gigabytes tenant can burst to (e.g., 16.0).
 | ||||
|     pub memory_limit_gb: Option<f32>, | ||||
| 
 | ||||
|     /// Total persistent storage allocation in Gigabytes across all volumes.
 | ||||
|     pub storage_total_gb: Option<u64>, | ||||
|     /// Maximum number of distinct persistent volumes/claims.
 | ||||
|     pub persistent_volume_claim_count: Option<u32>, | ||||
|     // /// Optional: Storage limits per class, if needed for more granular control.
 | ||||
|     // pub storage_gb_per_class: Option<HashMap<String, u64>>,
 | ||||
| 
 | ||||
|     /// Maximum number of load balancers.
 | ||||
|     pub load_balancer_count: Option<u32>, | ||||
|     /// Maximum number of public IP addresses.
 | ||||
|     pub public_ip_count: Option<u32>, | ||||
| 
 | ||||
|     /// Provider-specific or custom quotas (e.g., "gpu_count:2", "snapshot_count:10").
 | ||||
|     /// Values are strings to accommodate various provider formats.
 | ||||
|     pub custom_quotas: HashMap<String, String>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||||
| pub struct TenantNetworkPolicy { | ||||
|     /// Policy for ingress traffic originating from other tenants within the same Harmony-managed environment.
 | ||||
|     pub default_inter_tenant_ingress: InterTenantIngressPolicy, | ||||
| 
 | ||||
|     /// Policy for egress traffic destined for the public internet.
 | ||||
|     pub default_internet_egress: InternetEgressPolicy, | ||||
| 
 | ||||
|     /// List of common cluster-internal services this tenant should be ableto access.
 | ||||
|     pub allowed_cluster_services: Vec<ClusterServiceType>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||||
| pub enum InterTenantIngressPolicy { | ||||
|     /// Deny all traffic from other tenants by default.
 | ||||
|     DenyAll, | ||||
|     // Future: AllowFromSameGroup (if tenants can be logically grouped)
 | ||||
|     // Future: AllowLabeled (if tenants can specify labels for selective inter-tenant comms)
 | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||||
| pub enum InternetEgressPolicy { | ||||
|     /// Allow all outbound traffic to the internet.
 | ||||
|     AllowAll, | ||||
|     /// Deny all outbound traffic to the internet by default.
 | ||||
|     DenyAll, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||||
| pub enum ClusterServiceType { | ||||
|     /// e.g., kube-dns, CoreDNS.
 | ||||
|     Dns, | ||||
|     /// Access to an internal image registry.
 | ||||
|     InternalImageRegistry, | ||||
|     /// Access to centralized monitoring endpoints (e.g., Prometheus federation).
 | ||||
|     MonitoringService, | ||||
| } | ||||
| 
 | ||||
| use async_trait::async_trait; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| 
 | ||||
| use crate::executors::ExecutorError; | ||||
| 
 | ||||
| #[async_trait] | ||||
| pub trait TenantManager: Send + Sync + std::fmt::Debug { | ||||
|     /// Provisions a new tenant based on the provided configuration.
 | ||||
|     /// This operation should be idempotent; if a tenant with the same `config.name`
 | ||||
|     /// already exists and matches the config, it may succeed without changes.
 | ||||
|     /// If it exists but differs, it might return an error or attempt to update (TBD by implementer).
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     /// * `config`: The desired configuration for the new tenant.
 | ||||
|     ///
 | ||||
|     /// # Returns
 | ||||
|     /// A `TenantContext` representing the provisioned tenant.
 | ||||
|     async fn provision_tenant(&self, config: &TenantConfig) -> Result<TenantContext, ExecutorError>; | ||||
| 
 | ||||
|     /// Retrieves the current details and context of an existing tenant.
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     /// * `tenant_name`: The logical name of the tenant to retrieve.
 | ||||
|     ///
 | ||||
|     /// # Returns
 | ||||
|     /// An `Option<TenantContext>`, which is `None` if the tenant does not exist.
 | ||||
|     async fn get_tenant_details(&self, tenant_name: &str) -> Result<Option<TenantContext>, ExecutorError>; | ||||
| 
 | ||||
|     /// Updates the resource limits for an existing tenant.
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     /// * `tenant_name`: The logical name of the tenant to update.
 | ||||
|     /// * `new_limits`: The new set of resource limits to apply.
 | ||||
|     async fn update_tenant_resource_limits( | ||||
|         &self, | ||||
|         tenant_name: &str, | ||||
|         new_limits: &ResourceLimits, | ||||
|     ) -> Result<(), ExecutorError>; | ||||
| 
 | ||||
|     /// Updates the high-level network isolation policy for an existing tenant.
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     /// * `tenant_name`: The logical name of the tenant to update.
 | ||||
|     /// * `new_policy`: The new network policy to apply.
 | ||||
|     async fn update_tenant_network_policy( | ||||
|         &self, | ||||
|         tenant_name: &str, | ||||
|         new_policy: &TenantNetworkPolicy, | ||||
|     ) -> Result<(), ExecutorError>; | ||||
| 
 | ||||
|     /// Decommissions an existing tenant, removing its isolated context and associated resources.
 | ||||
|     /// This operation should be idempotent.
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     /// * `tenant_name`: The logical name of the tenant to deprovision.
 | ||||
|     async fn deprovision_tenant(&self, tenant_name: &str) -> Result<(), ExecutorError>; | ||||
| 
 | ||||
|     /// Lists the logical names of all tenants currently managed by this `TenantManager` instance.
 | ||||
|     async fn list_tenant_names(&self) -> Result<Vec<String>, ExecutorError>; | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user