Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion packages/manager/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- Linked Node Pool firewall in Node Pool footer for LKE-E clusters ([#12779](https://github.com/linode/manager/pull/12779))
- IAM RBAC: Implement IAM RBAC permissions for NodeBalancer ([#12780](https://github.com/linode/manager/pull/12780))
- IAM RBAC: Implement IAM RBAC permissions for NodeBalancer summary tab ([#12790](https://github.com/linode/manager/pull/12790))
- Additional device slots to Linode Config and Rescue Dialog to match new API limits ([#12791](https://github.com/linode/manager/pull/12791))

### Changed:

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

Expand Down
4 changes: 4 additions & 0 deletions packages/manager/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,7 @@ export const DISALLOWED_IMAGE_REGIONS = [
// Default tooltip text for actions without permission
export const NO_PERMISSION_TOOLTIP_TEXT =
'You do not have permission to perform this action.';

// Default device limit for Linode Configuration profiles. Configuration profiles can have have up to 64
// devices depending on the Linode's RAM, but will always be able to have at least 8.
export const DEFAULT_DEVICE_LIMIT = 8;
1 change: 1 addition & 0 deletions packages/manager/src/dev-tools/FeatureFlagTool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const options: { flag: keyof Flags; label: string }[] = [
{ flag: 'apl', label: 'Akamai App Platform' },
{ flag: 'aplGeneralAvailability', label: 'Akamai App Platform GA' },
{ flag: 'blockStorageEncryption', label: 'Block Storage Encryption (BSE)' },
{ flag: 'blockStorageVolumeLimit', label: 'Block Storage Volume Limit' },
{ flag: 'cloudNat', label: 'Cloud NAT' },
{ flag: 'disableLargestGbPlans', label: 'Disable Largest GB Plans' },
{ flag: 'gecko2', label: 'Gecko' },
Expand Down
1 change: 1 addition & 0 deletions packages/manager/src/featureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export interface Flags {
apl: boolean;
aplGeneralAvailability: boolean;
blockStorageEncryption: boolean;
blockStorageVolumeLimit: boolean;
cloudManagerDesignUpdatesBanner: DesignUpdatesBannerFlag;
cloudNat: CloudNatFlag;
databaseAdvancedConfig: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ import {
StyledFormGroup,
StyledRadioGroup,
} from './LinodeConfigDialog.styles';
import { getPrimaryInterfaceIndex } from './utilities';
import { getPrimaryInterfaceIndex, useGetDeviceLimit } from './utilities';

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

const { isLinodeInterfacesEnabled } = useIsLinodeInterfacesEnabled();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { linodeConfigInterfaceFactory } from '@linode/utilities';
import { renderHook } from '@testing-library/react';

import { getPrimaryInterfaceIndex } from './utilities';
import { wrapWithTheme } from 'src/utilities/testHelpers';

import { getPrimaryInterfaceIndex, useGetDeviceLimit } from './utilities';

describe('getPrimaryInterfaceIndex', () => {
it('returns null if there are no interfaces', () => {
Expand Down Expand Up @@ -34,3 +37,36 @@
expect(getPrimaryInterfaceIndex(interfaces)).toBe(null);
});
});

describe('useGetDeviceLimit', () => {
it.each([131072, 65536, 16384, 1024])(
'should always return 8 as the device limit',
(value) => {
const { result } = renderHook(() => useGetDeviceLimit(value), {
wrapper: (ui) =>
wrapWithTheme(ui.children, {

Check warning on line 47 in packages/manager/src/features/Linodes/LinodesDetail/LinodeConfigs/utilities.test.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Avoid direct Node access. Prefer using the methods from Testing Library. Raw Output: {"ruleId":"testing-library/no-node-access","severity":1,"message":"Avoid direct Node access. Prefer using the methods from Testing Library.","line":47,"column":28,"nodeType":"MemberExpression","messageId":"noNodeAccess"}

Check warning on line 47 in packages/manager/src/features/Linodes/LinodesDetail/LinodeConfigs/utilities.test.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Avoid direct Node access. Prefer using the methods from Testing Library. Raw Output: {"ruleId":"testing-library/no-node-access","severity":1,"message":"Avoid direct Node access. Prefer using the methods from Testing Library.","line":47,"column":28,"nodeType":"MemberExpression","messageId":"noNodeAccess"}
flags: { blockStorageVolumeLimit: false },
}),
});
expect(result.current).toEqual(8);
}
);

it.each([
[131072, 64],
[65536, 64],
[16384, 16],
[1024, 8],
])(
'should calculate the correct device limit for %d ram to be %d',
(value, expected) => {
const { result } = renderHook(() => useGetDeviceLimit(value), {
wrapper: (ui) =>
wrapWithTheme(ui.children, {

Check warning on line 65 in packages/manager/src/features/Linodes/LinodesDetail/LinodeConfigs/utilities.test.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Avoid direct Node access. Prefer using the methods from Testing Library. Raw Output: {"ruleId":"testing-library/no-node-access","severity":1,"message":"Avoid direct Node access. Prefer using the methods from Testing Library.","line":65,"column":28,"nodeType":"MemberExpression","messageId":"noNodeAccess"}

Check warning on line 65 in packages/manager/src/features/Linodes/LinodesDetail/LinodeConfigs/utilities.test.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Avoid direct Node access. Prefer using the methods from Testing Library. Raw Output: {"ruleId":"testing-library/no-node-access","severity":1,"message":"Avoid direct Node access. Prefer using the methods from Testing Library.","line":65,"column":28,"nodeType":"MemberExpression","messageId":"noNodeAccess"}
flags: { blockStorageVolumeLimit: true },
}),
});
expect(result.current).toEqual(expected);
}
);
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { isEmpty } from '@linode/api-v4';

import { DEFAULT_DEVICE_LIMIT } from 'src/constants';
import { useFlags } from 'src/hooks/useFlags';

import type { Interface } from '@linode/api-v4';

/**
Expand Down Expand Up @@ -47,3 +50,20 @@ export const getPrimaryInterfaceIndex = (interfaces: Interface[]) => {
// As an example, this is the case when a Linode only has a VLAN interface.
return null;
};

/**
* Determines the maximum available Linodes allowed for a configuration profile
*
* returns MAX(8, MIN(ram / 1024, 64))
*
* @param ram the Linode's available ram
* @returns the device limit allowed
*/
export const useGetDeviceLimit = (ram: number) => {
const flags = useFlags();
if (flags.blockStorageVolumeLimit) {
return Math.max(DEFAULT_DEVICE_LIMIT, Math.min(ram / 1024, 64));
}

return DEFAULT_DEVICE_LIMIT;
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import * as React from 'react';
import { useEventsPollingActions } from 'src/queries/events/events';

import { deviceSlots } from '../LinodeConfigs/constants';
import { useGetDeviceLimit } from '../LinodeConfigs/utilities';
import { LinodePermissionsError } from '../LinodePermissionsError';
import { DeviceSelection } from './DeviceSelection';
import { RescueDescription } from './RescueDescription';
Expand Down Expand Up @@ -79,7 +80,7 @@ export const StandardRescueDialog = (props: Props) => {
// eslint-disable-next-line no-console
console.warn('Invalid memory value:', availableMemory);
}
const overallDeviceLimit = Math.max(8, Math.min(availableMemory / 1024, 64));
const overallDeviceLimit = useGetDeviceLimit(availableMemory);
const rescueDeviceLimit = overallDeviceLimit - 2;

const {
Expand Down