it0/packages/services/inventory-service/src/interfaces/rest/controllers/server.controller.ts

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 };
}
}