From 677b280a1451f0e77871b840732a4b0092fde17c Mon Sep 17 00:00:00 2001 From: Bernt Christian Egeland Date: Sun, 19 May 2024 19:38:08 +0000 Subject: [PATCH 1/5] check if ip has been used --- src/server/api/routers/networkRouter.ts | 4 +++- src/server/api/services/networkService.ts | 12 +++++++++++- src/utils/IPv4gen.ts | 17 ++++++++++++----- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/server/api/routers/networkRouter.ts b/src/server/api/routers/networkRouter.ts index 91b805b1..e5da5ce2 100644 --- a/src/server/api/routers/networkRouter.ts +++ b/src/server/api/routers/networkRouter.ts @@ -50,6 +50,7 @@ export const networkRouter = createTRPCRouter({ if (input.central) { return await ztController.get_controller_networks(ctx, input.central); } + const networks = await ctx.prisma.network.findMany({ where: { authorId: ctx.session.user.id, @@ -138,7 +139,7 @@ export const networkRouter = createTRPCRouter({ ); // Generate CIDR options for IP configuration - const { cidrOptions } = IPv4gen(null); + const { cidrOptions } = IPv4gen(null, []); /** * Merging logic to ensure that members who only exist in local database ( added manually ) are also included in the response @@ -540,6 +541,7 @@ export const networkRouter = createTRPCRouter({ // generate network params const { ipAssignmentPools, routes, v4AssignMode } = IPv4gen( input.updateParams.routes[0].target, + [], ); // prepare update params diff --git a/src/server/api/services/networkService.ts b/src/server/api/services/networkService.ts index 94728d6f..803b2b78 100644 --- a/src/server/api/services/networkService.ts +++ b/src/server/api/services/networkService.ts @@ -45,9 +45,18 @@ export const networkProvisioningFactory = async ({ ctx, input }) => { ); } } + // get used IPs from the database + const usedCidr = await ctx.prisma.network.findMany({ + select: { + routes: true, + }, + }); + // Extract the target from the routes + const usedIPs = usedCidr.map((nw) => nw.routes?.map((r) => r.target)); + // Flatten the array // Generate ipv4 address, cidr, start & end - const ipAssignmentPools = IPv4gen(null); + const ipAssignmentPools = IPv4gen(null, usedIPs); if (!input?.name) { // Generate adjective and noun word @@ -74,6 +83,7 @@ export const networkProvisioningFactory = async ({ ctx, input }) => { create: { name: newNw.name, nwid: newNw.nwid, + routes: ipAssignmentPools.routes, }, }, }, diff --git a/src/utils/IPv4gen.ts b/src/utils/IPv4gen.ts index f6fb0287..60b40d70 100644 --- a/src/utils/IPv4gen.ts +++ b/src/utils/IPv4gen.ts @@ -23,12 +23,19 @@ const cidrOptions = [ "172.25.30.0/24", ]; -const generateCidr = () => { - return cidrOptions[Math.floor(Math.random() * cidrOptions.length)]; +// const generateCidr = () => { +// return cidrOptions[Math.floor(Math.random() * cidrOptions.length)]; +// }; +const generateCidr = (usedCidr: string[][]) => { + // Flatten the usedCidr array + const flattenedUsedCidr = usedCidr.flat(); + + // Filter the available CIDRs + const availableCidr = cidrOptions.filter((cidr) => !flattenedUsedCidr.includes(cidr)); + return availableCidr.length > 0 ? availableCidr[0] : cidrOptions[0]; }; - -export const IPv4gen = (CIDR: string | null) => { - const cidr = CIDR ? CIDR : generateCidr(); +export const IPv4gen = (CIDR: string | null, usedCidr) => { + const cidr = CIDR ? CIDR : generateCidr(usedCidr); const [start, prefix] = cidr.split("/"); const host32 = ((1 << (32 - parseInt(prefix))) - 1) >>> 0; From 720b22ec92aaff82d2f0e89ded2cec43a5a75f93 Mon Sep 17 00:00:00 2001 From: Bernt Christian Egeland Date: Sun, 19 May 2024 20:38:37 +0000 Subject: [PATCH 2/5] use least used subnet --- src/utils/IPv4gen.ts | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/utils/IPv4gen.ts b/src/utils/IPv4gen.ts index 60b40d70..37792663 100644 --- a/src/utils/IPv4gen.ts +++ b/src/utils/IPv4gen.ts @@ -23,16 +23,40 @@ const cidrOptions = [ "172.25.30.0/24", ]; -// const generateCidr = () => { -// return cidrOptions[Math.floor(Math.random() * cidrOptions.length)]; -// }; const generateCidr = (usedCidr: string[][]) => { // Flatten the usedCidr array const flattenedUsedCidr = usedCidr.flat(); + // Count the frequency of each CIDR in the usedCidr array + const cidrFrequency: { [key: string]: number } = {}; + for (const cidr of flattenedUsedCidr) { + if (cidrFrequency[cidr]) { + cidrFrequency[cidr]++; + } else { + cidrFrequency[cidr] = 1; + } + } + // Filter the available CIDRs const availableCidr = cidrOptions.filter((cidr) => !flattenedUsedCidr.includes(cidr)); - return availableCidr.length > 0 ? availableCidr[0] : cidrOptions[0]; + + // If there are available CIDRs, return the first one + if (availableCidr.length > 0) { + return availableCidr[0]; + } + + // If no available CIDRs, find the CIDR with the fewest occurrences + let leastUsedCidr = cidrOptions[0]; + let minCount = Infinity; + for (const cidr of cidrOptions) { + const count = cidrFrequency[cidr] || 0; + if (count < minCount) { + minCount = count; + leastUsedCidr = cidr; + } + } + + return leastUsedCidr; }; export const IPv4gen = (CIDR: string | null, usedCidr) => { const cidr = CIDR ? CIDR : generateCidr(usedCidr); From 0313f3c09d908f2f5797dd91e62d68852272f5c5 Mon Sep 17 00:00:00 2001 From: Bernt Christian Egeland Date: Sun, 19 May 2024 20:53:19 +0000 Subject: [PATCH 3/5] organization --- src/server/api/routers/organizationRouter.ts | 18 +++++++++++++++++- src/server/api/services/networkService.ts | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/server/api/routers/organizationRouter.ts b/src/server/api/routers/organizationRouter.ts index 4b534761..eec9c7f2 100644 --- a/src/server/api/routers/organizationRouter.ts +++ b/src/server/api/routers/organizationRouter.ts @@ -24,6 +24,7 @@ import { throwError } from "~/server/helpers/errorHandler"; import { sendWebhook } from "~/utils/webhook"; import { nameGeneratorConfig } from "../services/networkService"; import rateLimit from "~/utils/rateLimit"; +import { RoutesEntity } from "~/types/local/network"; // Create a Zod schema for the HookType enum const HookTypeEnum = z.enum(Object.values(HookType) as [HookType, ...HookType[]]); @@ -353,8 +354,22 @@ export const organizationRouter = createTRPCRouter({ }, }); + // get used IPs from the database + const usedCidr = await ctx.prisma.network.findMany({ + where: { + organizationId: input.organizationId, + }, + select: { + routes: true, + }, + }); + // Extract the target from the routes + const usedIPs = usedCidr.map((nw) => + (nw.routes as RoutesEntity[])?.map((r) => r.target), + ); + // Generate ipv4 address, cidr, start & end - const ipAssignmentPools = IPv4gen(null); + const ipAssignmentPools = IPv4gen(null, usedIPs); if (!input?.networkName) { // Generate adjective and noun word @@ -378,6 +393,7 @@ export const organizationRouter = createTRPCRouter({ name: input.networkName, nwid: newNw.nwid, description: input.orgName, + routes: ipAssignmentPools.routes, }, }, }, diff --git a/src/server/api/services/networkService.ts b/src/server/api/services/networkService.ts index 803b2b78..9519f11e 100644 --- a/src/server/api/services/networkService.ts +++ b/src/server/api/services/networkService.ts @@ -47,6 +47,9 @@ export const networkProvisioningFactory = async ({ ctx, input }) => { } // get used IPs from the database const usedCidr = await ctx.prisma.network.findMany({ + where: { + authorId: ctx.session.user.id, + }, select: { routes: true, }, From 97a6bcffe4bb446f4032eef3e0cb958922656125 Mon Sep 17 00:00:00 2001 From: Bernt Christian Egeland Date: Sun, 19 May 2024 20:57:12 +0000 Subject: [PATCH 4/5] central --- src/utils/ztApi.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/ztApi.ts b/src/utils/ztApi.ts index c7e3c484..4c9ef187 100644 --- a/src/utils/ztApi.ts +++ b/src/utils/ztApi.ts @@ -489,7 +489,7 @@ export const central_network_detail = async ( : []; // Get available cidr options. - const ipAssignmentPools = IPv4gen(null); + const ipAssignmentPools = IPv4gen(null,[]); const { cidrOptions } = ipAssignmentPools; const { id: networkId, config: networkConfig, ...restData } = network; From 727fc317f9b59b2d00d8deb0d93a7d0f0e1eb8d9 Mon Sep 17 00:00:00 2001 From: Bernt Christian Egeland Date: Sun, 19 May 2024 21:11:38 +0000 Subject: [PATCH 5/5] return random if central --- src/components/networkByIdPage/ipv4Assignment.tsx | 2 +- src/server/api/services/networkService.ts | 2 +- src/utils/IPv4gen.ts | 11 ++++++++--- src/utils/ztApi.ts | 5 ++++- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/components/networkByIdPage/ipv4Assignment.tsx b/src/components/networkByIdPage/ipv4Assignment.tsx index a0f591d7..9cb911a0 100644 --- a/src/components/networkByIdPage/ipv4Assignment.tsx +++ b/src/components/networkByIdPage/ipv4Assignment.tsx @@ -122,7 +122,7 @@ export const Ipv4Assignment = ({ central = false, organizationId }: IProp) => { return (
{/* if network.duplicateRoutes.length > 0 show badge */} - {network?.duplicateRoutes.length > 0 ? ( + {network?.duplicateRoutes?.length > 0 ? (
{ // Flatten the array // Generate ipv4 address, cidr, start & end - const ipAssignmentPools = IPv4gen(null, usedIPs); + const ipAssignmentPools = IPv4gen(null, usedIPs, input.central); if (!input?.name) { // Generate adjective and noun word diff --git a/src/utils/IPv4gen.ts b/src/utils/IPv4gen.ts index 37792663..d13ba111 100644 --- a/src/utils/IPv4gen.ts +++ b/src/utils/IPv4gen.ts @@ -23,7 +23,12 @@ const cidrOptions = [ "172.25.30.0/24", ]; -const generateCidr = (usedCidr: string[][]) => { +const generateCidr = (usedCidr: string[][], getRandom = false) => { + // If getRandom is true, return one randomly + if (getRandom) { + return cidrOptions[Math.floor(Math.random() * cidrOptions.length)]; + } + // Flatten the usedCidr array const flattenedUsedCidr = usedCidr.flat(); @@ -58,8 +63,8 @@ const generateCidr = (usedCidr: string[][]) => { return leastUsedCidr; }; -export const IPv4gen = (CIDR: string | null, usedCidr) => { - const cidr = CIDR ? CIDR : generateCidr(usedCidr); +export const IPv4gen = (CIDR: string | null, usedCidr, getRandom = false) => { + const cidr = CIDR ? CIDR : generateCidr(usedCidr, getRandom); const [start, prefix] = cidr.split("/"); const host32 = ((1 << (32 - parseInt(prefix))) - 1) >>> 0; diff --git a/src/utils/ztApi.ts b/src/utils/ztApi.ts index 4c9ef187..de342606 100644 --- a/src/utils/ztApi.ts +++ b/src/utils/ztApi.ts @@ -489,7 +489,10 @@ export const central_network_detail = async ( : []; // Get available cidr options. - const ipAssignmentPools = IPv4gen(null,[]); + const getRandomCidr = true; + const usedIps = []; + const ipAssignmentPools = IPv4gen(null, usedIps, getRandomCidr); + const { cidrOptions } = ipAssignmentPools; const { id: networkId, config: networkConfig, ...restData } = network;