1bbdd7acba
- Add apps/api/ — Hono REST API server for managing pentest scans via K8s Jobs - POST/GET /api/scans, GET /api/scans/:id, cancel, report endpoints - Bearer token auth, Temporal client integration, K8s Job builder - Dockerfile, Kustomize manifests (Deployment, Service, RBAC) - Add CLI orchestrator abstraction (docker.ts → Orchestrator interface) - DockerOrchestrator and K8sOrchestrator implementations - Backend detection via SHANNON_BACKEND env var or --backend flag - Add CI workflow: type-check + lint on PR, build+push both images on main - Switch all workflows to self-hosted runners (runners-farhoodliquor) - Add shannon-api image build to release and release-beta workflows - Add root infra/kustomization.yaml as Flux entry point - Export PipelineProgress from @shannon/worker/pipeline Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
/**
|
|
* Backend detection — Docker (default) vs Kubernetes.
|
|
*
|
|
* Orthogonal to the local/npx mode axis. Mode controls where state lives
|
|
* and where the image comes from. Backend controls how containers are orchestrated.
|
|
*/
|
|
|
|
import type { Orchestrator } from './orchestrator.js';
|
|
|
|
export type Backend = 'docker' | 'k8s';
|
|
|
|
let cachedBackend: Backend | undefined;
|
|
let cachedOrchestrator: Orchestrator | undefined;
|
|
|
|
/**
|
|
* Detect the orchestration backend.
|
|
* SHANNON_BACKEND env var takes precedence, otherwise defaults to docker.
|
|
*/
|
|
export function getBackend(): Backend {
|
|
if (cachedBackend !== undefined) return cachedBackend;
|
|
|
|
const env = process.env.SHANNON_BACKEND;
|
|
if (env === 'k8s' || env === 'kubernetes') {
|
|
cachedBackend = 'k8s';
|
|
} else {
|
|
cachedBackend = 'docker';
|
|
}
|
|
return cachedBackend;
|
|
}
|
|
|
|
export function setBackend(backend: Backend): void {
|
|
cachedBackend = backend;
|
|
cachedOrchestrator = undefined;
|
|
}
|
|
|
|
/**
|
|
* Get the orchestrator for the current backend.
|
|
* Lazy-loads the implementation to avoid importing unused dependencies.
|
|
*/
|
|
export async function getOrchestrator(): Promise<Orchestrator> {
|
|
if (cachedOrchestrator) return cachedOrchestrator;
|
|
|
|
let orchestrator: Orchestrator;
|
|
if (getBackend() === 'k8s') {
|
|
const { K8sOrchestrator } = await import('./k8s.js');
|
|
orchestrator = new K8sOrchestrator();
|
|
} else {
|
|
const { DockerOrchestrator } = await import('./docker.js');
|
|
orchestrator = new DockerOrchestrator();
|
|
}
|
|
|
|
cachedOrchestrator = orchestrator;
|
|
return orchestrator;
|
|
}
|