Add more missing ACME stuff

# Conflicts:
#	frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/ProfileRow.tsx

# Conflicts:
#	frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CreateProfileModal.tsx
This commit is contained in:
Fang-Pen Lin
2025-11-07 09:18:02 -08:00
parent 3916d48ba4
commit 2d8126c011
4 changed files with 36 additions and 13 deletions
@@ -225,11 +225,8 @@ export const certificateProfileServiceFactory = ({
message: "API enrollment requires API configuration" message: "API enrollment requires API configuration"
}); });
} }
if (data.enrollmentType === EnrollmentType.ACME && !data.acmeConfig) { // TODO: acme type currently doesn't require config obj, but add a check in the future if
throw new ForbiddenRequestError({ // we have options
message: "ACME enrollment requires ACME configuration"
});
}
// Create enrollment configs and profile // Create enrollment configs and profile
const profile = await certificateProfileDAL.transaction(async (tx) => { const profile = await certificateProfileDAL.transaction(async (tx) => {
@@ -5,7 +5,7 @@ export type TCertificateProfile = {
certificateTemplateId: string; certificateTemplateId: string;
slug: string; slug: string;
description?: string; description?: string;
enrollmentType: "api" | "est"; enrollmentType: "api" | "est" | "acme";
estConfigId?: string; estConfigId?: string;
apiConfigId?: string; apiConfigId?: string;
createdAt: string; createdAt: string;
@@ -44,7 +44,7 @@ export type TCreateCertificateProfileDTO = {
certificateTemplateId: string; certificateTemplateId: string;
slug: string; slug: string;
description?: string; description?: string;
enrollmentType: "api" | "est"; enrollmentType: "api" | "est" | "acme";
estConfig?: { estConfig?: {
disableBootstrapCaValidation?: boolean; disableBootstrapCaValidation?: boolean;
passphrase: string; passphrase: string;
@@ -54,6 +54,7 @@ export type TCreateCertificateProfileDTO = {
autoRenew?: boolean; autoRenew?: boolean;
renewBeforeDays?: number; renewBeforeDays?: number;
}; };
acmeConfig?: {};
}; };
export type TUpdateCertificateProfileDTO = { export type TUpdateCertificateProfileDTO = {
@@ -69,6 +70,7 @@ export type TUpdateCertificateProfileDTO = {
autoRenew?: boolean; autoRenew?: boolean;
renewBeforeDays?: number; renewBeforeDays?: number;
}; };
acmeConfig?: {};
}; };
export type TDeleteCertificateProfileDTO = { export type TDeleteCertificateProfileDTO = {
@@ -81,7 +83,7 @@ export type TListCertificateProfilesDTO = {
offset?: number; offset?: number;
search?: string; search?: string;
includeConfigs?: boolean; includeConfigs?: boolean;
enrollmentType?: "api" | "est"; enrollmentType?: "api" | "est" | "acme";
}; };
export type TGetCertificateProfileByIdDTO = { export type TGetCertificateProfileByIdDTO = {
@@ -72,7 +72,8 @@ const createSchema = z
autoRenew: z.boolean().optional(), autoRenew: z.boolean().optional(),
renewBeforeDays: z.number().min(1).max(365).optional() renewBeforeDays: z.number().min(1).max(365).optional()
}) })
.optional() .optional(),
acmeConfig: z.object({}).optional()
}) })
.refine( .refine(
(data) => { (data) => {
@@ -82,6 +83,9 @@ const createSchema = z
if (data.enrollmentType === "api" && !data.apiConfig) { if (data.enrollmentType === "api" && !data.apiConfig) {
return false; return false;
} }
if (data.enrollmentType === "acme" && !data.acmeConfig) {
return false;
}
return true; return true;
}, },
{ {
@@ -188,7 +192,8 @@ export const CreateProfileModal = ({ isOpen, onClose, profile, mode = "create" }
autoRenew: profile.apiConfig?.autoRenew || false, autoRenew: profile.apiConfig?.autoRenew || false,
renewBeforeDays: profile.apiConfig?.renewBeforeDays || 30 renewBeforeDays: profile.apiConfig?.renewBeforeDays || 30
} }
: undefined : undefined,
acmeConfig: profile.enrollmentType === "acme" ? {} : undefined
} }
: { : {
slug: "", slug: "",
@@ -199,7 +204,8 @@ export const CreateProfileModal = ({ isOpen, onClose, profile, mode = "create" }
apiConfig: { apiConfig: {
autoRenew: false, autoRenew: false,
renewBeforeDays: 30 renewBeforeDays: 30
} },
acmeConfig: {}
} }
}); });
@@ -230,7 +236,8 @@ export const CreateProfileModal = ({ isOpen, onClose, profile, mode = "create" }
autoRenew: profile.apiConfig?.autoRenew || false, autoRenew: profile.apiConfig?.autoRenew || false,
renewBeforeDays: profile.apiConfig?.renewBeforeDays || 30 renewBeforeDays: profile.apiConfig?.renewBeforeDays || 30
} }
: undefined : undefined,
acmeConfig: profile.enrollmentType === "acme" ? {} : undefined
}); });
} }
}, [isEdit, profile, reset]); }, [isEdit, profile, reset]);
@@ -249,6 +256,8 @@ export const CreateProfileModal = ({ isOpen, onClose, profile, mode = "create" }
updateData.estConfig = data.estConfig; updateData.estConfig = data.estConfig;
} else if (data.enrollmentType === "api" && data.apiConfig) { } else if (data.enrollmentType === "api" && data.apiConfig) {
updateData.apiConfig = data.apiConfig; updateData.apiConfig = data.apiConfig;
} else if (data.enrollmentType === "acme" && data.acmeConfig) {
updateData.acmeConfig = data.acmeConfig;
} }
await updateProfile.mutateAsync(updateData); await updateProfile.mutateAsync(updateData);
@@ -549,6 +558,20 @@ export const CreateProfileModal = ({ isOpen, onClose, profile, mode = "create" }
</div> </div>
)} )}
{/* ACME Configuration */}
{watchedEnrollmentType === "acme" && (
<div className="mb-4 space-y-4">
<Controller
control={control}
name="acmeConfig"
render={({ field, fieldState: { error } }) => (
<FormControl isError={Boolean(error)} errorText={error?.message}>
<div className="flex items-center gap-2">FIXME: ACME configuration</div>
</FormControl>
)}
/>
</div>
)}
{watchedAutoRenew && ( {watchedAutoRenew && (
<div className="mb-4 space-y-4"> <div className="mb-4 space-y-4">
<Controller <Controller
@@ -82,7 +82,8 @@ export const ProfileRow = ({ profile, onEditProfile, onDeleteProfile }: Props) =
const getEnrollmentTypeBadge = (enrollmentType: string) => { const getEnrollmentTypeBadge = (enrollmentType: string) => {
const config = { const config = {
api: { variant: "ghost" as const, label: "API" }, api: { variant: "ghost" as const, label: "API" },
est: { variant: "ghost" as const, label: "EST" } est: { variant: "ghost" as const, label: "EST" },
acme: { variant: "ghost" as const, label: "ACME" }
} as const; } as const;
const configKey = Object.keys(config).includes(enrollmentType) const configKey = Object.keys(config).includes(enrollmentType)