mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 20:26:44 +00:00
Add AWS secret manager PKI Sync
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
|
||||
import { FormControl, Select, SelectItem } from "@app/components/v2";
|
||||
import { AWS_REGIONS } from "@app/helpers/appConnections";
|
||||
import { PkiSync } from "@app/hooks/api/pkiSyncs";
|
||||
|
||||
import { TPkiSyncForm } from "./schemas/pki-sync-schema";
|
||||
import { PkiSyncConnectionField } from "./PkiSyncConnectionField";
|
||||
|
||||
export const AwsSecretsManagerPkiSyncFields = () => {
|
||||
const { control, setValue } = useFormContext<
|
||||
TPkiSyncForm & { destination: PkiSync.AwsSecretsManager }
|
||||
>();
|
||||
|
||||
return (
|
||||
<>
|
||||
<PkiSyncConnectionField
|
||||
onChange={() => {
|
||||
setValue("destinationConfig.region", "");
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
name="destinationConfig.region"
|
||||
control={control}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
label="AWS Region"
|
||||
tooltipText="Select the AWS region where your secrets will be stored in AWS Secrets Manager."
|
||||
>
|
||||
<Select
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
className="w-full border border-mineshaft-500 capitalize"
|
||||
position="popper"
|
||||
placeholder="Select an AWS region"
|
||||
>
|
||||
{AWS_REGIONS.map(({ name, slug }) => (
|
||||
<SelectItem value={slug} key={slug}>
|
||||
{name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -38,7 +38,7 @@ const getFormTabs = (
|
||||
{ name: "Sync Options", key: "options", fields: ["syncOptions"] as (keyof TPkiSyncForm)[] }
|
||||
];
|
||||
|
||||
if (destination === PkiSync.Chef) {
|
||||
if (destination === PkiSync.Chef || destination === PkiSync.AwsSecretsManager) {
|
||||
baseTabs.push({
|
||||
name: "Mappings",
|
||||
key: "mappings",
|
||||
@@ -82,13 +82,17 @@ export const CreatePkiSyncForm = ({ destination, onComplete, onCancel, initialDa
|
||||
canRemoveCertificates: false,
|
||||
preserveArn: true,
|
||||
certificateNameSchema: syncOption?.defaultCertificateNameSchema,
|
||||
...(destination === PkiSync.Chef && {
|
||||
...((destination === PkiSync.Chef || destination === PkiSync.AwsSecretsManager) && {
|
||||
fieldMappings: {
|
||||
certificate: "certificate",
|
||||
privateKey: "private_key",
|
||||
certificateChain: "certificate_chain",
|
||||
caCertificate: "ca_certificate"
|
||||
}
|
||||
}),
|
||||
...(destination === PkiSync.AwsSecretsManager && {
|
||||
preserveSecretOnRenewal: true,
|
||||
updateExistingCertificates: true
|
||||
})
|
||||
},
|
||||
...initialData
|
||||
@@ -259,7 +263,7 @@ export const CreatePkiSyncForm = ({ destination, onComplete, onCancel, initialDa
|
||||
}}
|
||||
/>
|
||||
</Tab.Panel>
|
||||
{destination === PkiSync.Chef && (
|
||||
{(destination === PkiSync.Chef || destination === PkiSync.AwsSecretsManager) && (
|
||||
<Tab.Panel className="max-h-full overflow-y-auto">
|
||||
<PkiSyncFieldMappingsFields destination={destination} />
|
||||
</Tab.Panel>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { PkiSync } from "@app/hooks/api/pkiSyncs";
|
||||
|
||||
import { TPkiSyncForm } from "./schemas/pki-sync-schema";
|
||||
import { AwsCertificateManagerPkiSyncFields } from "./AwsCertificateManagerPkiSyncFields";
|
||||
import { AwsSecretsManagerPkiSyncFields } from "./AwsSecretsManagerPkiSyncFields";
|
||||
import { AzureKeyVaultPkiSyncFields } from "./AzureKeyVaultPkiSyncFields";
|
||||
import { ChefPkiSyncFields } from "./ChefPkiSyncFields";
|
||||
|
||||
@@ -17,6 +18,8 @@ export const PkiSyncDestinationFields = () => {
|
||||
return <AzureKeyVaultPkiSyncFields />;
|
||||
case PkiSync.AwsCertificateManager:
|
||||
return <AwsCertificateManagerPkiSyncFields />;
|
||||
case PkiSync.AwsSecretsManager:
|
||||
return <AwsSecretsManagerPkiSyncFields />;
|
||||
case PkiSync.Chef:
|
||||
return <ChefPkiSyncFields />;
|
||||
default:
|
||||
|
||||
@@ -13,15 +13,15 @@ export const PkiSyncFieldMappingsFields = ({ destination }: Props) => {
|
||||
const { control, watch } = useFormContext<TPkiSyncForm>();
|
||||
const currentDestination = destination || watch("destination");
|
||||
|
||||
// Only show field mappings for Chef
|
||||
if (currentDestination !== PkiSync.Chef) {
|
||||
if (currentDestination !== PkiSync.Chef && currentDestination !== PkiSync.AwsSecretsManager) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="mb-4 text-sm text-bunker-300">
|
||||
Configure how certificate fields are mapped to your Chef data bag items.
|
||||
Configure how certificate fields are mapped to your{" "}
|
||||
{currentDestination === PkiSync.Chef ? "Chef data bag items" : "AWS secrets"}.
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
@@ -33,7 +33,7 @@ export const PkiSyncFieldMappingsFields = ({ destination }: Props) => {
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
label="Certificate Field"
|
||||
tooltipText="The field name used to store the certificate content in the Chef data bag item."
|
||||
tooltipText={`The field name used to store the certificate content in the ${currentDestination === PkiSync.Chef ? "Chef data bag item" : "AWS secret"}.`}
|
||||
>
|
||||
<Input {...field} placeholder="certificate" />
|
||||
</FormControl>
|
||||
@@ -48,7 +48,7 @@ export const PkiSyncFieldMappingsFields = ({ destination }: Props) => {
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
label="Private Key Field"
|
||||
tooltipText="The field name used to store the private key content in the Chef data bag item."
|
||||
tooltipText={`The field name used to store the private key content in the ${currentDestination === PkiSync.Chef ? "Chef data bag item" : "AWS secret"}.`}
|
||||
>
|
||||
<Input {...field} placeholder="private_key" />
|
||||
</FormControl>
|
||||
@@ -63,7 +63,7 @@ export const PkiSyncFieldMappingsFields = ({ destination }: Props) => {
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
label="Certificate Chain Field"
|
||||
tooltipText="The field name used to store the certificate chain content in the Chef data bag item."
|
||||
tooltipText={`The field name used to store the certificate chain content in the ${currentDestination === PkiSync.Chef ? "Chef data bag item" : "AWS secret"}.`}
|
||||
>
|
||||
<Input {...field} placeholder="certificate_chain" />
|
||||
</FormControl>
|
||||
@@ -78,7 +78,7 @@ export const PkiSyncFieldMappingsFields = ({ destination }: Props) => {
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
label="CA Certificate Field"
|
||||
tooltipText="The field name used to store the CA certificate content in the Chef data bag item."
|
||||
tooltipText={`The field name used to store the CA certificate content in the ${currentDestination === PkiSync.Chef ? "Chef data bag item" : "AWS secret"}.`}
|
||||
>
|
||||
<Input {...field} placeholder="ca_certificate" />
|
||||
</FormControl>
|
||||
|
||||
@@ -183,6 +183,51 @@ export const PkiSyncOptionsFields = ({ destination }: Props) => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentDestination === PkiSync.AwsSecretsManager && (
|
||||
<Controller
|
||||
control={control}
|
||||
name="syncOptions.preserveSecretOnRenewal"
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message}>
|
||||
<Switch
|
||||
className="bg-mineshaft-400/80 shadow-inner data-[state=checked]:bg-green/80"
|
||||
id="preserve-secret-on-renewal"
|
||||
thumbClassName="bg-mineshaft-800"
|
||||
onCheckedChange={onChange}
|
||||
isChecked={value}
|
||||
>
|
||||
<p>
|
||||
Preserve Secret on Renewal{" "}
|
||||
<Tooltip
|
||||
className="max-w-md"
|
||||
content={
|
||||
<>
|
||||
<p>
|
||||
<strong>Only applies to certificate renewals:</strong> When a certificate
|
||||
is renewed in Infisical, this option controls how the renewed certificate
|
||||
is handled in AWS Secrets Manager.
|
||||
</p>
|
||||
<p className="mt-4">
|
||||
When enabled, the renewed certificate will update the existing secret,
|
||||
preserving the same secret name and ARN. This allows consuming services to
|
||||
continue using the same secret reference without requiring updates.
|
||||
</p>
|
||||
<p className="mt-4">
|
||||
When disabled, the renewed certificate will be created as a new secret
|
||||
with a new name, and the old secret will be removed.
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<FontAwesomeIcon icon={faQuestionCircle} size="sm" className="ml-1" />
|
||||
</Tooltip>
|
||||
</p>
|
||||
</Switch>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentDestination === PkiSync.Chef && (
|
||||
<Controller
|
||||
control={control}
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { PkiSync } from "@app/hooks/api/pkiSyncs";
|
||||
|
||||
import { BasePkiSyncSchema } from "./base-pki-sync-schema";
|
||||
|
||||
const AwsSecretsManagerFieldMappingsSchema = 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 AwsSecretsManagerSyncOptionsSchema = z.object({
|
||||
canImportCertificates: z.boolean().default(false),
|
||||
canRemoveCertificates: z.boolean().default(true),
|
||||
preserveSecretOnRenewal: z.boolean().default(true),
|
||||
updateExistingCertificates: z.boolean().default(true),
|
||||
certificateNameSchema: z
|
||||
.string()
|
||||
.optional()
|
||||
.refine(
|
||||
(val) => {
|
||||
if (!val) return true;
|
||||
|
||||
const allowedOptionalPlaceholders = [
|
||||
"{{environment}}",
|
||||
"{{profileId}}",
|
||||
"{{commonName}}",
|
||||
"{{friendlyName}}"
|
||||
];
|
||||
|
||||
const allowedPlaceholdersRegexPart = ["{{certificateId}}", ...allowedOptionalPlaceholders]
|
||||
.map((p) => p.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"))
|
||||
.join("|");
|
||||
|
||||
const allowedContentRegex = new RegExp(
|
||||
`^([a-zA-Z0-9_\\-]|${allowedPlaceholdersRegexPart})*$`
|
||||
);
|
||||
const contentIsValid = allowedContentRegex.test(val);
|
||||
|
||||
if (val.trim()) {
|
||||
const certificateIdRegex = /\{\{certificateId\}\}/;
|
||||
const certificateIdIsPresent = certificateIdRegex.test(val);
|
||||
return contentIsValid && certificateIdIsPresent;
|
||||
}
|
||||
|
||||
return contentIsValid;
|
||||
},
|
||||
{
|
||||
message:
|
||||
"Certificate name schema must include exactly one {{certificateId}} placeholder. It can also include {{environment}}, {{profileId}}, {{commonName}}, or {{friendlyName}} placeholders. Only alphanumeric characters (a-z, A-Z, 0-9), hyphens (-), and underscores (_) are allowed besides the placeholders."
|
||||
}
|
||||
),
|
||||
fieldMappings: AwsSecretsManagerFieldMappingsSchema.optional().default({
|
||||
certificate: "certificate",
|
||||
privateKey: "private_key",
|
||||
certificateChain: "certificate_chain",
|
||||
caCertificate: "ca_certificate"
|
||||
})
|
||||
});
|
||||
|
||||
export const AwsSecretsManagerPkiSyncDestinationSchema = BasePkiSyncSchema(
|
||||
AwsSecretsManagerSyncOptionsSchema
|
||||
).merge(
|
||||
z.object({
|
||||
destination: z.literal(PkiSync.AwsSecretsManager),
|
||||
destinationConfig: z.object({
|
||||
region: z.string().min(1, "AWS region is required")
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
export const UpdateAwsSecretsManagerPkiSyncDestinationSchema =
|
||||
AwsSecretsManagerPkiSyncDestinationSchema.partial().merge(
|
||||
z.object({
|
||||
name: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "Name is required")
|
||||
.max(255, "Name must be less than 255 characters"),
|
||||
destination: z.literal(PkiSync.AwsSecretsManager),
|
||||
connection: z.object({
|
||||
id: z.string().uuid("Invalid connection ID format"),
|
||||
name: z
|
||||
.string()
|
||||
.min(1, "Connection name is required")
|
||||
.max(255, "Connection name must be less than 255 characters")
|
||||
})
|
||||
})
|
||||
);
|
||||
@@ -4,6 +4,10 @@ import {
|
||||
AwsCertificateManagerPkiSyncDestinationSchema,
|
||||
UpdateAwsCertificateManagerPkiSyncDestinationSchema
|
||||
} from "./aws-certificate-manager-pki-sync-destination-schema";
|
||||
import {
|
||||
AwsSecretsManagerPkiSyncDestinationSchema,
|
||||
UpdateAwsSecretsManagerPkiSyncDestinationSchema
|
||||
} from "./aws-secrets-manager-pki-sync-destination-schema";
|
||||
import {
|
||||
AzureKeyVaultPkiSyncDestinationSchema,
|
||||
UpdateAzureKeyVaultPkiSyncDestinationSchema
|
||||
@@ -16,12 +20,14 @@ import {
|
||||
const PkiSyncUnionSchema = z.discriminatedUnion("destination", [
|
||||
AzureKeyVaultPkiSyncDestinationSchema,
|
||||
AwsCertificateManagerPkiSyncDestinationSchema,
|
||||
AwsSecretsManagerPkiSyncDestinationSchema,
|
||||
ChefPkiSyncDestinationSchema
|
||||
]);
|
||||
|
||||
const UpdatePkiSyncUnionSchema = z.discriminatedUnion("destination", [
|
||||
UpdateAzureKeyVaultPkiSyncDestinationSchema,
|
||||
UpdateAwsCertificateManagerPkiSyncDestinationSchema,
|
||||
UpdateAwsSecretsManagerPkiSyncDestinationSchema,
|
||||
UpdateChefPkiSyncDestinationSchema
|
||||
]);
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@ export const PKI_SYNC_MAP: Record<
|
||||
name: "AWS Certificate Manager",
|
||||
image: "Amazon Web Services.png"
|
||||
},
|
||||
[PkiSync.AwsSecretsManager]: {
|
||||
name: "AWS Secrets Manager",
|
||||
image: "Amazon Web Services.png"
|
||||
},
|
||||
[PkiSync.Chef]: {
|
||||
name: "Chef",
|
||||
image: "Chef.png"
|
||||
@@ -25,5 +29,6 @@ export const PKI_SYNC_MAP: Record<
|
||||
export const PKI_SYNC_CONNECTION_MAP: Record<PkiSync, AppConnection> = {
|
||||
[PkiSync.AzureKeyVault]: AppConnection.AzureKeyVault,
|
||||
[PkiSync.AwsCertificateManager]: AppConnection.AWS,
|
||||
[PkiSync.AwsSecretsManager]: AppConnection.AWS,
|
||||
[PkiSync.Chef]: AppConnection.Chef
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export enum PkiSync {
|
||||
AzureKeyVault = "azure-key-vault",
|
||||
AwsCertificateManager = "aws-certificate-manager",
|
||||
AwsSecretsManager = "aws-secrets-manager",
|
||||
Chef = "chef"
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
|
||||
import { PkiSync } from "../enums";
|
||||
import { TRootPkiSync } from "./common";
|
||||
|
||||
export type TAwsSecretsManagerFieldMappings = {
|
||||
certificate: string;
|
||||
privateKey: string;
|
||||
certificateChain: string;
|
||||
caCertificate: string;
|
||||
};
|
||||
|
||||
export type TAwsSecretsManagerPkiSync = TRootPkiSync & {
|
||||
destination: PkiSync.AwsSecretsManager;
|
||||
destinationConfig: {
|
||||
region: string;
|
||||
keyId?: string;
|
||||
};
|
||||
connection: {
|
||||
app: AppConnection.AWS;
|
||||
name: string;
|
||||
id: string;
|
||||
};
|
||||
syncOptions: TRootPkiSync["syncOptions"] & {
|
||||
fieldMappings?: TAwsSecretsManagerFieldMappings;
|
||||
preserveSecretOnRenewal?: boolean;
|
||||
updateExistingCertificates?: boolean;
|
||||
};
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import { PkiSync } from "@app/hooks/api/pkiSyncs";
|
||||
|
||||
import { TAwsCertificateManagerPkiSync } from "./aws-certificate-manager-sync";
|
||||
import { TAwsSecretsManagerPkiSync } from "./aws-secrets-manager-sync";
|
||||
import { TAzureKeyVaultPkiSync } from "./azure-key-vault-sync";
|
||||
import { TChefPkiSync } from "./chef-sync";
|
||||
|
||||
@@ -17,7 +18,11 @@ export type TPkiSyncOption = {
|
||||
minCertificateNameLength?: number;
|
||||
};
|
||||
|
||||
export type TPkiSync = TAzureKeyVaultPkiSync | TAwsCertificateManagerPkiSync | TChefPkiSync;
|
||||
export type TPkiSync =
|
||||
| TAzureKeyVaultPkiSync
|
||||
| TAwsCertificateManagerPkiSync
|
||||
| TAwsSecretsManagerPkiSync
|
||||
| TChefPkiSync;
|
||||
|
||||
export type TListPkiSyncs = { pkiSyncs: TPkiSync[] };
|
||||
|
||||
@@ -36,6 +41,13 @@ type TCreatePkiSyncDTOBase = {
|
||||
enableVersioning?: boolean;
|
||||
preserveItemOnRenewal?: boolean;
|
||||
updateExistingCertificates?: boolean;
|
||||
preserveSecretOnRenewal?: boolean;
|
||||
fieldMappings?: {
|
||||
certificate: string;
|
||||
privateKey: string;
|
||||
certificateChain: string;
|
||||
caCertificate: string;
|
||||
};
|
||||
};
|
||||
isAutoSyncEnabled: boolean;
|
||||
subscriberId?: string | null;
|
||||
@@ -82,6 +94,7 @@ export type TTriggerPkiSyncRemoveCertificatesDTO = {
|
||||
};
|
||||
|
||||
export * from "./aws-certificate-manager-sync";
|
||||
export * from "./aws-secrets-manager-sync";
|
||||
export * from "./azure-key-vault-sync";
|
||||
export * from "./chef-sync";
|
||||
export * from "./common";
|
||||
|
||||
+4
@@ -13,6 +13,7 @@ import { PkiSync, TPkiSync } from "@app/hooks/api/pkiSyncs";
|
||||
|
||||
import {
|
||||
AwsCertificateManagerPkiSyncDestinationSection,
|
||||
AwsSecretsManagerPkiSyncDestinationSection,
|
||||
AzureKeyVaultPkiSyncDestinationSection,
|
||||
ChefPkiSyncDestinationSection
|
||||
} from "./PkiSyncDestinationSection/index";
|
||||
@@ -39,6 +40,9 @@ export const PkiSyncDestinationSection = ({ pkiSync, onEditDestination }: Props)
|
||||
case PkiSync.AwsCertificateManager:
|
||||
DestinationComponents = <AwsCertificateManagerPkiSyncDestinationSection pkiSync={pkiSync} />;
|
||||
break;
|
||||
case PkiSync.AwsSecretsManager:
|
||||
DestinationComponents = <AwsSecretsManagerPkiSyncDestinationSection pkiSync={pkiSync} />;
|
||||
break;
|
||||
case PkiSync.AzureKeyVault:
|
||||
DestinationComponents = <AzureKeyVaultPkiSyncDestinationSection pkiSync={pkiSync} />;
|
||||
break;
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import { TAwsSecretsManagerPkiSync, TPkiSync } from "@app/hooks/api/pkiSyncs";
|
||||
|
||||
const GenericFieldLabel = ({ label, children }: { label: string; children: React.ReactNode }) => (
|
||||
<div className="mb-4">
|
||||
<p className="text-sm font-medium text-mineshaft-300">{label}</p>
|
||||
<div className="text-sm text-mineshaft-300">{children}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
type Props = {
|
||||
pkiSync: TPkiSync;
|
||||
};
|
||||
|
||||
export const AwsSecretsManagerPkiSyncDestinationSection = ({ pkiSync }: Props) => {
|
||||
const awsSecretsManagerPkiSync = pkiSync as TAwsSecretsManagerPkiSync;
|
||||
const { destinationConfig } = awsSecretsManagerPkiSync;
|
||||
|
||||
return (
|
||||
<>
|
||||
<GenericFieldLabel label="AWS Region">
|
||||
{destinationConfig.region || "us-east-1"}
|
||||
</GenericFieldLabel>
|
||||
{destinationConfig.keyId && (
|
||||
<GenericFieldLabel label="KMS Key">{destinationConfig.keyId}</GenericFieldLabel>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
export { AwsCertificateManagerPkiSyncDestinationSection } from "./AwsCertificateManagerPkiSyncDestinationSection";
|
||||
export { AwsSecretsManagerPkiSyncDestinationSection } from "./AwsSecretsManagerPkiSyncDestinationSection";
|
||||
export { AzureKeyVaultPkiSyncDestinationSection } from "./AzureKeyVaultPkiSyncDestinationSection";
|
||||
export { ChefPkiSyncDestinationSection } from "./ChefPkiSyncDestinationSection";
|
||||
|
||||
+1
-2
@@ -30,8 +30,7 @@ type Props = {
|
||||
};
|
||||
|
||||
export const PkiSyncFieldMappingsSection = ({ pkiSync, onEditMappings }: Props) => {
|
||||
// Only show for Chef PKI syncs
|
||||
if (pkiSync.destination !== PkiSync.Chef) {
|
||||
if (pkiSync.destination !== PkiSync.Chef && pkiSync.destination !== PkiSync.AwsSecretsManager) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user