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

feat: [M3-7643] – Support VPC IPv4 Ranges in Linode Create flow #10116

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ba03023
Make display of 'BETA Feedback' link conditoned based solely on featu…
DevDW Jan 17, 2024
3576a6b
Display 'Auto-assign a VPC IPv4 address for this Linode' checkbox and…
DevDW Jan 17, 2024
9af0bfb
Basic structure & functionality in place for IPv4 range support; remo…
DevDW Jan 20, 2024
02d4044
Filter empty strings out from IP Ranges payload; update IPv4 Range in…
DevDW Jan 22, 2024
088a1e4
Use <Chip /> for '+X' piece
DevDW Jan 22, 2024
0b0e5bb
Use <Chip /> for '+X' piece pt 2
DevDW Jan 22, 2024
78ca148
Utility file and tests for chip function; spacing adjustments for <As…
DevDW Jan 23, 2024
c777aa5
Use <LinkButton /> to get desired styling for 'Add IPv4 Range' button
DevDW Jan 23, 2024
ff18de7
desired RemovableSelectionsList UI (refactor forthcoming)
DevDW Jan 23, 2024
493b4f4
RemovableSelectionsListTable.tsx
DevDW Jan 24, 2024
8019eec
refactor: [M3-7672] – Use flags.vpc to determine if beta chip gets di…
dwiley-akamai Jan 22, 2024
1c06c09
Minor refactor in SubnetAssignLinodesDrawer.tsx surrounding interface…
DevDW Jan 24, 2024
814a487
Changeset added for Cloud changes
DevDW Jan 24, 2024
6dd87a1
Added changeset: ip_ranges field in LinodeInterfaceSchema no longer l…
DevDW Jan 24, 2024
b97c083
Undo changes to RemovableSelectionsList.tsx
DevDW Jan 26, 2024
2d364ae
functional VPC IPv4 ranges support in Linode Create flow
DevDW Jan 26, 2024
28d5c2d
add spacing between 'Assign additional IPv4 ranges' title and the des…
DevDW Jan 26, 2024
4ae0234
add and populate 'VPC IPv4 Ranges' column to inner Subnet table
DevDW Jan 26, 2024
3c8432a
Added changeset: Support for VPC IPv4 Ranges in Linode Create flow an…
DevDW Jan 26, 2024
e78a014
Get latest, fix conflicts
jaalah Jan 28, 2024
79916f1
Fix broken tests
jaalah Jan 28, 2024
cc6cea5
Merge branch 'staging-off-release' into M3-7643-ipv4-range-support-li…
hana-akamai Jan 29, 2024
a8791c6
fix unit test
hana-akamai Jan 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-10116-added-1706293067938.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Added
---

