Backend layer wiring the panel to the host agent's per-instance command
channel (the unblocker for the Server-page rework):
- NatsService.requestScoped(): request-reply with a LICENSE-SCOPED reply
subject (corrosion.{license}.reply.<id>) so per-license-scoped agents
(no _INBOX permission) can actually reply — the design from the NATS
auth work, now exercised.
- InstancesModule: POST /api/instances/:id/lifecycle {action} (start/
stop/restart/status/steam_update, server.manage) and POST :id/rcon
{command} (server.console). Tenant-guarded via game_instances.
- GET /api/servers/agent-credentials: derives the agent's NATS user/
password (HMAC) so a customer can configure their agent — closes the
post-auth setup gap.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
35 lines
1.2 KiB
TypeScript
35 lines
1.2 KiB
TypeScript
import { Controller, Post, Body, Param } from '@nestjs/common';
|
|
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
|
|
import { CurrentTenant } from '../../common/decorators/current-tenant.decorator';
|
|
import { RequirePermission } from '../../common/decorators/require-permission.decorator';
|
|
import { InstancesService, LifecycleFunc } from './instances.service';
|
|
|
|
@ApiTags('instances')
|
|
@ApiBearerAuth()
|
|
@Controller('instances')
|
|
export class InstancesController {
|
|
constructor(private readonly instances: InstancesService) {}
|
|
|
|
@Post(':id/lifecycle')
|
|
@RequirePermission('server.manage')
|
|
@ApiOperation({ summary: 'Send a lifecycle command to a game instance (start/stop/restart/status/steam_update)' })
|
|
async lifecycle(
|
|
@CurrentTenant() licenseId: string,
|
|
@Param('id') id: string,
|
|
@Body() body: { action: LifecycleFunc },
|
|
) {
|
|
return this.instances.lifecycle(licenseId, id, body.action);
|
|
}
|
|
|
|
@Post(':id/rcon')
|
|
@RequirePermission('server.console')
|
|
@ApiOperation({ summary: 'Send an RCON/console command to a game instance' })
|
|
async rcon(
|
|
@CurrentTenant() licenseId: string,
|
|
@Param('id') id: string,
|
|
@Body() body: { command: string },
|
|
) {
|
|
return this.instances.rcon(licenseId, id, body.command);
|
|
}
|
|
}
|