Canvas: Add VM/PROXY dev modes support
- Update ServiceSchema to discriminate between VM and PROXY dev modes
- Add DevDisabled, DevVM, DevProxy TypeScript types
- Update ServiceData type in graph.ts for new dev structure
- Update generateDodoConfig to handle both VM and PROXY modes
- Update configToGraph to properly convert dev configurations
- Maintain backward compatibility with existing dev configurations
- Update UI and introduce two new DevVM and DevProxy components
- Fetch user machine list from headscale API
Change-Id: I8f9df4ab9bd34c049fffadb748115335e8260a54
diff --git a/apps/canvas/back/src/index.ts b/apps/canvas/back/src/index.ts
index 97df61f..f00549f 100644
--- a/apps/canvas/back/src/index.ts
+++ b/apps/canvas/back/src/index.ts
@@ -26,6 +26,7 @@
import { Instant, DateTimeFormatter, ZoneId } from "@js-joda/core";
import LogStore from "./log.js";
import { GraphOrConfigSchema, GraphSchema, GraphConfigOrDraft, AgentAccess } from "config/dist/graph.js";
+import { MachineManager } from "./machine_manager.js";
async function generateKey(root: string): Promise<[string, string]> {
const privKeyPath = path.join(root, "key");
@@ -41,6 +42,7 @@
const db = new PrismaClient();
const logStore = new LogStore(db);
const appManager = new AppManager();
+const machineManager = new MachineManager(env.VPN_API_ADDR!);
const projectMonitors = new Map<number, ProjectMonitor>();
@@ -791,6 +793,20 @@
};
};
+const handleMachines: express.Handler = async (req, resp) => {
+ try {
+ const machines = await machineManager.getUserMachines(resp.locals.username);
+ resp.status(200);
+ resp.write(JSON.stringify(machines));
+ } catch (error) {
+ console.error("Error getting machines:", error);
+ resp.status(500);
+ resp.write(JSON.stringify({ error: "Internal server error" }));
+ } finally {
+ resp.end();
+ }
+};
+
const handleEnv: express.Handler = async (req, resp) => {
const projectId = Number(req.params["projectId"]);
try {
@@ -1268,6 +1284,9 @@
// Public webhook route - no auth needed
app.post("/api/webhook/github/push", handleGithubPushWebhook);
+ // Public machines route - no auth needed
+ app.get("/api/machines", auth, handleMachines);
+
// Authenticated project routes
const projectRouter = express.Router();
projectRouter.use(auth);
diff --git a/apps/canvas/back/src/machine_manager.ts b/apps/canvas/back/src/machine_manager.ts
new file mode 100644
index 0000000..ab4d684
--- /dev/null
+++ b/apps/canvas/back/src/machine_manager.ts
@@ -0,0 +1,10 @@
+import { Machines, MachinesSchema } from "config";
+
+export class MachineManager {
+ constructor(private readonly apiAddr: string) {}
+
+ async getUserMachines(username: string): Promise<Machines> {
+ const response = await fetch(`${this.apiAddr}/user/${username}/node`);
+ return MachinesSchema.parse(await response.json());
+ }
+}