misc: connected aws add kms

This commit is contained in:
Sheen Capadngan
2024-07-16 14:17:54 +08:00
committed by =
parent 937b0c0a7c
commit 9c4bb79472
5 changed files with 139 additions and 6 deletions

View File

@@ -4,6 +4,7 @@ import { registerAuditLogStreamRouter } from "./audit-log-stream-router";
import { registerCaCrlRouter } from "./certificate-authority-crl-router";
import { registerDynamicSecretLeaseRouter } from "./dynamic-secret-lease-router";
import { registerDynamicSecretRouter } from "./dynamic-secret-router";
import { registerExternalKmsRouter } from "./external-kms-router";
import { registerGroupRouter } from "./group-router";
import { registerIdentityProjectAdditionalPrivilegeRouter } from "./identity-project-additional-privilege-router";
import { registerLdapRouter } from "./ldap-router";
@@ -87,4 +88,8 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => {
},
{ prefix: "/additional-privilege" }
);
await server.register(registerExternalKmsRouter, {
prefix: "/external-kms"
});
};

View File

@@ -0,0 +1 @@
export { useAddAwsExternalKms } from "./mutations";

View File

@@ -0,0 +1,53 @@
import { useMutation } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request";
export const useAddAwsExternalKms = () => {
return useMutation({
mutationFn: async ({
slug,
description,
credentialType,
accessKey,
secretKey,
assumeRoleArn,
externalId,
awsRegion,
kmsKeyId
}: {
slug: string;
description: string;
credentialType: string;
accessKey?: string;
secretKey?: string;
assumeRoleArn?: string;
externalId?: string;
awsRegion: string;
kmsKeyId?: string;
}) => {
const { data } = await apiRequest.post("/api/v1/external-kms", {
slug,
description,
provider: {
type: "aws",
inputs: {
credential: {
type: credentialType,
data: {
accessKey,
secretKey,
assumeRoleArn,
externalId
}
},
awsRegion,
kmsKeyId
}
}
});
return data;
},
onSuccess() {}
});
};

View File

@@ -90,7 +90,7 @@ export const AddExternalKmsForm = ({ isOpen, onToggle }: Props) => {
animate={{ opacity: 1, translateX: 0 }}
exit={{ opacity: 0, translateX: -30 }}
>
<AwsKmsForm />
<AwsKmsForm onCancel={() => {}} onCompleted={() => {}} />
</motion.div>
)}
</AnimatePresence>

View File

@@ -1,8 +1,11 @@
import { Controller, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import slugify from "@sindresorhus/slugify";
import { z } from "zod";
import { FormControl, Input, Select, SelectItem } from "@app/components/v2";
import { createNotification } from "@app/components/notifications";
import { Button, FormControl, Input, Select, SelectItem } from "@app/components/v2";
import { useAddAwsExternalKms } from "@app/hooks/api/kms";
const AWS_REGIONS = [
{ name: "US East (Ohio)", slug: "us-east-2" },
@@ -42,6 +45,14 @@ export enum KmsAwsCredentialType {
}
const formSchema = z.object({
slug: z
.string()
.trim()
.min(1)
.refine((v) => slugify(v) === v, {
message: "Slug must be a valid slug"
}),
description: z.string().trim().min(1).default(""),
credential: z.discriminatedUnion("type", [
z.object({
type: z.literal(KmsAwsCredentialType.AccessKey),
@@ -58,23 +69,78 @@ const formSchema = z.object({
})
})
]),
awsRegion: z.string().min(1).trim().describe("AWS region to connect"),
awsRegion: z.string().min(1).trim(),
kmsKeyId: z.string().trim().optional()
});
type TForm = z.infer<typeof formSchema>;
export const AwsKmsForm = () => {
const { control, handleSubmit, watch } = useForm<TForm>({
type Props = {
onCompleted: () => void;
onCancel: () => void;
};
export const AwsKmsForm = ({ onCompleted, onCancel }: Props) => {
const {
control,
handleSubmit,
watch,
formState: { isSubmitting }
} = useForm<TForm>({
resolver: zodResolver(formSchema)
});
const selectedAwsAuthType = watch("credential.type");
const handleAddAwsKms = () => {};
const { mutateAsync: addAwsExternalKms } = useAddAwsExternalKms();
const handleAddAwsKms = async (data: TForm) => {
const { slug, description, credential, awsRegion, kmsKeyId } = data;
await addAwsExternalKms({
slug,
description,
credentialType: credential.type,
awsRegion,
kmsKeyId,
...(credential.type === KmsAwsCredentialType.AccessKey
? {
accessKey: credential.data.accessKey,
secretKey: credential.data.secretKey
}
: {
assumeRoleArn: credential.data.assumeRoleArn,
externalId: credential.data.externalId
})
});
createNotification({
text: "Successfully added AWS External KMS",
type: "success"
});
onCompleted();
};
return (
<form onSubmit={handleSubmit(handleAddAwsKms)} autoComplete="off">
<Controller
control={control}
name="slug"
render={({ field, fieldState: { error } }) => (
<FormControl label="Slug" errorText={error?.message} isError={Boolean(error)}>
<Input placeholder="" {...field} />
</FormControl>
)}
/>
<Controller
control={control}
name="description"
render={({ field, fieldState: { error } }) => (
<FormControl label="Description" errorText={error?.message} isError={Boolean(error)}>
<Input placeholder="" {...field} />
</FormControl>
)}
/>
<Controller
control={control}
name="credential.type"
@@ -186,6 +252,14 @@ export const AwsKmsForm = () => {
</FormControl>
)}
/>
<div className="mt-6 flex items-center space-x-4">
<Button type="submit" isLoading={isSubmitting}>
Submit
</Button>
<Button variant="outline_bg" onClick={onCancel}>
Cancel
</Button>
</div>
</form>
);
};