Skip to content

Commit 0180606

Browse files
upcoming: [UIE-9837] - Generational plans changes for Databases (#13539)
* disable premium plan tab and display no region selected placeholder in dbaas create * only display no region selected message for dbaas if generational plans is enabled * add databaseGenerationalPlans feature flag * update resize flow and feature flag resizing to a different plan type * comment out hard-coded g7 types * rename databaseGenerationalPlans flag to databaseResizeGenerationalPlans * fix failing tests * do not display changes if there are no g7 plans for databases * clean up * remove legacy resize test * Added changeset: Generational plans changes for Databases * Added changeset: Mock databaseResizeGenerationalPlans feature flag to false for resize-database.spec.ts * Updating changelog * Removing temporary dbtypes json file and PR testing code prior to merging --------- Co-authored-by: Sam Mans <smans@akamai.com>
1 parent 535ef89 commit 0180606

15 files changed

Lines changed: 215 additions & 95 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@linode/manager': Tests
3+
---
4+
5+
Mock `databaseResizeGenerationalPlans` feature flag to false for resize-database.spec.ts ([#13539](https://github.com/linode/manager/pull/13539))
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Upcoming Features
3+
---
4+
5+
Generational plans changes for Databases ([#13539](https://github.com/linode/manager/pull/13539))

packages/manager/cypress/e2e/core/databases/resize-database.spec.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
/**
2-
* @file DBaaS integration tests for resize operations.
3-
*/
4-
import {
5-
ClusterSize,
6-
DatabaseStatus,
7-
RegionAvailability,
8-
} from '@linode/api-v4';
91
import { accountFactory } from '@src/factories';
102
import {
113
databaseConfigurationsResize,
@@ -20,13 +12,22 @@ import {
2012
mockResize,
2113
mockResizeProvisioningDatabase,
2214
} from 'support/intercepts/databases';
15+
import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags';
2316
import { mockGetRegionAvailability } from 'support/intercepts/regions';
2417
import { ui } from 'support/ui';
2518
import { randomIp, randomNumber, randomString } from 'support/util/random';
2619
import { getRegionById } from 'support/util/regions';
2720

2821
import { databaseFactory } from 'src/factories/databases';
2922

23+
/**
24+
* @file DBaaS integration tests for resize operations.
25+
*/
26+
import type {
27+
ClusterSize,
28+
DatabaseStatus,
29+
RegionAvailability,
30+
} from '@linode/api-v4';
3031
import type { DatabaseClusterConfiguration } from 'support/constants/databases';
3132

3233
/**
@@ -63,16 +64,20 @@ const resizeDatabase = (initialLabel: string) => {
6364
* @param clusterSize - Database Cluster Size
6465
*/
6566
const getNodes = (clusterSize: number) => {
66-
const nodes =
67-
clusterSize == 1
68-
? 'Primary (1 Node)'
69-
: clusterSize == 2
70-
? 'Primary (+1 Node)'
71-
: 'Primary (+2 Nodes)';
72-
return nodes;
67+
return clusterSize === 1
68+
? 'Primary (1 Node)'
69+
: clusterSize === 2
70+
? 'Primary (+1 Node)'
71+
: 'Primary (+2 Nodes)';
7372
};
7473

7574
describe('Resizing existing clusters', () => {
75+
beforeEach(() => {
76+
mockAppendFeatureFlags({
77+
databaseResizeGenerationalPlans: false,
78+
});
79+
});
80+
7681
databaseConfigurationsResize.forEach(
7782
(configuration: DatabaseClusterConfiguration) => {
7883
describe(`Resizes a ${configuration.linodeType} ${configuration.engine} v${configuration.version}.x ${configuration.clusterSize}-node cluster`, () => {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ const options: { flag: keyof Flags; label: string }[] = [
6060
{ flag: 'supportTicketSeverity', label: 'Support Ticket Severity' },
6161
{ flag: 'dbaasV2', label: 'Databases V2 Beta' },
6262
{ flag: 'dbaasV2MonitorMetrics', label: 'Databases V2 Monitor' },
63+
{
64+
flag: 'databaseResizeGenerationalPlans',
65+
label: 'Database Resize Generational Plans',
66+
},
6367
{ flag: 'databasePgBouncer', label: 'Database PgBouncer' },
6468
{ flag: 'databaseResize', label: 'Database Resize' },
6569
{ flag: 'databaseAdvancedConfig', label: 'Database Advanced Config' },

packages/manager/src/featureFlags.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ export interface Flags {
241241
databasePgBouncer: boolean;
242242
databasePremium: boolean;
243243
databaseResize: boolean;
244+
databaseResizeGenerationalPlans: boolean;
244245
databaseRestrictPlanResize: boolean;
245246
databases: boolean;
246247
databaseValkey: BetaFeatureFlag;

packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ import { DocumentTitleSegment } from 'src/components/DocumentTitle';
1818
import { ErrorMessage } from 'src/components/ErrorMessage';
1919
import { LandingHeader } from 'src/components/LandingHeader';
2020
import { getRestrictedResourceText } from 'src/features/Account/utils';
21-
import { getIsLimitedAvailability } from 'src/features/components/PlansPanel/utils';
21+
import {
22+
getIsLimitedAvailability,
23+
useShouldDisablePremiumPlansTab,
24+
} from 'src/features/components/PlansPanel/utils';
2225
import { DatabaseClusterData } from 'src/features/Databases/DatabaseCreate/DatabaseClusterData';
2326
import {
2427
StyledBtnCtn,
@@ -252,11 +255,15 @@ export const DatabaseCreate = () => {
252255
}
253256
};
254257

258+
const shouldDisablePremiumPlansTab = useShouldDisablePremiumPlansTab({
259+
types: dbtypes,
260+
});
261+
255262
if (regionsLoading || !regionsData || enginesLoading || typesLoading) {
256263
return <CircleProgress />;
257264
}
258265

259-
if (regionsError || typesError || enginesError) {
266+
if (regionsError || enginesError || typesError) {
260267
return <ErrorState errorText="An unexpected error occurred." />;
261268
}
262269

@@ -312,6 +319,9 @@ export const DatabaseCreate = () => {
312319
<StyledPlansPanel
313320
data-qa-select-plan
314321
disabled={isRestricted}
322+
disabledTabs={
323+
shouldDisablePremiumPlansTab ? ['premium'] : undefined
324+
}
315325
error={fieldState.error?.message}
316326
flow="database"
317327
handleTabChange={handleTabChange}
@@ -321,6 +331,11 @@ export const DatabaseCreate = () => {
321331
regionsData={regionsData}
322332
selectedId={field.value}
323333
selectedRegionID={region}
334+
tabDisabledMessage={
335+
shouldDisablePremiumPlansTab
336+
? 'Premium CPUs are now called G7 Dedicated plans.'
337+
: undefined
338+
}
324339
types={displayTypes}
325340
/>
326341
)}

packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.test.tsx

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ describe('database resize', () => {
151151
beta: false,
152152
enabled: true,
153153
},
154+
databasePremium: true,
154155
};
155156

156157
it('resize button should be disabled when no input is provided in the form', async () => {
@@ -485,45 +486,6 @@ describe('database resize', () => {
485486
});
486487
});
487488

488-
describe('should disable Shared Plans Tab for 2 nodes cluster', () => {
489-
const database = databaseFactory.build({
490-
cluster_size: 2,
491-
type: 'g6-dedicated-8',
492-
});
493-
it('should disable Shared Plans Tab', async () => {
494-
const standardTypes = [
495-
databaseTypeFactory.build({
496-
class: 'nanode',
497-
id: 'g6-nanode-1',
498-
label: `Nanode 1 GB`,
499-
memory: 1024,
500-
}),
501-
];
502-
server.use(
503-
http.get('*/databases/types', () => {
504-
return HttpResponse.json(
505-
makeResourcePage([...dedicatedTypes, ...standardTypes])
506-
);
507-
}),
508-
http.get('*/account', () => {
509-
const account = accountFactory.build();
510-
return HttpResponse.json(account);
511-
})
512-
);
513-
514-
const { getByTestId, getByText } = renderWithTheme(
515-
<DatabaseDetailContext.Provider
516-
value={{ database, engine, isResizeEnabled }}
517-
>
518-
<DatabaseResize />
519-
</DatabaseDetailContext.Provider>
520-
);
521-
expect(getByTestId(loadingTestId)).toBeInTheDocument();
522-
await waitForElementToBeRemoved(getByTestId(loadingTestId));
523-
expect(getByText('Shared CPU')).toHaveAttribute('aria-disabled', 'true');
524-
});
525-
});
526-
527489
describe('on rendering resize when databaseRestrictPlanResize feature flag is enabled', () => {
528490
beforeEach(() => {
529491
const standardTypes = [

packages/manager/src/features/Databases/DatabaseDetail/DatabaseResize/DatabaseResize.tsx

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ import {
3333
} from 'src/features/Databases/utilities';
3434
import { typeLabelDetails } from 'src/features/Linodes/presentation';
3535
import { useFlags } from 'src/hooks/useFlags';
36+
import { useIsGenerationalPlansEnabled } from 'src/utilities/linodes';
3637

3738
import {
3839
RESIZE_DISABLED_DEDICATED_SHARED_PLAN_TABS_TEXT,
40+
RESIZE_DISABLED_NON_G7_DEDICATED_SHARED_PLAN_TABS_TEXT,
3941
RESIZE_DISABLED_PREMIUM_PLAN_TAB_TEXT,
40-
RESIZE_DISABLED_SHARED_PLAN_TAB_LEGACY_TEXT,
4142
} from '../../constants';
4243
import { useDatabaseDetailContext } from '../DatabaseDetailContext';
4344
import {
@@ -112,45 +113,62 @@ export const DatabaseResize = () => {
112113
(type: DatabaseType) => type.id === database.type
113114
);
114115

115-
const isDisabledSharedTab = database.cluster_size === 2;
116-
117-
const premiumRestrictedTabsCopy =
118-
currentPlanType?.class === 'premium'
119-
? RESIZE_DISABLED_DEDICATED_SHARED_PLAN_TABS_TEXT
120-
: RESIZE_DISABLED_PREMIUM_PLAN_TAB_TEXT;
121-
122-
const restrictPlanTypes = () => {
123-
if (currentPlanType?.class === 'premium') {
124-
return ['shared', 'dedicated'];
125-
} else {
126-
return ['premium'];
127-
}
128-
};
116+
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled(
117+
dbTypes,
118+
currentPlanType?.class
119+
);
129120

130121
const disabledTabsConfig: {
131122
disabledTabs: string[];
132123
disabledTabsCopy: string;
133124
} = React.useMemo(() => {
134-
// For new database clusters, restrict plan types based on the current plan
135-
if (isDefaultDatabase(database) && flags.databaseRestrictPlanResize) {
125+
if (
126+
!flags.databaseRestrictPlanResize ||
127+
(flags.databaseResizeGenerationalPlans &&
128+
currentPlanType?.class === 'premium')
129+
) {
136130
return {
137-
disabledTabsCopy: premiumRestrictedTabsCopy,
138-
disabledTabs: restrictPlanTypes(),
131+
disabledTabs: [],
132+
disabledTabsCopy: '',
139133
};
140134
}
141-
// Disable shared tab for legacy database clusters when cluster size is 2
142-
if (!isNewDatabaseGA && isDisabledSharedTab) {
135+
136+
if (!isGenerationalPlansEnabled && currentPlanType?.class === 'premium') {
137+
return {
138+
disabledTabs: ['shared', 'dedicated'],
139+
disabledTabsCopy: RESIZE_DISABLED_DEDICATED_SHARED_PLAN_TABS_TEXT,
140+
};
141+
}
142+
143+
if (isGenerationalPlansEnabled && currentPlanType?.class === 'premium') {
143144
return {
144-
disabledTabsCopy: RESIZE_DISABLED_SHARED_PLAN_TAB_LEGACY_TEXT,
145145
disabledTabs: ['shared'],
146+
disabledTabsCopy:
147+
RESIZE_DISABLED_NON_G7_DEDICATED_SHARED_PLAN_TABS_TEXT,
148+
};
149+
}
150+
151+
if (
152+
isGenerationalPlansEnabled &&
153+
flags.databaseResizeGenerationalPlans &&
154+
currentPlanType?.class !== 'premium'
155+
) {
156+
return {
157+
disabledTabs: ['premium'],
158+
disabledTabsCopy: 'Premium CPUs are now called G7 Dedicated plans.',
146159
};
147160
}
148161

149162
return {
150-
disabledTabs: [],
151-
disabledTabsCopy: '',
163+
disabledTabs: ['premium'],
164+
disabledTabsCopy: RESIZE_DISABLED_PREMIUM_PLAN_TAB_TEXT,
152165
};
153-
}, [database, flags, isNewDatabaseGA]);
166+
}, [
167+
currentPlanType?.class,
168+
flags.databaseResizeGenerationalPlans,
169+
flags.databaseRestrictPlanResize,
170+
isGenerationalPlansEnabled,
171+
]);
154172

155173
const { enqueueSnackbar } = useSnackbar();
156174

@@ -314,13 +332,34 @@ export const DatabaseResize = () => {
314332
setSelectedTab(initialTab);
315333
}, []);
316334

317-
const disabledPlans = isSmallerOrEqualCurrentPlan(
335+
const disabledPlansDueToDiskSize = isSmallerOrEqualCurrentPlan(
318336
currentPlan?.id,
319337
database?.used_disk_size_gb,
320338
displayTypes,
321339
isNewDatabaseGA
322340
);
323341

342+
// @TODO remove dbaas resize class type restriction sometime post-release when we support resizing across different plans
343+
const isCurrentPlanAPremiumPlan =
344+
currentPlan?.class.includes('premium') ||
345+
currentPlan?.id.includes('g7-dedicated');
346+
347+
const disabledResizeToPremiumPlans =
348+
!flags.databaseResizeGenerationalPlans && !isCurrentPlanAPremiumPlan
349+
? displayTypes.filter(
350+
(type) =>
351+
type.class.includes('premium') || type.id.includes('g7-dedicated')
352+
)
353+
: [];
354+
355+
const disabledResizeFromPremiumPlans =
356+
!flags.databaseResizeGenerationalPlans && isCurrentPlanAPremiumPlan
357+
? displayTypes.filter(
358+
(type) =>
359+
!type.class.includes('premium') && !type.id.includes('g7-dedicated')
360+
)
361+
: [];
362+
324363
const shouldSubmitBeDisabled = React.useMemo(() => {
325364
return !summaryText;
326365
}, [summaryText]);
@@ -405,7 +444,10 @@ export const DatabaseResize = () => {
405444
currentPlanHeading={currentPlan?.heading}
406445
data-qa-select-plan
407446
disabled={disabled}
408-
disabledSmallerPlans={disabledPlans}
447+
// @TODO remove dbaas resize class type restriction sometime post-release when we support resizing across different plans
448+
disabledResizeFromPremiumPlans={disabledResizeFromPremiumPlans}
449+
disabledResizeToPremiumPlans={disabledResizeToPremiumPlans}
450+
disabledSmallerPlans={disabledPlansDueToDiskSize}
409451
disabledTabs={disabledTabsConfig.disabledTabs}
410452
flow="database"
411453
handleTabChange={handleTabChange}

packages/manager/src/features/Databases/constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ export const RESIZE_DISABLED_PREMIUM_PLAN_TAB_TEXT =
3838
export const RESIZE_DISABLED_DEDICATED_SHARED_PLAN_TABS_TEXT =
3939
'Resizing to a Shared CPU or a Dedicated CPU plan is not available for database clusters on a Premium CPU plan.';
4040

41-
export const RESIZE_DISABLED_SHARED_PLAN_TAB_LEGACY_TEXT =
42-
'Resizing a 2-node cluster is only allowed with Dedicated plans.';
41+
export const RESIZE_DISABLED_NON_G7_DEDICATED_SHARED_PLAN_TABS_TEXT =
42+
'Resizing to a Shared CPU or a non-G7 Dedicated CPU plan is not available for database clusters on a Premium CPU plan.';
4343

4444
export const BACKUPS_MAX_TIME_EXCEEDED_VALIDATON_TEXT =
4545
'Select a time from the past.';

packages/manager/src/features/components/PlansPanel/PlanContainer.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,8 @@ export const PlanContainer = (props: PlanContainerProps) => {
116116
} = props;
117117
const location = useLocation();
118118
const flags = useFlags();
119-
const { isGenerationalPlansEnabled } = useIsGenerationalPlansEnabled(
120-
plans,
121-
planType
122-
);
119+
const { isGenerationalPlansEnabled, hasG7DedicatedPlans } =
120+
useIsGenerationalPlansEnabled(plans, planType);
123121

124122
// Show the Transfer column if, for any plan, the api returned data and we're not in the Database Create flow
125123
const showTransfer =
@@ -135,8 +133,11 @@ export const PlanContainer = (props: PlanContainerProps) => {
135133
const isDatabaseResizeFlow =
136134
location.pathname.match(/\/databases\/.*\/(\d+\/resize)/)?.[0] ===
137135
location.pathname;
138-
const shouldDisplayNoRegionSelectedMessage =
139-
!selectedRegionId && !isDatabaseCreateFlow && !isDatabaseResizeFlow;
136+
137+
const shouldDisplayNoRegionSelectedMessage = Boolean(
138+
(!selectedRegionId && !isDatabaseCreateFlow) ||
139+
(isDatabaseCreateFlow && hasG7DedicatedPlans && !selectedRegionId)
140+
);
140141

141142
const isDatabaseGA =
142143
!flags.dbaasV2?.beta &&

0 commit comments

Comments
 (0)