mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 12:27:31 +00:00
Allow undefined value for tags to prevent unwanted overrides
This commit is contained in:
+2
-3
@@ -307,7 +307,6 @@ export const AwsParameterStoreSyncFns = {
|
|||||||
awsParameterStoreSecretsRecord,
|
awsParameterStoreSecretsRecord,
|
||||||
Boolean(syncOptions.tags?.length || syncOptions.syncSecretMetadataAsTags)
|
Boolean(syncOptions.tags?.length || syncOptions.syncSecretMetadataAsTags)
|
||||||
);
|
);
|
||||||
const syncTagsRecord = Object.fromEntries(syncOptions.tags?.map((tag) => [tag.key, tag.value]) ?? []);
|
|
||||||
|
|
||||||
for await (const entry of Object.entries(secretMap)) {
|
for await (const entry of Object.entries(secretMap)) {
|
||||||
const [key, { value, secretMetadata }] = entry;
|
const [key, { value, secretMetadata }] = entry;
|
||||||
@@ -342,13 +341,13 @@ export const AwsParameterStoreSyncFns = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldManageTags) {
|
if ((syncOptions.tags !== undefined || syncOptions.syncSecretMetadataAsTags) && shouldManageTags) {
|
||||||
const { tagsToAdd, tagKeysToRemove } = processParameterTags({
|
const { tagsToAdd, tagKeysToRemove } = processParameterTags({
|
||||||
syncTagsRecord: {
|
syncTagsRecord: {
|
||||||
// configured sync tags take preference over secret metadata
|
// configured sync tags take preference over secret metadata
|
||||||
...(syncOptions.syncSecretMetadataAsTags &&
|
...(syncOptions.syncSecretMetadataAsTags &&
|
||||||
Object.fromEntries(secretMetadata?.map((tag) => [tag.key, tag.value]) ?? [])),
|
Object.fromEntries(secretMetadata?.map((tag) => [tag.key, tag.value]) ?? [])),
|
||||||
...syncTagsRecord
|
...(syncOptions.tags && Object.fromEntries(syncOptions.tags?.map((tag) => [tag.key, tag.value]) ?? []))
|
||||||
},
|
},
|
||||||
awsTagsRecord: awsParameterStoreTagsRecord[key] ?? {}
|
awsTagsRecord: awsParameterStoreTagsRecord[key] ?? {}
|
||||||
});
|
});
|
||||||
|
|||||||
+55
-51
@@ -366,37 +366,39 @@ export const AwsSecretsManagerSyncFns = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tagsToAdd, tagKeysToRemove } = processTags({
|
if (syncOptions.tags !== undefined || syncOptions.syncSecretMetadataAsTags) {
|
||||||
syncTagsRecord: {
|
const { tagsToAdd, tagKeysToRemove } = processTags({
|
||||||
// configured sync tags take preference over secret metadata
|
syncTagsRecord: {
|
||||||
...(syncOptions.syncSecretMetadataAsTags &&
|
// configured sync tags take preference over secret metadata
|
||||||
Object.fromEntries(secretMetadata?.map((tag) => [tag.key, tag.value]) ?? [])),
|
...(syncOptions.syncSecretMetadataAsTags &&
|
||||||
...syncTagsRecord
|
Object.fromEntries(secretMetadata?.map((tag) => [tag.key, tag.value]) ?? [])),
|
||||||
},
|
...(syncOptions.tags !== undefined && syncTagsRecord)
|
||||||
awsTagsRecord: Object.fromEntries(
|
},
|
||||||
awsDescriptionsRecord[key]?.Tags?.map((tag) => [tag.Key!, tag.Value!]) ?? []
|
awsTagsRecord: Object.fromEntries(
|
||||||
)
|
awsDescriptionsRecord[key]?.Tags?.map((tag) => [tag.Key!, tag.Value!]) ?? []
|
||||||
});
|
)
|
||||||
|
});
|
||||||
|
|
||||||
if (tagsToAdd.length) {
|
if (tagsToAdd.length) {
|
||||||
try {
|
try {
|
||||||
await addTags(client, key, tagsToAdd);
|
await addTags(client, key, tagsToAdd);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new SecretSyncError({
|
throw new SecretSyncError({
|
||||||
error,
|
error,
|
||||||
secretKey: key
|
secretKey: key
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (tagKeysToRemove.length) {
|
if (tagKeysToRemove.length) {
|
||||||
try {
|
try {
|
||||||
await removeTags(client, key, tagKeysToRemove);
|
await removeTags(client, key, tagKeysToRemove);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new SecretSyncError({
|
throw new SecretSyncError({
|
||||||
error,
|
error,
|
||||||
secretKey: key
|
secretKey: key
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -439,32 +441,34 @@ export const AwsSecretsManagerSyncFns = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tagsToAdd, tagKeysToRemove } = processTags({
|
if (syncOptions.tags !== undefined) {
|
||||||
syncTagsRecord,
|
const { tagsToAdd, tagKeysToRemove } = processTags({
|
||||||
awsTagsRecord: Object.fromEntries(
|
syncTagsRecord,
|
||||||
awsDescriptionsRecord[destinationConfig.secretName]?.Tags?.map((tag) => [tag.Key!, tag.Value!]) ?? []
|
awsTagsRecord: Object.fromEntries(
|
||||||
)
|
awsDescriptionsRecord[destinationConfig.secretName]?.Tags?.map((tag) => [tag.Key!, tag.Value!]) ?? []
|
||||||
});
|
)
|
||||||
|
});
|
||||||
|
|
||||||
if (tagsToAdd.length) {
|
if (tagsToAdd.length) {
|
||||||
try {
|
try {
|
||||||
await addTags(client, destinationConfig.secretName, tagsToAdd);
|
await addTags(client, destinationConfig.secretName, tagsToAdd);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new SecretSyncError({
|
throw new SecretSyncError({
|
||||||
error,
|
error,
|
||||||
secretKey: destinationConfig.secretName
|
secretKey: destinationConfig.secretName
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (tagKeysToRemove.length) {
|
if (tagKeysToRemove.length) {
|
||||||
try {
|
try {
|
||||||
await removeTags(client, destinationConfig.secretName, tagKeysToRemove);
|
await removeTags(client, destinationConfig.secretName, tagKeysToRemove);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new SecretSyncError({
|
throw new SecretSyncError({
|
||||||
error,
|
error,
|
||||||
secretKey: destinationConfig.secretName
|
secretKey: destinationConfig.secretName
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+112
-70
@@ -22,87 +22,23 @@ import { SecretSync } from "@app/hooks/api/secretSyncs";
|
|||||||
|
|
||||||
import { TSecretSyncForm } from "../schemas";
|
import { TSecretSyncForm } from "../schemas";
|
||||||
|
|
||||||
export const AwsParameterStoreSyncOptionsFields = () => {
|
const AwsTagsSection = () => {
|
||||||
const { control, watch } = useFormContext<
|
const { control } = useFormContext<
|
||||||
TSecretSyncForm & { destination: SecretSync.AWSParameterStore }
|
TSecretSyncForm & { destination: SecretSync.AWSSecretsManager }
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const region = watch("destinationConfig.region");
|
|
||||||
const connectionId = useWatch({ name: "connection.id", control });
|
|
||||||
|
|
||||||
const { data: kmsKeys = [], isPending: isKmsKeysPending } = useListAwsConnectionKmsKeys(
|
|
||||||
{
|
|
||||||
connectionId,
|
|
||||||
region,
|
|
||||||
destination: SecretSync.AWSParameterStore
|
|
||||||
},
|
|
||||||
{ enabled: Boolean(connectionId && region) }
|
|
||||||
);
|
|
||||||
|
|
||||||
const tagFields = useFieldArray({
|
const tagFields = useFieldArray({
|
||||||
control,
|
control,
|
||||||
name: "syncOptions.tags"
|
name: "syncOptions.tags"
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="mb-4 mt-2 flex flex-col pl-2">
|
||||||
<Controller
|
|
||||||
name="syncOptions.keyId"
|
|
||||||
control={control}
|
|
||||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
tooltipText="The AWS KMS key to encrypt parameters with"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
label="KMS Key"
|
|
||||||
>
|
|
||||||
<FilterableSelect
|
|
||||||
isLoading={isKmsKeysPending && Boolean(connectionId && region)}
|
|
||||||
isDisabled={!connectionId}
|
|
||||||
value={kmsKeys.find((org) => org.alias === value) ?? null}
|
|
||||||
onChange={(option) =>
|
|
||||||
onChange((option as SingleValue<TAwsConnectionKmsKey>)?.alias ?? null)
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react/no-unstable-nested-components
|
|
||||||
noOptionsMessage={({ inputValue }) =>
|
|
||||||
inputValue ? undefined : (
|
|
||||||
<p>
|
|
||||||
To configure a KMS key, ensure the following permissions are present on the
|
|
||||||
selected IAM role:{" "}
|
|
||||||
<span className="rounded bg-mineshaft-600 text-mineshaft-300">
|
|
||||||
"kms:ListAliases"
|
|
||||||
</span>
|
|
||||||
,{" "}
|
|
||||||
<span className="rounded bg-mineshaft-600 text-mineshaft-300">
|
|
||||||
"kms:DescribeKey"
|
|
||||||
</span>
|
|
||||||
,{" "}
|
|
||||||
<span className="rounded bg-mineshaft-600 text-mineshaft-300">
|
|
||||||
"kms:Encrypt"
|
|
||||||
</span>
|
|
||||||
,{" "}
|
|
||||||
<span className="rounded bg-mineshaft-600 text-mineshaft-300">
|
|
||||||
"kms:Decrypt"
|
|
||||||
</span>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
options={kmsKeys}
|
|
||||||
placeholder="Leave blank to use default KMS key"
|
|
||||||
getOptionLabel={(option) =>
|
|
||||||
option.alias === "alias/aws/ssm" ? `${option.alias} (Default)` : option.alias
|
|
||||||
}
|
|
||||||
getOptionValue={(option) => option.alias}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormLabel
|
<FormLabel
|
||||||
label="Resource Tags"
|
label="Resource Tags"
|
||||||
tooltipText="Add resource tags to parameters synced by Infisical"
|
tooltipText="Add resource tags to parameters synced by Infisical"
|
||||||
/>
|
/>
|
||||||
<div className="mb-3 grid max-h-[20vh] grid-cols-12 flex-col items-end gap-2 overflow-y-auto">
|
<div className="grid max-h-[20vh] grid-cols-12 flex-col items-end gap-2 overflow-y-auto">
|
||||||
{tagFields.fields.map(({ id: tagFieldId }, i) => (
|
{tagFields.fields.map(({ id: tagFieldId }, i) => (
|
||||||
<Fragment key={tagFieldId}>
|
<Fragment key={tagFieldId}>
|
||||||
<div className="col-span-5">
|
<div className="col-span-5">
|
||||||
@@ -164,12 +100,118 @@ export const AwsParameterStoreSyncOptionsFields = () => {
|
|||||||
Add Tag
|
Add Tag
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AwsParameterStoreSyncOptionsFields = () => {
|
||||||
|
const { control, watch, setValue } = useFormContext<
|
||||||
|
TSecretSyncForm & { destination: SecretSync.AWSParameterStore }
|
||||||
|
>();
|
||||||
|
|
||||||
|
const region = watch("destinationConfig.region");
|
||||||
|
const connectionId = useWatch({ name: "connection.id", control });
|
||||||
|
const watchedTags = watch("syncOptions.tags");
|
||||||
|
|
||||||
|
const { data: kmsKeys = [], isPending: isKmsKeysPending } = useListAwsConnectionKmsKeys(
|
||||||
|
{
|
||||||
|
connectionId,
|
||||||
|
region,
|
||||||
|
destination: SecretSync.AWSParameterStore
|
||||||
|
},
|
||||||
|
{ enabled: Boolean(connectionId && region) }
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Controller
|
||||||
|
name="syncOptions.keyId"
|
||||||
|
control={control}
|
||||||
|
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
tooltipText="The AWS KMS key to encrypt parameters with"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
label="KMS Key"
|
||||||
|
>
|
||||||
|
<FilterableSelect
|
||||||
|
isLoading={isKmsKeysPending && Boolean(connectionId && region)}
|
||||||
|
isDisabled={!connectionId}
|
||||||
|
value={kmsKeys.find((org) => org.alias === value) ?? null}
|
||||||
|
onChange={(option) =>
|
||||||
|
onChange((option as SingleValue<TAwsConnectionKmsKey>)?.alias ?? null)
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react/no-unstable-nested-components
|
||||||
|
noOptionsMessage={({ inputValue }) =>
|
||||||
|
inputValue ? undefined : (
|
||||||
|
<p>
|
||||||
|
To configure a KMS key, ensure the following permissions are present on the
|
||||||
|
selected IAM role:{" "}
|
||||||
|
<span className="rounded bg-mineshaft-600 text-mineshaft-300">
|
||||||
|
"kms:ListAliases"
|
||||||
|
</span>
|
||||||
|
,{" "}
|
||||||
|
<span className="rounded bg-mineshaft-600 text-mineshaft-300">
|
||||||
|
"kms:DescribeKey"
|
||||||
|
</span>
|
||||||
|
,{" "}
|
||||||
|
<span className="rounded bg-mineshaft-600 text-mineshaft-300">
|
||||||
|
"kms:Encrypt"
|
||||||
|
</span>
|
||||||
|
,{" "}
|
||||||
|
<span className="rounded bg-mineshaft-600 text-mineshaft-300">
|
||||||
|
"kms:Decrypt"
|
||||||
|
</span>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
options={kmsKeys}
|
||||||
|
placeholder="Leave blank to use default KMS key"
|
||||||
|
getOptionLabel={(option) =>
|
||||||
|
option.alias === "alias/aws/ssm" ? `${option.alias} (Default)` : option.alias
|
||||||
|
}
|
||||||
|
getOptionValue={(option) => option.alias}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Switch
|
||||||
|
className="bg-mineshaft-400/50 shadow-inner data-[state=checked]:bg-green/80"
|
||||||
|
id="overwrite-tags"
|
||||||
|
thumbClassName="bg-mineshaft-800"
|
||||||
|
isChecked={Array.isArray(watchedTags)}
|
||||||
|
onCheckedChange={(isChecked) => {
|
||||||
|
if (isChecked) {
|
||||||
|
setValue("syncOptions.tags", []);
|
||||||
|
} else {
|
||||||
|
setValue("syncOptions.tags", undefined);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p className="w-[14rem]">
|
||||||
|
Override Resource Tags{" "}
|
||||||
|
<Tooltip
|
||||||
|
className="max-w-md"
|
||||||
|
content={
|
||||||
|
<p>
|
||||||
|
If enabled, AWS resource tags will be overwritten using static values defined below.
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faQuestionCircle} size="sm" className="ml-1" />
|
||||||
|
</Tooltip>
|
||||||
|
</p>
|
||||||
|
</Switch>
|
||||||
|
|
||||||
|
{Array.isArray(watchedTags) && <AwsTagsSection />}
|
||||||
|
|
||||||
<Controller
|
<Controller
|
||||||
name="syncOptions.syncSecretMetadataAsTags"
|
name="syncOptions.syncSecretMetadataAsTags"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
className="mt-6"
|
className="mt-4"
|
||||||
isError={Boolean(error?.message)}
|
isError={Boolean(error?.message)}
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
>
|
>
|
||||||
|
|||||||
+117
-70
@@ -23,14 +23,94 @@ import { AwsSecretsManagerSyncMappingBehavior } from "@app/hooks/api/secretSyncs
|
|||||||
|
|
||||||
import { TSecretSyncForm } from "../schemas";
|
import { TSecretSyncForm } from "../schemas";
|
||||||
|
|
||||||
|
const AwsTagsSection = () => {
|
||||||
|
const { control } = useFormContext<
|
||||||
|
TSecretSyncForm & { destination: SecretSync.AWSSecretsManager }
|
||||||
|
>();
|
||||||
|
|
||||||
|
const tagFields = useFieldArray({
|
||||||
|
control,
|
||||||
|
name: "syncOptions.tags"
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mb-4 mt-2 flex flex-col pl-2">
|
||||||
|
<FormLabel label="Tags" tooltipText="Add tags to secrets synced by Infisical" />
|
||||||
|
<div className="grid max-h-[20vh] grid-cols-12 flex-col items-end gap-2 overflow-y-auto">
|
||||||
|
{tagFields.fields.map(({ id: tagFieldId }, i) => (
|
||||||
|
<Fragment key={tagFieldId}>
|
||||||
|
<div className="col-span-5">
|
||||||
|
{i === 0 && <span className="text-xs text-mineshaft-400">Key</span>}
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`syncOptions.tags.${i}.key`}
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
isError={Boolean(error?.message)}
|
||||||
|
errorText={error?.message}
|
||||||
|
className="mb-0"
|
||||||
|
>
|
||||||
|
<Input className="text-xs" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-6">
|
||||||
|
{i === 0 && (
|
||||||
|
<FormLabel label="Value" className="text-xs text-mineshaft-400" isOptional />
|
||||||
|
)}
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name={`syncOptions.tags.${i}.value`}
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
isError={Boolean(error?.message)}
|
||||||
|
errorText={error?.message}
|
||||||
|
className="mb-0"
|
||||||
|
>
|
||||||
|
<Input className="text-xs" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Tooltip content="Remove tag" position="right">
|
||||||
|
<IconButton
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="Remove tag"
|
||||||
|
className="col-span-1 mb-1.5"
|
||||||
|
colorSchema="danger"
|
||||||
|
size="xs"
|
||||||
|
onClick={() => tagFields.remove(i)}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faTrash} />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 flex">
|
||||||
|
<Button
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
|
size="xs"
|
||||||
|
variant="outline_bg"
|
||||||
|
onClick={() => tagFields.append({ key: "", value: "" })}
|
||||||
|
>
|
||||||
|
Add Tag
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const AwsSecretsManagerSyncOptionsFields = () => {
|
export const AwsSecretsManagerSyncOptionsFields = () => {
|
||||||
const { control, watch } = useFormContext<
|
const { control, watch, setValue } = useFormContext<
|
||||||
TSecretSyncForm & { destination: SecretSync.AWSSecretsManager }
|
TSecretSyncForm & { destination: SecretSync.AWSSecretsManager }
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const region = watch("destinationConfig.region");
|
const region = watch("destinationConfig.region");
|
||||||
const connectionId = useWatch({ name: "connection.id", control });
|
const connectionId = useWatch({ name: "connection.id", control });
|
||||||
const mappingBehavior = watch("destinationConfig.mappingBehavior");
|
const mappingBehavior = watch("destinationConfig.mappingBehavior");
|
||||||
|
const watchedTags = watch("syncOptions.tags");
|
||||||
|
|
||||||
const { data: kmsKeys = [], isPending: isKmsKeysPending } = useListAwsConnectionKmsKeys(
|
const { data: kmsKeys = [], isPending: isKmsKeysPending } = useListAwsConnectionKmsKeys(
|
||||||
{
|
{
|
||||||
@@ -41,11 +121,6 @@ export const AwsSecretsManagerSyncOptionsFields = () => {
|
|||||||
{ enabled: Boolean(connectionId && region) }
|
{ enabled: Boolean(connectionId && region) }
|
||||||
);
|
);
|
||||||
|
|
||||||
const tagFields = useFieldArray({
|
|
||||||
control,
|
|
||||||
name: "syncOptions.tags"
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Controller
|
<Controller
|
||||||
@@ -102,75 +177,47 @@ export const AwsSecretsManagerSyncOptionsFields = () => {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<FormLabel label="Tags" tooltipText="Add tags to secrets synced by Infisical" />
|
|
||||||
<div className="mb-3 grid max-h-[20vh] grid-cols-12 flex-col items-end gap-2 overflow-y-auto">
|
<Switch
|
||||||
{tagFields.fields.map(({ id: tagFieldId }, i) => (
|
className="bg-mineshaft-400/50 shadow-inner data-[state=checked]:bg-green/80"
|
||||||
<Fragment key={tagFieldId}>
|
id="overwrite-tags"
|
||||||
<div className="col-span-5">
|
thumbClassName="bg-mineshaft-800"
|
||||||
{i === 0 && <span className="text-xs text-mineshaft-400">Key</span>}
|
isChecked={Array.isArray(watchedTags)}
|
||||||
<Controller
|
onCheckedChange={(isChecked) => {
|
||||||
control={control}
|
if (isChecked) {
|
||||||
name={`syncOptions.tags.${i}.key`}
|
setValue("syncOptions.tags", []);
|
||||||
render={({ field, fieldState: { error } }) => (
|
} else {
|
||||||
<FormControl
|
setValue("syncOptions.tags", undefined);
|
||||||
isError={Boolean(error?.message)}
|
}
|
||||||
errorText={error?.message}
|
}}
|
||||||
className="mb-0"
|
>
|
||||||
>
|
<p className="w-[14rem]">
|
||||||
<Input className="text-xs" {...field} />
|
Override Secret Tags{" "}
|
||||||
</FormControl>
|
<Tooltip
|
||||||
)}
|
className="max-w-md"
|
||||||
/>
|
content={
|
||||||
</div>
|
<p>
|
||||||
<div className="col-span-6">
|
If enabled, AWS secret tags will be overwritten using static values defined below.
|
||||||
{i === 0 && (
|
</p>
|
||||||
<FormLabel label="Value" className="text-xs text-mineshaft-400" isOptional />
|
}
|
||||||
)}
|
>
|
||||||
<Controller
|
<FontAwesomeIcon icon={faQuestionCircle} size="sm" className="ml-1" />
|
||||||
control={control}
|
</Tooltip>
|
||||||
name={`syncOptions.tags.${i}.value`}
|
</p>
|
||||||
render={({ field, fieldState: { error } }) => (
|
</Switch>
|
||||||
<FormControl
|
|
||||||
isError={Boolean(error?.message)}
|
{Array.isArray(watchedTags) && <AwsTagsSection />}
|
||||||
errorText={error?.message}
|
|
||||||
className="mb-0"
|
|
||||||
>
|
|
||||||
<Input className="text-xs" {...field} />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Tooltip content="Remove tag" position="right">
|
|
||||||
<IconButton
|
|
||||||
variant="plain"
|
|
||||||
ariaLabel="Remove tag"
|
|
||||||
className="col-span-1 mb-1.5"
|
|
||||||
colorSchema="danger"
|
|
||||||
size="xs"
|
|
||||||
onClick={() => tagFields.remove(i)}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faTrash} />
|
|
||||||
</IconButton>
|
|
||||||
</Tooltip>
|
|
||||||
</Fragment>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div className="mb-6 mt-2 flex">
|
|
||||||
<Button
|
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
|
||||||
size="xs"
|
|
||||||
variant="outline_bg"
|
|
||||||
onClick={() => tagFields.append({ key: "", value: "" })}
|
|
||||||
>
|
|
||||||
Add Tag
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
{mappingBehavior === AwsSecretsManagerSyncMappingBehavior.OneToOne && (
|
{mappingBehavior === AwsSecretsManagerSyncMappingBehavior.OneToOne && (
|
||||||
<Controller
|
<Controller
|
||||||
name="syncOptions.syncSecretMetadataAsTags"
|
name="syncOptions.syncSecretMetadataAsTags"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||||
<FormControl isError={Boolean(error?.message)} errorText={error?.message}>
|
<FormControl
|
||||||
|
isError={Boolean(error?.message)}
|
||||||
|
errorText={error?.message}
|
||||||
|
className="mt-4"
|
||||||
|
>
|
||||||
<Switch
|
<Switch
|
||||||
className="bg-mineshaft-400/50 shadow-inner data-[state=checked]:bg-green/80"
|
className="bg-mineshaft-400/50 shadow-inner data-[state=checked]:bg-green/80"
|
||||||
id="overwrite-existing-secrets"
|
id="overwrite-existing-secrets"
|
||||||
|
|||||||
Reference in New Issue
Block a user