95 lines
3.3 KiB
TypeScript
95 lines
3.3 KiB
TypeScript
import { Controller, Get, Post, Put, Delete, Body, Param, Query, NotFoundException, HttpException, HttpStatus } from '@nestjs/common';
|
|
import { ServerRepository } from '../../../infrastructure/repositories/server.repository';
|
|
import { Server } from '../../../domain/entities/server.entity';
|
|
import { TenantContextService } from '@it0/common';
|
|
import * as crypto from 'crypto';
|
|
|
|
@Controller('api/v1/inventory/servers')
|
|
export class ServerController {
|
|
constructor(private readonly serverRepository: ServerRepository) {}
|
|
|
|
private serializeServer(server: Server) {
|
|
return {
|
|
...server,
|
|
hostname: server.name,
|
|
sshPort: server.port,
|
|
};
|
|
}
|
|
|
|
@Get()
|
|
async listServers(@Query('environment') env?: string) {
|
|
const servers = env
|
|
? await this.serverRepository.findByEnvironment(env)
|
|
: await this.serverRepository.findAll();
|
|
return servers.map((s) => this.serializeServer(s));
|
|
}
|
|
|
|
@Post()
|
|
async createServer(@Body() body: any) {
|
|
// Quota enforcement
|
|
const tenant = TenantContextService.getTenant();
|
|
if (tenant && tenant.maxServers !== -1) {
|
|
const existing = await this.serverRepository.findAll();
|
|
if (existing.length >= tenant.maxServers) {
|
|
throw new HttpException(
|
|
{ message: `Server quota exceeded (${existing.length}/${tenant.maxServers}). Upgrade your plan to add more servers.`, code: 'QUOTA_EXCEEDED' },
|
|
HttpStatus.TOO_MANY_REQUESTS,
|
|
);
|
|
}
|
|
}
|
|
const server = new Server();
|
|
server.id = crypto.randomUUID();
|
|
server.tenantId = body.tenantId;
|
|
server.name = body.hostname ?? body.name;
|
|
server.host = body.host;
|
|
server.port = body.sshPort ?? body.port ?? 22;
|
|
server.environment = body.environment;
|
|
server.role = body.role;
|
|
server.clusterId = body.clusterId;
|
|
server.sshUser = body.sshUser;
|
|
server.credentialId = body.credentialId;
|
|
server.networkType = body.networkType ?? 'private';
|
|
server.jumpServerId = body.jumpServerId;
|
|
server.sshOptions = body.sshOptions ?? {};
|
|
server.tags = body.tags ?? {};
|
|
server.status = 'active';
|
|
server.description = body.description;
|
|
server.createdAt = new Date();
|
|
server.updatedAt = new Date();
|
|
return this.serializeServer(await this.serverRepository.save(server));
|
|
}
|
|
|
|
@Get(':id')
|
|
async getServer(@Param('id') id: string) {
|
|
const server = await this.serverRepository.findById(id);
|
|
if (!server) {
|
|
throw new NotFoundException(`Server ${id} not found`);
|
|
}
|
|
return this.serializeServer(server);
|
|
}
|
|
|
|
@Put(':id')
|
|
async updateServer(@Param('id') id: string, @Body() body: any) {
|
|
const server = await this.serverRepository.findById(id);
|
|
if (!server) {
|
|
throw new NotFoundException(`Server ${id} not found`);
|
|
}
|
|
const { hostname, sshPort, ...rest } = body;
|
|
if (hostname !== undefined) rest.name = hostname;
|
|
if (sshPort !== undefined) rest.port = sshPort;
|
|
Object.assign(server, rest);
|
|
server.updatedAt = new Date();
|
|
return this.serializeServer(await this.serverRepository.save(server));
|
|
}
|
|
|
|
@Delete(':id')
|
|
async deleteServer(@Param('id') id: string) {
|
|
const server = await this.serverRepository.findById(id);
|
|
if (!server) {
|
|
throw new NotFoundException(`Server ${id} not found`);
|
|
}
|
|
await this.serverRepository.remove(server);
|
|
return { message: 'Server deleted', id };
|
|
}
|
|
}
|