diff --git a/packages/manager/.changeset/pr-10238-upcoming-features-1709143092179.md b/packages/manager/.changeset/pr-10238-upcoming-features-1709143092179.md new file mode 100644 index 00000000000..fed4c1732b5 --- /dev/null +++ b/packages/manager/.changeset/pr-10238-upcoming-features-1709143092179.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Only support Edge to Edge Migrations ([#10238](https://github.com/linode/manager/pull/10238)) diff --git a/packages/manager/src/__data__/regionsData.ts b/packages/manager/src/__data__/regionsData.ts index 6e44c8dd739..8cc14196559 100644 --- a/packages/manager/src/__data__/regionsData.ts +++ b/packages/manager/src/__data__/regionsData.ts @@ -604,7 +604,7 @@ export const regions: Region[] = [ { capabilities: ['Linodes'], country: 'us', - id: 'us-edgetest', + id: 'us-edge-1', label: 'Gecko Edge Test', maximum_pgs_per_customer: 5, maximum_vms_per_pg: 10, @@ -617,4 +617,20 @@ export const regions: Region[] = [ site_type: 'edge', status: 'ok', }, + { + capabilities: ['Linodes'], + country: 'us', + id: 'us-edge-2', + label: 'Gecko Edge Test 2', + maximum_pgs_per_customer: 5, + maximum_vms_per_pg: 10, + resolvers: { + ipv4: + '139.162.130.5, 139.162.131.5, 139.162.132.5, 139.162.133.5, 139.162.134.5, 139.162.135.5, 139.162.136.5, 139.162.137.5, 139.162.138.5, 139.162.139.5', + ipv6: + '2a01:7e01::5, 2a01:7e01::9, 2a01:7e01::7, 2a01:7e01::c, 2a01:7e01::2, 2a01:7e01::4, 2a01:7e01::3, 2a01:7e01::6, 2a01:7e01::b, 2a01:7e01::8', + }, + site_type: 'edge', + status: 'ok', + }, ]; diff --git a/packages/manager/src/components/RegionSelect/RegionSelect.test.tsx b/packages/manager/src/components/RegionSelect/RegionSelect.test.tsx index dc1ed580610..43491f83564 100644 --- a/packages/manager/src/components/RegionSelect/RegionSelect.test.tsx +++ b/packages/manager/src/components/RegionSelect/RegionSelect.test.tsx @@ -68,7 +68,7 @@ describe('RegionSelect', () => { it('should render a Select component with edge region text', () => { const newProps = { ...props, - showGeckoHelperText: true, + showEdgeIconHelperText: true, }; const { getByTestId } = renderWithTheme(); expect(getByTestId('region-select-edge-text')).toBeInTheDocument(); @@ -77,7 +77,7 @@ describe('RegionSelect', () => { it('should render a Select component with no edge region text', () => { const newProps = { ...props, - showGeckoHelperText: false, + showEdgeIconHelperText: false, }; const { queryByTestId } = renderWithTheme(); expect(queryByTestId('region-select-edge-text')).not.toBeInTheDocument(); diff --git a/packages/manager/src/components/RegionSelect/RegionSelect.tsx b/packages/manager/src/components/RegionSelect/RegionSelect.tsx index 8e63085c29f..084da92f080 100644 --- a/packages/manager/src/components/RegionSelect/RegionSelect.tsx +++ b/packages/manager/src/components/RegionSelect/RegionSelect.tsx @@ -36,15 +36,15 @@ export const RegionSelect = React.memo((props: RegionSelectProps) => { currentCapability, disabled, errorText, - geckoEnabled, handleSelection, helperText, isClearable, label, + regionFilter, regions, required, selectedId, - showGeckoHelperText, + showEdgeIconHelperText, width, } = props; @@ -84,10 +84,10 @@ export const RegionSelect = React.memo((props: RegionSelectProps) => { getRegionOptions({ accountAvailabilityData: accountAvailability, currentCapability, - hideEdgeServers: !geckoEnabled, + regionFilter, regions, }), - [accountAvailability, currentCapability, regions, geckoEnabled] + [accountAvailability, currentCapability, regions, regionFilter] ); return ( @@ -110,7 +110,7 @@ export const RegionSelect = React.memo((props: RegionSelectProps) => { return ( { })} textFieldProps={{ InputProps: { - endAdornment: geckoEnabled && + endAdornment: regionFilter !== 'core' && selectedRegion?.site_type === 'edge' && ( } @@ -159,7 +159,7 @@ export const RegionSelect = React.memo((props: RegionSelectProps) => { placeholder="Select a Region" value={selectedRegion} /> - {showGeckoHelperText && ( // @TODO Gecko MVP: Add docs link + {showEdgeIconHelperText && ( // @TODO Gecko Beta: Add docs link void; helperText?: string; isClearable?: boolean; label?: string; + regionFilter?: RegionSite; regions: Region[]; required?: boolean; selectedId: null | string; - showGeckoHelperText?: boolean; + showEdgeIconHelperText?: boolean; width?: number; } @@ -72,7 +72,7 @@ export interface RegionOptionAvailability { } export interface GetRegionOptions extends RegionOptionAvailability { - hideEdgeServers?: boolean; + regionFilter?: RegionSite; regions: Region[]; } diff --git a/packages/manager/src/components/RegionSelect/RegionSelect.utils.test.tsx b/packages/manager/src/components/RegionSelect/RegionSelect.utils.test.tsx index 5b424acc1c7..95f52bf560c 100644 --- a/packages/manager/src/components/RegionSelect/RegionSelect.utils.test.tsx +++ b/packages/manager/src/components/RegionSelect/RegionSelect.utils.test.tsx @@ -47,6 +47,13 @@ const regionsWithEdge = [ label: 'Gecko Edge Test', site_type: 'edge', }), + regionFactory.build({ + capabilities: ['Linodes'], + country: 'us', + id: 'us-edge-2', + label: 'Gecko Edge Test 2', + site_type: 'edge', + }), ]; const expectedRegions: RegionSelectOption[] = [ @@ -76,6 +83,23 @@ const expectedRegions: RegionSelectOption[] = [ }, ]; +const expectedEdgeRegions = [ + { + data: { country: 'us', region: 'North America' }, + label: 'Gecko Edge Test (us-edge-1)', + site_type: 'edge', + unavailable: false, + value: 'us-edge-1', + }, + { + data: { country: 'us', region: 'North America' }, + label: 'Gecko Edge Test 2 (us-edge-2)', + site_type: 'edge', + unavailable: false, + value: 'us-edge-2', + }, +]; + describe('getRegionOptions', () => { it('should return an empty array if no regions are provided', () => { const regions: Region[] = []; @@ -118,33 +142,38 @@ describe('getRegionOptions', () => { expect(result).toEqual(expectedRegions); }); - it('should filter out edge regions if hideEdgeServers is true', () => { + it('should filter out edge regions if regionFilter is core', () => { const result: RegionSelectOption[] = getRegionOptions({ accountAvailabilityData, currentCapability: 'Linodes', - hideEdgeServers: true, + regionFilter: 'core', regions: regionsWithEdge, }); expect(result).toEqual(expectedRegions); }); - it('should not filter out edge regions if hideEdgeServers is false', () => { + it('should filter out core regions if regionFilter is edge', () => { + const result: RegionSelectOption[] = getRegionOptions({ + accountAvailabilityData, + currentCapability: 'Linodes', + regionFilter: 'edge', + regions: regionsWithEdge, + }); + + expect(result).toEqual(expectedEdgeRegions); + }); + + it('should not filter out any regions if regionFilter is undefined', () => { const expectedRegionsWithEdge = [ - { - data: { country: 'us', region: 'North America' }, - label: 'Gecko Edge Test (us-edge-1)', - site_type: 'edge', - unavailable: false, - value: 'us-edge-1', - }, + ...expectedEdgeRegions, ...expectedRegions, ]; const result: RegionSelectOption[] = getRegionOptions({ accountAvailabilityData, currentCapability: 'Linodes', - hideEdgeServers: false, + regionFilter: undefined, regions: regionsWithEdge, }); diff --git a/packages/manager/src/components/RegionSelect/RegionSelect.utils.ts b/packages/manager/src/components/RegionSelect/RegionSelect.utils.ts index 597b7b1276d..76bb1ea5db7 100644 --- a/packages/manager/src/components/RegionSelect/RegionSelect.utils.ts +++ b/packages/manager/src/components/RegionSelect/RegionSelect.utils.ts @@ -1,6 +1,5 @@ import { CONTINENT_CODE_TO_CONTINENT } from '@linode/api-v4'; -import { useFlags } from 'src/hooks/useFlags'; import { getRegionCountryGroup, getSelectedRegion, @@ -28,7 +27,7 @@ const NORTH_AMERICA = CONTINENT_CODE_TO_CONTINENT.NA; export const getRegionOptions = ({ accountAvailabilityData, currentCapability, - hideEdgeServers = false, + regionFilter, regions, }: GetRegionOptions): RegionSelectOption[] => { const filteredRegionsByCapability = currentCapability @@ -37,9 +36,9 @@ export const getRegionOptions = ({ ) : regions; - const filteredRegionsByCapabilityAndSiteType = hideEdgeServers + const filteredRegionsByCapabilityAndSiteType = regionFilter ? filteredRegionsByCapability.filter( - (region) => region.site_type !== 'edge' + (region) => region.site_type === regionFilter ) : filteredRegionsByCapability; @@ -191,17 +190,17 @@ export const getSelectedRegionsByIds = ({ /** * Util to determine whether a create type has support for edge regions. * - * @returns a boolean indicating whether or not to enable gecko. + * @returns a boolean indicating whether or not the create type is edge supported. */ -export const useIsGeckoEnabled = (createType: LinodeCreateType) => { - const flags = useFlags(); - +export const getIsLinodeCreateTypeEdgeSupported = ( + createType: LinodeCreateType +) => { const supportedEdgeTypes: SupportedEdgeTypes[] = [ 'Distributions', 'StackScripts', ]; - return Boolean( - flags.gecko && - !supportedEdgeTypes.includes(createType as SupportedEdgeTypes) + return ( + supportedEdgeTypes.includes(createType as SupportedEdgeTypes) || + typeof createType === 'undefined' // /linodes/create route ); }; diff --git a/packages/manager/src/components/SelectRegionPanel/SelectRegionPanel.tsx b/packages/manager/src/components/SelectRegionPanel/SelectRegionPanel.tsx index 0d3db1b4740..124169402ae 100644 --- a/packages/manager/src/components/SelectRegionPanel/SelectRegionPanel.tsx +++ b/packages/manager/src/components/SelectRegionPanel/SelectRegionPanel.tsx @@ -6,10 +6,11 @@ import { useLocation } from 'react-router-dom'; import { Notice } from 'src/components/Notice/Notice'; import { Paper } from 'src/components/Paper'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; -import { useIsGeckoEnabled } from 'src/components/RegionSelect/RegionSelect.utils'; +import { getIsLinodeCreateTypeEdgeSupported } from 'src/components/RegionSelect/RegionSelect.utils'; import { RegionHelperText } from 'src/components/SelectRegionPanel/RegionHelperText'; import { Typography } from 'src/components/Typography'; import { CROSS_DATA_CENTER_CLONE_WARNING } from 'src/features/Linodes/LinodesCreate/constants'; +import { useFlags } from 'src/hooks/useFlags'; import { useTypeQuery } from 'src/queries/types'; import { sendLinodeCreateDocsEvent } from 'src/utilities/analytics'; import { @@ -51,6 +52,7 @@ export const SelectRegionPanel = (props: SelectRegionPanelProps) => { selectedLinodeTypeId, } = props; + const flags = useFlags(); const location = useLocation(); const theme = useTheme(); const params = getQueryParamsFromQueryString(location.search); @@ -75,10 +77,12 @@ export const SelectRegionPanel = (props: SelectRegionPanelProps) => { type, }); - const geckoEnabled = useIsGeckoEnabled(params.type as LinodeCreateType); + const hideEdgeRegions = + !flags.gecko || + !getIsLinodeCreateTypeEdgeSupported(params.type as LinodeCreateType); - const showGeckoHelperText = Boolean( - geckoEnabled && + const showEdgeIconHelperText = Boolean( + !hideEdgeRegions && currentCapability && regions.find( (region) => @@ -131,12 +135,12 @@ export const SelectRegionPanel = (props: SelectRegionPanelProps) => { currentCapability={currentCapability} disabled={disabled} errorText={error} - geckoEnabled={geckoEnabled} handleSelection={handleSelection} helperText={helperText} + regionFilter={hideEdgeRegions ? 'core' : undefined} regions={regions} selectedId={selectedId || null} - showGeckoHelperText={showGeckoHelperText} + showEdgeIconHelperText={showEdgeIconHelperText} /> {showClonePriceWarning && ( { selectedRegion, } = props; + const flags = useFlags(); const { data: regions } = useRegionsQuery(); const { data: currentLinodeType } = useTypeQuery( linodeType || '', @@ -98,6 +103,8 @@ export const ConfigureForm = React.memo((props: Props) => { [backupEnabled, currentLinodeType] ); + const linodeIsInEdgeRegion = currentActualRegion?.site_type === 'edge'; + return ( Configure Migration @@ -109,6 +116,14 @@ export const ConfigureForm = React.memo((props: Props) => { {`${getRegionCountryGroup(currentActualRegion)}: ${ currentActualRegion?.label ?? currentRegion }`} + {linodeIsInEdgeRegion && ( + } + status="other" + sxTooltipIcon={sxEdgeIcon} + text="This region is an Edge server." + /> + )} {shouldDisplayPriceComparison && ( { errorText={errorText} handleSelection={handleSelectRegion} label="New Region" + regionFilter={flags.gecko && linodeIsInEdgeRegion ? 'edge' : 'core'} selectedId={selectedRegion} /> {shouldDisplayPriceComparison && selectedRegion && ( diff --git a/packages/manager/src/mocks/serverHandlers.ts b/packages/manager/src/mocks/serverHandlers.ts index 73f88217cf6..931cd596510 100644 --- a/packages/manager/src/mocks/serverHandlers.ts +++ b/packages/manager/src/mocks/serverHandlers.ts @@ -766,8 +766,8 @@ export const handlers = [ linodeFactory.build({ backups: { enabled: false }, id, - label: 'DC-Specific Pricing Linode', - region: 'id-cgk', + label: 'Gecko Edge Test', + region: 'us-edge-1', }) ) );