feat: Add Caddy platform service provider with core functionality and integration
This commit is contained in:
@@ -284,13 +284,13 @@ export class OneboxHttpServer {
|
||||
// Platform Services endpoints
|
||||
} else if (path === '/api/platform-services' && method === 'GET') {
|
||||
return await this.handleListPlatformServicesRequest();
|
||||
} else if (path.match(/^\/api\/platform-services\/(mongodb|minio|redis|postgresql|rabbitmq)$/) && method === 'GET') {
|
||||
} else if (path.match(/^\/api\/platform-services\/(mongodb|minio|redis|postgresql|rabbitmq|caddy)$/) && method === 'GET') {
|
||||
const type = path.split('/').pop()! as TPlatformServiceType;
|
||||
return await this.handleGetPlatformServiceRequest(type);
|
||||
} else if (path.match(/^\/api\/platform-services\/(mongodb|minio|redis|postgresql|rabbitmq)\/start$/) && method === 'POST') {
|
||||
} else if (path.match(/^\/api\/platform-services\/(mongodb|minio|redis|postgresql|rabbitmq|caddy)\/start$/) && method === 'POST') {
|
||||
const type = path.split('/')[3] as TPlatformServiceType;
|
||||
return await this.handleStartPlatformServiceRequest(type);
|
||||
} else if (path.match(/^\/api\/platform-services\/(mongodb|minio|redis|postgresql|rabbitmq)\/stop$/) && method === 'POST') {
|
||||
} else if (path.match(/^\/api\/platform-services\/(mongodb|minio|redis|postgresql|rabbitmq|caddy)\/stop$/) && method === 'POST') {
|
||||
const type = path.split('/')[3] as TPlatformServiceType;
|
||||
return await this.handleStopPlatformServiceRequest(type);
|
||||
} else if (path.match(/^\/api\/services\/[^/]+\/platform-resources$/) && method === 'GET') {
|
||||
@@ -1144,6 +1144,7 @@ export class OneboxHttpServer {
|
||||
redis: 6379,
|
||||
postgresql: 5432,
|
||||
rabbitmq: 5672,
|
||||
caddy: 80,
|
||||
};
|
||||
return ports[type] || 0;
|
||||
}
|
||||
@@ -1260,12 +1261,15 @@ export class OneboxHttpServer {
|
||||
// Build response with provider info
|
||||
const result = providers.map((provider) => {
|
||||
const service = platformServices.find((s) => s.type === provider.type);
|
||||
// Check if provider has isCore property (like CaddyProvider)
|
||||
const isCore = 'isCore' in provider && (provider as any).isCore === true;
|
||||
return {
|
||||
type: provider.type,
|
||||
displayName: provider.displayName,
|
||||
resourceTypes: provider.resourceTypes,
|
||||
status: service?.status || 'not-deployed',
|
||||
containerId: service?.containerId,
|
||||
isCore,
|
||||
createdAt: service?.createdAt,
|
||||
updatedAt: service?.updatedAt,
|
||||
};
|
||||
@@ -1362,6 +1366,15 @@ export class OneboxHttpServer {
|
||||
}, 404);
|
||||
}
|
||||
|
||||
// Check if this is a core service that cannot be stopped
|
||||
const isCore = 'isCore' in provider && (provider as any).isCore === true;
|
||||
if (isCore) {
|
||||
return this.jsonResponse({
|
||||
success: false,
|
||||
error: `${provider.displayName} is a core service and cannot be stopped`,
|
||||
}, 400);
|
||||
}
|
||||
|
||||
logger.info(`Stopping platform service: ${type}`);
|
||||
await this.oneboxRef.platformServices.stopPlatformService(type);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
import type { IPlatformServiceProvider } from './providers/base.ts';
|
||||
import { MongoDBProvider } from './providers/mongodb.ts';
|
||||
import { MinioProvider } from './providers/minio.ts';
|
||||
import { CaddyProvider } from './providers/caddy.ts';
|
||||
import { logger } from '../../logging.ts';
|
||||
import { getErrorMessage } from '../../utils/error.ts';
|
||||
import { credentialEncryption } from '../encryption.ts';
|
||||
@@ -37,6 +38,7 @@ export class PlatformServicesManager {
|
||||
// Register providers
|
||||
this.registerProvider(new MongoDBProvider(this.oneboxRef));
|
||||
this.registerProvider(new MinioProvider(this.oneboxRef));
|
||||
this.registerProvider(new CaddyProvider(this.oneboxRef));
|
||||
|
||||
logger.info(`Platform services manager initialized with ${this.providers.size} providers`);
|
||||
}
|
||||
|
||||
110
ts/classes/platform-services/providers/caddy.ts
Normal file
110
ts/classes/platform-services/providers/caddy.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Caddy Platform Service Provider
|
||||
*
|
||||
* Caddy is a core infrastructure service that provides reverse proxy functionality.
|
||||
* Unlike other platform services:
|
||||
* - It doesn't provision resources for user services
|
||||
* - It's started automatically by Onebox and cannot be stopped by users
|
||||
* - It delegates to the existing CaddyManager for actual operations
|
||||
*/
|
||||
|
||||
import { BasePlatformServiceProvider } from './base.ts';
|
||||
import type {
|
||||
IService,
|
||||
IPlatformResource,
|
||||
IPlatformServiceConfig,
|
||||
IProvisionedResource,
|
||||
IEnvVarMapping,
|
||||
TPlatformServiceType,
|
||||
TPlatformResourceType,
|
||||
} from '../../../types.ts';
|
||||
import { logger } from '../../../logging.ts';
|
||||
import type { Onebox } from '../../onebox.ts';
|
||||
|
||||
export class CaddyProvider extends BasePlatformServiceProvider {
|
||||
readonly type: TPlatformServiceType = 'caddy';
|
||||
readonly displayName = 'Caddy Reverse Proxy';
|
||||
readonly resourceTypes: TPlatformResourceType[] = []; // Caddy doesn't provision resources
|
||||
readonly isCore = true; // Core infrastructure - cannot be stopped by users
|
||||
|
||||
constructor(oneboxRef: Onebox) {
|
||||
super(oneboxRef);
|
||||
}
|
||||
|
||||
getDefaultConfig(): IPlatformServiceConfig {
|
||||
return {
|
||||
image: 'caddy:2-alpine',
|
||||
port: 80,
|
||||
volumes: [],
|
||||
environment: {},
|
||||
};
|
||||
}
|
||||
|
||||
getEnvVarMappings(): IEnvVarMapping[] {
|
||||
// Caddy doesn't inject any env vars into user services
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploy Caddy container - delegates to CaddyManager via reverseProxy
|
||||
*/
|
||||
async deployContainer(): Promise<string> {
|
||||
logger.info('Starting Caddy via reverse proxy manager...');
|
||||
|
||||
// Get the reverse proxy which manages Caddy
|
||||
const reverseProxy = this.oneboxRef.reverseProxy;
|
||||
|
||||
// Start reverse proxy (which starts Caddy)
|
||||
await reverseProxy.startHttp();
|
||||
|
||||
// Get Caddy status to find container ID
|
||||
const status = reverseProxy.getStatus();
|
||||
|
||||
// Update platform service record
|
||||
const platformService = this.oneboxRef.database.getPlatformServiceByType(this.type);
|
||||
if (platformService) {
|
||||
this.oneboxRef.database.updatePlatformService(platformService.id!, {
|
||||
status: 'running',
|
||||
containerId: 'onebox-caddy', // Service name for Swarm services
|
||||
});
|
||||
}
|
||||
|
||||
logger.success('Caddy platform service started');
|
||||
return 'onebox-caddy';
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop Caddy container - NOT ALLOWED for core infrastructure
|
||||
*/
|
||||
async stopContainer(_containerId: string): Promise<void> {
|
||||
throw new Error('Caddy is a core infrastructure service and cannot be stopped');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Caddy is healthy via the reverse proxy
|
||||
*/
|
||||
async healthCheck(): Promise<boolean> {
|
||||
try {
|
||||
const reverseProxy = this.oneboxRef.reverseProxy;
|
||||
const status = reverseProxy.getStatus();
|
||||
return status.http.running;
|
||||
} catch (error) {
|
||||
logger.debug(`Caddy health check failed: ${error}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Caddy doesn't provision resources for user services
|
||||
*/
|
||||
async provisionResource(_userService: IService): Promise<IProvisionedResource> {
|
||||
throw new Error('Caddy does not provision resources for user services');
|
||||
}
|
||||
|
||||
/**
|
||||
* Caddy doesn't deprovision resources
|
||||
*/
|
||||
async deprovisionResource(_resource: IPlatformResource, _credentials: Record<string, string>): Promise<void> {
|
||||
throw new Error('Caddy does not manage resources for user services');
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ export interface ITokenCreatedResponse {
|
||||
}
|
||||
|
||||
// Platform service types
|
||||
export type TPlatformServiceType = 'mongodb' | 'minio' | 'redis' | 'postgresql' | 'rabbitmq';
|
||||
export type TPlatformServiceType = 'mongodb' | 'minio' | 'redis' | 'postgresql' | 'rabbitmq' | 'caddy';
|
||||
export type TPlatformResourceType = 'database' | 'bucket' | 'cache' | 'queue';
|
||||
export type TPlatformServiceStatus = 'stopped' | 'starting' | 'running' | 'stopping' | 'failed';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user