feat: SSH key management on dev pod page — list, add, remove keys
Some checks failed
Build & Release / build (push) Has been cancelled
Some checks failed
Build & Release / build (push) Has been cancelled
This commit is contained in:
@@ -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 });
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user