- ops-agent/src/lib/flow-runner.ts: loads YAML flows, validates all steps
against the command whitelist, executes sequentially; supports dry_run
(emits WOULD RUN lines) and on_failure: abort|continue per step
- ops-agent/src/routes/flow.ts: POST /agent/v1/flow { flow_key, dry_run }
streams step_start/stdout/stderr/step_done/done SSE events
- ops-agent/src/index.ts: register flow route, add FLOWS_PATH env var
- ops-agent/flows.example/: three flow definitions — update_scrum4me_web,
update_mcp_worker, update_caddy_config; deploy to /etc/ops-agent/flows/
- ops-agent/commands.yml.example: add curl_smoke_scrum4me_web and
docker_compose_ps_worker smoke-test commands
- app/api/flows/run/route.ts: Next.js proxy — creates FlowRun/FlowStep
DB records per step, forwards SSE stream to browser
- hooks/useFlowRun.ts: add startFlow(flowKey, dryRun) method; handle
step_start events to display step headers in the terminal
- components/StreamingTerminal.tsx: add 'info' line type (sky-400) for
step headers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
import Fastify from 'fastify';
|
|
import cors from '@fastify/cors';
|
|
import { loadWhitelist } from './whitelist.js';
|
|
import { loadSecret, authHook } from './auth.js';
|
|
import { healthRoutes } from './routes/health.js';
|
|
import { execRoutes } from './routes/exec.js';
|
|
import { makeFlowRoutes } from './routes/flow.js';
|
|
|
|
const WHITELIST_PATH = process.env.OPS_AGENT_WHITELIST_PATH ?? '/etc/ops-agent/commands.yml';
|
|
const FLOWS_PATH = process.env.OPS_AGENT_FLOWS_PATH ?? '/etc/ops-agent/flows';
|
|
const PORT = parseInt(process.env.OPS_AGENT_PORT ?? '3099', 10);
|
|
const HOST = process.env.OPS_AGENT_HOST ?? '127.0.0.1';
|
|
|
|
async function main() {
|
|
loadWhitelist(WHITELIST_PATH);
|
|
loadSecret();
|
|
|
|
const app = Fastify({ logger: true });
|
|
|
|
await app.register(cors, { origin: false });
|
|
|
|
app.addHook('onRequest', authHook);
|
|
|
|
await app.register(healthRoutes);
|
|
await app.register(execRoutes);
|
|
await app.register(makeFlowRoutes(FLOWS_PATH));
|
|
|
|
await app.listen({ port: PORT, host: HOST });
|
|
console.log(`ops-agent listening on ${HOST}:${PORT}`);
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error(err);
|
|
process.exit(1);
|
|
});
|