Skip to content

Commit

Permalink
Datastore credentials tab (#4197)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feroze Mohideen authored Jan 25, 2024
1 parent 4fe7489 commit aee79b9
Show file tree
Hide file tree
Showing 27 changed files with 350 additions and 378 deletions.
62 changes: 20 additions & 42 deletions dashboard/src/lib/databases/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,99 +41,77 @@ export const datastoreValidator = z.object({
export type SerializedDatastore = z.infer<typeof datastoreValidator>;

export type ClientDatastore = SerializedDatastore & {
template: DatabaseTemplate;
template: DatastoreTemplate;
};

export const datastoreListResponseValidator = z.object({
datastores: datastoreValidator.array(),
});

export const cloudProviderValidator = z.object({
cloud_provider_id: z.string(),
project_id: z.number(),
});

export type CloudProviderWithSource = z.infer<typeof cloudProviderValidator>;

export const cloudProviderListResponseValidator = z.object({
accounts: cloudProviderValidator.array(),
});

export const cloudProviderDatastoreSchema = z.object({
project_id: z.number(),
cloud_provider_name: z.string(),
cloud_provider_id: z.string(),
datastore: datastoreValidator,
});

export type CloudProviderDatastore = z.infer<
typeof cloudProviderDatastoreSchema
>;

export type DatabaseEngine = {
export type DatastoreEngine = {
name: z.infer<typeof datastoreValidator>["engine"];
displayName: string;
};
export const DATABASE_ENGINE_POSTGRES = {
export const DATASTORE_ENGINE_POSTGRES = {
name: "POSTGRES" as const,
displayName: "PostgreSQL",
};
export const DATABASE_ENGINE_AURORA_POSTGRES = {
export const DATASTORE_ENGINE_AURORA_POSTGRES = {
name: "AURORA-POSTGRES" as const,
displayName: "Aurora PostgreSQL",
};
export const DATABASE_ENGINE_REDIS = {
export const DATASTORE_ENGINE_REDIS = {
name: "REDIS" as const,
displayName: "Redis",
};
export const DATABASE_ENGINE_MEMCACHED = {
export const DATASTORE_ENGINE_MEMCACHED = {
name: "MEMCACHED" as const,
displayName: "Memcached",
};

export type DatabaseType = z.infer<typeof datastoreValidator>["type"];
export const DATABASE_TYPE_RDS = "RDS" as const;
export const DATABASE_TYPE_ELASTICACHE = "ELASTICACHE" as const;
export type DatastoreType = z.infer<typeof datastoreValidator>["type"];
export const DATASTORE_TYPE_RDS = "RDS" as const;
export const DATASTORE_TYPE_ELASTICACHE = "ELASTICACHE" as const;

export type DatabaseState = {
export type DatastoreState = {
state: z.infer<typeof datastoreValidator>["status"];
displayName: string;
};
export const DATABASE_STATE_CREATING: DatabaseState = {
export const DATASTORE_STATE_CREATING: DatastoreState = {
state: "CREATING",
displayName: "Creating",
};
export const DATABASE_STATE_CONFIGURING_LOG_EXPORTS: DatabaseState = {
export const DATASTORE_STATE_CONFIGURING_LOG_EXPORTS: DatastoreState = {
state: "CONFIGURING_LOG_EXPORTS",
displayName: "Configuring log exports",
};
export const DATABASE_STATE_MODIFYING: DatabaseState = {
export const DATASTORE_STATE_MODIFYING: DatastoreState = {
state: "MODIFYING",
displayName: "Modifying",
};
export const DATABASE_STATE_CONFIGURING_ENHANCED_MONITORING: DatabaseState = {
export const DATASTORE_STATE_CONFIGURING_ENHANCED_MONITORING: DatastoreState = {
state: "CONFIGURING_ENHANCED_MONITORING",
displayName: "Configuring enhanced monitoring",
};
export const DATABASE_STATE_BACKING_UP: DatabaseState = {
export const DATASTORE_STATE_BACKING_UP: DatastoreState = {
state: "BACKING_UP",
displayName: "Backing up",
};
export const DATABASE_STATE_AVAILABLE: DatabaseState = {
export const DATASTORE_STATE_AVAILABLE: DatastoreState = {
state: "AVAILABLE",
displayName: "Finishing provision",
};

export type DatabaseTemplate = {
type: DatabaseType;
engine: DatabaseEngine;
export type DatastoreTemplate = {
type: DatastoreType;
engine: DatastoreEngine;
icon: string;
name: string;
description: string;
disabled: boolean;
instanceTiers: ResourceOption[];
formTitle: string;
creationStateProgression: DatabaseState[];
creationStateProgression: DatastoreState[];
};

const instanceTierValidator = z.enum([
Expand Down
12 changes: 6 additions & 6 deletions dashboard/src/lib/hooks/useDatabaseList.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { useContext } from "react";
import { useQuery } from "@tanstack/react-query";

import { SUPPORTED_DATABASE_TEMPLATES } from "main/home/database-dashboard/constants";
import { SUPPORTED_DATASTORE_TEMPLATES } from "main/home/database-dashboard/constants";
import {
datastoreListResponseValidator,
type DatabaseTemplate,
type DatastoreTemplate,
type SerializedDatastore,
} from "lib/databases/types";

import api from "shared/api";
import { Context } from "shared/Context";
import { valueExists } from "shared/util";

type DatabaseListType = {
datastores: Array<SerializedDatastore & { template: DatabaseTemplate }>;
type DatastoreListType = {
datastores: Array<SerializedDatastore & { template: DatastoreTemplate }>;
isLoading: boolean;
};
export const useDatabaseList = (): DatabaseListType => {
export const useDatastoreList = (): DatastoreListType => {
const { currentProject } = useContext(Context);

const { data: datastores, isLoading: isLoadingDatastores } = useQuery(
Expand All @@ -39,7 +39,7 @@ export const useDatabaseList = (): DatabaseListType => {
);
return parsed.datastores
.map((d) => {
const template = SUPPORTED_DATABASE_TEMPLATES.find(
const template = SUPPORTED_DATASTORE_TEMPLATES.find(
(t) => t.type === d.type && t.engine.name === d.engine
);

Expand Down
4 changes: 2 additions & 2 deletions dashboard/src/lib/hooks/useDatabaseMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { type DbFormData } from "lib/databases/types";
import api from "shared/api";
import { Context } from "shared/Context";

type DatabaseHook = {
type DatastoreHook = {
create: (values: DbFormData) => Promise<void>;
deleteDatastore: (name: string) => Promise<void>;
attachDatastoreToAppInstances: ({
Expand Down Expand Up @@ -84,7 +84,7 @@ const clientDbToCreateInput = (values: DbFormData): CreateDatastoreInput => {
.exhaustive();
};

export const useDatabaseMethods = (): DatabaseHook => {
export const useDatastoreMethods = (): DatastoreHook => {
const { currentProject, currentCluster } = useContext(Context);

const queryClient = useQueryClient();
Expand Down
12 changes: 6 additions & 6 deletions dashboard/src/main/home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -472,19 +472,19 @@ const Home: React.FC<Props> = (props) => {
)}
</Route>

<Route path="/databases/new/:type/:engine">
<Route path="/datastores/new/:type/:engine">
<CreateDatabase />
</Route>
<Route path="/databases/new">
<Route path="/datastores/new">
<CreateDatabase />
</Route>
<Route path="/databases/:datastoreName/:tab">
<Route path="/datastores/:datastoreName/:tab">
<DatabaseView />
</Route>
<Route path="/databases/:datastoreName">
<Route path="/datastores/:datastoreName">
<DatabaseView />
</Route>
<Route path="/databases">
<Route path="/datastores">
<DatabaseDashboard />
</Route>

Expand Down Expand Up @@ -544,7 +544,7 @@ const Home: React.FC<Props> = (props) => {
"/applications",
"/jobs",
"/env-groups",
"/databases",
"/datastores",
...(!currentProject?.validate_apply_v2
? ["/preview-environments"]
: []),
Expand Down
35 changes: 19 additions & 16 deletions dashboard/src/main/home/database-dashboard/CreateDatabase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,26 @@ import Back from "components/porter/Back";
import Spacer from "components/porter/Spacer";
import Text from "components/porter/Text";
import {
DATABASE_ENGINE_AURORA_POSTGRES,
DATABASE_ENGINE_POSTGRES,
DATABASE_ENGINE_REDIS,
DATABASE_TYPE_ELASTICACHE,
DATABASE_TYPE_RDS,
type DatabaseTemplate,
DATASTORE_ENGINE_AURORA_POSTGRES,
DATASTORE_ENGINE_POSTGRES,
DATASTORE_ENGINE_REDIS,
DATASTORE_TYPE_ELASTICACHE,
DATASTORE_TYPE_RDS,
type DatastoreTemplate,
} from "lib/databases/types";

import database from "assets/database.svg";

import DashboardHeader from "../cluster-dashboard/DashboardHeader";
import { SUPPORTED_DATABASE_TEMPLATES } from "./constants";
import { SUPPORTED_DATASTORE_TEMPLATES } from "./constants";
import DatabaseFormAuroraPostgres from "./forms/DatabaseFormAuroraPostgres";
import DatabaseFormElasticacheRedis from "./forms/DatabaseFormElasticacheRedis";
import DatabaseFormRDSPostgres from "./forms/DatabaseFormRDSPostgres";
import EngineTag from "./tags/EngineTag";

type Props = RouteComponentProps;
const CreateDatabase: React.FC<Props> = ({ history, match: queryMatch }) => {
const templateMatch: DatabaseTemplate | undefined = useMemo(() => {
const templateMatch: DatastoreTemplate | undefined = useMemo(() => {
const { params } = queryMatch;
const validParams = z
.object({
Expand All @@ -41,7 +41,7 @@ const CreateDatabase: React.FC<Props> = ({ history, match: queryMatch }) => {
return undefined;
}

return SUPPORTED_DATABASE_TEMPLATES.find(
return SUPPORTED_DATASTORE_TEMPLATES.find(
(t) =>
!t.disabled &&
t.type === validParams.data.type &&
Expand All @@ -53,23 +53,26 @@ const CreateDatabase: React.FC<Props> = ({ history, match: queryMatch }) => {
<StyledTemplateComponent>
{match(templateMatch)
.with(
{ type: DATABASE_TYPE_RDS, engine: DATABASE_ENGINE_POSTGRES },
{ type: DATASTORE_TYPE_RDS, engine: DATASTORE_ENGINE_POSTGRES },
(t) => <DatabaseFormRDSPostgres template={t} />
)
.with(
{ type: DATABASE_TYPE_RDS, engine: DATABASE_ENGINE_AURORA_POSTGRES },
{
type: DATASTORE_TYPE_RDS,
engine: DATASTORE_ENGINE_AURORA_POSTGRES,
},
(t) => <DatabaseFormAuroraPostgres template={t} />
)
.with(
{ type: DATABASE_TYPE_ELASTICACHE, engine: DATABASE_ENGINE_REDIS },
{ type: DATASTORE_TYPE_ELASTICACHE, engine: DATASTORE_ENGINE_REDIS },
(t) => <DatabaseFormElasticacheRedis template={t} />
)
.otherwise(() => (
<>
<Back to="/databases" />
<Back to="/datastores" />
<DashboardHeader
image={database}
title="Create a new database"
title="Create a new datastore"
capitalize={false}
disableLineBreak
/>
Expand All @@ -80,15 +83,15 @@ const CreateDatabase: React.FC<Props> = ({ history, match: queryMatch }) => {
</Text>
<Spacer y={0.5} />
<TemplateListWrapper>
{SUPPORTED_DATABASE_TEMPLATES.map((template) => {
{SUPPORTED_DATASTORE_TEMPLATES.map((template) => {
const { name, icon, description, disabled, engine, type } =
template;
return (
<TemplateBlock
disabled={disabled}
key={`${name}-${engine.name}`}
onClick={() => {
history.push(`/databases/new/${type}/${engine.name}`);
history.push(`/datastores/new/${type}/${engine.name}`);
}}
>
<TemplateHeader>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,31 @@ import api from "shared/api";
import { Context } from "shared/Context";
import notFound from "assets/not-found.png";

import { SUPPORTED_DATABASE_TEMPLATES } from "./constants";
import { SUPPORTED_DATASTORE_TEMPLATES } from "./constants";

type DatabaseContextType = {
type DatastoreContextType = {
datastore: ClientDatastore;
projectId: number;
};

const DatabaseContext = createContext<DatabaseContextType | null>(null);
const DatastoreContext = createContext<DatastoreContextType | null>(null);

export const useDatabaseContext = (): DatabaseContextType => {
const ctx = React.useContext(DatabaseContext);
export const useDatastoreContext = (): DatastoreContextType => {
const ctx = React.useContext(DatastoreContext);
if (!ctx) {
throw new Error(
"useDatabaseContext must be used within a DatabaseContextProvider"
"useDatastoreContext must be used within a DatastoreContextProvider"
);
}
return ctx;
};

type DatabaseContextProviderProps = {
type DatastoreContextProviderProps = {
datastoreName?: string;
children: JSX.Element;
};
export const DatabaseContextProvider: React.FC<
DatabaseContextProviderProps
export const DatastoreContextProvider: React.FC<
DatastoreContextProviderProps
> = ({ datastoreName, children }) => {
const { currentProject } = useContext(Context);
const paramsExist =
Expand All @@ -63,7 +63,7 @@ export const DatabaseContextProvider: React.FC<
.parseAsync(response.data);

const datastore = results.datastore;
const matchingTemplate = SUPPORTED_DATABASE_TEMPLATES.find(
const matchingTemplate = SUPPORTED_DATASTORE_TEMPLATES.find(
(t) => t.type === datastore.type && t.engine.name === datastore.engine
);

Expand Down Expand Up @@ -93,24 +93,24 @@ export const DatabaseContextProvider: React.FC<
<Container row>
<PlaceholderIcon src={notFound} />
<Text color="helper">
No database matching &quot;{datastoreName}&quot; was found.
No datastore matching &quot;{datastoreName}&quot; was found.
</Text>
</Container>
<Spacer y={1} />
<Link to="/databases">Return to dashboard</Link>
<Link to="/datastores">Return to dashboard</Link>
</Placeholder>
);
}

return (
<DatabaseContext.Provider
<DatastoreContext.Provider
value={{
datastore,
projectId: currentProject.id,
}}
>
{children}
</DatabaseContext.Provider>
</DatastoreContext.Provider>
);
};

Expand Down
Loading

0 comments on commit aee79b9

Please sign in to comment.