feat(settings): Add runtime settings management, node & baremetal managers, and settings UI

This commit is contained in:
2025-09-07 17:21:30 +00:00
parent 83abe37d8c
commit 54ef62e7af
36 changed files with 1914 additions and 301 deletions

View 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;
};
};
}

View File

@@ -1,8 +1,6 @@
import * as plugins from '../plugins.js';
export interface ICloudlyConfig {
cfToken?: string;
hetznerToken?: string;
environment?: 'production' | 'integration';
letsEncryptEmail?: string;
letsEncryptPrivateKey?: string;

View File

@@ -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.

View 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[];
};
}

View File

@@ -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;
};
}

View File

@@ -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';

View File

@@ -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: {

View 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;
};