import * as plugins from '../../plugins.ts'; import { logger } from '../../logging.ts'; import type { OpsServer } from '../classes.opsserver.ts'; import * as interfaces from '../../../ts_interfaces/index.ts'; import { requireValidIdentity } from '../helpers/guards.ts'; export class PlatformHandler { public typedrouter = new plugins.typedrequest.TypedRouter(); constructor(private opsServerRef: OpsServer) { this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter); this.registerHandlers(); } private registerHandlers(): void { // Get all platform services this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getPlatformServices', async (dataArg) => { await requireValidIdentity(this.opsServerRef.adminHandler, dataArg); const platformServices = this.opsServerRef.oneboxRef.platformServices.getAllPlatformServices(); const providers = this.opsServerRef.oneboxRef.platformServices.getAllProviders(); const result = providers.map((provider: any) => { const service = platformServices.find((s: any) => s.type === provider.type); const isCore = 'isCore' in provider && (provider as any).isCore === true; let status: string = service?.status || 'not-deployed'; if (provider.type === 'caddy') { const proxyStatus = this.opsServerRef.oneboxRef.reverseProxy.getStatus() as any; status = (proxyStatus.running ?? proxyStatus.http?.running) ? 'running' : 'stopped'; } return { type: provider.type, displayName: provider.displayName, resourceTypes: provider.resourceTypes, status: status as interfaces.data.TPlatformServiceStatus, containerId: service?.containerId, isCore, createdAt: service?.createdAt, updatedAt: service?.updatedAt, }; }); return { platformServices: result as interfaces.data.IPlatformService[] }; }, ), ); // Get specific platform service this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getPlatformService', async (dataArg) => { await requireValidIdentity(this.opsServerRef.adminHandler, dataArg); const provider = this.opsServerRef.oneboxRef.platformServices.getProvider(dataArg.serviceType); if (!provider) { throw new plugins.typedrequest.TypedResponseError(`Unknown platform service type: ${dataArg.serviceType}`); } const service = this.opsServerRef.oneboxRef.database.getPlatformServiceByType(dataArg.serviceType); const isCore = 'isCore' in provider && (provider as any).isCore === true; let rawStatus: string = service?.status || 'not-deployed'; if (dataArg.serviceType === 'caddy') { const proxyStatus = this.opsServerRef.oneboxRef.reverseProxy.getStatus() as any; rawStatus = (proxyStatus.running ?? proxyStatus.http?.running) ? 'running' : 'stopped'; } return { platformService: { type: provider.type, displayName: provider.displayName, resourceTypes: provider.resourceTypes, status: rawStatus as interfaces.data.TPlatformServiceStatus, containerId: service?.containerId, isCore, createdAt: service?.createdAt, updatedAt: service?.updatedAt, } as interfaces.data.IPlatformService, }; }, ), ); // Start platform service this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'startPlatformService', async (dataArg) => { await requireValidIdentity(this.opsServerRef.adminHandler, dataArg); const provider = this.opsServerRef.oneboxRef.platformServices.getProvider(dataArg.serviceType); if (!provider) { throw new plugins.typedrequest.TypedResponseError(`Unknown platform service type: ${dataArg.serviceType}`); } logger.info(`Starting platform service: ${dataArg.serviceType}`); const service = await this.opsServerRef.oneboxRef.platformServices.ensureRunning(dataArg.serviceType); return { platformService: { type: service.type, displayName: provider.displayName, resourceTypes: provider.resourceTypes, status: service.status, containerId: service.containerId, }, }; }, ), ); // Stop platform service this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'stopPlatformService', async (dataArg) => { await requireValidIdentity(this.opsServerRef.adminHandler, dataArg); const provider = this.opsServerRef.oneboxRef.platformServices.getProvider(dataArg.serviceType); if (!provider) { throw new plugins.typedrequest.TypedResponseError(`Unknown platform service type: ${dataArg.serviceType}`); } const isCore = 'isCore' in provider && (provider as any).isCore === true; if (isCore) { throw new plugins.typedrequest.TypedResponseError( `${provider.displayName} is a core service and cannot be stopped`, ); } logger.info(`Stopping platform service: ${dataArg.serviceType}`); await this.opsServerRef.oneboxRef.platformServices.stopPlatformService(dataArg.serviceType); return { platformService: { type: dataArg.serviceType, displayName: provider.displayName, resourceTypes: provider.resourceTypes, status: 'stopped' as const, }, }; }, ), ); // Get platform service stats this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getPlatformServiceStats', async (dataArg) => { await requireValidIdentity(this.opsServerRef.adminHandler, dataArg); const service = this.opsServerRef.oneboxRef.database.getPlatformServiceByType(dataArg.serviceType); if (!service || !service.containerId) { throw new plugins.typedrequest.TypedResponseError('Platform service has no container'); } const stats = await this.opsServerRef.oneboxRef.docker.getContainerStats(service.containerId); if (!stats) { throw new plugins.typedrequest.TypedResponseError('Could not retrieve container stats'); } return { stats }; }, ), ); } }