Add native host management and role-based operator authentication
Introduce an outbound Python host agent, Debian installer, durable remote operations, immutable game-file libraries, host-aware deployments and ports, and occupancy-safe campaigns and draining. Native hosts do not require Komodo. Add administrator, operator and viewer accounts, protected management routes, secure sessions, password recovery, audit history and separate telemetry tokens. Document first-admin setup, reporter migration and live-host acceptance checks. Validation: 1,343 TypeScript tests and 39 agent tests passed, along with type checking, the production build, compiled SSR/API smoke tests and administrator recovery. Real Debian/Docker T5/T6 acceptance remains unrun.
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { createEnrollment, createHost, listHosts } from '$lib/server/hosts/index.js';
|
||||
import { hostApiError, installerCommand, objectBody, requireManagementOrigin } from '$lib/server/hosts/http.js';
|
||||
|
||||
export function GET({ request }: { request: Request }) { requireManagementOrigin(request); return json({ hosts: listHosts() }); }
|
||||
export async function POST({ request }: { request: Request }) {
|
||||
requireManagementOrigin(request);
|
||||
try {
|
||||
const host = createHost(await objectBody(request));
|
||||
const enrollment = createEnrollment(host.id);
|
||||
return json({ host, enrollment: { ...enrollment, command: installerCommand(request.url, enrollment.token) } }, { status: 201, headers: { 'Cache-Control': 'no-store' } });
|
||||
} catch (cause) { return hostApiError(cause); }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { error, json } from '@sveltejs/kit';
|
||||
import { getHost, listHostOperations, updateHost } from '$lib/server/hosts/index.js';
|
||||
import { hostApiError, objectBody, requireManagementOrigin } from '$lib/server/hosts/http.js';
|
||||
type Event = { request: Request; params: { id: string } };
|
||||
export function GET({ request, params }: Event) {
|
||||
requireManagementOrigin(request); const host = getHost(params.id); if (!host) error(404, 'Host not found.');
|
||||
// Payloads and results can contain RCON keys or staged credentials. History
|
||||
// exposes metadata only; agent APIs remain the only command delivery path.
|
||||
return json({ host, operations: listHostOperations(host.id).map(({ payload: _payload, result: _result, ...operation }) => operation) });
|
||||
}
|
||||
export async function PATCH({ request, params }: Event) {
|
||||
requireManagementOrigin(request);
|
||||
try { return json({ host: updateHost(params.id, await objectBody(request)) }); } catch (cause) { return hostApiError(cause); }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { queueHostOperation, revokeCredentials } from '$lib/server/hosts/index.js';
|
||||
import { hostApiError, requireManagementOrigin } from '$lib/server/hosts/http.js';
|
||||
type Event = { request: Request; params: { id: string } };
|
||||
export function DELETE({ request, params }: Event) {
|
||||
requireManagementOrigin(request);
|
||||
try { revokeCredentials(params.id); return json({ ok: true }); } catch (cause) { return hostApiError(cause); }
|
||||
}
|
||||
export function POST({ request, params }: Event) {
|
||||
requireManagementOrigin(request);
|
||||
try { const operation = queueHostOperation(params.id, 'credentials.rotate', {}); return json({ operationId: operation.id }, { status: 202 }); } catch (cause) { return hostApiError(cause); }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { createEnrollment } from '$lib/server/hosts/index.js';
|
||||
import { hostApiError, installerCommand, requireManagementOrigin } from '$lib/server/hosts/http.js';
|
||||
export function POST({ request, params }: { request: Request; params: { id: string } }) {
|
||||
requireManagementOrigin(request);
|
||||
try { const enrollment = createEnrollment(params.id); return json({ enrollment: { ...enrollment, command: installerCommand(request.url, enrollment.token) } }, { headers: { 'Cache-Control': 'no-store' } }); }
|
||||
catch (cause) { return hostApiError(cause); }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { queueHostOperation } from '$lib/server/hosts/index.js';
|
||||
import { hostApiError, objectBody, requireManagementOrigin } from '$lib/server/hosts/http.js';
|
||||
export async function POST({ request, params }: { request: Request; params: { id: string } }) {
|
||||
requireManagementOrigin(request);
|
||||
try {
|
||||
const body = await objectBody(request);
|
||||
if (body.kind !== 'runtime.pull' || typeof body.image !== 'string' || !/^[a-zA-Z0-9][a-zA-Z0-9./_:@-]{0,511}$/.test(body.image)) throw new Error('Provide a runtime.pull request and a valid container image.');
|
||||
const operation = queueHostOperation(params.id, 'runtime.pull', { image: body.image });
|
||||
return json({ operationId: operation.id }, { status: 202 });
|
||||
} catch (cause) { return hostApiError(cause); }
|
||||
}
|
||||
Reference in New Issue
Block a user