Support for VPC IPv4 Ranges in Linode Create flow and 'VPC IPv4 Ranges' column to inner Subnets table on VPC Detail page ([#10116](https://github.com/linode/manager/pull/10116))
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export const MultipleIPInput = React.memo((props: Props) => {
direction="row"
justifyContent="center"
key={`domain-transfer-ip-${idx}`}
maxWidth={forVPCIPv4Ranges ? '415px' : undefined}
spacing={2}
>
<Grid xs={11}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,18 @@ import {
} from './types';

import type { Tab } from 'src/components/Tabs/TabLinkList';
import { ExtendedIP } from 'src/utilities/ipUtils';

export interface LinodeCreateProps {
additionalIPv4RangesForVPC: ExtendedIP[];
assignPublicIPv4Address: boolean;
autoassignIPv4WithinVPC: boolean;
checkValidation: LinodeCreateValidation;
createType: CreateTypes;
firewallId?: number;
handleAgreementChange: () => void;
handleFirewallChange: (firewallId: number) => void;
handleIPv4RangesForVPC: (ranges: ExtendedIP[]) => void;
handleShowApiAwarenessModal: () => void;
handleSubmitForm: HandleSubmit;
handleSubnetChange: (subnetId: number) => void;
Expand Down Expand Up @@ -641,9 +644,11 @@ export class LinodeCreate extends React.PureComponent<
toggleAutoassignIPv4WithinVPCEnabled={
this.props.toggleAutoassignIPv4WithinVPCEnabled
}
additionalIPv4RangesForVPC={this.props.additionalIPv4RangesForVPC}
assignPublicIPv4Address={this.props.assignPublicIPv4Address}
autoassignIPv4WithinVPC={this.props.autoassignIPv4WithinVPC}
from="linodeCreate"
handleIPv4RangeChange={this.props.handleIPv4RangesForVPC}
handleSelectVPC={this.props.setSelectedVPC}
handleSubnetChange={this.props.handleSubnetChange}
handleVPCIPv4Change={this.props.handleVPCIPv4Change}
Expand Down Expand Up @@ -822,6 +827,9 @@ export class LinodeCreate extends React.PureComponent<
this.props.selectedVPCId !== -1
) {
const vpcInterfaceData: InterfacePayload = {
ip_ranges: this.props.additionalIPv4RangesForVPC
.map((ipRange) => ipRange.address)
.filter((ipRange) => ipRange !== ''),
ipam_address: null,
ipv4: {
nat_1_1: this.props.assignPublicIPv4Address ? 'any' : undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import {
} from 'src/utilities/formatRegion';
import { isEURegion } from 'src/utilities/formatRegion';
import { UNKNOWN_PRICE } from 'src/utilities/pricing/constants';
import { getLinodeRegionPrice } from 'src/utilities/pricing/linodes';
import { getQueryParamsFromQueryString } from 'src/utilities/queryParams';
import { scrollErrorIntoView } from 'src/utilities/scrollErrorIntoView';
import { validatePassword } from 'src/utilities/validatePassword';
Expand All @@ -85,11 +86,12 @@ import type {
LinodeTypeClass,
PriceObject,
} from '@linode/api-v4/lib/linodes';
import { getLinodeRegionPrice } from 'src/utilities/pricing/linodes';
import { ExtendedIP } from 'src/utilities/ipUtils';

const DEFAULT_IMAGE = 'linode/debian11';

interface State {
additionalIPv4RangesForVPC: ExtendedIP[];
assignPublicIPv4Address: boolean;
attachedVLANLabel: null | string;
authorized_users: string[];
Expand Down Expand Up @@ -140,6 +142,7 @@ type CombinedProps = WithSnackbarProps &
WithAccountSettingsProps;

const defaultState: State = {
additionalIPv4RangesForVPC: [],
assignPublicIPv4Address: false,
attachedVLANLabel: '',
authorized_users: [],
Expand Down Expand Up @@ -277,6 +280,7 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
firewallId={this.state.selectedfirewallId}
handleAgreementChange={this.handleAgreementChange}
handleFirewallChange={this.handleFirewallChange}
handleIPv4RangesForVPC={this.handleVPCIPv4RangesChange}
handleSelectUDFs={this.setUDFs}
handleShowApiAwarenessModal={this.handleShowApiAwarenessModal}
handleSubmitForm={this.submitForm}
Expand Down Expand Up @@ -515,6 +519,10 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
this.setState({ vpcIPv4AddressOfLinode: IPv4 });
};

handleVPCIPv4RangesChange = (ranges: ExtendedIP[]) => {
this.setState({ additionalIPv4RangesForVPC: ranges });
};

params = getQueryParamsFromQueryString(this.props.location.search) as Record<
string,
string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ afterEach(() => {
});

const props = {
additionalIPv4RangesForVPC: [],
assignPublicIPv4Address: false,
autoassignIPv4WithinVPC: true,
from: 'linodeCreate' as VPCPanelProps['from'],
handleIPv4RangeChange: vi.fn(),
handleSelectVPC: vi.fn(),
handleSubnetChange: vi.fn(),
handleVPCIPv4Change: vi.fn(),
Expand Down Expand Up @@ -105,7 +107,12 @@ describe('VPCPanel', () => {
});

it('should have the VPC IPv4 auto-assign checkbox checked by default', async () => {
const _props = { ...props, region: 'us-east', selectedVPCId: 5 };
const _props = {
...props,
region: 'us-east',
selectedSubnetId: 2,
selectedVPCId: 5,
};

server.use(
rest.get('*/regions', (req, res, ctx) => {
Expand Down Expand Up @@ -234,6 +241,7 @@ describe('VPCPanel', () => {
...props,
autoassignIPv4WithinVPC: false,
region: 'us-east',
selectedSubnetId: 2,
selectedVPCId: 5,
vpcIPv4AddressOfLinode: '10.0.4.3',
};
Expand Down Expand Up @@ -269,6 +277,7 @@ describe('VPCPanel', () => {
...props,
assignPublicIPv4Address: true,
region: 'us-east',
selectedSubnetId: 2,
selectedVPCId: 5,
};

Expand Down
182 changes: 103 additions & 79 deletions packages/manager/src/features/Linodes/LinodesCreate/VPCPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Stack } from 'src/components/Stack';
import { TextField } from 'src/components/TextField';
import { TooltipIcon } from 'src/components/TooltipIcon';
import { Typography } from 'src/components/Typography';
import { AssignIPRanges } from 'src/features/VPCs/VPCDetail/AssignIPRanges';
import { VPC_AUTO_ASSIGN_IPV4_TOOLTIP } from 'src/features/VPCs/constants';
import { useAccountManagement } from 'src/hooks/useAccountManagement';
import { useFlags } from 'src/hooks/useFlags';
Expand All @@ -22,15 +23,18 @@ import { useVPCsQuery } from 'src/queries/vpcs';
import { isFeatureEnabled } from 'src/utilities/accountCapabilities';
import { doesRegionSupportFeature } from 'src/utilities/doesRegionSupportFeature';
import { getAPIErrorOrDefault } from 'src/utilities/errorUtils';
import { ExtendedIP } from 'src/utilities/ipUtils';
import { scrollErrorIntoView } from 'src/utilities/scrollErrorIntoView';

import { VPCCreateDrawer } from './VPCCreateDrawer';
import { REGION_CAVEAT_HELPER_TEXT } from './constants';

export interface VPCPanelProps {
additionalIPv4RangesForVPC: ExtendedIP[];
assignPublicIPv4Address: boolean;
autoassignIPv4WithinVPC: boolean;
from: 'linodeConfig' | 'linodeCreate';
handleIPv4RangeChange: (ranges: ExtendedIP[]) => void;
handleSelectVPC: (vpcId: number) => void;
handleSubnetChange: (subnetId: number) => void;
handleVPCIPv4Change: (IPv4: string) => void;
Expand All @@ -50,9 +54,11 @@ const ERROR_GROUP_STRING = 'vpc-errors';

export const VPCPanel = (props: VPCPanelProps) => {
const {
additionalIPv4RangesForVPC,
assignPublicIPv4Address,
autoassignIPv4WithinVPC,
from,
handleIPv4RangeChange,
handleSelectVPC,
handleSubnetChange,
handleVPCIPv4Change,
Expand Down Expand Up @@ -247,87 +253,105 @@ export const VPCPanel = (props: VPCPanelProps) => {
options={subnetDropdownOptions}
placeholder="Select Subnet"
/>
<Box
sx={(theme) => ({
marginLeft: '2px',
paddingTop: theme.spacing(),
})}
alignItems="center"
display="flex"
flexDirection="row"
>
<FormControlLabel
control={
<Checkbox
checked={autoassignIPv4WithinVPC}
onChange={toggleAutoassignIPv4WithinVPCEnabled}
{selectedSubnetId && (
<>
<Box
sx={(theme) => ({
marginLeft: '2px',
paddingTop: theme.spacing(),
})}
alignItems="center"
display="flex"
flexDirection="row"
>
<FormControlLabel
control={
<Checkbox
checked={autoassignIPv4WithinVPC}
onChange={toggleAutoassignIPv4WithinVPCEnabled}
/>
}
label={
<Box
alignItems="center"
display="flex"
flexDirection="row"
>
<Typography
noWrap={!isSmallBp && from === 'linodeConfig'}
>
Auto-assign a VPC IPv4 address for this Linode in
the VPC
</Typography>
<TooltipIcon
status="help"
text={VPC_AUTO_ASSIGN_IPV4_TOOLTIP}
/>
</Box>
}
data-testid="vpc-ipv4-checkbox"
/>
}
label={
<Box alignItems="center" display="flex" flexDirection="row">
<Typography
noWrap={!isSmallBp && from === 'linodeConfig'}
>
Auto-assign a VPC IPv4 address for this Linode in the
VPC
</Typography>
<TooltipIcon
status="help"
text={VPC_AUTO_ASSIGN_IPV4_TOOLTIP}
/>
</Box>
}
data-testid="vpc-ipv4-checkbox"
/>
</Box>
{!autoassignIPv4WithinVPC && (
<TextField
errorGroup={ERROR_GROUP_STRING}
errorText={vpcIPv4Error}
label="VPC IPv4"
onChange={(e) => handleVPCIPv4Change(e.target.value)}
required={!autoassignIPv4WithinVPC}
value={vpcIPv4AddressOfLinode}
/>
)}
<Box
sx={(theme) => ({
marginLeft: '2px',
marginTop: !autoassignIPv4WithinVPC ? theme.spacing() : 0,
})}
alignItems="center"
display="flex"
>
<FormControlLabel
control={
<Checkbox
checked={assignPublicIPv4Address}
onChange={toggleAssignPublicIPv4Address}
</Box>
{!autoassignIPv4WithinVPC && (
<TextField
errorGroup={ERROR_GROUP_STRING}
errorText={vpcIPv4Error}
label="VPC IPv4"
onChange={(e) => handleVPCIPv4Change(e.target.value)}
required={!autoassignIPv4WithinVPC}
value={vpcIPv4AddressOfLinode}
/>
}
label={
<Box alignItems="center" display="flex" flexDirection="row">
<Typography>
Assign a public IPv4 address for this Linode
</Typography>
<TooltipIcon
text={
'Access the internet through the public IPv4 address using static 1:1 NAT.'
}
status="help"
/>
</Box>
}
/>
</Box>
{assignPublicIPv4Address && publicIPv4Error && (
<Typography
sx={(theme) => ({
color: theme.color.red,
})}
>
{publicIPv4Error}
</Typography>
)}
<Box
sx={(theme) => ({
marginLeft: '2px',
marginTop: !autoassignIPv4WithinVPC ? theme.spacing() : 0,
})}
alignItems="center"
display="flex"
>
<FormControlLabel
control={
<Checkbox
checked={assignPublicIPv4Address}
onChange={toggleAssignPublicIPv4Address}
/>
}
label={
<Box
alignItems="center"
display="flex"
flexDirection="row"
>
<Typography>
Assign a public IPv4 address for this Linode
</Typography>
<TooltipIcon
text={
'Access the internet through the public IPv4 address using static 1:1 NAT.'
}
status="help"
/>
</Box>
}
/>
</Box>
{assignPublicIPv4Address && publicIPv4Error && (
<Typography
sx={(theme) => ({
color: theme.color.red,
})}
>
{publicIPv4Error}
</Typography>
)}
<AssignIPRanges
handleIPRangeChange={handleIPv4RangeChange}
ipRanges={additionalIPv4RangesForVPC}
ipRangesError={''}
sx={{}}
/>
</>
)}
</Stack>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,11 @@ export const InterfaceSelect = (props: CombinedProps) => {
toggleAutoassignIPv4WithinVPCEnabled={() =>
setAutoAssignVPCIPv4((autoAssignVPCIPv4) => !autoAssignVPCIPv4)
}
additionalIPv4RangesForVPC={[]} // @TODO VPC: temporary placeholder to before M3-7645 is worked on to prevent errors
assignPublicIPv4Address={autoAssignLinodeIPv4}
autoassignIPv4WithinVPC={autoAssignVPCIPv4}
from="linodeConfig"
handleIPv4RangeChange={() => null} // @TODO VPC: temporary placeholder to before M3-7645 is worked on to prevent errors
handleSelectVPC={handleVPCLabelChange}
handleSubnetChange={handleSubnetChange}
handleVPCIPv4Change={handleVPCIPv4Input}
Expand Down
Loading
Loading