feat(dynamic-secret): Vertica option improvements

This commit is contained in:
carlosmonastyrski
2025-06-03 10:45:58 -03:00
parent ce67e5f137
commit ce5712606f
7 changed files with 285 additions and 84 deletions
@@ -1,10 +1,12 @@
import { Controller, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useQuery } from "@tanstack/react-query";
import ms from "ms";
import { z } from "zod";
import { TtlFormLabel } from "@app/components/features";
import { createNotification } from "@app/components/notifications";
import { OrgPermissionCan } from "@app/components/permissions";
import {
Accordion,
AccordionContent,
@@ -14,9 +16,16 @@ import {
FilterableSelect,
FormControl,
Input,
TextArea
Select,
SelectItem,
TextArea,
Tooltip
} from "@app/components/v2";
import { useCreateDynamicSecret } from "@app/hooks/api";
import {
OrgGatewayPermissionActions,
OrgPermissionSubjects
} from "@app/context/OrgPermissionContext/types";
import { gatewaysQueryKeys, useCreateDynamicSecret } from "@app/hooks/api";
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
import { WorkspaceEnv } from "@app/hooks/api/types";
@@ -50,7 +59,8 @@ const formSchema = z.object({
password: z.string().min(1),
passwordRequirements: passwordRequirementsSchema.optional(),
creationStatement: z.string().min(1),
revocationStatement: z.string().min(1)
revocationStatement: z.string().min(1),
gatewayId: z.string().optional()
}),
defaultTTL: z.string().superRefine((val, ctx) => {
const valMs = ms(val);
@@ -124,6 +134,7 @@ GRANT CREATE ON SCHEMA public TO {{username}};`,
});
const createDynamicSecret = useCreateDynamicSecret();
const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list());
const handleCreateDynamicSecret = async ({
name,
@@ -184,7 +195,7 @@ GRANT CREATE ON SCHEMA public TO {{username}};`,
defaultValue="1h"
render={({ field, fieldState: { error } }) => (
<FormControl
label={<TtlFormLabel label="Max TTL" />}
label={<TtlFormLabel label="Default TTL" />}
isError={Boolean(error?.message)}
errorText={error?.message}
>
@@ -200,7 +211,7 @@ GRANT CREATE ON SCHEMA public TO {{username}};`,
defaultValue="24h"
render={({ field, fieldState: { error } }) => (
<FormControl
label={<TtlFormLabel label="Default TTL" />}
label={<TtlFormLabel label="Max TTL" />}
isError={Boolean(error?.message)}
errorText={error?.message}
>
@@ -214,6 +225,57 @@ GRANT CREATE ON SCHEMA public TO {{username}};`,
<div className="mb-4 mt-4 border-b border-mineshaft-500 pb-2 pl-1 font-medium text-mineshaft-200">
Configuration
</div>
<div>
<OrgPermissionCan
I={OrgGatewayPermissionActions.AttachGateways}
a={OrgPermissionSubjects.Gateway}
>
{(isAllowed) => (
<Controller
control={control}
name="provider.gatewayId"
defaultValue=""
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
isError={Boolean(error?.message)}
errorText={error?.message}
label="Gateway"
>
<Tooltip
isDisabled={isAllowed}
content="Restricted access. You don't have permission to attach gateways to resources."
>
<div>
<Select
isDisabled={!isAllowed}
value={value}
onValueChange={onChange}
className="w-full border border-mineshaft-500"
dropdownContainerClassName="max-w-none"
isLoading={isGatewaysLoading}
placeholder="Default: Internet Gateway"
position="popper"
>
<SelectItem
value={null as unknown as string}
onClick={() => onChange(undefined)}
>
Internet Gateway
</SelectItem>
{gateways?.map((el) => (
<SelectItem value={el.id} key={el.id}>
{el.name}
</SelectItem>
))}
</Select>
</div>
</Tooltip>
</FormControl>
)}
/>
)}
</OrgPermissionCan>
</div>
<div className="flex flex-col">
<div className="flex items-center space-x-2">
<Controller
@@ -227,7 +289,7 @@ GRANT CREATE ON SCHEMA public TO {{username}};`,
isError={Boolean(error?.message)}
errorText={error?.message}
>
<Input placeholder="92.41.22.72" {...field} />
<Input placeholder="Vertica Host" {...field} />
</FormControl>
)}
/>
@@ -1,10 +1,12 @@
import { Controller, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useQuery } from "@tanstack/react-query";
import ms from "ms";
import { z } from "zod";
import { TtlFormLabel } from "@app/components/features";
import { createNotification } from "@app/components/notifications";
import { OrgPermissionCan } from "@app/components/permissions";
import {
Accordion,
AccordionContent,
@@ -13,9 +15,14 @@ import {
Button,
FormControl,
Input,
TextArea
Select,
SelectItem,
TextArea,
Tooltip
} from "@app/components/v2";
import { useUpdateDynamicSecret } from "@app/hooks/api";
import { OrgPermissionSubjects } from "@app/context";
import { OrgGatewayPermissionActions } from "@app/context/OrgPermissionContext/types";
import { gatewaysQueryKeys, useUpdateDynamicSecret } from "@app/hooks/api";
import { TDynamicSecret } from "@app/hooks/api/dynamicSecret/types";
const passwordRequirementsSchema = z
@@ -49,7 +56,8 @@ const formSchema = z.object({
password: z.string().min(1),
passwordRequirements: passwordRequirementsSchema.optional(),
creationStatement: z.string().min(1),
revocationStatement: z.string().min(1)
revocationStatement: z.string().min(1),
gatewayId: z.string().optional().nullable()
})
.partial(),
defaultTTL: z.string().superRefine((val, ctx) => {
@@ -122,8 +130,12 @@ export const EditDynamicSecretVerticaForm = ({
}
});
const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list());
const updateDynamicSecret = useUpdateDynamicSecret();
const selectedGatewayId = watch("inputs.gatewayId");
const isGatewayInActive = gateways?.findIndex((el) => el.id === selectedGatewayId) === -1;
const handleUpdateDynamicSecret = async ({
inputs,
maxTTL,
@@ -143,7 +155,10 @@ export const EditDynamicSecretVerticaForm = ({
data: {
maxTTL: maxTTL || undefined,
defaultTTL,
inputs,
inputs: {
...inputs,
gatewayId: isGatewayInActive ? null : inputs.gatewayId
},
newName: newName === dynamicSecret.name ? undefined : newName,
usernameTemplate: !usernameTemplate || isDefaultUsernameTemplate ? null : usernameTemplate
}
@@ -219,6 +234,62 @@ export const EditDynamicSecretVerticaForm = ({
<div className="mb-4 mt-4 border-b border-mineshaft-500 pb-2 pl-1 font-medium text-mineshaft-200">
Configuration
</div>
<div>
<OrgPermissionCan
I={OrgGatewayPermissionActions.AttachGateways}
a={OrgPermissionSubjects.Gateway}
>
{(isAllowed) => (
<Controller
control={control}
name="inputs.gatewayId"
defaultValue=""
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
isError={Boolean(error?.message) || isGatewayInActive}
errorText={
isGatewayInActive && selectedGatewayId
? `Project Gateway ${selectedGatewayId} is removed`
: error?.message
}
label="Gateway"
helperText=""
>
<Tooltip
isDisabled={isAllowed}
content="Restricted access. You don't have permission to attach gateways to resources."
>
<div>
<Select
isDisabled={!isAllowed}
value={value || undefined}
onValueChange={onChange}
className="w-full border border-mineshaft-500"
dropdownContainerClassName="max-w-none"
isLoading={isGatewaysLoading}
placeholder="Default: Internet Gateway"
position="popper"
>
<SelectItem
value={null as unknown as string}
onClick={() => onChange(undefined)}
>
Internet Gateway
</SelectItem>
{gateways?.map((el) => (
<SelectItem value={el.id} key={el.id}>
{el.name}
</SelectItem>
))}
</Select>
</div>
</Tooltip>
</FormControl>
)}
/>
)}
</OrgPermissionCan>
</div>
<div className="flex flex-col">
<div className="flex items-center space-x-2">
<Controller