feat: replace profiles with kubernetes-style secrets
Replace the confused Profile abstraction with a dedicated Secret resource
following Kubernetes conventions. Servers now have env entries with inline
values or secretRef references. Env vars are resolved and passed to
containers at startup (fixes existing gap).
- Add Secret CRUD (model, repo, service, routes, CLI commands)
- Server env: {name, value} or {name, valueFrom: {secretRef: {name, key}}}
- Add env-resolver utility shared by instance startup and config generation
- Remove all profile-related code (models, services, routes, CLI, tests)
- Update backup/restore for secrets instead of profiles
- describe secret masks values by default, --show-values to reveal
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import type { McpInstance } from '@prisma/client';
|
||||
import type { IMcpInstanceRepository, IMcpServerRepository } from '../repositories/interfaces.js';
|
||||
import type { IMcpInstanceRepository, IMcpServerRepository, ISecretRepository } from '../repositories/interfaces.js';
|
||||
import type { McpOrchestrator, ContainerSpec, ContainerInfo } from './orchestrator.js';
|
||||
import { NotFoundError } from './mcp-server.service.js';
|
||||
import { resolveServerEnv } from './env-resolver.js';
|
||||
|
||||
export class InvalidStateError extends Error {
|
||||
readonly statusCode = 409;
|
||||
@@ -16,6 +17,7 @@ export class InstanceService {
|
||||
private instanceRepo: IMcpInstanceRepository,
|
||||
private serverRepo: IMcpServerRepository,
|
||||
private orchestrator: McpOrchestrator,
|
||||
private secretRepo?: ISecretRepository,
|
||||
) {}
|
||||
|
||||
async list(serverId?: string): Promise<McpInstance[]> {
|
||||
@@ -162,6 +164,19 @@ export class InstanceService {
|
||||
spec.command = command;
|
||||
}
|
||||
|
||||
// Resolve env vars from inline values and secret refs
|
||||
if (this.secretRepo) {
|
||||
try {
|
||||
const resolvedEnv = await resolveServerEnv(server, this.secretRepo);
|
||||
if (Object.keys(resolvedEnv).length > 0) {
|
||||
spec.env = resolvedEnv;
|
||||
}
|
||||
} catch (envErr) {
|
||||
// Log but don't prevent startup — env resolution failures are non-fatal
|
||||
// The container may still work if env vars are optional
|
||||
}
|
||||
}
|
||||
|
||||
const containerInfo = await this.orchestrator.createContainer(spec);
|
||||
|
||||
const updateFields: { containerId: string; port?: number } = {
|
||||
|
||||
Reference in New Issue
Block a user