UNPKG

@chimoney.io/iaas-k8s-deployment

Version:

Kubernetes Infrastructure as a Service deployment package for streamlined multi-cloud environments

499 lines (460 loc) 12.9 kB
// ============================================================================= // Plan Tier Definitions and Resource Specifications // ============================================================================= export enum PlanTier { BASIC = "basic", STANDARD = "standard", PREMIUM = "premium", ENTERPRISE = "enterprise", } export interface ResourceAllocation { cpu: string; // e.g., "1000m", "2000m" memory: string; // e.g., "2Gi", "4Gi" storage: string; // e.g., "10Gi", "20Gi" replicas: number; } export interface ServiceResourceAllocation { rafikiAuth: ResourceAllocation; rafikiBackend: ResourceAllocation; nginx: ResourceAllocation; redis: ResourceAllocation; } export interface TierResourceAllocation { tier: PlanTier; displayName: string; description: string; monthlyPriceUSD: number; maxNamespaces: number; maxPersistentVolumeClaims: number; networkPoliciesEnabled: boolean; services: ServiceResourceAllocation; quota: { requests: { cpu: string; memory: string; storage: string; }; limits: { cpu: string; memory: string; storage: string; }; pods: number; services: number; secrets: number; configmaps: number; persistentvolumeclaims: number; }; } export interface KubecostConfig { enabled: boolean; namespace: string; currency: string; billingAccountId?: string; costAllocationLabels: string[]; alertingEnabled: boolean; budgetAlerts: { enabled: boolean; thresholds: number[]; // Percentage thresholds (e.g., [50, 80, 100]) }; } export interface TierConfiguration { planTier: PlanTier; resourceAllocation: TierResourceAllocation; kubecostConfig?: KubecostConfig; billingMetadata?: { customerId: string; subscriptionId: string; billingCycle: "monthly" | "annual"; }; } // ============================================================================= // Pre-defined Tier Specifications // ============================================================================= export const PLAN_TIER_DEFINITIONS: Record<PlanTier, TierResourceAllocation> = { [PlanTier.BASIC]: { tier: PlanTier.BASIC, displayName: "Basic Plan", description: "Ideal for small applications and development environments", monthlyPriceUSD: 99, maxNamespaces: 1, maxPersistentVolumeClaims: 3, networkPoliciesEnabled: false, services: { rafikiAuth: { cpu: "500m", memory: "1Gi", storage: "5Gi", replicas: 1, }, rafikiBackend: { cpu: "500m", memory: "1Gi", storage: "5Gi", replicas: 1, }, nginx: { cpu: "100m", memory: "256Mi", storage: "1Gi", replicas: 1, }, redis: { cpu: "100m", memory: "256Mi", storage: "2Gi", replicas: 1, }, }, quota: { requests: { cpu: "1200m", // Sum of all service requests + 20% buffer memory: "2.5Gi", storage: "15Gi", }, limits: { cpu: "2000m", // ~66% overhead for bursting memory: "4Gi", storage: "20Gi", }, pods: 10, services: 10, secrets: 20, configmaps: 20, persistentvolumeclaims: 3, }, }, [PlanTier.STANDARD]: { tier: PlanTier.STANDARD, displayName: "Standard Plan", description: "Perfect for growing businesses with moderate traffic", monthlyPriceUSD: 299, maxNamespaces: 2, maxPersistentVolumeClaims: 6, networkPoliciesEnabled: true, services: { rafikiAuth: { cpu: "1000m", memory: "2Gi", storage: "10Gi", replicas: 2, }, rafikiBackend: { cpu: "1000m", memory: "2Gi", storage: "10Gi", replicas: 2, }, nginx: { cpu: "200m", memory: "512Mi", storage: "2Gi", replicas: 2, }, redis: { cpu: "200m", memory: "512Mi", storage: "5Gi", replicas: 1, }, }, quota: { requests: { cpu: "2400m", // Sum of all service requests + 20% buffer memory: "5Gi", storage: "30Gi", }, limits: { cpu: "4000m", memory: "8Gi", storage: "40Gi", }, pods: 20, services: 15, secrets: 30, configmaps: 30, persistentvolumeclaims: 6, }, }, [PlanTier.PREMIUM]: { tier: PlanTier.PREMIUM, displayName: "Premium Plan", description: "High-performance solution for production workloads", monthlyPriceUSD: 599, maxNamespaces: 3, maxPersistentVolumeClaims: 10, networkPoliciesEnabled: true, services: { rafikiAuth: { cpu: "2000m", memory: "4Gi", storage: "20Gi", replicas: 3, }, rafikiBackend: { cpu: "2000m", memory: "4Gi", storage: "20Gi", replicas: 3, }, nginx: { cpu: "500m", memory: "1Gi", storage: "5Gi", replicas: 3, }, redis: { cpu: "500m", memory: "1Gi", storage: "10Gi", replicas: 2, }, }, quota: { requests: { cpu: "5000m", // Sum of all service requests + 20% buffer memory: "10Gi", storage: "60Gi", }, limits: { cpu: "8000m", memory: "16Gi", storage: "80Gi", }, pods: 40, services: 25, secrets: 50, configmaps: 50, persistentvolumeclaims: 10, }, }, [PlanTier.ENTERPRISE]: { tier: PlanTier.ENTERPRISE, displayName: "Enterprise Plan", description: "Scalable solution for enterprise applications", monthlyPriceUSD: 1299, maxNamespaces: 5, maxPersistentVolumeClaims: 20, networkPoliciesEnabled: true, services: { rafikiAuth: { cpu: "4000m", memory: "8Gi", storage: "40Gi", replicas: 5, }, rafikiBackend: { cpu: "4000m", memory: "8Gi", storage: "40Gi", replicas: 5, }, nginx: { cpu: "1000m", memory: "2Gi", storage: "10Gi", replicas: 5, }, redis: { cpu: "1000m", memory: "2Gi", storage: "20Gi", replicas: 3, }, }, quota: { requests: { cpu: "10000m", // Sum of all service requests + 20% buffer memory: "20Gi", storage: "120Gi", }, limits: { cpu: "16000m", memory: "32Gi", storage: "160Gi", }, pods: 80, services: 50, secrets: 100, configmaps: 100, persistentvolumeclaims: 20, }, }, }; // ============================================================================= // Default Kubecost Configuration // ============================================================================= export const DEFAULT_KUBECOST_CONFIG: KubecostConfig = { enabled: true, namespace: "kubecost", currency: "USD", costAllocationLabels: [ "app.kubernetes.io/name", "app.kubernetes.io/component", "iaas.deployment/company", "iaas.deployment/tier", "iaas.deployment/type", ], alertingEnabled: true, budgetAlerts: { enabled: true, thresholds: [75, 90, 100], // Alert at 75%, 90%, and 100% of budget }, }; // ============================================================================= // Tier Validation Functions // ============================================================================= export function validateTierConfiguration(config: TierConfiguration): string[] { const errors: string[] = []; // Validate tier exists if (!Object.values(PlanTier).includes(config.planTier)) { errors.push(`Invalid plan tier: ${config.planTier}`); } // Validate resource allocation matches tier definition const tierDef = PLAN_TIER_DEFINITIONS[config.planTier]; if (!tierDef) { errors.push(`No definition found for tier: ${config.planTier}`); return errors; } // Validate CPU and memory formats const resourceRegex = /^\d+(\.\d+)?(m|Mi|Gi|Ti)?$/; const services = config.resourceAllocation.services; Object.entries(services).forEach(([serviceName, allocation]) => { if (!resourceRegex.test(allocation.cpu)) { errors.push(`Invalid CPU format for ${serviceName}: ${allocation.cpu}`); } if (!resourceRegex.test(allocation.memory)) { errors.push( `Invalid memory format for ${serviceName}: ${allocation.memory}` ); } if (!resourceRegex.test(allocation.storage)) { errors.push( `Invalid storage format for ${serviceName}: ${allocation.storage}` ); } if (allocation.replicas < 1 || allocation.replicas > 10) { errors.push( `Invalid replica count for ${serviceName}: ${allocation.replicas} (must be 1-10)` ); } }); return errors; } export function getTierConfiguration(tier: PlanTier): TierConfiguration { const tierDef = PLAN_TIER_DEFINITIONS[tier]; if (!tierDef) { throw new Error(`Invalid tier: ${tier}`); } return { planTier: tier, resourceAllocation: tierDef, kubecostConfig: DEFAULT_KUBECOST_CONFIG, }; } export function calculateTierCosts( tier: PlanTier, usageDays: number = 30 ): { baseCost: number; estimatedResourceCost: number; totalEstimatedCost: number; } { const tierDef = PLAN_TIER_DEFINITIONS[tier]; const baseCost = tierDef.monthlyPriceUSD; // Rough resource cost estimation (this would be replaced with actual Kubecost data) const cpuCostPerCore = 0.03; // $0.03 per CPU hour const memoryCostPerGi = 0.004; // $0.004 per GB hour const storageCostPerGi = 0.0001; // $0.0001 per GB hour const services = tierDef.services; let totalCpuHours = 0; let totalMemoryGiHours = 0; let totalStorageGiHours = 0; Object.values(services).forEach((service) => { const cpuCores = parseFloat(service.cpu.replace("m", "")) / 1000; const memoryGi = parseFloat(service.memory.replace("Gi", "")); const storageGi = parseFloat(service.storage.replace("Gi", "")); totalCpuHours += cpuCores * service.replicas * 24 * usageDays; totalMemoryGiHours += memoryGi * service.replicas * 24 * usageDays; totalStorageGiHours += storageGi * service.replicas * 24 * usageDays; }); const estimatedResourceCost = totalCpuHours * cpuCostPerCore + totalMemoryGiHours * memoryCostPerGi + totalStorageGiHours * storageCostPerGi; return { baseCost, estimatedResourceCost: Math.round(estimatedResourceCost * 100) / 100, totalEstimatedCost: Math.round((baseCost + estimatedResourceCost) * 100) / 100, }; } // ============================================================================= // Tier Comparison Utilities // ============================================================================= export function compareTiers( currentTier: PlanTier, targetTier: PlanTier ): { isUpgrade: boolean; isDowngrade: boolean; resourceDelta: { cpu: string; memory: string; storage: string; replicas: number; }; costDelta: number; } { const currentDef = PLAN_TIER_DEFINITIONS[currentTier]; const targetDef = PLAN_TIER_DEFINITIONS[targetTier]; const tierOrder = [ PlanTier.BASIC, PlanTier.STANDARD, PlanTier.PREMIUM, PlanTier.ENTERPRISE, ]; const currentIndex = tierOrder.indexOf(currentTier); const targetIndex = tierOrder.indexOf(targetTier); const isUpgrade = targetIndex > currentIndex; const isDowngrade = targetIndex < currentIndex; // Calculate total resource differences const currentTotal = calculateTotalResources(currentDef); const targetTotal = calculateTotalResources(targetDef); return { isUpgrade, isDowngrade, resourceDelta: { cpu: `${targetTotal.cpu - currentTotal.cpu}m`, memory: `${targetTotal.memory - currentTotal.memory}Mi`, storage: `${targetTotal.storage - currentTotal.storage}Gi`, replicas: targetTotal.replicas - currentTotal.replicas, }, costDelta: targetDef.monthlyPriceUSD - currentDef.monthlyPriceUSD, }; } function calculateTotalResources(tierDef: TierResourceAllocation): { cpu: number; memory: number; storage: number; replicas: number; } { let totalCpu = 0; let totalMemory = 0; let totalStorage = 0; let totalReplicas = 0; Object.values(tierDef.services).forEach((service) => { totalCpu += parseFloat(service.cpu.replace("m", "")) * service.replicas; totalMemory += parseFloat(service.memory.replace(/[^0-9.]/g, "")) * service.replicas; totalStorage += parseFloat(service.storage.replace(/[^0-9.]/g, "")) * service.replicas; totalReplicas += service.replicas; }); return { cpu: totalCpu, memory: totalMemory, storage: totalStorage, replicas: totalReplicas, }; }