import { NextRequest, NextResponse } from 'next/server' import { exec } from 'child_process' import { promisify } from 'util' const execAsync = promisify(exec) // Blocked resources (no read access from terminal) const BLOCKED_RESOURCES = [ 'secret', 'secrets', 'configmap', 'configmaps', 'certificate', 'certificates', 'key', 'keys', 'token', 'tokens', 'serviceaccount', 'serviceaccounts', ] export async function POST(request: NextRequest) { try { const { command } = await request.json() if (!command || typeof command !== 'string') { return NextResponse.json({ error: 'Invalid command' }, { status: 400 }) } // Must start with kubectl (enforced by terminal, but double-check) if (!command.trim().startsWith('kubectl ')) { return NextResponse.json({ error: 'Only kubectl commands allowed' }, { status: 403 }) } // Check for blocked resources const cmdLower = command.toLowerCase() for (const blocked of BLOCKED_RESOURCES) { if (cmdLower.includes(blocked)) { return NextResponse.json( { error: `Access denied: cannot read '${blocked}'` }, { status: 403 } ) } } // Execute kubectl (uses homelab-agent read-only context) const { stdout, stderr } = await execAsync(command, { timeout: 10000, // 10s timeout maxBuffer: 1024 * 1024, // 1MB max output }) return NextResponse.json({ output: stdout || stderr, status: 'success', }) } catch (error) { const err = error as Error & { code?: number } // Timeout or execution error if (err.message.includes('ETIMEDOUT')) { return NextResponse.json( { error: 'Command timeout (10s limit)' }, { status: 504 } ) } return NextResponse.json( { error: err.message || 'Command failed' }, { status: 500 } ) } }