feat(platform-api): split lightweight platform service from Lab image
New platform/api/ service owns students, cohorts, curriculum, progress, scenario attempts, and student/admin sessions. No k3s, no --privileged, no terminal runtime — starts instantly, unlike the old identity service which booted an unused k3s cluster just to serve roster/progress APIs. Provisioner calls (student and admin) are consolidated here too, in provisioner-client.js, so it's the only service that talks to the Provisioner directly.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
// Thin client for the Provisioner's internal API — same role as
|
||||
// platform/gateway/src/provisioner-client.js. Phase 2B consolidates ALL Provisioner access
|
||||
// (both student launch/reset and admin prepare/destroy/reset) into this one service, per
|
||||
// "environment orchestration calls" being a Platform API responsibility
|
||||
// (docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md §1). The Gateway no longer calls the Provisioner
|
||||
// directly — it proxies /api/environment/* to here instead.
|
||||
|
||||
const PROVISIONER_URL = process.env.PROVISIONER_URL || 'http://localhost:4100';
|
||||
const PROVISIONER_SHARED_SECRET = process.env.PROVISIONER_SHARED_SECRET;
|
||||
|
||||
if (!PROVISIONER_SHARED_SECRET) {
|
||||
console.error('FATAL: PROVISIONER_SHARED_SECRET is not set. Refusing to start.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
async function call(method, path, body) {
|
||||
const res = await fetch(`${PROVISIONER_URL}${path}`, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json', 'X-Provisioner-Key': PROVISIONER_SHARED_SECRET },
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
});
|
||||
const text = await res.text();
|
||||
let json; try { json = JSON.parse(text); } catch { json = null; }
|
||||
return { status: res.status, body: json };
|
||||
}
|
||||
|
||||
const provisioner = {
|
||||
getEnvironmentByToken: (token) => call('GET', `/environments/by-token/${encodeURIComponent(token)}`),
|
||||
getEnvironment: (id) => call('GET', `/environments/${encodeURIComponent(id)}`),
|
||||
getToken: (id) => call('GET', `/environments/${encodeURIComponent(id)}/token`),
|
||||
listForStudent: (studentId) => call('GET', `/environments?student_id=${encodeURIComponent(studentId)}`),
|
||||
provision: (studentId) => call('POST', '/environments', { student_id: studentId }),
|
||||
reset: (id) => call('POST', `/environments/${encodeURIComponent(id)}/reset`),
|
||||
destroy: (id) => call('DELETE', `/environments/${encodeURIComponent(id)}`),
|
||||
events: (id) => call('GET', `/environments/${encodeURIComponent(id)}/events`),
|
||||
};
|
||||
|
||||
module.exports = { provisioner };
|
||||
Reference in New Issue
Block a user