Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change: [M3-7227] - Update VPC-related API types in accordance with new API changes #9824

Merged
merged 10 commits into from
Oct 24, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/api-v4": Upcoming Features
---

Update the `Subnet` and `Interface` interfaces to match new API spec ([#9824](https://github.com/linode/manager/pull/9824))
3 changes: 2 additions & 1 deletion packages/api-v4/src/linodes/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,15 @@ export interface Interface {
purpose: InterfacePurpose;
ipam_address: string | null;
primary?: boolean;
active: boolean;
subnet_id?: number | null;
vpc_id?: number | null;
ipv4?: ConfigInterfaceIPv4;
ipv6?: ConfigInterfaceIPv6;
ip_ranges?: string[];
}

export type InterfacePayload = Omit<Interface, 'id'>;
export type InterfacePayload = Omit<Interface, 'id' | 'active'>;

export interface ConfigInterfaceOrderPayload {
ids: number[];
Expand Down
11 changes: 10 additions & 1 deletion packages/api-v4/src/vpcs/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Interface } from 'src/linodes';

export interface VPC {
id: number;
label: string;
Expand Down Expand Up @@ -28,11 +30,18 @@ export interface CreateSubnetPayload {

export interface Subnet extends CreateSubnetPayload {
id: number;
linodes: number[];
linodes: SubnetAssignedLinodeData[];
created: string;
updated: string;
}

export interface ModifySubnetPayload {
label: string;
}

export type SubnetLinodeInterfaceData = Pick<Interface, 'active' | 'id'>;

export interface SubnetAssignedLinodeData {
id: number;
interfaces: SubnetLinodeInterfaceData[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Properly support new shapes of `Subnet` and `Interface` return objects ([#9824](https://github.com/linode/manager/pull/9824))
12 changes: 7 additions & 5 deletions packages/manager/src/factories/linodeConfigInterfaceFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as Factory from 'factory.ts';

export const LinodeConfigInterfaceFactory = Factory.Sync.makeFactory<Interface>(
{
active: false,
id: Factory.each((i) => i),
ipam_address: '10.0.0.1/24',
label: Factory.each((i) => `interface-${i}`),
Expand All @@ -12,19 +13,20 @@ export const LinodeConfigInterfaceFactory = Factory.Sync.makeFactory<Interface>(

export const LinodeConfigInterfaceFactoryWithVPC = Factory.Sync.makeFactory<Interface>(
{
active: false,
id: Factory.each((i) => i),
ip_ranges: ['192.0.2.0/24'],
ipam_address: '10.0.0.1/24',
label: Factory.each((i) => `interface-${i}`),
purpose: 'vpc',
ipv4: {
vpc: '10.0.0.0',
nat_1_1: 'some nat',
vpc: '10.0.0.0',
},
ipv6: {
vpc: '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
},
ip_ranges: ['192.0.2.0/24'],
vpc_id: Factory.each((i) => i + 1),
label: Factory.each((i) => `interface-${i}`),
purpose: 'vpc',
subnet_id: Factory.each((i) => i),
vpc_id: Factory.each((i) => i + 1),
}
);
24 changes: 21 additions & 3 deletions packages/manager/src/factories/subnets.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
import { Subnet } from '@linode/api-v4/lib/vpcs/types';
import {
Subnet,
SubnetAssignedLinodeData,
} from '@linode/api-v4/lib/vpcs/types';
import * as Factory from 'factory.ts';

// NOTE: Changing to fixed array length for the interfaces and linodes fields of the
// subnetAssignedLinodeDataFactory and subnetFactory respectively -- see [M3-7227] for more details

export const subnetAssignedLinodeDataFactory = Factory.Sync.makeFactory<SubnetAssignedLinodeData>(
{
id: Factory.each((i) => i),
interfaces: Array.from({ length: 5 }, () => ({
active: false,
id: Math.floor(Math.random() * 100),
})),
}
);

export const subnetFactory = Factory.Sync.makeFactory<Subnet>({
created: '2023-07-12T16:08:53',
id: Factory.each((i) => i),
ipv4: '0.0.0.0/0',
label: Factory.each((i) => `subnet-${i}`),
linodes: Factory.each((i) =>
Array.from({ length: i }, () => Math.floor(Math.random() * 100))
linodes: Array.from({ length: 5 }, () =>
subnetAssignedLinodeDataFactory.build({
id: Math.floor(Math.random() * 100),
})
),
updated: '2023-07-12T16:08:53',
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as React from 'react';
import {
accountFactory,
linodeFactory,
subnetAssignedLinodeDataFactory,
subnetFactory,
vpcFactory,
} from 'src/factories';
Expand Down Expand Up @@ -40,7 +41,7 @@ describe('Linode Entity Detail', () => {

const subnet = subnetFactory.build({
id: 2,
linodes: [5],
linodes: [subnetAssignedLinodeDataFactory.build({ id: 5 })],
});

const vpc = vpcFactory.build({
Expand Down Expand Up @@ -81,7 +82,7 @@ describe('Linode Entity Detail', () => {

const subnet = subnetFactory.build({
id: 4,
linodes: [85],
linodes: [subnetAssignedLinodeDataFactory.build({ id: 85 })],
});

const vpc = vpcFactory.build({
Expand Down Expand Up @@ -116,7 +117,7 @@ describe('Linode Entity Detail', () => {
const subnet = subnetFactory.build({
id: 4,
label: '1st-subnet',
linodes: [linode.id],
linodes: [subnetAssignedLinodeDataFactory.build({ id: linode.id })],
});

const _vpcs = vpcFactory.buildList(3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,11 @@ export const Body = React.memo((props: BodyProps) => {
const vpcLinodeIsAssignedTo = vpcsList.find((vpc) => {
const subnets = vpc.subnets;

return Boolean(subnets.find((subnet) => subnet.linodes.includes(linodeId)));
return Boolean(
subnets.find((subnet) =>
subnet.linodes.some((linodeInfo) => linodeInfo.id === linodeId)
)
);
});

const { data: configs } = useAllLinodeConfigsQuery(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export const SubnetAssignLinodesDrawer = (
// assigned to this subnet
const findUnassignedLinodes = React.useCallback(() => {
return linodes?.filter((linode) => {
return !subnet?.linodes.includes(linode.id);
return !subnet?.linodes.some((linodeInfo) => linodeInfo.id === linode.id);
});
}, [subnet, linodes]);

Expand Down Expand Up @@ -232,7 +232,9 @@ export const SubnetAssignLinodesDrawer = (
// Check if the selected Linode is already assigned to the subnet
if (
values.selectedLinode &&
subnet?.linodes.includes(values.selectedLinode.id)
subnet?.linodes.some(
(linodeInfo) => linodeInfo.id === values.selectedLinode?.id
)
) {
const configId = getConfigId(linodeConfigs, values.selectedConfig);

Expand Down Expand Up @@ -280,7 +282,9 @@ export const SubnetAssignLinodesDrawer = (
// we want to remove it from assignedLinodesAndConfigData
const isLinodeToRemoveValid =
removedLinodeId.current !== -1 &&
!subnet?.linodes.includes(removedLinodeId.current) &&
!subnet?.linodes.some(
(linodeInfo) => linodeInfo.id === removedLinodeId.current
) &&
!!assignedLinodesAndConfigData.find(
(data) => data.id === removedLinodeId.current
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ export const SubnetUnassignLinodesDrawer = React.memo(
// 2. We need to filter only the linodes that are assigned to the subnet.
const findAssignedLinodes = React.useCallback(() => {
return linodes?.filter((linode) => {
return subnetLinodeIds?.includes(linode.id);
return subnetLinodeIds?.some(
(linodeInfo) => linodeInfo.id === linode.id
);
});
}, [linodes, subnetLinodeIds]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,5 @@ describe('VPC Detail Summary section', () => {

fireEvent.click(readMoreButton);
expect(readMoreButton.innerHTML).toBe('Read Less');
});
}, 10000);
coliu-akamai marked this conversation as resolved.
Show resolved Hide resolved
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { waitForElementToBeRemoved } from '@testing-library/react';
import * as React from 'react';
import { QueryClient } from 'react-query';

import { subnetFactory } from 'src/factories/subnets';
import {
subnetAssignedLinodeDataFactory,
subnetFactory,
} from 'src/factories/subnets';
import { makeResourcePage } from 'src/mocks/serverHandlers';
import { rest, server } from 'src/mocks/testServer';
import { mockMatchMedia, renderWithTheme } from 'src/utilities/testHelpers';
Expand All @@ -21,7 +24,13 @@ const loadingTestId = 'circle-progress';

describe('VPC Subnets table', () => {
it('should display filter input, subnet label, id, ip range, number of linodes, and action menu', async () => {
const subnet = subnetFactory.build({ linodes: [1, 2, 3] });
const subnet = subnetFactory.build({
linodes: [
subnetAssignedLinodeDataFactory.build({ id: 1 }),
subnetAssignedLinodeDataFactory.build({ id: 2 }),
subnetAssignedLinodeDataFactory.build({ id: 3 }),
],
});
server.use(
rest.get('*/vpcs/:vpcId/subnets', (req, res, ctx) => {
return res(ctx.json(makeResourcePage([subnet])));
Expand Down Expand Up @@ -81,7 +90,9 @@ describe('VPC Subnets table', () => {
});

it('should show linode table head data when table is expanded', async () => {
const subnet = subnetFactory.build({ linodes: [1] });
const subnet = subnetFactory.build({
linodes: [subnetAssignedLinodeDataFactory.build({ id: 1 })],
});
server.use(
rest.get('*/vpcs/:vpcId/subnets', (req, res, ctx) => {
return res(ctx.json(makeResourcePage([subnet])));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,11 @@ export const VPCSubnetsTable = (props: Props) => {
</TableHead>
<TableBody>
{subnet.linodes.length > 0 ? (
subnet.linodes.map((linodeId) => (
subnet.linodes.map((linodeInfo) => (
<SubnetLinodeRow
handleUnassignLinode={handleSubnetUnassignLinode}
key={linodeId}
linodeId={linodeId}
key={linodeInfo.id}
linodeId={linodeInfo.id}
subnet={subnet}
subnetId={subnet.id}
/>
Expand Down
38 changes: 31 additions & 7 deletions packages/manager/src/features/VPCs/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,50 @@
import { LinodeConfigInterfaceFactoryWithVPC } from 'src/factories/linodeConfigInterfaceFactory';
import { linodeConfigFactory } from 'src/factories/linodeConfigs';
import { subnetFactory } from 'src/factories/subnets';
import {
subnetAssignedLinodeDataFactory,
subnetFactory,
} from 'src/factories/subnets';

import {
getSubnetInterfaceFromConfigs,
getUniqueLinodesFromSubnets,
} from './utils';

const subnetLinodeInfoList1 = subnetAssignedLinodeDataFactory.buildList(4);
const subnetLinodeInfoId1 = subnetAssignedLinodeDataFactory.build({ id: 1 });
const subnetLinodeInfoId3 = subnetAssignedLinodeDataFactory.build({ id: 3 });

describe('getUniqueLinodesFromSubnets', () => {
it(`returns the number of unique linodes within a VPC's subnets`, () => {
const subnets0 = [subnetFactory.build({ linodes: [] })];
const subnets1 = [subnetFactory.build({ linodes: [1, 2, 3] })];
const subnets2 = [subnetFactory.build({ linodes: [1, 1, 3, 3] })];
const subnets1 = [subnetFactory.build({ linodes: subnetLinodeInfoList1 })];
const subnets2 = [
subnetFactory.build({
linodes: [
subnetLinodeInfoId1,
subnetLinodeInfoId1,
subnetLinodeInfoId3,
subnetLinodeInfoId3,
],
}),
];
const subnets3 = [
subnetFactory.build({ linodes: [1, 2, 3] }),
subnetFactory.build({ linodes: subnetLinodeInfoList1 }),
subnetFactory.build({ linodes: [] }),
subnetFactory.build({ linodes: [3] }),
subnetFactory.build({ linodes: [6, 7, 8, 9, 1] }),
subnetFactory.build({ linodes: [subnetLinodeInfoId3] }),
subnetFactory.build({
linodes: [
subnetAssignedLinodeDataFactory.build({ id: 6 }),
subnetAssignedLinodeDataFactory.build({ id: 7 }),
subnetAssignedLinodeDataFactory.build({ id: 8 }),
subnetAssignedLinodeDataFactory.build({ id: 9 }),
subnetLinodeInfoId1,
],
}),
];

expect(getUniqueLinodesFromSubnets(subnets0)).toBe(0);
expect(getUniqueLinodesFromSubnets(subnets1)).toBe(3);
expect(getUniqueLinodesFromSubnets(subnets1)).toBe(4);
expect(getUniqueLinodesFromSubnets(subnets2)).toBe(2);
expect(getUniqueLinodesFromSubnets(subnets3)).toBe(7);
});
Expand Down
6 changes: 3 additions & 3 deletions packages/manager/src/features/VPCs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import type { Config, Subnet } from '@linode/api-v4';
export const getUniqueLinodesFromSubnets = (subnets: Subnet[]) => {
const linodes: number[] = [];
for (const subnet of subnets) {
subnet.linodes.forEach((linodeId) => {
if (!linodes.includes(linodeId)) {
linodes.push(linodeId);
subnet.linodes.forEach((linodeInfo) => {
if (!linodes.includes(linodeInfo.id)) {
linodes.push(linodeInfo.id);
}
});
}
Expand Down