89 lines
2.4 KiB
JavaScript
89 lines
2.4 KiB
JavaScript
// /opt/zpack-api/src/utils/portAllocation.js
|
|
import prisma from '../services/prisma.js';
|
|
|
|
|
|
|
|
export class PortAllocationService {
|
|
static async allocatePortBlock(customerId, portCount = 3) {
|
|
return await prisma.$transaction(async (tx) => {
|
|
// Check customer exists and get current allocations
|
|
const customer = await tx.customer.findUnique({
|
|
where: { id: customerId },
|
|
include: { ports: true }
|
|
})
|
|
|
|
if (!customer) throw new Error('Customer not found')
|
|
|
|
// Return existing allocation if found
|
|
const existingAllocation = customer.ports[0]
|
|
if (existingAllocation) {
|
|
return {
|
|
customerId,
|
|
basePort: existingAllocation.basePort,
|
|
ports: Array.from({length: existingAllocation.count},
|
|
(_, i) => existingAllocation.basePort + i),
|
|
isExisting: true
|
|
}
|
|
}
|
|
|
|
// Find available port range
|
|
const basePort = await this.findAvailablePortRange(tx, portCount)
|
|
|
|
// Create new allocation
|
|
const allocation = await tx.portAllocation.create({
|
|
data: {
|
|
customerId,
|
|
basePort,
|
|
count: portCount
|
|
}
|
|
})
|
|
|
|
return {
|
|
customerId,
|
|
basePort,
|
|
ports: Array.from({length: portCount}, (_, i) => basePort + i),
|
|
isExisting: false
|
|
}
|
|
})
|
|
}
|
|
|
|
static async findAvailablePortRange(tx, count) {
|
|
// Get all existing allocations sorted by basePort
|
|
const allocations = await tx.portAllocation.findMany({
|
|
orderBy: { basePort: 'asc' }
|
|
})
|
|
|
|
let startPort = 50000 // Your port range start
|
|
|
|
for (const allocation of allocations) {
|
|
// Check if there's a gap before this allocation
|
|
if (startPort + count <= allocation.basePort) {
|
|
return startPort
|
|
}
|
|
// Move past this allocation
|
|
startPort = allocation.basePort + allocation.count
|
|
}
|
|
|
|
// No conflicts found, return next available
|
|
if (startPort > 60000) {
|
|
throw new Error('Port range exhausted')
|
|
}
|
|
|
|
return startPort
|
|
}
|
|
|
|
static async getCustomerPorts(customerId) {
|
|
const allocation = await prisma.portAllocation.findFirst({
|
|
where: { customerId }
|
|
})
|
|
|
|
if (!allocation) return null
|
|
|
|
return {
|
|
customerId,
|
|
basePort: allocation.basePort,
|
|
ports: Array.from({length: allocation.count},
|
|
(_, i) => allocation.basePort + i)
|
|
}
|
|
}
|
|
} |