General improvements to Terraform Integration

This commit is contained in:
carlosmonastyrski
2025-04-09 20:15:24 -03:00
parent 05af70161a
commit 993eb4d239
16 changed files with 109 additions and 139 deletions
@@ -17,7 +17,6 @@ export const SecretSyncDestinationFields = () => {
const { watch } = useFormContext<TSecretSyncForm>();
const destination = watch("destination");
console.log(destination);
switch (destination) {
case SecretSync.AWSParameterStore:
@@ -1,10 +1,8 @@
import { Controller, useFormContext, useWatch } from "react-hook-form";
import { SingleValue } from "react-select";
import { faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { SecretSyncConnectionField } from "@app/components/secret-syncs/forms/SecretSyncConnectionField";
import { FilterableSelect, FormControl, Select, SelectItem, Tooltip } from "@app/components/v2";
import { FilterableSelect, FormControl, Select, SelectItem } from "@app/components/v2";
import {
TERRAFORM_CLOUD_SYNC_SCOPES,
TerraformCloudSyncCategory,
@@ -82,6 +80,28 @@ export const TerraformCloudSyncFields = () => {
errorText={error?.message}
isError={Boolean(error?.message)}
label="Category"
tooltipClassName="max-w-lg py-3"
tooltipText={
<div className="flex flex-col gap-3">
<ul className="flex list-disc flex-col gap-3 pl-4">
<li>
<p className="text-mineshaft-300">
<span className="font-medium text-bunker-200">
Environment variables configure Terraform&apos;s behavior (e.g.,
credentials).
</span>
</p>
</li>
<li>
<p className="text-mineshaft-300">
<span className="font-medium text-bunker-200">
Terraform variables are used as input values in your configuration.
</span>
</p>
</li>
</ul>
</div>
}
>
<Select
value={value}
@@ -92,9 +112,9 @@ export const TerraformCloudSyncFields = () => {
placeholder="Select category..."
dropdownContainerClassName="max-w-none"
>
{Object.values(TerraformCloudSyncCategory).map((category) => (
<SelectItem className="capitalize" value={category} key={category}>
{category.replace("-", " ")}
{Object.entries(TerraformCloudSyncCategory).map(([envKey, envValue]) => (
<SelectItem className="capitalize" value={envValue} key={envValue}>
{envKey.replace("-", " ")}
</SelectItem>
))}
</Select>
@@ -157,22 +177,7 @@ export const TerraformCloudSyncFields = () => {
name="destinationConfig.destinationId"
control={control}
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
isError={Boolean(error)}
errorText={error?.message}
label="Variable Set"
helperText={
<Tooltip
className="max-w-md"
content="Ensure that the variable set exists in the selected organization and the service account used on this connection has write permissions for the specified variable set."
>
<div>
<span>Don&#39;t see the variable set you&#39;re looking for?</span>{" "}
<FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-400" />
</div>
</Tooltip>
}
>
<FormControl isError={Boolean(error)} errorText={error?.message} label="Variable Set">
<FilterableSelect
menuPlacement="top"
isLoading={isOrganizationsPending && Boolean(connectionId) && Boolean(currentOrg)}
@@ -203,22 +208,7 @@ export const TerraformCloudSyncFields = () => {
name="destinationConfig.destinationId"
control={control}
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
isError={Boolean(error)}
errorText={error?.message}
label="Workspace"
helperText={
<Tooltip
className="max-w-md"
content="Ensure that the workspace exists in the selected organization and the service account used on this connection has write permissions for the specified workspace."
>
<div>
<span>Don&#39;t see the workspace you&#39;re looking for?</span>{" "}
<FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-400" />
</div>
</Tooltip>
}
>
<FormControl isError={Boolean(error)} errorText={error?.message} label="Workspace">
<FilterableSelect
menuPlacement="top"
isLoading={isOrganizationsPending && Boolean(connectionId) && Boolean(currentOrg)}
@@ -14,14 +14,14 @@ export const TerraformCloudSyncDestinationSchema = BaseSecretSyncSchema().merge(
z.object({
scope: z.literal(TerraformCloudSyncScope.VariableSet),
org: z.string().trim().min(1, "Organization required"),
destinationId: z.string().trim().min(1, "Variable set id required"),
destinationId: z.string().trim().min(1, "Variable Set required"),
destinationName: z.string().trim().min(1, "Variable set name required"),
category: z.nativeEnum(TerraformCloudSyncCategory)
}),
z.object({
scope: z.literal(TerraformCloudSyncScope.Workspace),
org: z.string().trim().min(1, "Organization required"),
destinationId: z.string().trim().min(1, "Workspace id required"),
destinationId: z.string().trim().min(1, "Workspace required"),
destinationName: z.string().trim().min(1, "Workspace name required"),
category: z.nativeEnum(TerraformCloudSyncCategory)
})
-1
View File
@@ -52,7 +52,6 @@ export const getAppConnectionMethodDetails = (method: TAppConnection["method"])
case DatabricksConnectionMethod.ServicePrincipal:
return { name: "Service Principal", icon: faUser };
case HumanitecConnectionMethod.ApiToken:
return { name: "API Token", icon: faKey };
case TerraformCloudConnectionMethod.ApiToken:
return { name: "API Token", icon: faKey };
case PostgresConnectionMethod.UsernameAndPassword:
@@ -35,7 +35,7 @@ const formSchema = z.discriminatedUnion("method", [
rootSchema.extend({
method: z.literal(TerraformCloudConnectionMethod.ApiToken),
credentials: z.object({
apiToken: z.string().trim().min(1, "Service API Token required")
apiToken: z.string().trim().min(1, "API Token required")
})
})
]);
@@ -102,7 +102,7 @@ export const TerraformCloudConnectionForm = ({ appConnection, onSubmit }: Props)
<FormControl
errorText={error?.message}
isError={Boolean(error?.message)}
label="Service API Token"
label="API Token"
>
<SecretInput
containerClassName="text-gray-400 group-focus-within:!border-primary-400/50 border border-mineshaft-500 bg-mineshaft-900 px-2.5 py-1.5"
@@ -9,7 +9,6 @@ import { ProjectPermissionSub } from "@app/context";
import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types";
import { APP_CONNECTION_MAP } from "@app/helpers/appConnections";
import { SecretSync, TSecretSync } from "@app/hooks/api/secretSyncs";
import { TerraformCloudSyncDestinationCol } from "@app/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/TerraformCloudSyncDestinationCol";
import { AwsParameterStoreSyncDestinationSection } from "@app/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/AwsParameterStoreSyncDestinationSection";
import { AwsSecretsManagerSyncDestinationSection } from "@app/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/AwsSecretsManagerSyncDestinationSection";
import { DatabricksSyncDestinationSection } from "@app/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/DatabricksSyncDestinationSection";
@@ -19,6 +18,7 @@ import { AzureAppConfigurationSyncDestinationSection } from "./AzureAppConfigura
import { AzureKeyVaultSyncDestinationSection } from "./AzureKeyVaultSyncDestinationSection";
import { GcpSyncDestinationSection } from "./GcpSyncDestinationSection";
import { HumanitecSyncDestinationSection } from "./HumanitecSyncDestinationSection";
import { TerraformCloudSyncDestinationSection } from "./TerraformCloudSyncDestinationCol";
type Props = {
secretSync: TSecretSync;
@@ -59,7 +59,7 @@ export const SecretSyncDestinationSection = ({ secretSync, onEditDestination }:
DestinationComponents = <HumanitecSyncDestinationSection secretSync={secretSync} />;
break;
case SecretSync.TerraformCloud:
DestinationComponents = <TerraformCloudSyncDestinationCol secretSync={secretSync} />;
DestinationComponents = <TerraformCloudSyncDestinationSection secretSync={secretSync} />;
break;
default:
throw new Error(`Unhandled Destination Section components: ${destination}`);