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-7641] – Support IPv4 ranges in VPC "Assign Linodes" drawer #10089

Conversation

dwiley-akamai
Copy link
Contributor

@dwiley-akamai dwiley-akamai commented Jan 20, 2024

Description πŸ“

Rework the "Assign Linodes" drawer to support the assigning and display of IPv4 ranges.

This PR will not be merged into develop but rather into a to-be created branch to accommodate the off-cycle release next week to release this for VPC.

Changes πŸ”„

  • Rely on VPC feature flag to determine whether the "BETA Feedback" link is displayed or not on the VPC landing & detail pages
  • Update LinodeInterfaceSchema to remove max length of 1 for ip_ranges field
  • New AssignIPRanges component (will be used in the Linode Create flow & Add/Edit Linode Config dialog as well in subsequent tickets)
  • Added RemovableSelectionsListTable component instead of muddying RemovableSelectionsList (the latter will be getting used in other projects also, not just VPC anymore)
  • Minor adjustments in MultipleIPInput.tsx so it can be used for this use case

Preview πŸ“·

Before After
Screen.Recording.2024-01-24.at.5.03.21.PM.mov
Screen.Recording.2024-01-24.at.5.04.23.PM.mov

How to test πŸ§ͺ

Verification steps

For the "BETA Feedback" link, toggle the VPC feature flag in our DevTool and confirm the link on the VPC landing and detail pages doesn't show when the flag is off.

