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>
91 lines
3.2 KiB
TypeScript
91 lines
3.2 KiB
TypeScript
import { Controller, Get, Put, Post, Body, UseGuards } from '@nestjs/common';
|
|
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
|
|
import { ServersService } from './servers.service';
|
|
import { UpdateServerConfigDto } from './dto/update-config.dto';
|
|
import { SendCommandDto } from './dto/send-command.dto';
|
|
import { DeployServerDto } from './dto/deploy-server.dto';
|
|
import { CurrentTenant } from '../../common/decorators/current-tenant.decorator';
|
|
import { RequirePermission } from '../../common/decorators/require-permission.decorator';
|
|
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
|
|
import { PermissionsGuard } from '../../common/guards/permissions.guard';
|
|
|
|
@ApiTags('Servers')
|
|
@ApiBearerAuth()
|
|
@Controller('servers')
|
|
@UseGuards(JwtAuthGuard, PermissionsGuard)
|
|
export class ServersController {
|
|
constructor(private readonly serversService: ServersService) {}
|
|
|
|
@Get()
|
|
@RequirePermission('server.view')
|
|
@ApiOperation({ summary: 'Get server connection and config' })
|
|
async getServer(@CurrentTenant() licenseId: string) {
|
|
return await this.serversService.getServer(licenseId);
|
|
}
|
|
|
|
@Get('agent-credentials')
|
|
@RequirePermission('server.manage')
|
|
@ApiOperation({ summary: 'NATS credentials for this license\'s host agent' })
|
|
async getAgentCredentials(@CurrentTenant() licenseId: string) {
|
|
return await this.serversService.getAgentCredentials(licenseId);
|
|
}
|
|
|
|
@Put('config')
|
|
@RequirePermission('server.manage')
|
|
@ApiOperation({ summary: 'Update server configuration' })
|
|
async updateConfig(
|
|
@CurrentTenant() licenseId: string,
|
|
@Body() dto: UpdateServerConfigDto,
|
|
) {
|
|
return await this.serversService.updateConfig(licenseId, dto);
|
|
}
|
|
|
|
@Post('command')
|
|
@RequirePermission('server.console')
|
|
@ApiOperation({ summary: 'Send console command to server' })
|
|
async sendCommand(
|
|
@CurrentTenant() licenseId: string,
|
|
@Body() dto: SendCommandDto,
|
|
) {
|
|
return await this.serversService.sendCommand(licenseId, dto.command);
|
|
}
|
|
|
|
@Post('start')
|
|
@RequirePermission('server.manage')
|
|
@ApiOperation({ summary: 'Start the server' })
|
|
async startServer(@CurrentTenant() licenseId: string) {
|
|
return await this.serversService.startServer(licenseId);
|
|
}
|
|
|
|
@Post('stop')
|
|
@RequirePermission('server.manage')
|
|
@ApiOperation({ summary: 'Stop the server' })
|
|
async stopServer(@CurrentTenant() licenseId: string) {
|
|
return await this.serversService.stopServer(licenseId);
|
|
}
|
|
|
|
@Post('restart')
|
|
@RequirePermission('server.manage')
|
|
@ApiOperation({ summary: 'Restart the server' })
|
|
async restartServer(@CurrentTenant() licenseId: string) {
|
|
return await this.serversService.restartServer(licenseId);
|
|
}
|
|
|
|
@Post('deploy')
|
|
@RequirePermission('server.manage')
|
|
@ApiOperation({ summary: 'Deploy Rust server via companion agent' })
|
|
async deployServer(
|
|
@CurrentTenant() licenseId: string,
|
|
@Body() dto: DeployServerDto,
|
|
) {
|
|
return await this.serversService.deployServer(licenseId, dto);
|
|
}
|
|
|
|
@Post('install-oxide')
|
|
@RequirePermission('server.manage')
|
|
@ApiOperation({ summary: 'Install Oxide/uMod via companion agent' })
|
|
async installOxide(@CurrentTenant() licenseId: string) {
|
|
return await this.serversService.installOxide(licenseId);
|
|
}
|
|
}
|