Change overview dynamic secret creation modal to set only one env

This commit is contained in:
carlosmonastyrski
2025-03-14 14:59:19 -03:00
parent 94d7d2b029
commit 6905029455
15 changed files with 335 additions and 456 deletions
@@ -53,7 +53,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -91,7 +91,7 @@ export const AwsElastiCacheInputForm = ({
"UserId": "{{username}}" "UserId": "{{username}}"
}` }`
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -102,33 +102,26 @@ export const AwsElastiCacheInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.AwsElastiCache, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL,
provider: { type: DynamicSecretProviders.AwsElastiCache, inputs: provider }, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch {
hasErrors = true;
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -319,19 +312,18 @@ export const AwsElastiCacheInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
/> />
@@ -42,7 +42,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -68,7 +68,7 @@ export const AwsIamInputForm = ({
} = useForm<TForm>({ } = useForm<TForm>({
resolver: zodResolver(formSchema), resolver: zodResolver(formSchema),
defaultValues: { defaultValues: {
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -79,33 +79,27 @@ export const AwsIamInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false;
const promises = selectedEnvs.map(async (env) => { try {
try { await createDynamicSecret.mutateAsync({
await createDynamicSecret.mutateAsync({ provider: { type: DynamicSecretProviders.AwsIam, inputs: provider },
provider: { type: DynamicSecretProviders.AwsIam, inputs: provider }, maxTTL,
maxTTL, name,
name, path: secretPath,
path: secretPath, defaultTTL,
defaultTTL, projectSlug,
projectSlug, environmentSlug: environment.slug
environmentSlug: env.slug });
});
} catch {
hasErrors = true;
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -307,19 +301,18 @@ export const AwsIamInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -62,7 +62,7 @@ const formSchema = z.object({
.string() .string()
.min(1) .min(1)
.refine((val) => val.toLowerCase() === val, "Must be lowercase"), .refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -89,7 +89,7 @@ export const AzureEntraIdInputForm = ({
} = useForm<TForm>({ } = useForm<TForm>({
resolver: zodResolver(formSchema), resolver: zodResolver(formSchema),
defaultValues: { defaultValues: {
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
const tenantId = watch("provider.tenantId"); const tenantId = watch("provider.tenantId");
@@ -113,44 +113,37 @@ export const AzureEntraIdInputForm = ({
provider, provider,
maxTTL, maxTTL,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { selectedUsers.map(async (user: { id: string; name: string; email: string }) => {
try { await createDynamicSecret.mutateAsync({
selectedUsers.map(async (user: { id: string; name: string; email: string }) => { provider: {
await createDynamicSecret.mutateAsync({ type: DynamicSecretProviders.AzureEntraId,
provider: { inputs: {
type: DynamicSecretProviders.AzureEntraId, userId: user.id,
inputs: { tenantId: provider.tenantId,
userId: user.id, email: user.email,
tenantId: provider.tenantId, applicationId: provider.applicationId,
email: user.email, clientSecret: provider.clientSecret
applicationId: provider.applicationId, }
clientSecret: provider.clientSecret },
} maxTTL,
}, name: `${name}-${user.name}`,
maxTTL, path: secretPath,
name: `${name}-${user.name}`, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug,
environmentSlug: env.slug
});
}); });
} catch { });
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -389,19 +382,18 @@ export const AzureEntraIdInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -55,7 +55,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -91,7 +91,7 @@ export const CassandraInputForm = ({
resolver: zodResolver(formSchema), resolver: zodResolver(formSchema),
defaultValues: { defaultValues: {
provider: getSqlStatements(), provider: getSqlStatements(),
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -102,33 +102,27 @@ export const CassandraInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false;
const promises = selectedEnvs.map(async (env) => { try {
try { await createDynamicSecret.mutateAsync({
await createDynamicSecret.mutateAsync({ provider: { type: DynamicSecretProviders.Cassandra, inputs: provider },
provider: { type: DynamicSecretProviders.Cassandra, inputs: provider }, maxTTL,
maxTTL, name,
name, path: secretPath,
path: secretPath, defaultTTL,
defaultTTL, projectSlug,
projectSlug, environmentSlug: environment.slug
environmentSlug: env.slug });
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -365,19 +359,18 @@ export const CassandraInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -76,7 +76,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -111,7 +111,7 @@ export const ElasticSearchInputForm = ({
roles: ["superuser"], roles: ["superuser"],
port: 443 port: 443
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -122,33 +122,26 @@ export const ElasticSearchInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.ElasticSearch, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL,
provider: { type: DynamicSecretProviders.ElasticSearch, inputs: provider }, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -426,19 +419,18 @@ export const ElasticSearchInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -79,7 +79,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -118,7 +118,7 @@ export const LdapInputForm = ({
rollbackLdif: "", rollbackLdif: "",
credentialType: CredentialType.Dynamic credentialType: CredentialType.Dynamic
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -131,33 +131,26 @@ export const LdapInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.Ldap, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL,
provider: { type: DynamicSecretProviders.Ldap, inputs: provider }, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -396,19 +389,18 @@ export const LdapInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -66,7 +66,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -112,7 +112,7 @@ export const MongoAtlasInputForm = ({
provider: { provider: {
roles: [{ databaseName: "", roleName: "" }] roles: [{ databaseName: "", roleName: "" }]
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -133,33 +133,26 @@ export const MongoAtlasInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.MongoAtlas, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL,
provider: { type: DynamicSecretProviders.MongoAtlas, inputs: provider }, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -458,19 +451,18 @@ export const MongoAtlasInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -56,7 +56,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -87,7 +87,7 @@ export const MongoDBDatabaseInputForm = ({
provider: { provider: {
roles: [{ roleName: "readWrite" }] roles: [{ roleName: "readWrite" }]
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -103,40 +103,33 @@ export const MongoDBDatabaseInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: {
await createDynamicSecret.mutateAsync({ type: DynamicSecretProviders.MongoDB,
provider: { inputs: {
type: DynamicSecretProviders.MongoDB, ...provider,
inputs: { port: provider?.port ? provider.port : undefined,
...provider, roles: provider.roles.map((el) => el.roleName)
port: provider?.port ? provider.port : undefined, }
roles: provider.roles.map((el) => el.roleName) },
} maxTTL,
}, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -348,19 +341,18 @@ export const MongoDBDatabaseInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -60,7 +60,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -100,7 +100,7 @@ export const RabbitMqInputForm = ({
}, },
tags: [] tags: []
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -111,33 +111,26 @@ export const RabbitMqInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.RabbitMq, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL,
provider: { type: DynamicSecretProviders.RabbitMq, inputs: provider }, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -432,19 +425,18 @@ export const RabbitMqInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -53,7 +53,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -85,7 +85,7 @@ export const RedisInputForm = ({
creationStatement: "ACL SETUSER {{username}} on >{{password}} ~* &* +@all", creationStatement: "ACL SETUSER {{username}} on >{{password}} ~* &* +@all",
revocationStatement: "ACL DELUSER {{username}}" revocationStatement: "ACL DELUSER {{username}}"
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -96,33 +96,26 @@ export const RedisInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.Redis, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL,
provider: { type: DynamicSecretProviders.Redis, inputs: provider }, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -333,19 +326,18 @@ export const RedisInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -51,7 +51,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -86,7 +86,7 @@ sp_role 'grant', 'mon_role', '{{username}}';`,
revocationStatement: `sp_dropuser '{{username}}'; revocationStatement: `sp_dropuser '{{username}}';
sp_droplogin '{{username}}';` sp_droplogin '{{username}}';`
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -97,33 +97,26 @@ sp_droplogin '{{username}}';`
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.SapAse, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL,
provider: { type: DynamicSecretProviders.SapAse, inputs: provider }, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -311,19 +304,18 @@ sp_droplogin '{{username}}';`
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -53,7 +53,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -86,7 +86,7 @@ GRANT "MONITORING" TO {{username}};`,
DROP USER {{username}};`, DROP USER {{username}};`,
renewStatement: "ALTER USER {{username}} VALID UNTIL '{{expiration}}';" renewStatement: "ALTER USER {{username}} VALID UNTIL '{{expiration}}';"
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -97,33 +97,26 @@ DROP USER {{username}};`,
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.SapHana, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL,
provider: { type: DynamicSecretProviders.SapHana, inputs: provider }, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret in environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -331,19 +324,18 @@ DROP USER {{username}};`,
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -57,7 +57,7 @@ const formSchema = z.object({
.trim() .trim()
.min(1) .min(1)
.refine((val) => val.toLowerCase() === val, "Must be lowercase"), .refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -89,7 +89,7 @@ export const SnowflakeInputForm = ({
revocationStatement: "DROP USER {{username}};", revocationStatement: "DROP USER {{username}};",
renewStatement: "ALTER USER {{username}} SET DAYS_TO_EXPIRY = {{expiration}};" renewStatement: "ALTER USER {{username}} SET DAYS_TO_EXPIRY = {{expiration}};"
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -100,33 +100,26 @@ export const SnowflakeInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.Snowflake, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL,
provider: { type: DynamicSecretProviders.Snowflake, inputs: provider }, name,
maxTTL, path: secretPath,
name, defaultTTL,
path: secretPath, projectSlug,
defaultTTL, environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch (err) {
createNotification({
type: "error",
text: err instanceof Error ? err.message : "Failed to create dynamic secret"
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch (err) {
createNotification({
type: "error",
text: err instanceof Error ? err.message : "Failed to create dynamic secret"
});
} }
}; };
@@ -334,19 +327,18 @@ export const SnowflakeInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -82,7 +82,7 @@ const formSchema = z.object({
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
}), }),
name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"), name: z.string().refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -176,7 +176,7 @@ export const SqlDatabaseInputForm = ({
allowedSymbols: "-_.~!*" allowedSymbols: "-_.~!*"
} }
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : undefined
} }
}); });
@@ -190,33 +190,27 @@ export const SqlDatabaseInputForm = ({
maxTTL, maxTTL,
provider, provider,
defaultTTL, defaultTTL,
environments: selectedEnvs environment
}: TForm) => { }: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false;
const promises = selectedEnvs.map(async (env) => { try {
try { await createDynamicSecret.mutateAsync({
await createDynamicSecret.mutateAsync({ provider: { type: DynamicSecretProviders.SqlDatabase, inputs: provider },
provider: { type: DynamicSecretProviders.SqlDatabase, inputs: provider }, maxTTL,
maxTTL, name,
name, path: secretPath,
path: secretPath, defaultTTL,
defaultTTL, projectSlug,
projectSlug, environmentSlug: environment.slug
environmentSlug: env.slug });
});
} catch {
createNotification({
type: "error",
text: `Failed to create dynamic secret for environment ${env.name}`
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch {
createNotification({
type: "error",
text: "Failed to create dynamic secret"
});
} }
}; };
@@ -669,19 +663,18 @@ export const SqlDatabaseInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"
@@ -61,7 +61,7 @@ const formSchema = z.object({
.trim() .trim()
.min(1) .min(1)
.refine((val) => val.toLowerCase() === val, "Must be lowercase"), .refine((val) => val.toLowerCase() === val, "Must be lowercase"),
environments: z.object({ name: z.string(), slug: z.string() }).array() environment: z.object({ name: z.string(), slug: z.string() })
}); });
type TForm = z.infer<typeof formSchema>; type TForm = z.infer<typeof formSchema>;
@@ -92,7 +92,7 @@ export const TotpInputForm = ({
provider: { provider: {
configType: ConfigType.URL configType: ConfigType.URL
}, },
environments: environments.length === 1 ? environments : [] environment: environments.length === 1 ? environments[0] : environments[0]
} }
}); });
@@ -100,36 +100,25 @@ export const TotpInputForm = ({
const createDynamicSecret = useCreateDynamicSecret(); const createDynamicSecret = useCreateDynamicSecret();
const handleCreateDynamicSecret = async ({ const handleCreateDynamicSecret = async ({ name, provider, environment }: TForm) => {
name,
provider,
environments: selectedEnvs
}: TForm) => {
// wait till previous request is finished // wait till previous request is finished
if (createDynamicSecret.isPending) return; if (createDynamicSecret.isPending) return;
let hasErrors = false; try {
const promises = selectedEnvs.map(async (env) => { await createDynamicSecret.mutateAsync({
try { provider: { type: DynamicSecretProviders.Totp, inputs: provider },
await createDynamicSecret.mutateAsync({ maxTTL: "24h",
provider: { type: DynamicSecretProviders.Totp, inputs: provider }, name,
maxTTL: "24h", path: secretPath,
name, defaultTTL: "1m",
path: secretPath, projectSlug,
defaultTTL: "1m", environmentSlug: environment.slug
projectSlug, });
environmentSlug: env.slug
});
} catch (err) {
createNotification({
type: "error",
text: err instanceof Error ? err.message : "Failed to create dynamic secret"
});
hasErrors = true;
}
});
await Promise.all(promises);
if (!hasErrors) {
onCompleted(); onCompleted();
} catch (err) {
createNotification({
type: "error",
text: err instanceof Error ? err.message : "Failed to create dynamic secret"
});
} }
}; };
@@ -319,19 +308,18 @@ export const TotpInputForm = ({
{environments.length > 1 && ( {environments.length > 1 && (
<Controller <Controller
control={control} control={control}
name="environments" name="environment"
render={({ field: { value, onChange }, fieldState: { error } }) => ( render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl <FormControl
label="Environments" label="Environment"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
> >
<FilterableSelect <FilterableSelect
isMulti
options={environments} options={environments}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder="Select environments to create secret in..." placeholder="Select the environment to create secret in..."
getOptionLabel={(option) => option.name} getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.slug} getOptionValue={(option) => option.slug}
menuPlacement="top" menuPlacement="top"