Have the vpc-extra-beta tag on your account and a VPC containing at least one subnet. Navigate to the "Assign Linodes to subnet" drawer (VPC Details > three-dot menu on subnet line item > "Assign Linodes")...

  • the "Auto-assign a VPC IPv4 address for this Linode" checkbox and "Assign additional IPv4 ranges" section should be hidden until you select a linode
  • the "Auto-assign a VPC IPv4 address for this Linode" checkbox functionality should not have been adversely impacted (i.e., the payload with it checked and unchecked should look as expected. If it's unchecked, it should have the input of the "VPC IPv4" field)
  • Add 3 or more IPv4 ranges and assign the linode. Observe: the table under "Linodes Assigned to Subnet" should be populated with the details for the linode you just added. The "+X" chip in the "VPC IPv4 Ranges" column should (after an initial click, and then any time after that upon hover) show the other ranges beyond the first one displayed in the table.
  • Clicking the "X" for the linode in the "Linodes Assigned to Subnet" table should unassign it from the subnet.

There were slight changes to MultipleIPInput.tsx so it could be used satisfactorily here. Please confirm there have been no adverse impacts to its use elsewhere in the app (Database "Add Access Control" drawer, "Edit Domain" drawer for secondary domains, etc.)

As an Author I have considered πŸ€”

  • πŸ‘€ Doing a self review
  • ❔ Our contribution guidelines
  • 🀏 Splitting feature into small PRs
  • βž• Adding a changeset
  • πŸ§ͺ Providing/Improving test coverage
  • πŸ” Removing all sensitive information from the code and PR description
  • 🚩 Using a feature flag to protect the release
  • πŸ‘£ Providing comprehensive reproduction steps
  • πŸ“‘ Providing or updating our documentation
  • πŸ•› Scheduling a pair reviewing session
  • πŸ“± Providing mobile support
  • β™Ώ Providing accessibility support

@dwiley-akamai dwiley-akamai added Work in Progress @linode/validation Changes are made to the @linode/validation package VPC Relating to VPC project labels Jan 20, 2024
@dwiley-akamai dwiley-akamai self-assigned this Jan 20, 2024
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opted to separate this out into its own component as opposed to having a bunch of conditionals in RemovableSelectionsList.tsx in order to display the data in table form. RemovableSelectionsList.tsx was initially created for VPC but is being used moving forward in other projects.

This is the only current use case for this component. VPC-specific data is hard-coded in here. There might be an elegant way around that but I think it's basically the same dilemma we faced with tables/table rows in the past: we used to have something called EntityTable IIRC and that was flexible enough to consume different headers and data for the rows. We got rid of that and have been doing entity-specific rows, so perhaps this file should be renamed to be specific for VPC.

@@ -161,6 +161,7 @@ export const LinodeSelect = (
helperText={helperText}
id={id}
inputValue={inputValue}
isOptionEqualToValue={(option, value) => option.id === value.id}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, I was seeing a warning error getting aggressively logged to the console every time I was in the drawer. I added this line based on this StackOverflow comment. I didn't observe any adverse impacts of this change where this component is used elsewhere, e.g. the Volume Create flow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should be safe and only pass this to your instance via optional prop. No harm in only targeting the smallest audience as we're unaware of potential side effects

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair -- I made an adjustment in 60f99db so it doesn't get passed unconditionally as an prop

Comment on lines +75 to +94
it.skip('should show the IPv4 textbox when the checkmark is clicked', async () => {
const { findByText, getByLabelText } = renderWithTheme(
<SubnetAssignLinodesDrawer {...props} />,
{
queryClient,
}
);

const checkbox = getByText(
const selectField = getByLabelText('Linode');
fireEvent.change(selectField, { target: { value: 'this-linode' } });

const checkbox = await findByText(
'Auto-assign a VPC IPv4 address for this Linode'
);
expect(checkbox).toBeVisible();

await waitFor(() => expect(checkbox).toBeVisible());
fireEvent.click(checkbox);

const ipv4Textbox = getByText('VPC IPv4');
expect(ipv4Textbox).toBeVisible();
const ipv4Textbox = await findByText('VPC IPv4');
await waitFor(() => expect(ipv4Textbox).toBeVisible());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the changes to this UI is that the "Auto-assign a VPC IPv4 address for this Linode" checkbox is no longer exposed by default, but rather only when a user selects a linode. I couldn't quite get the test working as I had hoped (console.log'ing the value of linodes in SubnetAssignLinodesDrawer.tsx showed it as undefined despite L40 up above).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine - we've done this in other places too

@@ -57,7 +61,7 @@ interface SubnetAssignLinodesDrawerProps {

type LinodeAndConfigData = Linode & {
configId: number;
interfaceId: number;
interfaceData: Interface | undefined;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was made so that the needed VPC IPv4 & VPC IPv4 Ranges data could be passed into the RemovableSelectionsListTable for display.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
interfaceData: Interface | undefined;
interfaceData?: Interface;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking, it's not an optional property. The undefined piece is there because it gets stored in the newInterface ref which gets initialized as undefined.

@dwiley-akamai dwiley-akamai marked this pull request as ready for review January 24, 2024 22:23
@dwiley-akamai dwiley-akamai requested a review from a team as a code owner January 24, 2024 22:23
@dwiley-akamai dwiley-akamai requested review from bnussman-akamai, abailly-akamai, hana-linode and jaalah-akamai and removed request for a team January 24, 2024 22:23
Copy link

github-actions bot commented Jan 24, 2024

Coverage Report: βœ…
Base Coverage: 79.94%
Current Coverage: 80.07%

Copy link
Contributor

@abailly-akamai abailly-akamai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UI looks great, and functionality worked as expected. Added comments to ad tests and cleanup some things, also have a few questions:

Do we want to show the array index here?
Screenshot 2024-01-25 at 10 11 56

I am confused about the difference between the error returned by the API and what is displayed to the user. Can you clarify if this is expected?
Screenshot 2024-01-25 at 10 16 16

className?: string;
error?: string;
forDatabaseAccessControls?: boolean;
forVPCIPv4Ranges?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am not crazy about making a feature specific prop for a reusable component. Any way we can make this more generic? This prop could be more than a boolean (could be a custom object serving your purpose)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about passing in a custom button JSX element?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the custom button JSX element option, but it presents some difficulties since the onClick handler (addNewInput) gets defined in this file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to time constraints we'll revisit making this more generic in a follow-up ticket

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. Let's add a todo reminder comment

</Table>
</>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we get a test for this new component and add it to the existing story?

@@ -161,6 +161,7 @@ export const LinodeSelect = (
helperText={helperText}
id={id}
inputValue={inputValue}
isOptionEqualToValue={(option, value) => option.id === value.id}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should be safe and only pass this to your instance via optional prop. No harm in only targeting the smallest audience as we're unaware of potential side effects

/>
</>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless it is covered somewhere else, can we also add unit test for this?

Copy link
Contributor

@hana-linode hana-linode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality LGTM

@@ -57,7 +61,7 @@ interface SubnetAssignLinodesDrawerProps {

type LinodeAndConfigData = Linode & {
configId: number;
interfaceId: number;
interfaceData: Interface | undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
interfaceData: Interface | undefined;
interfaceData?: Interface;

className?: string;
error?: string;
forDatabaseAccessControls?: boolean;
forVPCIPv4Ranges?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about passing in a custom button JSX element?

Comment on lines 36 to 40
{ASSIGN_IPV4_RANGES_DESCRIPTION}{' '}
<Link to="https://www.linode.com/docs/guides/how-to-understand-ip-addresses/">
Learn more
</Link>
.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in a tooltip? In the Add/Edit Linode Config Mocks, it's in a tooltip

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the Add/Edit Linode Config context it should be in a tooltip because of how long and dense that form is, but elsewhere the copy is exposed

…re flag so the link disappears once we turn off the feature flag for GA
… field tied to it only if a linode has been selected
…ved schema limit on how many IP ranges can be provided; added prop to <Autocomplete /> in LinodeSelect.tsx to prevent 'The value provided to Autocomplete is invalid' console error
…put placeholder and button text per updated mockups
…signIPRanges />; temp skip in SubnetAssignLinodesDrawer.test.tsx and remove some assertions given changed behavior
@dwiley-akamai dwiley-akamai force-pushed the M3-7641-range-support-assign-drawer branch from f7146be to 6dd87a1 Compare January 26, 2024 15:26
@dwiley-akamai dwiley-akamai changed the base branch from develop to staging-off-release January 26, 2024 15:35
Copy link
Contributor

@jaalah-akamai jaalah-akamai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added unit test AssignIPRanges.test.tsx.
Second time reviewing this PR and things are working as intended. I also reviewed Domains & Firewalls since those use similar components.

Copy link
Contributor

@hana-linode hana-linode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • "BETA Feedback" link is hidden when the vpc feature flag is off
  • "Auto-assign a VPC IPv4 address for this Linode" checkbox and "Assign additional IPv4 ranges" section is hidden until a Linode is selected
  • Able to assign IPv4 ranges to the Linode
    • "+X" chip is present when assigning more than one range
    • Chip tooltip displays the additional ranges
  • Clicking "X" unassigns the Linode from the subnet
  • No regressions found for MultipleIPInput

@hana-linode hana-linode added the Approved Multiple approvals and ready to merge! label Jan 26, 2024
hana-linode added a commit that referenced this pull request Jan 26, 2024
… Table (#10108)

## Description πŸ“
Add support for displaying VPC IPv4 addresses and ranges in the Linode Details -> Network tab -> "IP Addresses" table

## Changes  πŸ”„
List any change relevant to the reviewer.
- Add Support for VPC IPv4 addresses and ranges to the Linode IP Address table
  - If there is a VPC interface with 1:1 NAT, hide the Public IPv4 IP address row
- Improve mobile text display of the Type column

## How to test πŸ§ͺ

### Prerequisites
(How to setup test environment)
- Have the `vpc-extra-beta` tag on your account and a VPC with at least one Subnet
- Assign a Linode to the Subnet and check both the checkboxes (Auto-assign a VPC IPv4 address & Assign a public IPv4 address)
- To add `ip_ranges`, check out #10089

### Verification steps 
(How to verify changes)
- Go to the Linode Details -> Network tab of the assigned Linode and check the IP Addresses table
- You should see IP Address rows for `IPv4 – VPC`, `VPC IPv4 – NAT`, and `IPv4 – VPC – Range` for each range
- You should _not_ see an IP address row for the type `IPv4 - Public`
```
yarn test LinodeIPAddressRow
```
@dwiley-akamai dwiley-akamai merged commit f35b249 into linode:staging-off-release Jan 26, 2024
16 of 18 checks passed
@dwiley-akamai dwiley-akamai deleted the M3-7641-range-support-assign-drawer branch January 26, 2024 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Approved Multiple approvals and ready to merge! @linode/validation Changes are made to the @linode/validation package VPC Relating to VPC project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants