Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PMM-11667-Adding-DBaaS-templates: add templates field #623

Merged
merged 5 commits into from
Mar 9, 2023
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
13 changes: 13 additions & 0 deletions public/app/percona/dbaas/components/DBCluster/DBCluster.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import {
DBClusterListResponse,
DBClusterSecretsResponse,
DBClusterSecretsRequest,
DBClusterTemplatesResponse,
DBClusterTemplatesRequest,
DBClusterType,
} from './DBCluster.types';
import { formatResources } from './DBCluster.utils';

Expand Down Expand Up @@ -108,4 +111,14 @@ export abstract class DBClusterService {
};
});
}
static async getDBClusterTemplates(
kubernetesClusterName: string,
k8sClusterType: DBClusterType
): Promise<DBClusterTemplatesResponse> {
return apiManagement.post<DBClusterTemplatesResponse, DBClusterTemplatesRequest>(
'/DBaaS/Templates/List',
{ kubernetes_cluster_name: kubernetesClusterName, cluster_type: k8sClusterType },
true
);
}
}
20 changes: 20 additions & 0 deletions public/app/percona/dbaas/components/DBCluster/DBCluster.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export enum DBClusterType {
psmdb = 'DB_CLUSTER_TYPE_PSMDB',
}

export const DatabaseToDBClusterTypeMapping: Partial<Record<Databases, DBClusterType>> = {
[Databases.mysql]: DBClusterType.pxc,
[Databases.mongodb]: DBClusterType.psmdb,
};

