diff --git a/packages/api-v4/.changeset/pr-10651-changed-1720544132377.md b/packages/api-v4/.changeset/pr-10651-changed-1720544132377.md new file mode 100644 index 00000000000..877f1769d96 --- /dev/null +++ b/packages/api-v4/.changeset/pr-10651-changed-1720544132377.md @@ -0,0 +1,5 @@ +--- +"@linode/api-v4": Changed +--- + +Breaking: change Placement Group `affinity_type` to `placement_group_type` ([#10651](https://github.com/linode/manager/pull/10651)) diff --git a/packages/api-v4/.changeset/pr-10651-changed-1720544224086.md b/packages/api-v4/.changeset/pr-10651-changed-1720544224086.md new file mode 100644 index 00000000000..c844b930e47 --- /dev/null +++ b/packages/api-v4/.changeset/pr-10651-changed-1720544224086.md @@ -0,0 +1,5 @@ +--- +"@linode/api-v4": Changed +--- + +Breaking: change Placement Group `is_strict` to `placement_group_policy` ([#10651](https://github.com/linode/manager/pull/10651)) diff --git a/packages/api-v4/src/placement-groups/types.ts b/packages/api-v4/src/placement-groups/types.ts index e092d401ff3..4b79bba15fe 100644 --- a/packages/api-v4/src/placement-groups/types.ts +++ b/packages/api-v4/src/placement-groups/types.ts @@ -1,29 +1,34 @@ import type { Region } from '../regions/types'; -export const AFFINITY_TYPES = { +export const PLACEMENT_GROUP_TYPES = { 'affinity:local': 'Affinity', 'anti_affinity:local': 'Anti-affinity', } as const; -export type AffinityType = keyof typeof AFFINITY_TYPES; -export type AffinityTypeEnforcement = 'Strict' | 'Flexible'; +export const PLACEMENT_GROUP_POLICIES = { + strict: 'Strict', + flexible: 'Flexible', +} as const; + +export type PlacementGroupType = keyof typeof PLACEMENT_GROUP_TYPES; +export type PlacementGroupPolicy = keyof typeof PLACEMENT_GROUP_POLICIES; export interface PlacementGroup { id: number; label: string; region: Region['id']; - affinity_type: AffinityType; + placement_group_type: PlacementGroupType; is_compliant: boolean; members: { linode_id: number; is_compliant: boolean; }[]; - is_strict: boolean; + placement_group_policy: PlacementGroupPolicy; } export type PlacementGroupPayload = Pick< PlacementGroup, - 'id' | 'label' | 'affinity_type' | 'is_strict' + 'id' | 'label' | 'placement_group_type' | 'placement_group_policy' >; export interface CreatePlacementGroupPayload diff --git a/packages/manager/.changeset/pr-10651-changed-1720544282083.md b/packages/manager/.changeset/pr-10651-changed-1720544282083.md new file mode 100644 index 00000000000..fcfe9893e73 --- /dev/null +++ b/packages/manager/.changeset/pr-10651-changed-1720544282083.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Changed +--- + +Update Placement Group affinity labels and nomenclature ([#10651](https://github.com/linode/manager/pull/10651)) diff --git a/packages/manager/cypress/e2e/core/placementGroups/create-linode-with-placement-groups.spec.ts b/packages/manager/cypress/e2e/core/placementGroups/create-linode-with-placement-groups.spec.ts index c0ad5c28d4c..554bf09e06d 100644 --- a/packages/manager/cypress/e2e/core/placementGroups/create-linode-with-placement-groups.spec.ts +++ b/packages/manager/cypress/e2e/core/placementGroups/create-linode-with-placement-groups.spec.ts @@ -18,7 +18,7 @@ import { mockGetPlacementGroups, } from 'support/intercepts/placement-groups'; import { randomString } from 'support/util/random'; -import { CANNOT_CHANGE_AFFINITY_TYPE_ENFORCEMENT_MESSAGE } from 'src/features/PlacementGroups/constants'; +import { CANNOT_CHANGE_PLACEMENT_GROUP_POLICY_MESSAGE } from 'src/features/PlacementGroups/constants'; import type { Region } from '@linode/api-v4'; import type { Flags } from 'src/featureFlags'; @@ -119,8 +119,8 @@ describe('Linode create flow with Placement Group', () => { const mockPlacementGroup = placementGroupFactory.build({ label: 'pg-1-us-east', region: mockRegions[0].id, - affinity_type: 'anti_affinity:local', - is_strict: true, + placement_group_type: 'anti_affinity:local', + placement_group_policy: 'strict', is_compliant: true, }); @@ -133,10 +133,10 @@ describe('Linode create flow with Placement Group', () => { .within(() => { // Confirm that the drawer contains the expected default information. // - A selection region - // - An Affinity Type Enforcement message + // - An Placement Group Policy message // - a disabled "Create Placement Group" button. cy.findByText('Newark, NJ (us-east)').should('be.visible'); - cy.findByText(CANNOT_CHANGE_AFFINITY_TYPE_ENFORCEMENT_MESSAGE).should( + cy.findByText(CANNOT_CHANGE_PLACEMENT_GROUP_POLICY_MESSAGE).should( 'be.visible' ); ui.buttonGroup @@ -156,8 +156,10 @@ describe('Linode create flow with Placement Group', () => { // Wait for outgoing API request and confirm that payload contains expected data. cy.wait('@createPlacementGroup').then((xhr) => { const requestPayload = xhr.request?.body; - expect(requestPayload['affinity_type']).to.equal('anti_affinity:local'); - expect(requestPayload['is_strict']).to.equal(true); + expect(requestPayload['placement_group_type']).to.equal( + 'anti_affinity:local' + ); + expect(requestPayload['placement_group_policy']).to.equal('strict'); expect(requestPayload['label']).to.equal(mockPlacementGroup.label); expect(requestPayload['region']).to.equal(mockRegions[0].id); }); diff --git a/packages/manager/cypress/e2e/core/placementGroups/create-placement-groups.spec.ts b/packages/manager/cypress/e2e/core/placementGroups/create-placement-groups.spec.ts index ceb4b9669b9..5a833e72296 100644 --- a/packages/manager/cypress/e2e/core/placementGroups/create-placement-groups.spec.ts +++ b/packages/manager/cypress/e2e/core/placementGroups/create-placement-groups.spec.ts @@ -17,7 +17,7 @@ import { import { randomLabel, randomNumber } from 'support/util/random'; import { chooseRegion } from 'support/util/regions'; -import { CANNOT_CHANGE_AFFINITY_TYPE_ENFORCEMENT_MESSAGE } from 'src/features/PlacementGroups/constants'; +import { CANNOT_CHANGE_PLACEMENT_GROUP_POLICY_MESSAGE } from 'src/features/PlacementGroups/constants'; const mockAccount = accountFactory.build(); @@ -65,8 +65,8 @@ describe('Placement Group create flow', () => { const mockPlacementGroup = placementGroupFactory.build({ label: randomLabel(), region: mockPlacementGroupRegion.id, - affinity_type: 'anti_affinity:local', - is_strict: true, + placement_group_type: 'anti_affinity:local', + placement_group_policy: 'strict', is_compliant: true, }); @@ -103,7 +103,7 @@ describe('Placement Group create flow', () => { .type(`${mockPlacementGroupRegion.label}{enter}`); cy.findByText(placementGroupLimitMessage).should('be.visible'); - cy.findByText(CANNOT_CHANGE_AFFINITY_TYPE_ENFORCEMENT_MESSAGE).should( + cy.findByText(CANNOT_CHANGE_PLACEMENT_GROUP_POLICY_MESSAGE).should( 'be.visible' ); @@ -118,8 +118,10 @@ describe('Placement Group create flow', () => { // the options/data chosen by the user. cy.wait('@createPlacementGroup').then((xhr) => { const requestPayload = xhr.request?.body; - expect(requestPayload['affinity_type']).to.equal('anti_affinity:local'); - expect(requestPayload['is_strict']).to.equal(true); + expect(requestPayload['placement_group_type']).to.equal( + 'anti_affinity:local' + ); + expect(requestPayload['placement_group_policy']).to.equal('strict'); expect(requestPayload['label']).to.equal(mockPlacementGroup.label); expect(requestPayload['region']).to.equal(mockPlacementGroupRegion.id); }); diff --git a/packages/manager/cypress/e2e/core/placementGroups/delete-placement-groups.spec.ts b/packages/manager/cypress/e2e/core/placementGroups/delete-placement-groups.spec.ts index c1dfd05220a..cae1fb1f4ef 100644 --- a/packages/manager/cypress/e2e/core/placementGroups/delete-placement-groups.spec.ts +++ b/packages/manager/cypress/e2e/core/placementGroups/delete-placement-groups.spec.ts @@ -21,7 +21,7 @@ import { linodeFactory, placementGroupFactory, } from 'src/factories'; - +import { headers as emptyStatePageHeaders } from 'src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsLandingEmptyStateData'; import type { Flags } from 'src/featureFlags'; import { randomLabel, randomNumber } from 'support/util/random'; import { chooseRegion } from 'support/util/regions'; @@ -41,8 +41,7 @@ const unassignWarning = 'You need to unassign all Linodes before deleting a placement group.'; // Landing page empty state text. -const emptyStateMessage = - 'Control the physical placement or distribution of Linode instances within a data center or availability zone.'; +const emptyStateMessage = emptyStatePageHeaders.description; // Error message that when an unexpected error occurs. const PlacementGroupErrorMessage = 'An unknown error has occurred.'; diff --git a/packages/manager/cypress/e2e/core/placementGroups/placement-groups-landing-page.spec.ts b/packages/manager/cypress/e2e/core/placementGroups/placement-groups-landing-page.spec.ts index 83bf7947603..1b2fb9f1e7c 100644 --- a/packages/manager/cypress/e2e/core/placementGroups/placement-groups-landing-page.spec.ts +++ b/packages/manager/cypress/e2e/core/placementGroups/placement-groups-landing-page.spec.ts @@ -73,9 +73,9 @@ describe('VM Placement landing page', () => { id: randomNumber(), label: randomLabel(), region: mockPlacementGroupCompliantRegion.id, - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', is_compliant: true, - is_strict: false, + placement_group_policy: 'flexible', members: [], }); @@ -83,9 +83,9 @@ describe('VM Placement landing page', () => { id: randomNumber(), label: randomLabel(), region: mockPlacementGroupNoncompliantRegion.id, - affinity_type: 'affinity:local', + placement_group_type: 'affinity:local', is_compliant: false, - is_strict: true, + placement_group_policy: 'strict', members: [ { linode_id: mockPlacementGroupLinode.id, is_compliant: false }, ], diff --git a/packages/manager/cypress/e2e/core/placementGroups/placement-groups-linode-assignment.spec.ts b/packages/manager/cypress/e2e/core/placementGroups/placement-groups-linode-assignment.spec.ts index b8d75101965..882febd4cc1 100644 --- a/packages/manager/cypress/e2e/core/placementGroups/placement-groups-linode-assignment.spec.ts +++ b/packages/manager/cypress/e2e/core/placementGroups/placement-groups-linode-assignment.spec.ts @@ -188,7 +188,7 @@ describe('Placement Groups Linode assignment', () => { * - Confirms that UI automatically updates and shows a warning indicating the non-compliance status. * - Confirms that non-compliance status is indicated on the Placement Group landing page. */ - it('can assign non-compliant Linode with weak enforcement', () => { + it('can assign non-compliant Linode with flexible placement group policy', () => { const mockPlacementGroupRegion = chooseRegion({ regions: mockRegions }); const mockLinode = linodeFactory.build({ id: randomNumber(10000, 99999), @@ -202,7 +202,7 @@ describe('Placement Groups Linode assignment', () => { members: [], region: mockPlacementGroupRegion.id, is_compliant: true, - is_strict: false, + placement_group_policy: 'flexible', }); const mockPlacementGroupAfterAssignment = { @@ -231,7 +231,7 @@ describe('Placement Groups Linode assignment', () => { cy.visitWithLogin(`/placement-groups/${mockPlacementGroup.id}`); cy.wait('@getPlacementGroup'); - // Confirm that weak affinity enforcement type is indicated on page, then + // Confirm that `flexible` Placement Group Policy is indicated on page, then // initiate Linode assignment. cy.findByText('Flexible'); @@ -288,9 +288,9 @@ describe('Placement Groups Linode assignment', () => { /** * - Confirms UI flow when attempting to assign non-compliant Linode using mock API data. - * - Confirms graceful error handling when Placement Group enforcement is strict. + * - Confirms graceful error handling when Placement Group Policy is `strict`. */ - it('cannot assign non-compliant Linode with strict enforcement', () => { + it('cannot assign non-compliant Linode with `strict` Placement Group Policy', () => { const mockPlacementGroupRegion = chooseRegion({ regions: mockRegions }); const mockLinode = linodeFactory.build({ id: randomNumber(10000, 99999), @@ -304,7 +304,7 @@ describe('Placement Groups Linode assignment', () => { members: [], region: mockPlacementGroupRegion.id, is_compliant: true, - is_strict: true, + placement_group_policy: 'strict', }); const complianceErrorMessage = `Assignment would break Placement Group's compliance, non compliant Linode IDs: [${mockLinode.id}]`; @@ -322,7 +322,7 @@ describe('Placement Groups Linode assignment', () => { cy.visitWithLogin(`/placement-groups/${mockPlacementGroup.id}`); cy.wait('@getPlacementGroup'); - // Confirm that weak affinity enforcement type is indicated on page, then + // Confirm that `strict` Placement Group Policy is indicated on page, then // initiate Linode assignment. cy.findByText('Strict'); diff --git a/packages/manager/cypress/e2e/core/placementGroups/update-placement-group-label.spec.ts b/packages/manager/cypress/e2e/core/placementGroups/update-placement-group-label.spec.ts index 5ee32465d36..6b9f172f397 100644 --- a/packages/manager/cypress/e2e/core/placementGroups/update-placement-group-label.spec.ts +++ b/packages/manager/cypress/e2e/core/placementGroups/update-placement-group-label.spec.ts @@ -49,9 +49,9 @@ describe('Placement Group update label flow', () => { id: randomNumber(), label: randomLabel(), region: mockPlacementGroupCompliantRegion.id, - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', is_compliant: true, - is_strict: false, + placement_group_policy: 'flexible', members: [], }); @@ -115,9 +115,9 @@ describe('Placement Group update label flow', () => { id: randomNumber(), label: randomLabel(), region: mockPlacementGroupCompliantRegion.id, - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', is_compliant: true, - is_strict: false, + placement_group_policy: 'flexible', members: [], }); diff --git a/packages/manager/src/__data__/linodes.ts b/packages/manager/src/__data__/linodes.ts index ab5ad7a97ca..2c12ef53df9 100644 --- a/packages/manager/src/__data__/linodes.ts +++ b/packages/manager/src/__data__/linodes.ts @@ -26,9 +26,9 @@ export const linode1: Linode = { label: 'test', lke_cluster_id: null, placement_group: { - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, - is_strict: true, + placement_group_policy: 'strict', label: 'pg-1', }, region: 'us-east', @@ -72,9 +72,9 @@ export const linode2: Linode = { label: 'another-test', lke_cluster_id: null, placement_group: { - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, - is_strict: true, + placement_group_policy: 'strict', label: 'pg-1', }, region: 'us-east', @@ -118,9 +118,9 @@ export const linode3: Linode = { label: 'another-test', lke_cluster_id: null, placement_group: { - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, - is_strict: true, + placement_group_policy: 'strict', label: 'pg-1', }, region: 'us-east', @@ -164,9 +164,9 @@ export const linode4: Linode = { label: 'another-test-eu', lke_cluster_id: null, placement_group: { - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, - is_strict: true, + placement_group_policy: 'strict', label: 'pg-1', }, region: 'eu-west', diff --git a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupSelectOption.tsx b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupSelectOption.tsx index bc9c85d1c94..3473c7273c7 100644 --- a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupSelectOption.tsx +++ b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupSelectOption.tsx @@ -1,4 +1,4 @@ -import { AFFINITY_TYPES, PlacementGroup } from '@linode/api-v4'; +import { PLACEMENT_GROUP_TYPES, PlacementGroup } from '@linode/api-v4'; import { visuallyHidden } from '@mui/utils'; import React from 'react'; @@ -73,7 +73,7 @@ export const PlacementGroupSelectOption = ({ right: selected ? 14 : 34, }} > - ({AFFINITY_TYPES[value.affinity_type]}) + ({PLACEMENT_GROUP_TYPES[value.placement_group_type]}) {disabled && ( diff --git a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.test.tsx b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.test.tsx index 5aa8c727be2..e1b25164191 100644 --- a/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.test.tsx +++ b/packages/manager/src/components/PlacementGroupsSelect/PlacementGroupsSelect.test.tsx @@ -34,10 +34,10 @@ describe('PlacementGroupSelect', () => { queryMocks.useAllPlacementGroupsQuery.mockReturnValue({ data: [ placementGroupFactory.build({ - affinity_type: 'affinity:local', + placement_group_type: 'affinity:local', id: 1, is_compliant: true, - is_strict: true, + placement_group_policy: 'strict', label: 'my-placement-group', members: [ { @@ -67,10 +67,10 @@ describe('PlacementGroupSelect', () => { queryMocks.useAllPlacementGroupsQuery.mockReturnValue({ data: [ placementGroupFactory.build({ - affinity_type: 'affinity:local', + placement_group_type: 'affinity:local', id: 1, is_compliant: true, - is_strict: true, + placement_group_policy: 'strict', label: 'my-placement-group', members: [ { diff --git a/packages/manager/src/factories/linodes.ts b/packages/manager/src/factories/linodes.ts index 41adb044a39..58badc05c70 100644 --- a/packages/manager/src/factories/linodes.ts +++ b/packages/manager/src/factories/linodes.ts @@ -265,7 +265,7 @@ export const linodeFactory = Factory.Sync.makeFactory({ label: Factory.each((i) => `linode-${i}`), lke_cluster_id: null, placement_group: placementGroupFactory.build({ - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, label: 'pg-1', }), diff --git a/packages/manager/src/factories/placementGroups.ts b/packages/manager/src/factories/placementGroups.ts index c3fa3b8dfea..dd13d13f6a4 100644 --- a/packages/manager/src/factories/placementGroups.ts +++ b/packages/manager/src/factories/placementGroups.ts @@ -8,10 +8,10 @@ import type { } from '@linode/api-v4'; export const placementGroupFactory = Factory.Sync.makeFactory({ - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: Factory.each((id) => id), is_compliant: Factory.each(() => pickRandom([true, false])), - is_strict: true, + placement_group_policy: 'strict', label: Factory.each((id) => `pg-${id}`), members: [ { @@ -56,8 +56,8 @@ export const placementGroupFactory = Factory.Sync.makeFactory({ export const createPlacementGroupPayloadFactory = Factory.Sync.makeFactory( { - affinity_type: 'anti_affinity:local', - is_strict: true, + placement_group_type: 'anti_affinity:local', + placement_group_policy: 'strict', label: Factory.each((id) => `mock-pg-${id}`), region: pickRandom(['us-east', 'us-southeast', 'ca-central']), } diff --git a/packages/manager/src/features/Linodes/LinodesCreate/AddonsPanel.test.tsx b/packages/manager/src/features/Linodes/LinodesCreate/AddonsPanel.test.tsx index 7c5041323ed..0012f4ba1db 100644 --- a/packages/manager/src/features/Linodes/LinodesCreate/AddonsPanel.test.tsx +++ b/packages/manager/src/features/Linodes/LinodesCreate/AddonsPanel.test.tsx @@ -64,9 +64,9 @@ const props: AddonsPanelProps = { label: 'test_instance', lke_cluster_id: null, placement_group: { - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, - is_strict: true, + placement_group_policy: 'strict', label: 'test', }, region: 'us-central', @@ -110,9 +110,9 @@ const props: AddonsPanelProps = { label: 'debian-ca-central', lke_cluster_id: null, placement_group: { - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, - is_strict: true, + placement_group_policy: 'strict', label: 'test', }, region: 'ca-central', @@ -155,9 +155,9 @@ const props: AddonsPanelProps = { label: 'almalinux-us-west', lke_cluster_id: null, placement_group: { - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, - is_strict: true, + placement_group_policy: 'strict', label: 'test', }, region: 'us-west', diff --git a/packages/manager/src/features/Linodes/LinodesCreate/LinodeCreateContainer.tsx b/packages/manager/src/features/Linodes/LinodesCreate/LinodeCreateContainer.tsx index 5e5bd9ff713..8c60c889991 100644 --- a/packages/manager/src/features/Linodes/LinodesCreate/LinodeCreateContainer.tsx +++ b/packages/manager/src/features/Linodes/LinodesCreate/LinodeCreateContainer.tsx @@ -635,7 +635,7 @@ class LinodeCreateContainer extends React.PureComponent { { field: 'placement_group', reason: `${this.state.placementGroupSelection?.label} (${ - this.state.placementGroupSelection?.affinity_type === + this.state.placementGroupSelection?.placement_group_type === 'affinity:local' ? 'Affinity' : 'Anti-affinity' diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsAffinityEnforcementRadioGroup.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupPolicyRadioGroup.tsx similarity index 63% rename from packages/manager/src/features/PlacementGroups/PlacementGroupsAffinityEnforcementRadioGroup.tsx rename to packages/manager/src/features/PlacementGroups/PlacementGroupPolicyRadioGroup.tsx index a171803e064..7360d1c22f0 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsAffinityEnforcementRadioGroup.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupPolicyRadioGroup.tsx @@ -8,20 +8,21 @@ import { Radio } from 'src/components/Radio/Radio'; import { RadioGroup } from 'src/components/RadioGroup'; import { Typography } from 'src/components/Typography'; -import { CANNOT_CHANGE_AFFINITY_TYPE_ENFORCEMENT_MESSAGE } from './constants'; +import { CANNOT_CHANGE_PLACEMENT_GROUP_POLICY_MESSAGE } from './constants'; +import type { PlacementGroup } from '@linode/api-v4'; import type { FormikHelpers } from 'formik'; interface Props { disabledPlacementGroupCreateButton: boolean; handleChange: (e: React.ChangeEvent) => void; setFieldValue: FormikHelpers['setFieldValue']; - value: boolean; + value: PlacementGroup['placement_group_policy']; } -export const PlacementGroupsAffinityTypeEnforcementRadioGroup = ( - props: Props -) => { +const ariaIdentifier = 'placement-group-policy-radio-group'; + +export const PlacementGroupPolicyRadioGroup = (props: Props) => { const { disabledPlacementGroupCreateButton, handleChange, @@ -31,45 +32,43 @@ export const PlacementGroupsAffinityTypeEnforcementRadioGroup = ( return ( - - Affinity Type Enforcement - + Placement Group Policy { handleChange(event); - setFieldValue('is_strict', event.target.value === 'true'); + setFieldValue('placement_group_policy', event.target.value); }} - id="affinity-type-enforcement-radio-group" - name="is_strict" + id={ariaIdentifier} + name="placement_group_policy" value={value} > Strict. You can’t assign Linodes if the preferred - container defined by your Affinity Type lacks capacity or is - unavailable (best practice). + container defined by your Placement Group Type lacks capacity or + is unavailable (best practice). } control={} disabled={disabledPlacementGroupCreateButton} - value={true} + value={'strict'} /> Flexible. You can assign Linodes, even if they’re - not in the preferred container defined by your Affinity Type, but - your placement group will be non-compliant. + not in the preferred container defined by your Placement Group + Type, but your placement group will be non-compliant. } control={} disabled={disabledPlacementGroupCreateButton} sx={{ mt: 2 }} - value={false} + value={'flexible'} /> diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsAffinityTypeSelect.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupTypeSelect.tsx similarity index 88% rename from packages/manager/src/features/PlacementGroups/PlacementGroupsAffinityTypeSelect.tsx rename to packages/manager/src/features/PlacementGroups/PlacementGroupTypeSelect.tsx index 65262a69776..58b3f23cb64 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsAffinityTypeSelect.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupTypeSelect.tsx @@ -7,7 +7,7 @@ import { Tooltip } from 'src/components/Tooltip'; import { Typography } from 'src/components/Typography'; import { PLACEMENT_GROUPS_DOCS_LINK } from './constants'; -import { affinityTypeOptions } from './utils'; +import { placementGroupTypeOptions } from './utils'; import type { FormikHelpers } from 'formik'; @@ -17,15 +17,15 @@ interface Props { setFieldValue: FormikHelpers['setFieldValue']; } -export const PlacementGroupsAffinityTypeSelect = (props: Props) => { +export const PlacementGroupTypeSelect = (props: Props) => { const { disabledPlacementGroupCreateButton, error, setFieldValue } = props; return ( option.value === 'anti_affinity:local' )} onChange={(_, value) => { - setFieldValue('affinity_type', value?.value ?? ''); + setFieldValue('placement_group_type', value?.value ?? ''); }} renderOption={(props, option) => { const isDisabledMenuItem = option.value === 'affinity:local'; @@ -86,9 +86,9 @@ export const PlacementGroupsAffinityTypeSelect = (props: Props) => { disableClearable={true} disabled={disabledPlacementGroupCreateButton} errorText={error} - label="Affinity Type" - options={affinityTypeOptions} - placeholder="Select an Affinity Type" + label="Placement Group Type" + options={placementGroupTypeOptions} + placeholder="Select an Placement Group Type" /> ); }; diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsAssignLinodesDrawer.test.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsAssignLinodesDrawer.test.tsx index 9395d3b5e09..756eda226fa 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsAssignLinodesDrawer.test.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsAssignLinodesDrawer.test.tsx @@ -120,7 +120,7 @@ describe('PlacementGroupsAssignLinodesDrawer', () => { const { getByPlaceholderText, getByRole, getByText } = renderWithTheme( { expect(getByLabelText('Label')).toBeEnabled(); expect(getByLabelText('Region')).toBeEnabled(); - expect(getByLabelText('Affinity Type')).toBeEnabled(); - expect(getByText('Affinity Type Enforcement')).toBeInTheDocument(); + expect(getByLabelText('Placement Group Type')).toBeEnabled(); + expect(getByText('Placement Group Policy')).toBeInTheDocument(); const radioInputs = getAllByRole('radio'); expect(radioInputs).toHaveLength(2); expect(radioInputs[0]).toBeChecked(); }); - it('Affinity Type select should have the correct options', async () => { + it('Placement Group Type select should have the correct options', async () => { const { getByPlaceholderText, getByText } = renderWithTheme( ); - const inputElement = getByPlaceholderText('Select an Affinity Type'); + const inputElement = getByPlaceholderText('Select an Placement Group Type'); fireEvent.focus(inputElement); fireEvent.change(inputElement, { target: { value: 'Affinity' } }); @@ -107,8 +107,8 @@ describe('PlacementGroupsCreateDrawer', () => { expect( queryMocks.useCreatePlacementGroup().mutateAsync ).toHaveBeenCalledWith({ - affinity_type: 'anti_affinity:local', - is_strict: true, + placement_group_type: 'anti_affinity:local', + placement_group_policy: 'strict', label: 'my-label', region: 'us-east', }); diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsCreateDrawer.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsCreateDrawer.tsx index 167f6fc107a..1c2c7e486a0 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsCreateDrawer.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsCreateDrawer.tsx @@ -8,6 +8,8 @@ import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { DescriptionList } from 'src/components/DescriptionList/DescriptionList'; import { Divider } from 'src/components/Divider'; import { Drawer } from 'src/components/Drawer'; +import { List } from 'src/components/List'; +import { ListItem } from 'src/components/ListItem'; import { Notice } from 'src/components/Notice/Notice'; import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; import { getNewRegionLabel } from 'src/components/RegionSelect/RegionSelect.utils'; @@ -26,15 +28,19 @@ import { getFormikErrorsFromAPIErrors } from 'src/utilities/formikErrorUtils'; import { scrollErrorIntoView } from 'src/utilities/scrollErrorIntoView'; import { MAXIMUM_NUMBER_OF_PLACEMENT_GROUPS_IN_REGION } from './constants'; -import { PlacementGroupsAffinityTypeEnforcementRadioGroup } from './PlacementGroupsAffinityEnforcementRadioGroup'; -import { PlacementGroupsAffinityTypeSelect } from './PlacementGroupsAffinityTypeSelect'; +import { PlacementGroupPolicyRadioGroup } from './PlacementGroupPolicyRadioGroup'; +import { PlacementGroupTypeSelect } from './PlacementGroupTypeSelect'; import { getMaxPGsPerCustomer, hasRegionReachedPlacementGroupCapacity, } from './utils'; import type { PlacementGroupsCreateDrawerProps } from './types'; -import type { CreatePlacementGroupPayload, Region } from '@linode/api-v4'; +import type { + CreatePlacementGroupPayload, + PlacementGroup, + Region, +} from '@linode/api-v4'; import type { FormikHelpers } from 'formik'; import type { DisableRegionOption } from 'src/components/RegionSelect/RegionSelect.types'; @@ -117,9 +123,9 @@ export const PlacementGroupsCreateDrawer = ( } = useFormik({ enableReinitialize: true, initialValues: { - affinity_type: 'anti_affinity:local', - is_strict: true, label: '', + placement_group_policy: 'strict' as PlacementGroup['placement_group_policy'], + placement_group_type: 'anti_affinity:local' as PlacementGroup['placement_group_type'], region: selectedRegionId ?? '', }, onSubmit: handleFormSubmit, @@ -128,7 +134,7 @@ export const PlacementGroupsCreateDrawer = ( validationSchema: createPlacementGroupSchema, }); - const generalError = error?.find((e) => !e.field)?.reason; + const hasApiError = error?.[0]?.reason; const selectedRegion = React.useMemo( () => regions?.find((region) => region.id == values.region), @@ -187,7 +193,21 @@ export const PlacementGroupsCreateDrawer = ( )}
- {generalError && } + {hasApiError && ( + + + {error.map((e) => ( + + - {e.reason} + + ))} + + + )} {selectedRegion && displayRegionHeaderText && ( )} - - { }), ]} selectedPlacementGroup={placementGroupFactory.build({ - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, label: 'PG-to-delete', members: [ @@ -84,7 +84,7 @@ describe('PlacementGroupsDeleteModal', () => { }), ]} selectedPlacementGroup={placementGroupFactory.build({ - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, label: 'PG-to-delete', members: [], diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.test.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.test.tsx index 020451d6c7b..30d11496904 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.test.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.test.tsx @@ -92,7 +92,7 @@ describe('PlacementGroupsLanding', () => { it('renders breadcrumbs, docs link and tabs', () => { queryMocks.usePlacementGroupQuery.mockReturnValue({ data: placementGroupFactory.build({ - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, is_compliant: true, label: 'My first PG', diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.tsx index 89f60601778..a08be23e7b8 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsDetail.tsx @@ -1,4 +1,4 @@ -import { AFFINITY_TYPES } from '@linode/api-v4'; +import { PLACEMENT_GROUP_TYPES } from '@linode/api-v4'; import * as React from 'react'; import { useParams } from 'react-router-dom'; @@ -75,10 +75,10 @@ export const PlacementGroupsDetail = () => { placementGroup?.members.some((pgLinode) => pgLinode.linode_id === linode.id) ); - const { affinity_type, label } = placementGroup; + const { placement_group_type, label } = placementGroup; const resetEditableLabel = () => { - return `${label} (${AFFINITY_TYPES[affinity_type]})`; + return `${label} (${PLACEMENT_GROUP_TYPES[placement_group_type]})`; }; const handleLabelEdit = (newLabel: string) => { diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.test.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.test.tsx index 341ad6ef7a7..73b8a19223e 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.test.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.test.tsx @@ -10,7 +10,7 @@ describe('PlacementGroups Summary', () => { const { getByTestId, getByText } = renderWithTheme( { expect(getByText('Placement Group Configuration')).toBeInTheDocument(); expect(getByText('Linodes')).toBeInTheDocument(); expect(getByTestId('HelpOutlineIcon')).toBeInTheDocument(); - expect(getByText('Affinity Type')).toBeInTheDocument(); + expect(getByText('Placement Group Type')).toBeInTheDocument(); expect(getByText('Region')).toBeInTheDocument(); }); }); diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.tsx index 55689fa703f..1778518729c 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetail/PlacementGroupsSummary/PlacementGroupsSummary.tsx @@ -1,4 +1,7 @@ -import { AFFINITY_TYPES } from '@linode/api-v4'; +import { + PLACEMENT_GROUP_TYPES, + PLACEMENT_GROUP_POLICIES, +} from '@linode/api-v4'; import { useTheme } from '@mui/material'; import { styled } from '@mui/material/styles'; import * as React from 'react'; @@ -14,7 +17,6 @@ import { PLACEMENT_GROUP_TOOLTIP_TEXT, PLACEMENT_GROUPS_DOCS_LINK, } from '../../constants'; -import { getAffinityTypeEnforcement } from '../../utils'; import type { PlacementGroup, Region } from '@linode/api-v4'; @@ -62,18 +64,20 @@ export const PlacementGroupsSummary = (props: Props) => { tooltip: { text: PLACEMENT_GROUP_TOOLTIP_TEXT, width: 275 }, }, { - description: AFFINITY_TYPES[placementGroup?.affinity_type], - title: 'Affinity Type', + description: + PLACEMENT_GROUP_TYPES[placementGroup?.placement_group_type], + title: 'Placement Group Type', }, { description: region?.label ?? 'Unknown', title: 'Region', }, { - description: getAffinityTypeEnforcement( - placementGroup?.is_strict - ), - title: 'Affinity Type Enforcement', + description: + PLACEMENT_GROUP_POLICIES[ + placementGroup?.placement_group_policy + ], + title: 'Placement Group Policy', }, ]} displayMode="grid" diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetailPanel.test.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetailPanel.test.tsx index 3b073403274..b788bcd91d8 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsDetailPanel.test.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsDetailPanel.test.tsx @@ -61,10 +61,10 @@ describe('PlacementGroupsDetailPanel', () => { queryMocks.useAllPlacementGroupsQuery.mockReturnValue({ data: [ placementGroupFactory.build({ - affinity_type: 'affinity:local', + placement_group_type: 'affinity:local', id: 1, is_compliant: true, - is_strict: true, + placement_group_policy: 'strict', label: 'my-placement-group', members: [ { diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsEditDrawer.test.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsEditDrawer.test.tsx index ffd0dc56c36..9c039a125e8 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsEditDrawer.test.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsEditDrawer.test.tsx @@ -37,7 +37,7 @@ describe('PlacementGroupsCreateDrawer', () => { const { getByLabelText, getByRole, getByText } = renderWithTheme( ({ usePlacementGroupsQuery: vi.fn().mockReturnValue({}), @@ -87,11 +88,7 @@ describe('PlacementGroupsLanding', () => { const { getByText } = renderWithTheme(); - expect( - getByText( - 'Control the physical placement or distribution of Linode instances within a data center or availability zone.' - ) - ).toBeInTheDocument(); + expect(getByText(headers.description)).toBeInTheDocument(); }); it('should render placement group Getting Started Guides on landing page with empty state', () => { diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsLanding.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsLanding.tsx index 154e9cc6621..92d7d75778d 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsLanding.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsLanding.tsx @@ -215,23 +215,23 @@ export const PlacementGroupsLanding = React.memo(() => { - Affinity Type + Placement Group Type - Affinity Type Enforcement + Placement Group Policy Linodes diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsLandingEmptyStateData.ts b/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsLandingEmptyStateData.ts index c06bbe7b6a5..f8c81034424 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsLandingEmptyStateData.ts +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsLandingEmptyStateData.ts @@ -11,7 +11,7 @@ import type { export const headers: ResourcesHeaders = { description: - 'Control the physical placement or distribution of Linode instances within a data center or availability zone.', + 'Control the physical placement of compute instances within a compute region.', subtitle: '', title: PLACEMENT_GROUP_LABEL, }; diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsRow.test.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsRow.test.tsx index d84a2b78b46..54ba5906a06 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsRow.test.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsRow.test.tsx @@ -22,7 +22,7 @@ const linode = linodeFactory.build({ }); const placementGroup = placementGroupFactory.build({ - affinity_type: 'anti_affinity:local', + placement_group_type: 'anti_affinity:local', id: 1, is_compliant: false, label: 'group 1', diff --git a/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsRow.tsx b/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsRow.tsx index 2664c099451..a2d4ae43b58 100644 --- a/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsRow.tsx +++ b/packages/manager/src/features/PlacementGroups/PlacementGroupsLanding/PlacementGroupsRow.tsx @@ -1,4 +1,7 @@ -import { AFFINITY_TYPES } from '@linode/api-v4'; +import { + PLACEMENT_GROUP_TYPES, + PLACEMENT_GROUP_POLICIES, +} from '@linode/api-v4'; import React from 'react'; import { Hidden } from 'src/components/Hidden'; @@ -11,7 +14,6 @@ import { TableRow } from 'src/components/TableRow'; import { TextTooltip } from 'src/components/TextTooltip'; import { Typography } from 'src/components/Typography'; -import { getAffinityTypeEnforcement } from '../utils'; import { StyledWarningIcon } from './PlacementGroupsRow.styles'; import type { Linode, PlacementGroup, Region } from '@linode/api-v4'; @@ -37,11 +39,11 @@ export const PlacementGroupsRow = React.memo( region, } = props; const { - affinity_type, id, is_compliant, - is_strict, label, + placement_group_policy, + placement_group_type, } = placementGroup; const actions: Action[] = [ { @@ -72,10 +74,12 @@ export const PlacementGroupsRow = React.memo( )} - {AFFINITY_TYPES[affinity_type]} + {PLACEMENT_GROUP_TYPES[placement_group_type]} - {getAffinityTypeEnforcement(is_strict)} + + {PLACEMENT_GROUP_POLICIES[placement_group_policy]} + {assignedLinodes?.length === 0 ? ( diff --git a/packages/manager/src/features/PlacementGroups/constants.ts b/packages/manager/src/features/PlacementGroups/constants.ts index a23f7f17886..973bbe2241f 100644 --- a/packages/manager/src/features/PlacementGroups/constants.ts +++ b/packages/manager/src/features/PlacementGroups/constants.ts @@ -7,7 +7,7 @@ export const MAX_NUMBER_OF_LINODES_IN_PLACEMENT_GROUP_MESSAGE = export const PLACEMENT_GROUP_LINODES_ERROR_MESSAGE = 'There was an error loading Linodes for this Placement Group.'; -export const PLACEMENT_GROUP_TOOLTIP_TEXT = `The Affinity Type and Region you selected determine the maximum number of Linodes per placement group.`; +export const PLACEMENT_GROUP_TOOLTIP_TEXT = `The Placement Group Type and Region you selected determine the maximum number of Linodes per placement group.`; export const PLACEMENT_GROUP_SELECT_TOOLTIP_COPY = ` Add your Linode to a group to best meet your needs. @@ -25,8 +25,8 @@ export const NO_PLACEMENT_GROUPS_IN_SELECTED_REGION_MESSAGE = export const NO_REGIONS_SUPPORT_PLACEMENT_GROUPS_MESSAGE = 'No regions currently support Placement Groups.'; -export const CANNOT_CHANGE_AFFINITY_TYPE_ENFORCEMENT_MESSAGE = - 'Once you create a placement group, you cannot change its Affinity Type Enforcement setting.'; +export const CANNOT_CHANGE_PLACEMENT_GROUP_POLICY_MESSAGE = + 'Once you create a placement group, you cannot change its Placement Group Policy.'; // Links export const PLACEMENT_GROUPS_DOCS_LINK = diff --git a/packages/manager/src/features/PlacementGroups/utils.test.ts b/packages/manager/src/features/PlacementGroups/utils.test.ts index 28e76b68c9e..3c44ddc531b 100644 --- a/packages/manager/src/features/PlacementGroups/utils.test.ts +++ b/packages/manager/src/features/PlacementGroups/utils.test.ts @@ -7,13 +7,12 @@ import { } from 'src/factories'; import { - affinityTypeOptions, - getAffinityTypeEnforcement, getLinodesFromAllPlacementGroups, getMaxPGsPerCustomer, getPlacementGroupLinodes, hasPlacementGroupReachedCapacity, hasRegionReachedPlacementGroupCapacity, + placementGroupTypeOptions, useIsPlacementGroupsEnabled, } from './utils'; @@ -55,7 +54,7 @@ const initialLinodeData = [ describe('affinityTypeOptions', () => { it('returns an array of objects with label and value properties', () => { - expect(affinityTypeOptions).toEqual( + expect(placementGroupTypeOptions).toEqual( expect.arrayContaining([ expect.objectContaining({ label: expect.any(String), @@ -128,16 +127,6 @@ describe('getLinodesFromAllPlacementGroups', () => { }); }); -describe('getAffinityTypeEnforcement', () => { - it('returns "Strict" if `is_strict` is true', () => { - expect(getAffinityTypeEnforcement(true)).toBe('Strict'); - }); - - it('returns "Flexible" if `is_strict` is false', () => { - expect(getAffinityTypeEnforcement(false)).toBe('Flexible'); - }); -}); - describe('hasRegionReachedPlacementGroupCapacity', () => { it('returns true if the region has reached its placement group capacity', () => { expect( diff --git a/packages/manager/src/features/PlacementGroups/utils.ts b/packages/manager/src/features/PlacementGroups/utils.ts index 269cac2b537..c466a0ff6a2 100644 --- a/packages/manager/src/features/PlacementGroups/utils.ts +++ b/packages/manager/src/features/PlacementGroups/utils.ts @@ -1,25 +1,15 @@ -import { AFFINITY_TYPES } from '@linode/api-v4/lib/placement-groups'; +import { PLACEMENT_GROUP_TYPES } from '@linode/api-v4/lib/placement-groups'; import { useFlags } from 'src/hooks/useFlags'; import { useAccount } from 'src/queries/account/account'; import type { - AffinityTypeEnforcement, CreatePlacementGroupPayload, Linode, PlacementGroup, Region, } from '@linode/api-v4'; -/** - * Helper to get the affinity type enforcement readable string. - */ -export const getAffinityTypeEnforcement = ( - is_strict: boolean -): AffinityTypeEnforcement => { - return is_strict ? 'Strict' : 'Flexible'; -}; - /** * Helper to get the full linodes objects assigned to a Placement Group. */ @@ -95,15 +85,15 @@ export const hasRegionReachedPlacementGroupCapacity = ({ }; /** - * Helper to populate the affinity_type select options. + * Helper to populate the placement_group_type select options. */ -export const affinityTypeOptions = Object.entries(AFFINITY_TYPES).map( - ([key, value]) => ({ - disabled: false, - label: value, - value: key as CreatePlacementGroupPayload['affinity_type'], - }) -); +export const placementGroupTypeOptions = Object.entries( + PLACEMENT_GROUP_TYPES +).map(([key, value]) => ({ + disabled: false, + label: value, + value: key as CreatePlacementGroupPayload['placement_group_type'], +})); /** * Helper to get all linodes assigned to any placement group. (and reduce to unique linodes) diff --git a/packages/manager/src/mocks/serverHandlers.ts b/packages/manager/src/mocks/serverHandlers.ts index 198d63e9244..70aad5a7db2 100644 --- a/packages/manager/src/mocks/serverHandlers.ts +++ b/packages/manager/src/mocks/serverHandlers.ts @@ -2171,21 +2171,19 @@ export const handlers = [ return HttpResponse.json( makeResourcePage([ placementGroupFactory.build({ - affinity_type: 'anti_affinity:local', id: 1, is_compliant: true, - is_strict: true, members: [1, 2, 3, 4, 5, 6, 7, 8, 43].map((linode) => ({ is_compliant: true, linode_id: linode, })), + placement_group_policy: 'strict', + placement_group_type: 'anti_affinity:local', region: 'us-east', }), placementGroupFactory.build({ - affinity_type: 'affinity:local', id: 2, is_compliant: true, - is_strict: true, members: [ { is_compliant: true, @@ -2200,19 +2198,21 @@ export const handlers = [ linode_id: 11, }, ], + placement_group_policy: 'strict', + placement_group_type: 'affinity:local', region: 'us-west', }), placementGroupFactory.build({ - affinity_type: 'affinity:local', id: 3, is_compliant: true, - is_strict: true, members: [ { is_compliant: true, linode_id: 12, }, ], + placement_group_policy: 'strict', + placement_group_type: 'affinity:local', region: 'ca-central', }), ]) @@ -2271,7 +2271,6 @@ export const handlers = [ } const response = placementGroupFactory.build({ - affinity_type: 'anti_affinity:local', id: Number(params.placementGroupId) ?? -1, label: 'pg-1', members: [ @@ -2316,6 +2315,7 @@ export const handlers = [ linode_id: (body as any).linodes[0], }, ], + placement_group_type: 'anti_affinity:local', }); return HttpResponse.json(response); @@ -2327,7 +2327,6 @@ export const handlers = [ } const response = placementGroupFactory.build({ - affinity_type: 'anti_affinity:local', id: Number(params.placementGroupId) ?? -1, label: 'pg-1', members: [ @@ -2369,6 +2368,7 @@ export const handlers = [ linode_id: 43, }, ], + placement_group_type: 'anti_affinity:local', }); return HttpResponse.json(response); @@ -2377,52 +2377,52 @@ export const handlers = [ const response = { data: [ { + created: '2024-04-29T17:09:29', id: 1, - type: 'standard', - service_type: 'linode', label: 'Linode Service I/O Statistics', - created: '2024-04-29T17:09:29', + service_type: 'linode', + type: 'standard', updated: null, widgets: [ { - metric: 'system_cpu_utilization_percent', - unit: '%', - label: 'CPU utilization', + aggregate_function: 'avg', + chart_type: 'area', color: 'blue', + label: 'CPU utilization', + metric: 'system_cpu_utilization_percent', size: 12, - chart_type: 'area', + unit: '%', y_label: 'system_cpu_utilization_ratio', - aggregate_function: 'avg', }, { - metric: 'system_memory_usage_by_resource', - unit: 'Bytes', - label: 'Memory Usage', + aggregate_function: 'avg', + chart_type: 'area', color: 'red', + label: 'Memory Usage', + metric: 'system_memory_usage_by_resource', size: 12, - chart_type: 'area', + unit: 'Bytes', y_label: 'system_memory_usage_bytes', - aggregate_function: 'avg', }, { - metric: 'system_network_io_by_resource', - unit: 'Bytes', - label: 'Network Traffic', + aggregate_function: 'avg', + chart_type: 'area', color: 'green', + label: 'Network Traffic', + metric: 'system_network_io_by_resource', size: 6, - chart_type: 'area', + unit: 'Bytes', y_label: 'system_network_io_bytes_total', - aggregate_function: 'avg', }, { - metric: 'system_disk_OPS_total', - unit: 'OPS', - label: 'Disk I/O', + aggregate_function: 'avg', + chart_type: 'area', color: 'yellow', + label: 'Disk I/O', + metric: 'system_disk_OPS_total', size: 6, - chart_type: 'area', + unit: 'OPS', y_label: 'system_disk_operations_total', - aggregate_function: 'avg', }, ], }, diff --git a/packages/validation/src/placement-groups.schema.ts b/packages/validation/src/placement-groups.schema.ts index 00a41399794..ce4eddff3d1 100644 --- a/packages/validation/src/placement-groups.schema.ts +++ b/packages/validation/src/placement-groups.schema.ts @@ -1,4 +1,4 @@ -import { boolean, object, string } from 'yup'; +import { object, string } from 'yup'; const labelValidation = string() .required('Label is required.') @@ -7,9 +7,11 @@ const labelValidation = string() export const createPlacementGroupSchema = object({ label: labelValidation, - affinity_type: string().required('Affinity type is required.'), + placement_group_type: string().required('Placement Group Type is required.'), region: string().required('Region is required.'), - is_strict: boolean().required('Is strict is required.'), + placement_group_policy: string().required( + 'Placement Group Policy is required.' + ), }); export const updatePlacementGroupSchema = object({