feat(settings): Add runtime settings management, node & baremetal managers, and settings UI
This commit is contained in:
		
							
								
								
									
										73
									
								
								ts_interfaces/data/baremetal.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								ts_interfaces/data/baremetal.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| export interface IBareMetal { | ||||
|   id: string; | ||||
|   data: { | ||||
|     hostname: string; | ||||
|      | ||||
|     /** | ||||
|      * IPMI management IP address | ||||
|      */ | ||||
|     ipmiAddress?: string; | ||||
|      | ||||
|     /** | ||||
|      * Encrypted IPMI credentials | ||||
|      */ | ||||
|     ipmiCredentials?: { | ||||
|       username: string; | ||||
|       passwordEncrypted: string; | ||||
|     }; | ||||
|      | ||||
|     /** | ||||
|      * Primary network IP address | ||||
|      */ | ||||
|     primaryIp: string; | ||||
|      | ||||
|     /** | ||||
|      * Provider of the physical server | ||||
|      */ | ||||
|     provider: 'hetzner' | 'aws' | 'digitalocean' | 'onpremise'; | ||||
|      | ||||
|     /** | ||||
|      * Data center or location | ||||
|      */ | ||||
|     location: string; | ||||
|      | ||||
|     /** | ||||
|      * Hardware specifications | ||||
|      */ | ||||
|     specs: { | ||||
|       cpuModel: string; | ||||
|       cpuCores: number; | ||||
|       memoryGB: number; | ||||
|       storageGB: number; | ||||
|       storageType: 'ssd' | 'hdd' | 'nvme'; | ||||
|     }; | ||||
|      | ||||
|     /** | ||||
|      * Current power state | ||||
|      */ | ||||
|     powerState: 'on' | 'off' | 'unknown'; | ||||
|      | ||||
|     /** | ||||
|      * Operating system information | ||||
|      */ | ||||
|     osInfo: { | ||||
|       name: string; | ||||
|       version: string; | ||||
|       kernel?: string; | ||||
|     }; | ||||
|      | ||||
|     /** | ||||
|      * Array of ClusterNode IDs running on this hardware | ||||
|      */ | ||||
|     assignedNodeIds: string[]; | ||||
|      | ||||
|     /** | ||||
|      * Metadata for provider-specific information | ||||
|      */ | ||||
|     providerMetadata?: { | ||||
|       [key: string]: any; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
| @@ -1,8 +1,6 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| export interface ICloudlyConfig { | ||||
|   cfToken?: string; | ||||
|   hetznerToken?: string; | ||||
|   environment?: 'production' | 'integration'; | ||||
|   letsEncryptEmail?: string; | ||||
|   letsEncryptPrivateKey?: string; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { type IDockerRegistryInfo } from '../data/docker.js'; | ||||
| import type { IServer } from './server.js'; | ||||
| import type { IClusterNode } from './clusternode.js'; | ||||
|  | ||||
| export interface ICluster { | ||||
|   id: string; | ||||
| @@ -24,9 +24,9 @@ export interface ICluster { | ||||
|     setupMode?: 'manual' | 'hetzner' | 'aws' | 'digitalocean'; | ||||
|  | ||||
|     /** | ||||
|      * what servers are expected to be part of the cluster | ||||
|      * Nodes that are part of the cluster | ||||
|      */ | ||||
|     servers: IServer[]; | ||||
|     nodes: IClusterNode[]; | ||||
|  | ||||
|     /** | ||||
|      * ACME info. This is used to get SSL certificates. | ||||
|   | ||||
							
								
								
									
										71
									
								
								ts_interfaces/data/clusternode.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								ts_interfaces/data/clusternode.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| export interface IClusterNodeMetrics { | ||||
|   cpuUsagePercent: number; | ||||
|   memoryUsedMB: number; | ||||
|   memoryAvailableMB: number; | ||||
|   diskUsedGB: number; | ||||
|   diskAvailableGB: number; | ||||
|   containerCount: number; | ||||
|   timestamp: number; | ||||
| } | ||||
|  | ||||
| export interface IClusterNode { | ||||
|   id: string; | ||||
|   data: { | ||||
|     /** | ||||
|      * Reference to the cluster this node belongs to | ||||
|      */ | ||||
|     clusterId: string; | ||||
|      | ||||
|     /** | ||||
|      * Reference to the physical server (if applicable) | ||||
|      */ | ||||
|     baremetalId?: string; | ||||
|      | ||||
|     /** | ||||
|      * Type of node | ||||
|      */ | ||||
|     nodeType: 'baremetal' | 'vm' | 'container'; | ||||
|      | ||||
|     /** | ||||
|      * Current status of the node | ||||
|      */ | ||||
|     status: 'initializing' | 'online' | 'offline' | 'maintenance'; | ||||
|      | ||||
|     /** | ||||
|      * Role of the node in the cluster | ||||
|      */ | ||||
|     role: 'master' | 'worker'; | ||||
|      | ||||
|     /** | ||||
|      * Timestamp when node joined the cluster | ||||
|      */ | ||||
|     joinedAt: number; | ||||
|      | ||||
|     /** | ||||
|      * Last health check timestamp | ||||
|      */ | ||||
|     lastHealthCheck: number; | ||||
|      | ||||
|     /** | ||||
|      * Current metrics for the node | ||||
|      */ | ||||
|     metrics?: IClusterNodeMetrics; | ||||
|      | ||||
|     /** | ||||
|      * Docker swarm node ID if part of swarm | ||||
|      */ | ||||
|     swarmNodeId?: string; | ||||
|      | ||||
|     /** | ||||
|      * SSH keys deployed to this node | ||||
|      */ | ||||
|     sshKeys: plugins.tsclass.network.ISshKey[]; | ||||
|      | ||||
|     /** | ||||
|      * Debian packages installed on this node | ||||
|      */ | ||||
|     requiredDebianPackages: string[]; | ||||
|   }; | ||||
| } | ||||
| @@ -6,8 +6,58 @@ import * as plugins from '../plugins.js'; | ||||
|  */ | ||||
| export interface IDeployment { | ||||
|   id: string; | ||||
|   affectedServiceIds: string[]; | ||||
|    | ||||
|   /** | ||||
|    * The service being deployed (single service per deployment) | ||||
|    */ | ||||
|   serviceId: string; | ||||
|    | ||||
|   /** | ||||
|    * The node this deployment is running on | ||||
|    */ | ||||
|   nodeId: string; | ||||
|    | ||||
|   /** | ||||
|    * Docker container ID for this deployment | ||||
|    */ | ||||
|   containerId?: string; | ||||
|    | ||||
|   /** | ||||
|    * Image used for this deployment | ||||
|    */ | ||||
|   usedImageId: string; | ||||
|    | ||||
|   /** | ||||
|    * Version of the service deployed | ||||
|    */ | ||||
|   version: string; | ||||
|    | ||||
|   /** | ||||
|    * Timestamp when deployed | ||||
|    */ | ||||
|   deployedAt: number; | ||||
|    | ||||
|   /** | ||||
|    * Deployment log entries | ||||
|    */ | ||||
|   deploymentLog: string[]; | ||||
|   status: 'scheduled' | 'running' | 'deployed' | 'failed'; | ||||
|    | ||||
|   /** | ||||
|    * Current status of the deployment | ||||
|    */ | ||||
|   status: 'scheduled' | 'starting' | 'running' | 'stopping' | 'stopped' | 'failed'; | ||||
|    | ||||
|   /** | ||||
|    * Health status of the deployment | ||||
|    */ | ||||
|   healthStatus?: 'healthy' | 'unhealthy' | 'unknown'; | ||||
|    | ||||
|   /** | ||||
|    * Resource usage for this deployment | ||||
|    */ | ||||
|   resourceUsage?: { | ||||
|     cpuUsagePercent: number; | ||||
|     memoryUsedMB: number; | ||||
|     lastUpdated: number; | ||||
|   }; | ||||
| } | ||||
| @@ -7,8 +7,10 @@ export * from './event.js'; | ||||
| export * from './externalregistry.js'; | ||||
| export * from './image.js'; | ||||
| export * from './secretbundle.js'; | ||||
| export * from './secretgroup.js' | ||||
| export * from './server.js'; | ||||
| export * from './secretgroup.js'; | ||||
| export * from './baremetal.js'; | ||||
| export * from './clusternode.js'; | ||||
| export * from './settings.js'; | ||||
| export * from './service.js'; | ||||
| export * from './status.js'; | ||||
| export * from './traffic.js'; | ||||
|   | ||||
| @@ -17,6 +17,35 @@ export interface IService { | ||||
|      * and thus live past the service lifecycle | ||||
|      */ | ||||
|     additionalSecretBundleIds?: string[]; | ||||
|      | ||||
|     /** | ||||
|      * Service category determines deployment behavior | ||||
|      * - base: Core services that run on every node (coreflow, coretraffic, corelog) | ||||
|      * - distributed: Services that run on limited nodes (cores3, coremongo) | ||||
|      * - workload: User applications | ||||
|      */ | ||||
|     serviceCategory: 'base' | 'distributed' | 'workload'; | ||||
|      | ||||
|     /** | ||||
|      * Deployment strategy for the service | ||||
|      * - all-nodes: Deploy to every node in the cluster | ||||
|      * - limited-replicas: Deploy to a limited number of nodes | ||||
|      * - custom: Custom deployment logic | ||||
|      */ | ||||
|     deploymentStrategy: 'all-nodes' | 'limited-replicas' | 'custom'; | ||||
|      | ||||
|     /** | ||||
|      * Maximum number of replicas for distributed services | ||||
|      * For example, 3 for cores3 or coremongo | ||||
|      */ | ||||
|     maxReplicas?: number; | ||||
|      | ||||
|     /** | ||||
|      * Whether to enforce anti-affinity rules | ||||
|      * When true, tries to spread deployments across different BareMetal servers | ||||
|      */ | ||||
|     antiAffinity?: boolean; | ||||
|      | ||||
|     scaleFactor: number; | ||||
|     balancingStrategy: 'round-robin' | 'least-connections'; | ||||
|     ports: { | ||||
|   | ||||
							
								
								
									
										56
									
								
								ts_interfaces/data/settings.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								ts_interfaces/data/settings.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| /** | ||||
|  * Interface for Cloudly settings stored in EasyStore | ||||
|  * These are runtime-configurable settings that can be modified via the UI | ||||
|  */ | ||||
| export interface ICloudlySettings { | ||||
|   // Cloud Provider Tokens | ||||
|   hetznerToken?: string; | ||||
|   cloudflareToken?: string; | ||||
|    | ||||
|   // AWS Credentials | ||||
|   awsAccessKey?: string; | ||||
|   awsSecretKey?: string; | ||||
|   awsRegion?: string; | ||||
|    | ||||
|   // DigitalOcean | ||||
|   digitalOceanToken?: string; | ||||
|    | ||||
|   // Azure Credentials | ||||
|   azureClientId?: string; | ||||
|   azureClientSecret?: string; | ||||
|   azureTenantId?: string; | ||||
|   azureSubscriptionId?: string; | ||||
|    | ||||
|   // Google Cloud | ||||
|   googleCloudKeyJson?: string; | ||||
|   googleCloudProjectId?: string; | ||||
|    | ||||
|   // Vultr | ||||
|   vultrApiKey?: string; | ||||
|    | ||||
|   // Linode | ||||
|   linodeToken?: string; | ||||
|    | ||||
|   // OVH | ||||
|   ovhApplicationKey?: string; | ||||
|   ovhApplicationSecret?: string; | ||||
|   ovhConsumerKey?: string; | ||||
|    | ||||
|   // Scaleway | ||||
|   scalewayAccessKey?: string; | ||||
|   scalewaySecretKey?: string; | ||||
|   scalewayOrganizationId?: string; | ||||
|    | ||||
|   // Other settings that might be added in the future | ||||
|   [key: string]: string | undefined; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Interface for masked settings (used in API responses) | ||||
|  * Shows only last 4 characters of sensitive tokens | ||||
|  */ | ||||
| export type ICloudlySettingsMasked = { | ||||
|   [K in keyof ICloudlySettings]: string | undefined; | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user