export interface DBCluster {
clusterName: string;
kubernetesClusterName: string;
Expand All @@ -39,6 +44,7 @@ export interface DBCluster {
storageClass?: string;
backup?: DBaaSBackup;
restore?: DBaaSRestore;
template?: DBClusterTemplate;
}

interface DBaaSBackup {
Expand Down Expand Up @@ -189,6 +195,7 @@ export interface DBClusterPayload {
pxcConfiguration?: string;
internet_facing?: boolean;
source_ranges?: string[];
template?: DBClusterTemplate;
}

export interface DBClusterActionAPI {
Expand Down Expand Up @@ -243,6 +250,19 @@ export interface DBClusterSecretsRequest {
kubernetes_cluster_name: string;
}

export interface DBClusterTemplate {
name: string;
kind: string;
}
export interface DBClusterTemplatesResponse {
templates: DBClusterTemplate[];
}

export interface DBClusterTemplatesRequest {
kubernetes_cluster_name: string;
cluster_type: DBClusterType;
}

export interface DBClusterSecret {
name: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ describe('DBClusterAdvancedOptions::', () => {
const advancedOptions = screen.getByTestId('dbCluster-advanced-settings');
waitFor(() => fireEvent.click(advancedOptions));

expect(await screen.getByTestId('template-field-container')).toBeInTheDocument();
expect(await screen.getByTestId('nodes-number-input')).toBeInTheDocument();
expect(await screen.getByTestId('resources-field-container')).toBeInTheDocument();
expect(await screen.getByTestId('memory-number-input')).toBeInTheDocument();
Expand Down Expand Up @@ -81,6 +82,7 @@ describe('DBClusterAdvancedOptions::', () => {
)
);

expect(await screen.getByTestId('template-field-container')).toBeInTheDocument();
expect(await screen.getByTestId('nodes-number-input')).toBeInTheDocument();
expect(await screen.getByTestId('resources-field-container')).toBeInTheDocument();
expect(await screen.getByTestId('memory-number-input')).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { getStyles } from './DBClusterAdvancedOptions.styles';
import { AdvancedOptionsFields, DBClusterResources } from './DBClusterAdvancedOptions.types';
import { canGetExpectedResources, nodesValidator, resourceValidator } from './DBClusterAdvancedOptions.utils';
import NetworkAndSecurity from './NetworkAndSecurity/NetworkAndSecurity';
import Templates from './Templates/Templates';

export interface DBClusterAdvancedOptionsProps extends FormRenderProps {
mode: DBClusterPageMode;
Expand Down Expand Up @@ -206,6 +207,10 @@ export const DBClusterAdvancedOptions: FC<DBClusterAdvancedOptionsProps> = ({
return (
<FieldSet label={Messages.fieldSets.advancedSettings} {...collapsableProps}>
<>{showUnsafeConfigurationWarning && <UnsafeConfigurationWarning />}</>
<Templates
k8sClusterName={selectedCluster ? selectedCluster.kubernetesClusterName : kubernetesCluster?.value}
databaseType={databaseType?.value}
/>
<div className={styles.line}>
<NumberInputField
name={AdvancedOptionsFields.nodes}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export enum AdvancedOptionsFields {
memory = 'memory',
cpu = 'cpu',
disk = 'disk',
template = 'template',
}

export enum DBClusterResources {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const Messages = {
labels: {
templates: 'Templates',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { SelectableValue } from '@grafana/data';

import { Databases } from '../../../../../../shared/core';
import { DBClusterService } from '../../../DBCluster.service';
import { DatabaseToDBClusterTypeMapping } from '../../../DBCluster.types';

export const TemplatesService = {
async loadTemplatesOptions(k8sClusterName: string, databaseType: Databases): Promise<Array<SelectableValue<string>>> {
const dbClusterType = DatabaseToDBClusterTypeMapping[databaseType];
const templatesResponse =
dbClusterType && (await DBClusterService.getDBClusterTemplates(k8sClusterName, dbClusterType));
const templates = templatesResponse?.templates || [];
return templates.map((template) => ({
label: template.name,
value: template.kind,
}));
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { AsyncSelectField } from '@percona/platform-core';
import React, { FC } from 'react';

import { AdvancedOptionsFields } from '../DBClusterAdvancedOptions.types';

import { Messages } from './Templates.messages';
import { TemplatesService } from './Templates.service';
import { TemplatesProps } from './Templates.types';

export const Templates: FC<TemplatesProps> = ({ k8sClusterName, databaseType }) => {
return (
<AsyncSelectField
name={AdvancedOptionsFields.template}
label={Messages.labels.templates}
loadOptions={() => TemplatesService.loadTemplatesOptions(k8sClusterName, databaseType)}
defaultOptions
/>
);
};

export default Templates;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Databases } from '../../../../../../shared/core';

export interface TemplatesProps {
k8sClusterName: string;
databaseType: Databases;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export const Messages = {
clusterName: 'Cluster Name',
kubernetesCluster: 'Kubernetes Cluster',
databaseType: 'Database Type',
databaseVersion: 'Database Version',
noOperatorsMessage: 'No clusters found with installed operators',
labels: {
clusterName: 'Cluster Name',
databaseType: 'Database Type',
databaseVersion: 'Database Version',
kubernetesCluster: 'Kubernetes Cluster',
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export const DBClusterBasicOptions: FC<DBClusterBasicOptionsProps> = ({ kubernet
<Field
dataTestId="dbcluster-kubernetes-cluster-field"
name={BasicOptionsFields.kubernetesCluster}
label={Messages.kubernetesCluster}
label={Messages.labels.kubernetesCluster}
options={kubernetesOptions}
component={SelectFieldAdapter}
noOptionsMessage={Messages.noOperatorsMessage}
Expand All @@ -105,7 +105,7 @@ export const DBClusterBasicOptions: FC<DBClusterBasicOptionsProps> = ({ kubernet
disabled={!form.getState().values[BasicOptionsFields.kubernetesCluster] || !databaseOptions.length}
dataTestId="dbcluster-database-type-field"
name={BasicOptionsFields.databaseType}
label={Messages.databaseType}
label={Messages.labels.databaseType}
options={databaseOptions}
component={SelectFieldAdapter}
validate={optionRequired}
Expand All @@ -115,7 +115,7 @@ export const DBClusterBasicOptions: FC<DBClusterBasicOptionsProps> = ({ kubernet
disabled={isDatabaseVersionDisabled}
dataTestId="dbcluster-database-version-field"
name={BasicOptionsFields.databaseVersion}
label={Messages.databaseVersion}
label={Messages.labels.databaseVersion}
component={AsyncSelectFieldAdapter}
loading={loadingDatabaseVersions}
options={databaseVersions}
Expand All @@ -124,7 +124,7 @@ export const DBClusterBasicOptions: FC<DBClusterBasicOptionsProps> = ({ kubernet
</div>
<TextInputField
name={BasicOptionsFields.name}
label={Messages.clusterName}
label={Messages.labels.clusterName}
validators={[required, kubernetesClusterNameValidator, maxLength(CLUSTER_NAME_MAX_LENGTH)]}
/>
{settings?.backupEnabled && <Restore form={form} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,28 +67,28 @@ export const getEditInitialValues = (
selectedDBCluster: DBCluster,
configuration: DBClusterPayload | undefined
): UpdateDBClusterFormValues => {
const isCluster = selectedDBCluster.clusterSize > 1;
const sourceRangesArray = configuration?.source_ranges?.map((item) => ({ sourceRange: item })) || [{}];
const { template, clusterSize, sourceRanges, databaseType, cpu, disk, memory } = selectedDBCluster;
const isCluster = clusterSize > 1;
const sourceRangesArray = sourceRanges?.map((item) => ({ sourceRange: item })) || [{}];
const storageClass = configuration?.params?.replicaset?.storage_class || configuration?.params?.pxc?.storage_class;
const clusterParameters: UpdateDBClusterFormValues = {
nodes: isCluster ? selectedDBCluster.clusterSize : MIN_NODES,
nodes: isCluster ? clusterSize : MIN_NODES,
databaseType: {
value: selectedDBCluster.databaseType,
label: DATABASE_LABELS[selectedDBCluster.databaseType],
value: databaseType,
label: DATABASE_LABELS[databaseType],
},
cpu: selectedDBCluster.cpu,
disk: selectedDBCluster.disk,
memory: selectedDBCluster.memory,
cpu,
disk,
memory,
configuration: configuration?.params?.pxc?.configuration || configuration?.params?.replicaset?.configuration,
expose: configuration?.exposed,
internetFacing: configuration?.internet_facing,
sourceRanges: sourceRangesArray,
...(storageClass && { storageClass: { label: storageClass, value: storageClass } }),
...(template && { template: { label: template.name, value: template.kind } }),
};
const isMatchSize = (type: DBClusterResources) =>
DEFAULT_SIZES[type].cpu === selectedDBCluster.cpu &&
DEFAULT_SIZES[type].memory === selectedDBCluster.memory &&
DEFAULT_SIZES[type].disk === selectedDBCluster.disk;
DEFAULT_SIZES[type].cpu === cpu && DEFAULT_SIZES[type].memory === memory && DEFAULT_SIZES[type].disk === disk;

if (isMatchSize(DBClusterResources.small)) {
clusterParameters.resources = DBClusterResources.small;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Kubernetes } from '../../../Kubernetes/Kubernetes.types';
import { KubernetesClusterStatus } from '../../../Kubernetes/KubernetesClusterStatus/KubernetesClusterStatus.types';
import { KubernetesOperatorStatus } from '../../../Kubernetes/OperatorStatusItem/KubernetesOperatorStatus/KubernetesOperatorStatus.types';
import { DBClusterStatus } from '../../DBCluster.types';
import { dbClusterTemplatesApi } from '../../__mocks__/dbClustersStubs';
import { DBClusterResources } from '../DBClusterAdvancedOptions/DBClusterAdvancedOptions.types';
import { AddDBClusterFormValues, UpdateDBClusterFormValues } from '../EditDBClusterPage.types';

Expand Down Expand Up @@ -120,6 +121,7 @@ describe('DBClusterHooks::', () => {
disk: 1003,
status: DBClusterStatus.unknown,
message: 'Error',
template: dbClusterTemplatesApi[0],
},
},
},
Expand All @@ -138,6 +140,7 @@ describe('DBClusterHooks::', () => {
disk: 1003,
nodes: 1,
resources: DBClusterResources.custom,
template: expect.objectContaining({ value: dbClusterTemplatesApi[0].kind }),
})
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export class PSMDBService extends DBClusterService {
expose: dbCluster.exposed,
installedImage: dbCluster.installed_image,
availableImage: dbCluster.available_image,
template: dbCluster.template,
};
}
}
Expand Down Expand Up @@ -185,6 +186,12 @@ const toAPI = (dbCluster: DBCluster): DBClusterPayload => ({
},
}),
},
...(dbCluster.template && {
template: {
name: dbCluster.template.name,
kind: dbCluster.template.kind,
},
}),
});

const toSuspendAPI = (dbCluster: DBCluster) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export class XtraDBService extends DBClusterService {
expose: dbCluster.exposed,
installedImage: dbCluster.installed_image,
availableImage: dbCluster.available_image,
template: dbCluster.template,
};
}
}
Expand Down Expand Up @@ -202,6 +203,12 @@ const toAPI = (dbCluster: DBCluster): DBClusterPayload => ({
},
}),
},
...(dbCluster.template && {
template: {
name: dbCluster.template.name,
kind: dbCluster.template.kind,
},
}),
});

const toSuspendAPI = (dbCluster: DBCluster) => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DBClusterAllocatedResources } from '../DBCluster.types';

import { dbCLusterAllocatedResourcesStub, dbClusterLogsAPI } from './dbClustersStubs';
import { dbCLusterAllocatedResourcesStub, dbClusterLogsAPI, dbClusterTemplatesApi } from './dbClustersStubs';

export class DBClusterService {
static async getLogs() {
Expand All @@ -13,4 +13,8 @@ export class DBClusterService {
static async getDBClusters() {
return Promise.resolve();
}

static getDBClusterTemplates() {
return Promise.resolve(dbClusterTemplatesApi);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
DBClusterComponentVersionStatus,
DBClusterAllocatedResources,
ResourcesWithUnits,
DBClusterTemplate,
} from '../DBCluster.types';
import { Operators } from '../EditDBClusterPage/DBClusterBasicOptions/DBClusterBasicOptions.types';

Expand Down Expand Up @@ -179,6 +180,13 @@ export const dbClusterLogsAPI = {
],
};

export const dbClusterTemplatesApi: DBClusterTemplate[] = [
{
name: 'template-name',
kind: 'template-kind',
},
];

export const dbCLusterAllocatedResourcesStub: DBClusterAllocatedResources = {
total: {
cpu: { value: 10, units: CpuUnits.MILLI, original: 10 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const addDbClusterAction = createAsyncThunk(
secretsName,
enableRestore,
enableBackups,
template,
} = args.values;

const dbClusterService = newDBClusterService(databaseType.value);
Expand Down Expand Up @@ -120,6 +121,12 @@ export const addDbClusterAction = createAsyncThunk(
secretsName: secretsName?.value || '',
},
}),
...(template && {
template: {
name: template.label,
kind: template.value,
},
}),
}),
{
successMessage: 'Cluster was successfully added',
Expand Down
Loading