18.1 概述
部署与运维管理是低代码平台的重要组成部分,负责应用的部署、监控、维护和扩展。本章将详细介绍如何构建一个完整的部署与运维管理系统。
18.2 架构概览
// 部署与运维管理器接口
interface DeploymentManager {
// 部署管理
deploy(config: DeploymentConfig): Promise<DeploymentResult>;
undeploy(deploymentId: string): Promise<void>;
redeploy(deploymentId: string, config?: Partial<DeploymentConfig>): Promise<DeploymentResult>;
rollback(deploymentId: string, version?: string): Promise<DeploymentResult>;
// 部署查询
getDeployment(deploymentId: string): Promise<Deployment | null>;
listDeployments(query?: DeploymentQuery): Promise<Deployment[]>;
getDeploymentHistory(deploymentId: string): Promise<DeploymentHistory[]>;
// 监控管理
startMonitoring(deploymentId: string): Promise<void>;
stopMonitoring(deploymentId: string): Promise<void>;
getMetrics(deploymentId: string, query?: MetricsQuery): Promise<DeploymentMetrics>;
// 扩展管理
scale(deploymentId: string, config: ScalingConfig): Promise<ScalingResult>;
autoScale(deploymentId: string, config: AutoScalingConfig): Promise<void>;
// 健康检查
healthCheck(deploymentId: string): Promise<HealthStatus>;
// 日志管理
getLogs(deploymentId: string, query?: LogQuery): Promise<LogEntry[]>;
streamLogs(deploymentId: string, callback: (log: LogEntry) => void): Promise<() => void>;
}
// 低代码部署与运维管理器实现
class LowCodeDeploymentManager implements DeploymentManager {
private deployments: Map<string, Deployment> = new Map();
private containerOrchestrator: ContainerOrchestrator;
private monitoringService: MonitoringService;
private loggingService: LoggingService;
private notificationService: NotificationService;
private configManager: ConfigurationManager;
constructor(
containerOrchestrator: ContainerOrchestrator,
monitoringService: MonitoringService,
loggingService: LoggingService,
notificationService: NotificationService,
configManager: ConfigurationManager
) {
this.containerOrchestrator = containerOrchestrator;
this.monitoringService = monitoringService;
this.loggingService = loggingService;
this.notificationService = notificationService;
this.configManager = configManager;
}
async deploy(config: DeploymentConfig): Promise<DeploymentResult> {
const deploymentId = this.generateDeploymentId();
const startTime = new Date();
try {
// 验证配置
await this.validateDeploymentConfig(config);
// 准备部署环境
const environment = await this.prepareEnvironment(config);
// 构建应用
const buildResult = await this.buildApplication(config);
// 部署到容器编排器
const orchestrationResult = await this.containerOrchestrator.deploy({
id: deploymentId,
image: buildResult.imageTag,
replicas: config.replicas || 1,
resources: config.resources,
environment: environment,
ports: config.ports,
volumes: config.volumes,
networks: config.networks
});
// 创建部署记录
const deployment: Deployment = {
id: deploymentId,
config,
status: DeploymentStatus.DEPLOYED,
version: config.version || '1.0.0',
createdAt: startTime,
updatedAt: new Date(),
environment: config.environment,
replicas: config.replicas || 1,
resources: config.resources,
endpoints: orchestrationResult.endpoints,
metadata: {
buildId: buildResult.buildId,
imageTag: buildResult.imageTag,
orchestrationId: orchestrationResult.id
}
};
this.deployments.set(deploymentId, deployment);
// 启动监控
if (config.monitoring?.enabled !== false) {
await this.startMonitoring(deploymentId);
}
// 执行健康检查
await this.waitForHealthy(deploymentId, config.healthCheck);
// 发送通知
await this.notificationService.send({
type: 'deployment_success',
title: '部署成功',
message: `应用 ${config.name} 已成功部署`,
data: { deploymentId, config }
});
return {
deploymentId,
status: DeploymentStatus.DEPLOYED,
endpoints: orchestrationResult.endpoints,
duration: Date.now() - startTime.getTime(),
metadata: deployment.metadata
};
} catch (error) {
// 清理失败的部署
await this.cleanup(deploymentId);
// 发送失败通知
await this.notificationService.send({
type: 'deployment_failed',
title: '部署失败',
message: `应用 ${config.name} 部署失败: ${error.message}`,
data: { deploymentId, config, error: error.message }
});
throw new Error(`Deployment failed: ${error.message}`);
}
}
async undeploy(deploymentId: string): Promise<void> {
const deployment = this.deployments.get(deploymentId);
if (!deployment) {
throw new Error(`Deployment ${deploymentId} not found`);
}
try {
// 停止监控
await this.stopMonitoring(deploymentId);
// 从容器编排器中删除
if (deployment.metadata?.orchestrationId) {
await this.containerOrchestrator.undeploy(deployment.metadata.orchestrationId);
}
// 清理资源
await this.cleanup(deploymentId);
// 更新状态
deployment.status = DeploymentStatus.UNDEPLOYED;
deployment.updatedAt = new Date();
// 发送通知
await this.notificationService.send({
type: 'deployment_undeployed',
title: '应用已下线',
message: `应用 ${deployment.config.name} 已成功下线`,
data: { deploymentId, deployment }
});
} catch (error) {
throw new Error(`Undeploy failed: ${error.message}`);
}
}
async redeploy(deploymentId: string, config?: Partial<DeploymentConfig>): Promise<DeploymentResult> {
const deployment = this.deployments.get(deploymentId);
if (!deployment) {
throw new Error(`Deployment ${deploymentId} not found`);
}
// 合并配置
const newConfig = { ...deployment.config, ...config };
// 先下线旧版本
await this.undeploy(deploymentId);
// 部署新版本
return await this.deploy(newConfig);
}
async rollback(deploymentId: string, version?: string): Promise<DeploymentResult> {
const deployment = this.deployments.get(deploymentId);
if (!deployment) {
throw new Error(`Deployment ${deploymentId} not found`);
}
// 获取历史版本
const history = await this.getDeploymentHistory(deploymentId);
const targetVersion = version || this.getPreviousVersion(history);
if (!targetVersion) {
throw new Error('No previous version found for rollback');
}
const targetConfig = history.find(h => h.version === targetVersion)?.config;
if (!targetConfig) {
throw new Error(`Version ${targetVersion} not found`);
}
// 执行回滚
return await this.redeploy(deploymentId, targetConfig);
}
async getDeployment(deploymentId: string): Promise<Deployment | null> {
return this.deployments.get(deploymentId) || null;
}
async listDeployments(query?: DeploymentQuery): Promise<Deployment[]> {
let deployments = Array.from(this.deployments.values());
if (query) {
if (query.environment) {
deployments = deployments.filter(d => d.environment === query.environment);
}
if (query.status) {
deployments = deployments.filter(d => query.status!.includes(d.status));
}
if (query.name) {
deployments = deployments.filter(d =>
d.config.name.toLowerCase().includes(query.name!.toLowerCase())
);
}
if (query.tags) {
deployments = deployments.filter(d =>
query.tags!.every(tag => d.config.tags?.includes(tag))
);
}
}
return deployments;
}
async getDeploymentHistory(deploymentId: string): Promise<DeploymentHistory[]> {
// 这里应该从持久化存储中获取历史记录
// 简化实现,返回模拟数据
return [];
}
async startMonitoring(deploymentId: string): Promise<void> {
const deployment = this.deployments.get(deploymentId);
if (!deployment) {
throw new Error(`Deployment ${deploymentId} not found`);
}
await this.monitoringService.startMonitoring({
deploymentId,
endpoints: deployment.endpoints,
metrics: deployment.config.monitoring?.metrics || ['cpu', 'memory', 'network'],
interval: deployment.config.monitoring?.interval || 30000,
alerts: deployment.config.monitoring?.alerts
});
}
async stopMonitoring(deploymentId: string): Promise<void> {
await this.monitoringService.stopMonitoring(deploymentId);
}
async getMetrics(deploymentId: string, query?: MetricsQuery): Promise<DeploymentMetrics> {
return await this.monitoringService.getMetrics(deploymentId, query);
}
async scale(deploymentId: string, config: ScalingConfig): Promise<ScalingResult> {
const deployment = this.deployments.get(deploymentId);
if (!deployment) {
throw new Error(`Deployment ${deploymentId} not found`);
}
const startTime = Date.now();
try {
// 执行扩展
const result = await this.containerOrchestrator.scale(
deployment.metadata?.orchestrationId!,
config
);
// 更新部署信息
deployment.replicas = config.replicas;
deployment.updatedAt = new Date();
return {
deploymentId,
previousReplicas: deployment.replicas,
newReplicas: config.replicas,
duration: Date.now() - startTime,
status: 'success'
};
} catch (error) {
throw new Error(`Scaling failed: ${error.message}`);
}
}
async autoScale(deploymentId: string, config: AutoScalingConfig): Promise<void> {
const deployment = this.deployments.get(deploymentId);
if (!deployment) {
throw new Error(`Deployment ${deploymentId} not found`);
}
// 启用自动扩展
await this.containerOrchestrator.enableAutoScaling(
deployment.metadata?.orchestrationId!,
config
);
// 更新配置
deployment.config.autoScaling = config;
deployment.updatedAt = new Date();
}
async healthCheck(deploymentId: string): Promise<HealthStatus> {
const deployment = this.deployments.get(deploymentId);
if (!deployment) {
throw new Error(`Deployment ${deploymentId} not found`);
}
return await this.containerOrchestrator.healthCheck(
deployment.metadata?.orchestrationId!
);
}
async getLogs(deploymentId: string, query?: LogQuery): Promise<LogEntry[]> {
const deployment = this.deployments.get(deploymentId);
if (!deployment) {
throw new Error(`Deployment ${deploymentId} not found`);
}
return await this.loggingService.getLogs({
deploymentId,
...query
});
}
async streamLogs(deploymentId: string, callback: (log: LogEntry) => void): Promise<() => void> {
const deployment = this.deployments.get(deploymentId);
if (!deployment) {
throw new Error(`Deployment ${deploymentId} not found`);
}
return await this.loggingService.streamLogs(deploymentId, callback);
}
// 私有方法
private generateDeploymentId(): string {
return `deploy-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
private async validateDeploymentConfig(config: DeploymentConfig): Promise<void> {
if (!config.name) {
throw new Error('Deployment name is required');
}
if (!config.image && !config.source) {
throw new Error('Either image or source must be specified');
}
if (config.replicas && config.replicas < 1) {
throw new Error('Replicas must be at least 1');
}
}
private async prepareEnvironment(config: DeploymentConfig): Promise<Record<string, string>> {
const environment: Record<string, string> = {
NODE_ENV: config.environment || 'production',
PORT: config.ports?.[0]?.containerPort?.toString() || '3000',
...config.environment
};
// 添加配置管理器中的环境变量
const envConfig = await this.configManager.getEnvironmentConfig(config.environment || 'production');
Object.assign(environment, envConfig);
return environment;
}
private async buildApplication(config: DeploymentConfig): Promise<BuildResult> {
if (config.image) {
// 使用预构建镜像
return {
buildId: `prebuild-${Date.now()}`,
imageTag: config.image,
duration: 0
};
}
// 从源码构建
const buildId = `build-${Date.now()}`;
const imageTag = `${config.name}:${config.version || 'latest'}`;
// 这里应该实现实际的构建逻辑
// 简化实现,返回模拟结果
return {
buildId,
imageTag,
duration: 60000 // 1分钟
};
}
private async waitForHealthy(deploymentId: string, healthCheck?: HealthCheckConfig): Promise<void> {
const maxAttempts = healthCheck?.maxAttempts || 30;
const interval = healthCheck?.interval || 10000;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
const health = await this.healthCheck(deploymentId);
if (health.status === 'healthy') {
return;
}
} catch (error) {
// 忽略健康检查错误,继续重试
}
if (attempt < maxAttempts) {
await new Promise(resolve => setTimeout(resolve, interval));
}
}
throw new Error('Health check timeout');
}
private async cleanup(deploymentId: string): Promise<void> {
try {
// 清理容器编排器资源
const deployment = this.deployments.get(deploymentId);
if (deployment?.metadata?.orchestrationId) {
await this.containerOrchestrator.cleanup(deployment.metadata.orchestrationId);
}
// 清理监控
await this.stopMonitoring(deploymentId).catch(() => {});
// 清理日志
await this.loggingService.cleanup(deploymentId).catch(() => {});
} catch (error) {
console.error(`Cleanup failed for deployment ${deploymentId}:`, error);
}
}
private getPreviousVersion(history: DeploymentHistory[]): string | null {
if (history.length < 2) {
return null;
}
// 返回倒数第二个版本
return history[history.length - 2].version;
}
}
18.3 核心数据结构
// 部署配置
interface DeploymentConfig {
name: string;
version?: string;
description?: string;
// 镜像或源码
image?: string;
source?: {
type: 'git' | 'zip' | 'tar';
url: string;
branch?: string;
tag?: string;
credentials?: {
username: string;
password: string;
};
};
// 运行时配置
environment?: string; // development, staging, production
replicas?: number;
resources?: {
requests?: {
cpu: string;
memory: string;
};
limits?: {
cpu: string;
memory: string;
};
};
// 网络配置
ports?: PortConfig[];
networks?: string[];
// 存储配置
volumes?: VolumeConfig[];
// 环境变量
env?: Record<string, string>;
// 健康检查
healthCheck?: HealthCheckConfig;
// 监控配置
monitoring?: MonitoringConfig;
// 自动扩展
autoScaling?: AutoScalingConfig;
// 标签
tags?: string[];
// 元数据
metadata?: Record<string, any>;
}
interface PortConfig {
name?: string;
containerPort: number;
hostPort?: number;
protocol?: 'TCP' | 'UDP';
}
interface VolumeConfig {
name: string;
mountPath: string;
type: 'emptyDir' | 'hostPath' | 'persistentVolume';
source?: string;
readOnly?: boolean;
}
interface HealthCheckConfig {
type: 'http' | 'tcp' | 'exec';
path?: string; // for http
port?: number; // for http/tcp
command?: string[]; // for exec
initialDelaySeconds?: number;
periodSeconds?: number;
timeoutSeconds?: number;
successThreshold?: number;
failureThreshold?: number;
maxAttempts?: number;
interval?: number;
}
interface MonitoringConfig {
enabled?: boolean;
metrics?: string[];
interval?: number;
alerts?: AlertConfig[];
}
interface AlertConfig {
name: string;
metric: string;
condition: 'gt' | 'lt' | 'eq' | 'ne';
threshold: number;
duration?: number;
severity: 'low' | 'medium' | 'high' | 'critical';
notifications?: string[];
}
interface AutoScalingConfig {
enabled: boolean;
minReplicas: number;
maxReplicas: number;
targetCPUUtilization?: number;
targetMemoryUtilization?: number;
scaleUpPolicy?: ScalingPolicy;
scaleDownPolicy?: ScalingPolicy;
}
interface ScalingPolicy {
stabilizationWindowSeconds?: number;
selectPolicy?: 'Max' | 'Min' | 'Disabled';
policies?: {
type: 'Pods' | 'Percent';
value: number;
periodSeconds: number;
}[];
}
// 部署结果
interface DeploymentResult {
deploymentId: string;
status: DeploymentStatus;
endpoints?: string[];
duration: number;
metadata?: Record<string, any>;
}
// 部署状态
enum DeploymentStatus {
PENDING = 'pending',
BUILDING = 'building',
DEPLOYING = 'deploying',
DEPLOYED = 'deployed',
FAILED = 'failed',
UNDEPLOYING = 'undeploying',
UNDEPLOYED = 'undeployed'
}
// 部署信息
interface Deployment {
id: string;
config: DeploymentConfig;
status: DeploymentStatus;
version: string;
createdAt: Date;
updatedAt: Date;
environment: string;
replicas: number;
resources?: {
requests?: {
cpu: string;
memory: string;
};
limits?: {
cpu: string;
memory: string;
};
};
endpoints?: string[];
metadata?: Record<string, any>;
}
// 部署查询
interface DeploymentQuery {
environment?: string;
status?: DeploymentStatus[];
name?: string;
tags?: string[];
limit?: number;
offset?: number;
sortBy?: 'createdAt' | 'updatedAt' | 'name';
sortOrder?: 'asc' | 'desc';
}
// 部署历史
interface DeploymentHistory {
id: string;
deploymentId: string;
version: string;
config: DeploymentConfig;
status: DeploymentStatus;
createdAt: Date;
duration?: number;
error?: string;
}
// 扩展配置
interface ScalingConfig {
replicas: number;
strategy?: 'RollingUpdate' | 'Recreate';
maxUnavailable?: number | string;
maxSurge?: number | string;
}
// 扩展结果
interface ScalingResult {
deploymentId: string;
previousReplicas: number;
newReplicas: number;
duration: number;
status: 'success' | 'failed';
}
// 健康状态
interface HealthStatus {
status: 'healthy' | 'unhealthy' | 'unknown';
checks: HealthCheck[];
lastChecked: Date;
}
interface HealthCheck {
name: string;
status: 'pass' | 'fail' | 'warn';
message?: string;
duration?: number;
}
// 部署指标
interface DeploymentMetrics {
deploymentId: string;
timestamp: Date;
cpu: {
usage: number;
limit: number;
percentage: number;
};
memory: {
usage: number;
limit: number;
percentage: number;
};
network: {
bytesIn: number;
bytesOut: number;
packetsIn: number;
packetsOut: number;
};
replicas: {
desired: number;
available: number;
ready: number;
};
requests: {
total: number;
successful: number;
failed: number;
averageResponseTime: number;
};
}
// 指标查询
interface MetricsQuery {
startTime?: Date;
endTime?: Date;
interval?: number;
metrics?: string[];
}
// 日志查询
interface LogQuery {
startTime?: Date;
endTime?: Date;
level?: 'debug' | 'info' | 'warn' | 'error';
search?: string;
limit?: number;
offset?: number;
}
// 日志条目
interface LogEntry {
timestamp: Date;
level: 'debug' | 'info' | 'warn' | 'error';
message: string;
source: string;
metadata?: Record<string, any>;
}
// 构建结果
interface BuildResult {
buildId: string;
imageTag: string;
duration: number;
logs?: string[];
}
18.4 容器编排器
// 容器编排器接口
interface ContainerOrchestrator {
deploy(config: OrchestrationConfig): Promise<OrchestrationResult>;
undeploy(orchestrationId: string): Promise<void>;
scale(orchestrationId: string, config: ScalingConfig): Promise<void>;
healthCheck(orchestrationId: string): Promise<HealthStatus>;
enableAutoScaling(orchestrationId: string, config: AutoScalingConfig): Promise<void>;
disableAutoScaling(orchestrationId: string): Promise<void>;
cleanup(orchestrationId: string): Promise<void>;
}
// Kubernetes编排器实现
class KubernetesOrchestrator implements ContainerOrchestrator {
private kubeConfig: any;
private k8sApi: any;
constructor(kubeConfig: any) {
this.kubeConfig = kubeConfig;
// 初始化Kubernetes API客户端
this.k8sApi = this.initializeK8sApi(kubeConfig);
}
async deploy(config: OrchestrationConfig): Promise<OrchestrationResult> {
const namespace = config.namespace || 'default';
const deploymentName = `${config.id}-deployment`;
const serviceName = `${config.id}-service`;
try {
// 创建Deployment
const deployment = {
apiVersion: 'apps/v1',
kind: 'Deployment',
metadata: {
name: deploymentName,
namespace,
labels: {
app: config.id,
version: config.version || '1.0.0'
}
},
spec: {
replicas: config.replicas,
selector: {
matchLabels: {
app: config.id
}
},
template: {
metadata: {
labels: {
app: config.id,
version: config.version || '1.0.0'
}
},
spec: {
containers: [{
name: config.id,
image: config.image,
ports: config.ports?.map(p => ({
containerPort: p.containerPort,
protocol: p.protocol || 'TCP'
})),
env: Object.entries(config.environment || {}).map(([key, value]) => ({
name: key,
value: value
})),
resources: config.resources,
volumeMounts: config.volumes?.map(v => ({
name: v.name,
mountPath: v.mountPath,
readOnly: v.readOnly
}))
}],
volumes: config.volumes?.map(v => ({
name: v.name,
[v.type]: v.source ? { path: v.source } : {}
}))
}
}
}
};
await this.k8sApi.createNamespacedDeployment(namespace, deployment);
// 创建Service
if (config.ports && config.ports.length > 0) {
const service = {
apiVersion: 'v1',
kind: 'Service',
metadata: {
name: serviceName,
namespace,
labels: {
app: config.id
}
},
spec: {
selector: {
app: config.id
},
ports: config.ports.map(p => ({
name: p.name || `port-${p.containerPort}`,
port: p.hostPort || p.containerPort,
targetPort: p.containerPort,
protocol: p.protocol || 'TCP'
})),
type: 'ClusterIP'
}
};
await this.k8sApi.createNamespacedService(namespace, service);
}
// 等待部署就绪
await this.waitForDeploymentReady(namespace, deploymentName);
// 获取服务端点
const endpoints = await this.getServiceEndpoints(namespace, serviceName);
return {
id: config.id,
deploymentName,
serviceName,
namespace,
endpoints
};
} catch (error) {
// 清理失败的资源
await this.cleanup(config.id);
throw error;
}
}
async undeploy(orchestrationId: string): Promise<void> {
await this.cleanup(orchestrationId);
}
async scale(orchestrationId: string, config: ScalingConfig): Promise<void> {
const namespace = 'default'; // 应该从配置中获取
const deploymentName = `${orchestrationId}-deployment`;
try {
// 更新Deployment的副本数
const patch = {
spec: {
replicas: config.replicas
}
};
await this.k8sApi.patchNamespacedDeployment(
deploymentName,
namespace,
patch,
undefined,
undefined,
undefined,
undefined,
{ headers: { 'Content-Type': 'application/merge-patch+json' } }
);
// 等待扩展完成
await this.waitForDeploymentReady(namespace, deploymentName);
} catch (error) {
throw new Error(`Scaling failed: ${error.message}`);
}
}
async healthCheck(orchestrationId: string): Promise<HealthStatus> {
const namespace = 'default';
const deploymentName = `${orchestrationId}-deployment`;
try {
const deployment = await this.k8sApi.readNamespacedDeployment(deploymentName, namespace);
const status = deployment.body.status;
const checks: HealthCheck[] = [
{
name: 'deployment-ready',
status: status.readyReplicas === status.replicas ? 'pass' : 'fail',
message: `${status.readyReplicas || 0}/${status.replicas || 0} replicas ready`
},
{
name: 'deployment-available',
status: status.availableReplicas === status.replicas ? 'pass' : 'fail',
message: `${status.availableReplicas || 0}/${status.replicas || 0} replicas available`
}
];
const allHealthy = checks.every(check => check.status === 'pass');
return {
status: allHealthy ? 'healthy' : 'unhealthy',
checks,
lastChecked: new Date()
};
} catch (error) {
return {
status: 'unknown',
checks: [{
name: 'deployment-check',
status: 'fail',
message: error.message
}],
lastChecked: new Date()
};
}
}
async enableAutoScaling(orchestrationId: string, config: AutoScalingConfig): Promise<void> {
const namespace = 'default';
const hpaName = `${orchestrationId}-hpa`;
const deploymentName = `${orchestrationId}-deployment`;
const hpa = {
apiVersion: 'autoscaling/v2',
kind: 'HorizontalPodAutoscaler',
metadata: {
name: hpaName,
namespace
},
spec: {
scaleTargetRef: {
apiVersion: 'apps/v1',
kind: 'Deployment',
name: deploymentName
},
minReplicas: config.minReplicas,
maxReplicas: config.maxReplicas,
metrics: [
...(config.targetCPUUtilization ? [{
type: 'Resource',
resource: {
name: 'cpu',
target: {
type: 'Utilization',
averageUtilization: config.targetCPUUtilization
}
}
}] : []),
...(config.targetMemoryUtilization ? [{
type: 'Resource',
resource: {
name: 'memory',
target: {
type: 'Utilization',
averageUtilization: config.targetMemoryUtilization
}
}
}] : [])
]
}
};
await this.k8sApi.createNamespacedHorizontalPodAutoscaler(namespace, hpa);
}
async disableAutoScaling(orchestrationId: string): Promise<void> {
const namespace = 'default';
const hpaName = `${orchestrationId}-hpa`;
try {
await this.k8sApi.deleteNamespacedHorizontalPodAutoscaler(hpaName, namespace);
} catch (error) {
// 忽略不存在的错误
if (error.response?.statusCode !== 404) {
throw error;
}
}
}
async cleanup(orchestrationId: string): Promise<void> {
const namespace = 'default';
const deploymentName = `${orchestrationId}-deployment`;
const serviceName = `${orchestrationId}-service`;
const hpaName = `${orchestrationId}-hpa`;
try {
// 删除HPA
await this.disableAutoScaling(orchestrationId);
// 删除Service
try {
await this.k8sApi.deleteNamespacedService(serviceName, namespace);
} catch (error) {
if (error.response?.statusCode !== 404) {
console.warn(`Failed to delete service ${serviceName}:`, error.message);
}
}
// 删除Deployment
try {
await this.k8sApi.deleteNamespacedDeployment(deploymentName, namespace);
} catch (error) {
if (error.response?.statusCode !== 404) {
console.warn(`Failed to delete deployment ${deploymentName}:`, error.message);
}
}
} catch (error) {
console.error(`Cleanup failed for ${orchestrationId}:`, error);
}
}
// 私有方法
private initializeK8sApi(kubeConfig: any): any {
// 这里应该初始化实际的Kubernetes API客户端
// 简化实现,返回模拟对象
return {
createNamespacedDeployment: async (namespace: string, deployment: any) => {
console.log(`Creating deployment in namespace ${namespace}:`, deployment.metadata.name);
},
createNamespacedService: async (namespace: string, service: any) => {
console.log(`Creating service in namespace ${namespace}:`, service.metadata.name);
},
createNamespacedHorizontalPodAutoscaler: async (namespace: string, hpa: any) => {
console.log(`Creating HPA in namespace ${namespace}:`, hpa.metadata.name);
},
readNamespacedDeployment: async (name: string, namespace: string) => {
return {
body: {
status: {
replicas: 1,
readyReplicas: 1,
availableReplicas: 1
}
}
};
},
patchNamespacedDeployment: async (name: string, namespace: string, patch: any) => {
console.log(`Patching deployment ${name} in namespace ${namespace}`);
},
deleteNamespacedDeployment: async (name: string, namespace: string) => {
console.log(`Deleting deployment ${name} in namespace ${namespace}`);
},
deleteNamespacedService: async (name: string, namespace: string) => {
console.log(`Deleting service ${name} in namespace ${namespace}`);
},
deleteNamespacedHorizontalPodAutoscaler: async (name: string, namespace: string) => {
console.log(`Deleting HPA ${name} in namespace ${namespace}`);
}
};
}
private async waitForDeploymentReady(namespace: string, deploymentName: string): Promise<void> {
const maxAttempts = 60; // 10分钟
const interval = 10000; // 10秒
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
const deployment = await this.k8sApi.readNamespacedDeployment(deploymentName, namespace);
const status = deployment.body.status;
if (status.readyReplicas === status.replicas) {
return;
}
} catch (error) {
// 忽略错误,继续重试
}
if (attempt < maxAttempts) {
await new Promise(resolve => setTimeout(resolve, interval));
}
}
throw new Error(`Deployment ${deploymentName} not ready after ${maxAttempts} attempts`);
}
private async getServiceEndpoints(namespace: string, serviceName: string): Promise<string[]> {
try {
// 这里应该获取实际的服务端点
// 简化实现,返回模拟端点
return [`http://${serviceName}.${namespace}.svc.cluster.local`];
} catch (error) {
return [];
}
}
}
// Docker编排器实现
class DockerOrchestrator implements ContainerOrchestrator {
private docker: any;
private containers: Map<string, any> = new Map();
constructor() {
// 初始化Docker客户端
this.docker = this.initializeDockerApi();
}
async deploy(config: OrchestrationConfig): Promise<OrchestrationResult> {
try {
// 创建容器
const container = await this.docker.createContainer({
Image: config.image,
name: `${config.id}-container`,
Env: Object.entries(config.environment || {}).map(([key, value]) => `${key}=${value}`),
ExposedPorts: config.ports?.reduce((acc, port) => {
acc[`${port.containerPort}/${port.protocol?.toLowerCase() || 'tcp'}`] = {};
return acc;
}, {} as any),
HostConfig: {
PortBindings: config.ports?.reduce((acc, port) => {
const key = `${port.containerPort}/${port.protocol?.toLowerCase() || 'tcp'}`;
acc[key] = [{ HostPort: (port.hostPort || port.containerPort).toString() }];
return acc;
}, {} as any),
RestartPolicy: {
Name: 'unless-stopped'
},
Memory: this.parseMemory(config.resources?.limits?.memory),
CpuShares: this.parseCpu(config.resources?.limits?.cpu)
}
});
// 启动容器
await container.start();
this.containers.set(config.id, container);
// 获取容器信息
const containerInfo = await container.inspect();
const endpoints = this.getContainerEndpoints(containerInfo, config.ports);
return {
id: config.id,
containerId: container.id,
endpoints
};
} catch (error) {
throw new Error(`Docker deployment failed: ${error.message}`);
}
}
async undeploy(orchestrationId: string): Promise<void> {
const container = this.containers.get(orchestrationId);
if (container) {
try {
await container.stop();
await container.remove();
this.containers.delete(orchestrationId);
} catch (error) {
console.warn(`Failed to undeploy container ${orchestrationId}:`, error.message);
}
}
}
async scale(orchestrationId: string, config: ScalingConfig): Promise<void> {
// Docker单容器不支持直接扩展,需要使用Docker Swarm或其他编排工具
throw new Error('Scaling not supported in standalone Docker mode');
}
async healthCheck(orchestrationId: string): Promise<HealthStatus> {
const container = this.containers.get(orchestrationId);
if (!container) {
return {
status: 'unknown',
checks: [{
name: 'container-exists',
status: 'fail',
message: 'Container not found'
}],
lastChecked: new Date()
};
}
try {
const containerInfo = await container.inspect();
const isRunning = containerInfo.State.Running;
return {
status: isRunning ? 'healthy' : 'unhealthy',
checks: [{
name: 'container-running',
status: isRunning ? 'pass' : 'fail',
message: isRunning ? 'Container is running' : `Container is ${containerInfo.State.Status}`
}],
lastChecked: new Date()
};
} catch (error) {
return {
status: 'unknown',
checks: [{
name: 'container-check',
status: 'fail',
message: error.message
}],
lastChecked: new Date()
};
}
}
async enableAutoScaling(orchestrationId: string, config: AutoScalingConfig): Promise<void> {
throw new Error('Auto-scaling not supported in standalone Docker mode');
}
async disableAutoScaling(orchestrationId: string): Promise<void> {
// No-op for Docker
}
async cleanup(orchestrationId: string): Promise<void> {
await this.undeploy(orchestrationId);
}
// 私有方法
private initializeDockerApi(): any {
// 这里应该初始化实际的Docker API客户端
// 简化实现,返回模拟对象
return {
createContainer: async (options: any) => {
const containerId = `container-${Date.now()}`;
console.log(`Creating Docker container:`, options.name);
return {
id: containerId,
start: async () => {
console.log(`Starting container ${containerId}`);
},
stop: async () => {
console.log(`Stopping container ${containerId}`);
},
remove: async () => {
console.log(`Removing container ${containerId}`);
},
inspect: async () => {
return {
Id: containerId,
State: {
Running: true,
Status: 'running'
},
NetworkSettings: {
Ports: options.HostConfig?.PortBindings || {}
}
};
}
};
}
};
}
private parseMemory(memory?: string): number | undefined {
if (!memory) return undefined;
const match = memory.match(/^(\d+)(\w+)?$/);
if (!match) return undefined;
const value = parseInt(match[1]);
const unit = match[2]?.toLowerCase() || 'b';
const multipliers: Record<string, number> = {
'b': 1,
'k': 1024,
'kb': 1024,
'm': 1024 * 1024,
'mb': 1024 * 1024,
'g': 1024 * 1024 * 1024,
'gb': 1024 * 1024 * 1024
};
return value * (multipliers[unit] || 1);
}
private parseCpu(cpu?: string): number | undefined {
if (!cpu) return undefined;
if (cpu.endsWith('m')) {
// milliCPU
return parseInt(cpu.slice(0, -1));
}
// CPU cores to shares (1 core = 1024 shares)
return Math.floor(parseFloat(cpu) * 1024);
}
private getContainerEndpoints(containerInfo: any, ports?: PortConfig[]): string[] {
if (!ports || ports.length === 0) {
return [];
}
const endpoints: string[] = [];
const portBindings = containerInfo.NetworkSettings.Ports;
for (const port of ports) {
const key = `${port.containerPort}/${port.protocol?.toLowerCase() || 'tcp'}`;
const binding = portBindings[key];
if (binding && binding.length > 0) {
const hostPort = binding[0].HostPort;
endpoints.push(`http://localhost:${hostPort}`);
}
}
return endpoints;
}
}
// 编排配置
interface OrchestrationConfig {
id: string;
image: string;
replicas: number;
resources?: {
requests?: {
cpu: string;
memory: string;
};
limits?: {
cpu: string;
memory: string;
};
};
ports?: PortConfig[];
volumes?: VolumeConfig[];
networks?: string[];
environment?: Record<string, string>;
namespace?: string;
version?: string;
}
// 编排结果
interface OrchestrationResult {
id: string;
endpoints: string[];
[key: string]: any;
}
18.5 监控服务
// 监控服务接口
interface MonitoringService {
startMonitoring(config: MonitoringStartConfig): Promise<void>;
stopMonitoring(deploymentId: string): Promise<void>;
getMetrics(deploymentId: string, query?: MetricsQuery): Promise<DeploymentMetrics>;
getAlerts(deploymentId: string): Promise<Alert[]>;
createAlert(deploymentId: string, config: AlertConfig): Promise<string>;
updateAlert(alertId: string, config: Partial<AlertConfig>): Promise<void>;
deleteAlert(alertId: string): Promise<void>;
}
// 监控服务实现
class LowCodeMonitoringService implements MonitoringService {
private activeMonitors: Map<string, MonitoringSession> = new Map();
private alerts: Map<string, Alert> = new Map();
private metricsStore: MetricsStore;
private notificationService: NotificationService;
constructor(
metricsStore: MetricsStore,
notificationService: NotificationService
) {
this.metricsStore = metricsStore;
this.notificationService = notificationService;
}
async startMonitoring(config: MonitoringStartConfig): Promise<void> {
const session: MonitoringSession = {
deploymentId: config.deploymentId,
config,
startTime: new Date(),
collectors: [],
intervalId: null
};
// 创建指标收集器
for (const metric of config.metrics) {
const collector = this.createMetricCollector(metric, config);
session.collectors.push(collector);
}
// 启动定期收集
session.intervalId = setInterval(async () => {
await this.collectMetrics(session);
}, config.interval);
this.activeMonitors.set(config.deploymentId, session);
// 立即收集一次指标
await this.collectMetrics(session);
}
async stopMonitoring(deploymentId: string): Promise<void> {
const session = this.activeMonitors.get(deploymentId);
if (session) {
if (session.intervalId) {
clearInterval(session.intervalId);
}
// 停止所有收集器
for (const collector of session.collectors) {
await collector.stop();
}
this.activeMonitors.delete(deploymentId);
}
}
async getMetrics(deploymentId: string, query?: MetricsQuery): Promise<DeploymentMetrics> {
return await this.metricsStore.getMetrics(deploymentId, query);
}
async getAlerts(deploymentId: string): Promise<Alert[]> {
return Array.from(this.alerts.values())
.filter(alert => alert.deploymentId === deploymentId);
}
async createAlert(deploymentId: string, config: AlertConfig): Promise<string> {
const alertId = this.generateAlertId();
const alert: Alert = {
id: alertId,
deploymentId,
config,
status: AlertStatus.ACTIVE,
createdAt: new Date(),
updatedAt: new Date(),
lastTriggered: null,
triggerCount: 0
};
this.alerts.set(alertId, alert);
return alertId;
}
async updateAlert(alertId: string, config: Partial<AlertConfig>): Promise<void> {
const alert = this.alerts.get(alertId);
if (!alert) {
throw new Error(`Alert ${alertId} not found`);
}
alert.config = { ...alert.config, ...config };
alert.updatedAt = new Date();
}
async deleteAlert(alertId: string): Promise<void> {
this.alerts.delete(alertId);
}
// 私有方法
private createMetricCollector(metric: string, config: MonitoringStartConfig): MetricCollector {
switch (metric) {
case 'cpu':
return new CpuMetricCollector(config);
case 'memory':
return new MemoryMetricCollector(config);
case 'network':
return new NetworkMetricCollector(config);
case 'requests':
return new RequestMetricCollector(config);
default:
return new CustomMetricCollector(metric, config);
}
}
private async collectMetrics(session: MonitoringSession): Promise<void> {
const timestamp = new Date();
const metrics: Partial<DeploymentMetrics> = {
deploymentId: session.deploymentId,
timestamp
};
// 收集所有指标
for (const collector of session.collectors) {
try {
const metricData = await collector.collect();
Object.assign(metrics, metricData);
} catch (error) {
console.error(`Failed to collect metric from ${collector.constructor.name}:`, error);
}
}
// 存储指标
await this.metricsStore.storeMetrics(metrics as DeploymentMetrics);
// 检查告警
await this.checkAlerts(session.deploymentId, metrics as DeploymentMetrics);
}
private async checkAlerts(deploymentId: string, metrics: DeploymentMetrics): Promise<void> {
const alerts = await this.getAlerts(deploymentId);
for (const alert of alerts) {
if (alert.status !== AlertStatus.ACTIVE) {
continue;
}
const shouldTrigger = this.evaluateAlertCondition(alert.config, metrics);
if (shouldTrigger) {
await this.triggerAlert(alert, metrics);
}
}
}
private evaluateAlertCondition(config: AlertConfig, metrics: DeploymentMetrics): boolean {
const value = this.getMetricValue(config.metric, metrics);
if (value === undefined) {
return false;
}
switch (config.condition) {
case 'gt':
return value > config.threshold;
case 'lt':
return value < config.threshold;
case 'eq':
return value === config.threshold;
case 'ne':
return value !== config.threshold;
default:
return false;
}
}
private getMetricValue(metric: string, metrics: DeploymentMetrics): number | undefined {
switch (metric) {
case 'cpu_usage':
return metrics.cpu?.usage;
case 'cpu_percentage':
return metrics.cpu?.percentage;
case 'memory_usage':
return metrics.memory?.usage;
case 'memory_percentage':
return metrics.memory?.percentage;
case 'network_bytes_in':
return metrics.network?.bytesIn;
case 'network_bytes_out':
return metrics.network?.bytesOut;
case 'requests_total':
return metrics.requests?.total;
case 'requests_failed':
return metrics.requests?.failed;
case 'response_time':
return metrics.requests?.averageResponseTime;
default:
return undefined;
}
}
private async triggerAlert(alert: Alert, metrics: DeploymentMetrics): Promise<void> {
const now = new Date();
// 检查是否在静默期内
if (alert.lastTriggered) {
const timeSinceLastTrigger = now.getTime() - alert.lastTriggered.getTime();
const silenceDuration = (alert.config.duration || 300) * 1000; // 默认5分钟
if (timeSinceLastTrigger < silenceDuration) {
return;
}
}
// 更新告警状态
alert.lastTriggered = now;
alert.triggerCount++;
alert.updatedAt = now;
// 发送通知
if (alert.config.notifications) {
for (const notification of alert.config.notifications) {
await this.notificationService.send({
type: 'alert',
title: `告警: ${alert.config.name}`,
message: this.formatAlertMessage(alert, metrics),
severity: alert.config.severity,
data: {
alertId: alert.id,
deploymentId: alert.deploymentId,
metrics,
config: alert.config
},
recipients: [notification]
});
}
}
}
private formatAlertMessage(alert: Alert, metrics: DeploymentMetrics): string {
const value = this.getMetricValue(alert.config.metric, metrics);
return `指标 ${alert.config.metric} 当前值 ${value} ${alert.config.condition} 阈值 ${alert.config.threshold}`;
}
private generateAlertId(): string {
return `alert-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
}
// 指标收集器接口
interface MetricCollector {
collect(): Promise<Partial<DeploymentMetrics>>;
stop(): Promise<void>;
}
// CPU指标收集器
class CpuMetricCollector implements MetricCollector {
private config: MonitoringStartConfig;
constructor(config: MonitoringStartConfig) {
this.config = config;
}
async collect(): Promise<Partial<DeploymentMetrics>> {
// 这里应该实现实际的CPU指标收集
// 简化实现,返回模拟数据
const usage = Math.random() * 100; // 0-100%
const limit = 100;
return {
cpu: {
usage,
limit,
percentage: usage
}
};
}
async stop(): Promise<void> {
// 清理资源
}
}
// 内存指标收集器
class MemoryMetricCollector implements MetricCollector {
private config: MonitoringStartConfig;
constructor(config: MonitoringStartConfig) {
this.config = config;
}
async collect(): Promise<Partial<DeploymentMetrics>> {
// 这里应该实现实际的内存指标收集
const usage = Math.random() * 1024 * 1024 * 1024; // 0-1GB
const limit = 2 * 1024 * 1024 * 1024; // 2GB
return {
memory: {
usage,
limit,
percentage: (usage / limit) * 100
}
};
}
async stop(): Promise<void> {
// 清理资源
}
}
// 网络指标收集器
class NetworkMetricCollector implements MetricCollector {
private config: MonitoringStartConfig;
private lastBytesIn = 0;
private lastBytesOut = 0;
constructor(config: MonitoringStartConfig) {
this.config = config;
}
async collect(): Promise<Partial<DeploymentMetrics>> {
// 这里应该实现实际的网络指标收集
const bytesIn = this.lastBytesIn + Math.random() * 1024 * 1024; // 增量
const bytesOut = this.lastBytesOut + Math.random() * 1024 * 1024;
this.lastBytesIn = bytesIn;
this.lastBytesOut = bytesOut;
return {
network: {
bytesIn,
bytesOut,
packetsIn: Math.floor(bytesIn / 1500), // 假设平均包大小1500字节
packetsOut: Math.floor(bytesOut / 1500)
}
};
}
async stop(): Promise<void> {
// 清理资源
}
}
// 请求指标收集器
class RequestMetricCollector implements MetricCollector {
private config: MonitoringStartConfig;
private totalRequests = 0;
private successfulRequests = 0;
private failedRequests = 0;
constructor(config: MonitoringStartConfig) {
this.config = config;
}
async collect(): Promise<Partial<DeploymentMetrics>> {
// 这里应该实现实际的请求指标收集
const newRequests = Math.floor(Math.random() * 100);
const newFailed = Math.floor(newRequests * 0.05); // 5%失败率
const newSuccessful = newRequests - newFailed;
this.totalRequests += newRequests;
this.successfulRequests += newSuccessful;
this.failedRequests += newFailed;
return {
requests: {
total: this.totalRequests,
successful: this.successfulRequests,
failed: this.failedRequests,
averageResponseTime: 100 + Math.random() * 200 // 100-300ms
}
};
}
async stop(): Promise<void> {
// 清理资源
}
}
// 自定义指标收集器
class CustomMetricCollector implements MetricCollector {
private metric: string;
private config: MonitoringStartConfig;
constructor(metric: string, config: MonitoringStartConfig) {
this.metric = metric;
this.config = config;
}
async collect(): Promise<Partial<DeploymentMetrics>> {
// 这里应该实现自定义指标的收集逻辑
return {};
}
async stop(): Promise<void> {
// 清理资源
}
}
// 监控相关数据结构
interface MonitoringStartConfig {
deploymentId: string;
endpoints: string[];
metrics: string[];
interval: number;
alerts?: AlertConfig[];
}
interface MonitoringSession {
deploymentId: string;
config: MonitoringStartConfig;
startTime: Date;
collectors: MetricCollector[];
intervalId: NodeJS.Timeout | null;
}
interface Alert {
id: string;
deploymentId: string;
config: AlertConfig;
status: AlertStatus;
createdAt: Date;
updatedAt: Date;
lastTriggered: Date | null;
triggerCount: number;
}
enum AlertStatus {
ACTIVE = 'active',
PAUSED = 'paused',
RESOLVED = 'resolved'
}
// 指标存储接口
interface MetricsStore {
storeMetrics(metrics: DeploymentMetrics): Promise<void>;
getMetrics(deploymentId: string, query?: MetricsQuery): Promise<DeploymentMetrics>;
getMetricsHistory(deploymentId: string, query?: MetricsQuery): Promise<DeploymentMetrics[]>;
cleanup(deploymentId: string): Promise<void>;
}
// 内存指标存储实现
class MemoryMetricsStore implements MetricsStore {
private metrics: Map<string, DeploymentMetrics[]> = new Map();
private maxHistorySize = 1000; // 每个部署最多保存1000条记录
async storeMetrics(metrics: DeploymentMetrics): Promise<void> {
const deploymentId = metrics.deploymentId;
if (!this.metrics.has(deploymentId)) {
this.metrics.set(deploymentId, []);
}
const history = this.metrics.get(deploymentId)!;
history.push(metrics);
// 限制历史记录大小
if (history.length > this.maxHistorySize) {
history.splice(0, history.length - this.maxHistorySize);
}
}
async getMetrics(deploymentId: string, query?: MetricsQuery): Promise<DeploymentMetrics> {
const history = this.metrics.get(deploymentId);
if (!history || history.length === 0) {
throw new Error(`No metrics found for deployment ${deploymentId}`);
}
// 返回最新的指标
return history[history.length - 1];
}
async getMetricsHistory(deploymentId: string, query?: MetricsQuery): Promise<DeploymentMetrics[]> {
let history = this.metrics.get(deploymentId) || [];
if (query) {
// 应用时间过滤
if (query.startTime || query.endTime) {
history = history.filter(metric => {
const timestamp = metric.timestamp.getTime();
const start = query.startTime?.getTime() || 0;
const end = query.endTime?.getTime() || Date.now();
return timestamp >= start && timestamp <= end;
});
}
}
return history;
}
async cleanup(deploymentId: string): Promise<void> {
this.metrics.delete(deploymentId);
}
}
18.6 日志服务
// 日志服务接口
interface LoggingService {
getLogs(query: LogQueryWithDeployment): Promise<LogEntry[]>;
streamLogs(deploymentId: string, callback: (log: LogEntry) => void): Promise<() => void>;
storeLogs(deploymentId: string, logs: LogEntry[]): Promise<void>;
cleanup(deploymentId: string): Promise<void>;
}
// 日志服务实现
class LowCodeLoggingService implements LoggingService {
private logs: Map<string, LogEntry[]> = new Map();
private streams: Map<string, Set<(log: LogEntry) => void>> = new Map();
private maxLogsPerDeployment = 10000;
async getLogs(query: LogQueryWithDeployment): Promise<LogEntry[]> {
let logs = this.logs.get(query.deploymentId) || [];
// 应用过滤条件
if (query.level) {
logs = logs.filter(log => log.level === query.level);
}
if (query.search) {
const searchLower = query.search.toLowerCase();
logs = logs.filter(log =>
log.message.toLowerCase().includes(searchLower) ||
log.source.toLowerCase().includes(searchLower)
);
}
if (query.startTime || query.endTime) {
logs = logs.filter(log => {
const timestamp = log.timestamp.getTime();
const start = query.startTime?.getTime() || 0;
const end = query.endTime?.getTime() || Date.now();
return timestamp >= start && timestamp <= end;
});
}
// 排序(最新的在前)
logs.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
// 应用分页
const offset = query.offset || 0;
const limit = query.limit || 100;
return logs.slice(offset, offset + limit);
}
async streamLogs(deploymentId: string, callback: (log: LogEntry) => void): Promise<() => void> {
if (!this.streams.has(deploymentId)) {
this.streams.set(deploymentId, new Set());
}
const callbacks = this.streams.get(deploymentId)!;
callbacks.add(callback);
// 返回取消订阅函数
return () => {
callbacks.delete(callback);
if (callbacks.size === 0) {
this.streams.delete(deploymentId);
}
};
}
async storeLogs(deploymentId: string, logs: LogEntry[]): Promise<void> {
if (!this.logs.has(deploymentId)) {
this.logs.set(deploymentId, []);
}
const existingLogs = this.logs.get(deploymentId)!;
existingLogs.push(...logs);
// 限制日志数量
if (existingLogs.length > this.maxLogsPerDeployment) {
existingLogs.splice(0, existingLogs.length - this.maxLogsPerDeployment);
}
// 通知流订阅者
const callbacks = this.streams.get(deploymentId);
if (callbacks) {
for (const log of logs) {
for (const callback of callbacks) {
try {
callback(log);
} catch (error) {
console.error('Error in log stream callback:', error);
}
}
}
}
}
async cleanup(deploymentId: string): Promise<void> {
this.logs.delete(deploymentId);
this.streams.delete(deploymentId);
}
}
// 日志查询(包含部署ID)
interface LogQueryWithDeployment extends LogQuery {
deploymentId: string;
}
18.7 配置管理器
// 配置管理器接口
interface ConfigurationManager {
getEnvironmentConfig(environment: string): Promise<Record<string, string>>;
setEnvironmentConfig(environment: string, config: Record<string, string>): Promise<void>;
getSecret(key: string): Promise<string | null>;
setSecret(key: string, value: string): Promise<void>;
deleteSecret(key: string): Promise<void>;
getConfigTemplate(templateName: string): Promise<ConfigTemplate | null>;
createConfigTemplate(template: ConfigTemplate): Promise<void>;
updateConfigTemplate(templateName: string, template: Partial<ConfigTemplate>): Promise<void>;
deleteConfigTemplate(templateName: string): Promise<void>;
}
// 配置管理器实现
class LowCodeConfigurationManager implements ConfigurationManager {
private environmentConfigs: Map<string, Record<string, string>> = new Map();
private secrets: Map<string, string> = new Map();
private templates: Map<string, ConfigTemplate> = new Map();
private encryptionService: EncryptionService;
constructor(encryptionService: EncryptionService) {
this.encryptionService = encryptionService;
this.initializeDefaultConfigs();
}
async getEnvironmentConfig(environment: string): Promise<Record<string, string>> {
return this.environmentConfigs.get(environment) || {};
}
async setEnvironmentConfig(environment: string, config: Record<string, string>): Promise<void> {
this.environmentConfigs.set(environment, { ...config });
}
async getSecret(key: string): Promise<string | null> {
const encryptedValue = this.secrets.get(key);
if (!encryptedValue) {
return null;
}
try {
return await this.encryptionService.decrypt(encryptedValue);
} catch (error) {
console.error(`Failed to decrypt secret ${key}:`, error);
return null;
}
}
async setSecret(key: string, value: string): Promise<void> {
const encryptedValue = await this.encryptionService.encrypt(value);
this.secrets.set(key, encryptedValue);
}
async deleteSecret(key: string): Promise<void> {
this.secrets.delete(key);
}
async getConfigTemplate(templateName: string): Promise<ConfigTemplate | null> {
return this.templates.get(templateName) || null;
}
async createConfigTemplate(template: ConfigTemplate): Promise<void> {
this.templates.set(template.name, { ...template });
}
async updateConfigTemplate(templateName: string, template: Partial<ConfigTemplate>): Promise<void> {
const existing = this.templates.get(templateName);
if (!existing) {
throw new Error(`Template ${templateName} not found`);
}
this.templates.set(templateName, { ...existing, ...template });
}
async deleteConfigTemplate(templateName: string): Promise<void> {
this.templates.delete(templateName);
}
// 私有方法
private initializeDefaultConfigs(): void {
// 开发环境配置
this.environmentConfigs.set('development', {
NODE_ENV: 'development',
LOG_LEVEL: 'debug',
API_TIMEOUT: '30000',
CACHE_TTL: '300'
});
// 测试环境配置
this.environmentConfigs.set('staging', {
NODE_ENV: 'staging',
LOG_LEVEL: 'info',
API_TIMEOUT: '15000',
CACHE_TTL: '600'
});
// 生产环境配置
this.environmentConfigs.set('production', {
NODE_ENV: 'production',
LOG_LEVEL: 'warn',
API_TIMEOUT: '10000',
CACHE_TTL: '3600'
});
// 默认配置模板
this.templates.set('web-app', {
name: 'web-app',
description: 'Web应用配置模板',
config: {
PORT: '3000',
NODE_ENV: '${ENVIRONMENT}',
LOG_LEVEL: 'info',
SESSION_SECRET: '${SECRET:session_secret}',
DATABASE_URL: '${SECRET:database_url}'
},
secrets: ['session_secret', 'database_url'],
variables: ['ENVIRONMENT']
});
this.templates.set('api-service', {
name: 'api-service',
description: 'API服务配置模板',
config: {
PORT: '8080',
NODE_ENV: '${ENVIRONMENT}',
LOG_LEVEL: 'info',
JWT_SECRET: '${SECRET:jwt_secret}',
DATABASE_URL: '${SECRET:database_url}',
REDIS_URL: '${SECRET:redis_url}'
},
secrets: ['jwt_secret', 'database_url', 'redis_url'],
variables: ['ENVIRONMENT']
});
}
}
// 配置模板
interface ConfigTemplate {
name: string;
description: string;
config: Record<string, string>;
secrets: string[];
variables: string[];
}
// 加密服务接口(简化版)
interface EncryptionService {
encrypt(data: string): Promise<string>;
decrypt(encryptedData: string): Promise<string>;
}
// 简单加密服务实现
class SimpleEncryptionService implements EncryptionService {
private key: string;
constructor(key: string = 'default-encryption-key') {
this.key = key;
}
async encrypt(data: string): Promise<string> {
// 这里应该使用真正的加密算法,如AES
// 简化实现,使用Base64编码
return Buffer.from(data).toString('base64');
}
async decrypt(encryptedData: string): Promise<string> {
// 这里应该使用真正的解密算法
// 简化实现,使用Base64解码
return Buffer.from(encryptedData, 'base64').toString('utf-8');
}
}