feat: SSH key management on dev pod page — list, add, remove keys
Some checks failed
Build & Release / build (push) Has been cancelled

This commit is contained in:
Ryan Moon
2026-04-05 09:36:56 -05:00
parent daa6035f0e
commit 3f79939bd3
2 changed files with 95 additions and 1 deletions

View File

@@ -1,8 +1,11 @@
import type { FastifyInstance } from "fastify";
import { k8sFetch, rolloutRestart } from "../lib/k8s";
import { z } from "zod";
import { k8sFetch, rolloutRestart, getSecret, patchSecret } from "../lib/k8s";
const NAMESPACE = "dev";
const DEPLOYMENT = "dev";
const SECRET = "dev-secrets";
const KEY_FIELD = "ssh-authorized-keys";
export async function devpodRoutes(app: FastifyInstance) {
app.get("/devpod/status", async (_req, reply) => {
@@ -63,4 +66,30 @@ export async function devpodRoutes(app: FastifyInstance) {
await rolloutRestart(NAMESPACE, DEPLOYMENT);
return reply.send({ message: "Dev pod restarting" });
});
app.get("/devpod/keys", async (_req, reply) => {
const secrets = await getSecret(NAMESPACE, SECRET);
const raw = secrets[KEY_FIELD] ?? "";
const keys = raw.split("\n").map(k => k.trim()).filter(Boolean);
return reply.send({ keys });
});
app.post("/devpod/keys", async (req, reply) => {
const { key } = z.object({ key: z.string().min(10) }).parse(req.body);
const secrets = await getSecret(NAMESPACE, SECRET);
const existing = (secrets[KEY_FIELD] ?? "").split("\n").map(k => k.trim()).filter(Boolean);
if (existing.includes(key.trim())) return reply.send({ keys: existing });
const updated = [...existing, key.trim()].join("\n");
await patchSecret(NAMESPACE, SECRET, { [KEY_FIELD]: updated });
return reply.send({ keys: [...existing, key.trim()] });
});
app.delete("/devpod/keys", async (req, reply) => {
const { key } = z.object({ key: z.string().min(10) }).parse(req.body);
const secrets = await getSecret(NAMESPACE, SECRET);
const existing = (secrets[KEY_FIELD] ?? "").split("\n").map(k => k.trim()).filter(Boolean);
const updated = existing.filter(k => k !== key.trim());
await patchSecret(NAMESPACE, SECRET, { [KEY_FIELD]: updated.join("\n") });
return reply.send({ keys: updated });
});
}