mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-09 07:28:21 +00:00
Add CA certs to Chef sync and make field names more dynamic
This commit is contained in:
@@ -139,6 +139,7 @@ export const chefPkiSyncFactory = ({ certificateDAL, certificateSyncDAL }: TChef
|
||||
cert: string;
|
||||
privateKey: string;
|
||||
certificateChain?: string;
|
||||
caCertificate?: string;
|
||||
certificateId: string;
|
||||
isUpdate: boolean;
|
||||
targetItemName: string;
|
||||
@@ -150,15 +151,32 @@ export const chefPkiSyncFactory = ({ certificateDAL, certificateSyncDAL }: TChef
|
||||
const validationErrors: Array<{ name: string; error: string }> = [];
|
||||
|
||||
const syncOptions = pkiSync.syncOptions as
|
||||
| { canRemoveCertificates?: boolean; preserveItemOnRenewal?: boolean }
|
||||
| {
|
||||
canRemoveCertificates?: boolean;
|
||||
preserveItemOnRenewal?: boolean;
|
||||
fieldMappings?: {
|
||||
certificate?: string;
|
||||
privateKey?: string;
|
||||
certificateChain?: string;
|
||||
caCertificate?: string;
|
||||
metadata?: string;
|
||||
};
|
||||
}
|
||||
| undefined;
|
||||
const canRemoveCertificates = syncOptions?.canRemoveCertificates ?? true;
|
||||
const preserveItemOnRenewal = syncOptions?.preserveItemOnRenewal ?? true;
|
||||
|
||||
const fieldMappings = {
|
||||
certificate: syncOptions?.fieldMappings?.certificate ?? "certificate",
|
||||
privateKey: syncOptions?.fieldMappings?.privateKey ?? "private_key",
|
||||
certificateChain: syncOptions?.fieldMappings?.certificateChain ?? "certificate_chain",
|
||||
caCertificate: syncOptions?.fieldMappings?.caCertificate ?? "ca_certificate"
|
||||
};
|
||||
|
||||
const activeExternalIdentifiers = new Set<string>();
|
||||
|
||||
for (const [certName, certData] of Object.entries(certificateMap)) {
|
||||
const { cert, privateKey: certPrivateKey, certificateChain, certificateId } = certData;
|
||||
const { cert, privateKey: certPrivateKey, certificateChain, caCertificate, certificateId } = certData;
|
||||
|
||||
if (!cert || cert.trim().length === 0) {
|
||||
validationErrors.push({
|
||||
@@ -218,6 +236,7 @@ export const chefPkiSyncFactory = ({ certificateDAL, certificateSyncDAL }: TChef
|
||||
cert,
|
||||
privateKey: certPrivateKey,
|
||||
certificateChain,
|
||||
caCertificate,
|
||||
certificateId,
|
||||
isUpdate,
|
||||
targetItemName,
|
||||
@@ -240,18 +259,17 @@ export const chefPkiSyncFactory = ({ certificateDAL, certificateSyncDAL }: TChef
|
||||
cert,
|
||||
privateKey: certPrivateKey,
|
||||
certificateChain,
|
||||
certificateId,
|
||||
isUpdate
|
||||
caCertificate,
|
||||
certificateId
|
||||
} = certificateData;
|
||||
|
||||
try {
|
||||
const chefDataBagItem: ChefCertificateDataBagItem = {
|
||||
id: targetItemName,
|
||||
certificate: cert,
|
||||
private_key: certPrivateKey,
|
||||
...(certificateChain && { certificate_chain: certificateChain }),
|
||||
...(isUpdate ? {} : { created_at: new Date().toISOString() }),
|
||||
updated_at: new Date().toISOString()
|
||||
[fieldMappings.certificate]: cert,
|
||||
[fieldMappings.privateKey]: certPrivateKey,
|
||||
...(certificateChain && { [fieldMappings.certificateChain]: certificateChain }),
|
||||
...(caCertificate && { [fieldMappings.caCertificate]: caCertificate })
|
||||
};
|
||||
|
||||
const itemExists = chefDataBagItems[targetItemName] === true;
|
||||
|
||||
@@ -19,6 +19,13 @@ export const ChefPkiSyncConfigSchema = z.object({
|
||||
)
|
||||
});
|
||||
|
||||
const ChefFieldMappingsSchema = z.object({
|
||||
certificate: z.string().min(1, "Certificate field name is required").default("certificate"),
|
||||
privateKey: z.string().min(1, "Private key field name is required").default("private_key"),
|
||||
certificateChain: z.string().min(1, "Certificate chain field name is required").default("certificate_chain"),
|
||||
caCertificate: z.string().min(1, "CA certificate field name is required").default("ca_certificate")
|
||||
});
|
||||
|
||||
const ChefPkiSyncOptionsSchema = z.object({
|
||||
canImportCertificates: z.boolean().default(false),
|
||||
canRemoveCertificates: z.boolean().default(true),
|
||||
@@ -57,7 +64,13 @@ const ChefPkiSyncOptionsSchema = z.object({
|
||||
message:
|
||||
"Certificate item name schema must include {{certificateId}} placeholder and result in names that contain only alphanumeric characters, underscores, and hyphens and be 1-255 characters long for Chef data bag items."
|
||||
}
|
||||
)
|
||||
),
|
||||
fieldMappings: ChefFieldMappingsSchema.optional().default({
|
||||
certificate: "certificate",
|
||||
privateKey: "private_key",
|
||||
certificateChain: "certificate_chain",
|
||||
caCertificate: "ca_certificate"
|
||||
})
|
||||
});
|
||||
|
||||
export const ChefPkiSyncSchema = PkiSyncSchema.extend({
|
||||
@@ -95,3 +108,5 @@ export const ChefPkiSyncListItemSchema = z.object({
|
||||
canImportCertificates: z.literal(false),
|
||||
canRemoveCertificates: z.literal(true)
|
||||
});
|
||||
|
||||
export { ChefFieldMappingsSchema };
|
||||
|
||||
@@ -3,6 +3,7 @@ import { z } from "zod";
|
||||
import { TChefConnection } from "@app/ee/services/app-connections/chef/chef-connection-types";
|
||||
|
||||
import {
|
||||
ChefFieldMappingsSchema,
|
||||
ChefPkiSyncConfigSchema,
|
||||
ChefPkiSyncSchema,
|
||||
CreateChefPkiSyncSchema,
|
||||
@@ -11,6 +12,8 @@ import {
|
||||
|
||||
export type TChefPkiSyncConfig = z.infer<typeof ChefPkiSyncConfigSchema>;
|
||||
|
||||
export type TChefFieldMappings = z.infer<typeof ChefFieldMappingsSchema>;
|
||||
|
||||
export type TChefPkiSync = z.infer<typeof ChefPkiSyncSchema>;
|
||||
|
||||
export type TChefPkiSyncInput = z.infer<typeof CreateChefPkiSyncSchema>;
|
||||
@@ -23,16 +26,7 @@ export type TChefPkiSyncWithCredentials = TChefPkiSync & {
|
||||
|
||||
export interface ChefCertificateDataBagItem {
|
||||
id: string;
|
||||
certificate: string;
|
||||
private_key: string;
|
||||
certificate_chain?: string;
|
||||
common_name?: string;
|
||||
alternative_names?: string;
|
||||
serial_number?: string;
|
||||
not_before?: string;
|
||||
not_after?: string;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface SyncCertificatesResult {
|
||||
|
||||
@@ -236,13 +236,15 @@ export const pkiSyncQueueFactory = ({
|
||||
}
|
||||
|
||||
let certificateChain: string | undefined;
|
||||
let caCertificate: string | undefined;
|
||||
try {
|
||||
if (certBody.encryptedCertificateChain) {
|
||||
const decryptedCertChain = await kmsDecryptor({
|
||||
cipherTextBlob: certBody.encryptedCertificateChain
|
||||
});
|
||||
certificateChain = decryptedCertChain.toString();
|
||||
} else if (certificate.caCertId) {
|
||||
}
|
||||
if (certificate.caCertId) {
|
||||
const { caCert, caCertChain } = await getCaCertChain({
|
||||
caCertId: certificate.caCertId,
|
||||
certificateAuthorityDAL,
|
||||
@@ -250,7 +252,10 @@ export const pkiSyncQueueFactory = ({
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
certificateChain = `${caCert}\n${caCertChain}`.trim();
|
||||
if (!certBody.encryptedCertificateChain) {
|
||||
certificateChain = `${caCert}\n${caCertChain}`.trim();
|
||||
}
|
||||
caCertificate = caCert;
|
||||
}
|
||||
} catch (chainError) {
|
||||
logger.warn(
|
||||
@@ -259,6 +264,7 @@ export const pkiSyncQueueFactory = ({
|
||||
);
|
||||
// Continue without certificate chain
|
||||
certificateChain = undefined;
|
||||
caCertificate = undefined;
|
||||
}
|
||||
|
||||
let certificateName: string;
|
||||
@@ -298,6 +304,7 @@ export const pkiSyncQueueFactory = ({
|
||||
cert: certificatePem,
|
||||
privateKey: certPrivateKey || "",
|
||||
certificateChain,
|
||||
caCertificate,
|
||||
alternativeNames,
|
||||
certificateId: certificate.id
|
||||
};
|
||||
|
||||
@@ -73,7 +73,14 @@ export type TPkiSyncListItem = TPkiSync & {
|
||||
|
||||
export type TCertificateMap = Record<
|
||||
string,
|
||||
{ cert: string; privateKey: string; certificateChain?: string; alternativeNames?: string[]; certificateId?: string }
|
||||
{
|
||||
cert: string;
|
||||
privateKey: string;
|
||||
certificateChain?: string;
|
||||
caCertificate?: string;
|
||||
alternativeNames?: string[];
|
||||
certificateId?: string;
|
||||
}
|
||||
>;
|
||||
|
||||
export type TCreatePkiSyncDTO = {
|
||||
|
||||
Reference in New Issue
Block a user