Skip to content

Commit 5f8ee20

Browse files
upcoming: Hide new Volume count limit changes behind a feature flag (#12830)
* add feature flag, clean up logic * add tests * update changelog + catch unsaved work * update tests * Update packages/manager/src/features/Linodes/LinodesDetail/LinodeConfigs/utilities.ts Co-authored-by: Banks Nussman <[email protected]> --------- Co-authored-by: Banks Nussman <[email protected]>
1 parent e7a77c8 commit 5f8ee20

File tree

8 files changed

+68
-5
lines changed

8 files changed

+68
-5
lines changed

packages/manager/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
1414
- Linked Node Pool firewall in Node Pool footer for LKE-E clusters ([#12779](https://github.com/linode/manager/pull/12779))
1515
- IAM RBAC: Implement IAM RBAC permissions for NodeBalancer ([#12780](https://github.com/linode/manager/pull/12780))
1616
- IAM RBAC: Implement IAM RBAC permissions for NodeBalancer summary tab ([#12790](https://github.com/linode/manager/pull/12790))
17-
- Additional device slots to Linode Config and Rescue Dialog to match new API limits ([#12791](https://github.com/linode/manager/pull/12791))
1817

1918
### Changed:
2019

@@ -77,6 +76,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
7776
- ACLP-Metrics,Alerts: enforce validation for 100 characters for TextField components ([#12771](https://github.com/linode/manager/pull/12771))
7877
- Disable legacy interface selection for Linode Interfaces when creating a Linode from backups ([#12772](https://github.com/linode/manager/pull/12772))
7978
- UX feedback: Change /settings to /account-settings and profile/settings to profile/preferences ([#12785](https://github.com/linode/manager/pull/12785))
79+
- Add additional device slots to Linode Config and Rescue Dialog to match new API limits ([#12791](https://github.com/linode/manager/pull/12791))
8080
- Add Firewall option to the Add Node Pool Drawer for LKE Enterprise Kubernetes Clusters ([#12793](https://github.com/linode/manager/pull/12793))
8181
- CloudPulse-Metrics: Update CloudPulseRegionSelect.tsx to handle default linode region selection in firewalls contextual view ([#12805](https://github.com/linode/manager/pull/12805))
8282

packages/manager/src/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,3 +290,7 @@ export const DISALLOWED_IMAGE_REGIONS = [
290290
// Default tooltip text for actions without permission
291291
export const NO_PERMISSION_TOOLTIP_TEXT =
292292
'You do not have permission to perform this action.';
293+
294+
// Default device limit for Linode Configuration profiles. Configuration profiles can have have up to 64
295+
// devices depending on the Linode's RAM, but will always be able to have at least 8.
296+
export const DEFAULT_DEVICE_LIMIT = 8;

packages/manager/src/dev-tools/FeatureFlagTool.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const options: { flag: keyof Flags; label: string }[] = [
2626
{ flag: 'apl', label: 'Akamai App Platform' },
2727
{ flag: 'aplGeneralAvailability', label: 'Akamai App Platform GA' },
2828
{ flag: 'blockStorageEncryption', label: 'Block Storage Encryption (BSE)' },
29+
{ flag: 'blockStorageVolumeLimit', label: 'Block Storage Volume Limit' },
2930
{ flag: 'cloudNat', label: 'Cloud NAT' },
3031
{ flag: 'disableLargestGbPlans', label: 'Disable Largest GB Plans' },
3132
{ flag: 'gecko2', label: 'Gecko' },

packages/manager/src/featureFlags.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export interface Flags {
144144
apl: boolean;
145145
aplGeneralAvailability: boolean;
146146
blockStorageEncryption: boolean;
147+
blockStorageVolumeLimit: boolean;
147148
cloudManagerDesignUpdatesBanner: DesignUpdatesBannerFlag;
148149
cloudNat: CloudNatFlag;
149150
databaseAdvancedConfig: boolean;

packages/manager/src/features/Linodes/LinodesDetail/LinodeConfigs/LinodeConfigDialog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ import {
6868
StyledFormGroup,
6969
StyledRadioGroup,
7070
} from './LinodeConfigDialog.styles';
71-
import { getPrimaryInterfaceIndex } from './utilities';
71+
import { getPrimaryInterfaceIndex, useGetDeviceLimit } from './utilities';
7272

7373
import type { ExtendedInterface } from '../LinodeSettings/InterfaceSelect';
7474
import type {
@@ -243,7 +243,7 @@ export const LinodeConfigDialog = (props: Props) => {
243243
// eslint-disable-next-line no-console
244244
console.warn('Invalid memory value:', availableMemory);
245245
}
246-
const deviceLimit = Math.max(8, Math.min(availableMemory / 1024, 64));
246+
const deviceLimit = useGetDeviceLimit(availableMemory);
247247

248248
const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled();
249249

packages/manager/src/features/Linodes/LinodesDetail/LinodeConfigs/utilities.test.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { linodeConfigInterfaceFactory } from '@linode/utilities';
2+
import { renderHook } from '@testing-library/react';
23

3-
import { getPrimaryInterfaceIndex } from './utilities';
4+
import { wrapWithTheme } from 'src/utilities/testHelpers';
5+
6+
import { getPrimaryInterfaceIndex, useGetDeviceLimit } from './utilities';
47

58
describe('getPrimaryInterfaceIndex', () => {
69
it('returns null if there are no interfaces', () => {
@@ -34,3 +37,36 @@ describe('getPrimaryInterfaceIndex', () => {
3437
expect(getPrimaryInterfaceIndex(interfaces)).toBe(null);
3538
});
3639
});
40+
41+
describe('useGetDeviceLimit', () => {
42+
it.each([131072, 65536, 16384, 1024])(
43+
'should always return 8 as the device limit',
44+
(value) => {
45+
const { result } = renderHook(() => useGetDeviceLimit(value), {
46+
wrapper: (ui) =>
47+
wrapWithTheme(ui.children, {
48+
flags: { blockStorageVolumeLimit: false },
49+
}),
50+
});
51+
expect(result.current).toEqual(8);
52+
}
53+
);
54+
55+
it.each([
56+
[131072, 64],
57+
[65536, 64],
58+
[16384, 16],
59+
[1024, 8],
60+
])(
61+
'should calculate the correct device limit for %d ram to be %d',
62+
(value, expected) => {
63+
const { result } = renderHook(() => useGetDeviceLimit(value), {
64+
wrapper: (ui) =>
65+
wrapWithTheme(ui.children, {
66+
flags: { blockStorageVolumeLimit: true },
67+
}),
68+
});
69+
expect(result.current).toEqual(expected);
70+
}
71+
);
72+
});

packages/manager/src/features/Linodes/LinodesDetail/LinodeConfigs/utilities.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { isEmpty } from '@linode/api-v4';
22

3+
import { DEFAULT_DEVICE_LIMIT } from 'src/constants';
4+
import { useFlags } from 'src/hooks/useFlags';
5+
36
import type { Interface } from '@linode/api-v4';
47

58
/**
@@ -47,3 +50,20 @@ export const getPrimaryInterfaceIndex = (interfaces: Interface[]) => {
4750
// As an example, this is the case when a Linode only has a VLAN interface.
4851
return null;
4952
};
53+
54+
/**
55+
* Determines the maximum available Linodes allowed for a configuration profile
56+
*
57+
* returns MAX(8, MIN(ram / 1024, 64))
58+
*
59+
* @param ram the Linode's available ram
60+
* @returns the device limit allowed
61+
*/
62+
export const useGetDeviceLimit = (ram: number) => {
63+
const flags = useFlags();
64+
if (flags.blockStorageVolumeLimit) {
65+
return Math.max(DEFAULT_DEVICE_LIMIT, Math.min(ram / 1024, 64));
66+
}
67+
68+
return DEFAULT_DEVICE_LIMIT;
69+
};

packages/manager/src/features/Linodes/LinodesDetail/LinodeRescue/StandardRescueDialog.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import * as React from 'react';
2323
import { useEventsPollingActions } from 'src/queries/events/events';
2424

2525
import { deviceSlots } from '../LinodeConfigs/constants';
26+
import { useGetDeviceLimit } from '../LinodeConfigs/utilities';
2627
import { LinodePermissionsError } from '../LinodePermissionsError';
2728
import { DeviceSelection } from './DeviceSelection';
2829
import { RescueDescription } from './RescueDescription';
@@ -79,7 +80,7 @@ export const StandardRescueDialog = (props: Props) => {
7980
// eslint-disable-next-line no-console
8081
console.warn('Invalid memory value:', availableMemory);
8182
}
82-
const overallDeviceLimit = Math.max(8, Math.min(availableMemory / 1024, 64));
83+
const overallDeviceLimit = useGetDeviceLimit(availableMemory);
8384
const rescueDeviceLimit = overallDeviceLimit - 2;
8485

8586
const {

0 commit comments

Comments
 (0)