refactor: prettify json of each setting

This commit is contained in:
Mauricio Siu
2024-05-18 14:38:55 -06:00
parent 5a70e616e6
commit 683a62f418
4 changed files with 272 additions and 99 deletions

View File

@@ -70,14 +70,16 @@ const PlacementSwarmSchema = z
}) })
.strict(); .strict();
const UpdateConfigSwarmSchema = z.object({ const UpdateConfigSwarmSchema = z
Parallelism: z.number(), .object({
Delay: z.number().optional(), Parallelism: z.number(),
FailureAction: z.string().optional(), Delay: z.number().optional(),
Monitor: z.number().optional(), FailureAction: z.string().optional(),
MaxFailureRatio: z.number().optional(), Monitor: z.number().optional(),
Order: z.string(), MaxFailureRatio: z.number().optional(),
}); Order: z.string(),
})
.strict();
const ReplicatedSchema = z const ReplicatedSchema = z
.object({ .object({
@@ -92,12 +94,14 @@ const ReplicatedJobSchema = z
}) })
.strict(); .strict();
const ServiceModeSwarmSchema = z.object({ const ServiceModeSwarmSchema = z
Replicated: ReplicatedSchema.optional(), .object({
Global: z.object({}).optional(), Replicated: ReplicatedSchema.optional(),
ReplicatedJob: ReplicatedJobSchema.optional(), Global: z.object({}).optional(),
GlobalJob: z.object({}).optional(), ReplicatedJob: ReplicatedJobSchema.optional(),
}); GlobalJob: z.object({}).optional(),
})
.strict();
const LabelsSwarmSchema = z.record(z.string()); const LabelsSwarmSchema = z.record(z.string());
@@ -191,40 +195,42 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
useEffect(() => { useEffect(() => {
if (data) { if (data) {
console.log(data.healthCheckSwarm, null);
form.reset({ form.reset({
healthCheckSwarm: data.healthCheckSwarm || null, healthCheckSwarm: data.healthCheckSwarm
restartPolicySwarm: data.restartPolicySwarm || null, ? JSON.stringify(data.healthCheckSwarm, null, 2)
placementSwarm: data.placementSwarm || null, : null,
updateConfigSwarm: data.updateConfigSwarm || null, restartPolicySwarm: data.restartPolicySwarm
rollbackConfigSwarm: data.rollbackConfigSwarm || null, ? JSON.stringify(data.restartPolicySwarm, null, 2)
modeSwarm: data.modeSwarm || null, : null,
labelsSwarm: data.labelsSwarm || null, placementSwarm: data.placementSwarm
? JSON.stringify(data.placementSwarm, null, 2)
: null,
updateConfigSwarm: data.updateConfigSwarm
? JSON.stringify(data.updateConfigSwarm, null, 2)
: null,
rollbackConfigSwarm: data.rollbackConfigSwarm
? JSON.stringify(data.rollbackConfigSwarm, null, 2)
: null,
modeSwarm: data.modeSwarm
? JSON.stringify(data.modeSwarm, null, 2)
: null,
labelsSwarm: data.labelsSwarm
? JSON.stringify(data.labelsSwarm, null, 2)
: null,
}); });
} }
}, [form, form.formState.isSubmitSuccessful, form.reset, data]); }, [form, form.reset, data]);
const onSubmit = async (data: AddSwarmSettings) => { const onSubmit = async (data: AddSwarmSettings) => {
console.log(data.restartPolicySwarm);
await mutateAsync({ await mutateAsync({
applicationId, applicationId,
healthCheckSwarm: data.healthCheckSwarm healthCheckSwarm: data.healthCheckSwarm,
? JSON.stringify(data.healthCheckSwarm) restartPolicySwarm: data.restartPolicySwarm,
: null, placementSwarm: data.placementSwarm,
restartPolicySwarm: data.restartPolicySwarm updateConfigSwarm: data.updateConfigSwarm,
? JSON.stringify(data.restartPolicySwarm) rollbackConfigSwarm: data.rollbackConfigSwarm,
: null, modeSwarm: data.modeSwarm,
placementSwarm: data.placementSwarm labelsSwarm: data.labelsSwarm,
? JSON.stringify(data.placementSwarm)
: null,
updateConfigSwarm: data.updateConfigSwarm
? JSON.stringify(data.updateConfigSwarm)
: null,
rollbackConfigSwarm: data.rollbackConfigSwarm
? JSON.stringify(data.rollbackConfigSwarm)
: null,
modeSwarm: data.modeSwarm ? JSON.stringify(data.modeSwarm) : null,
labelsSwarm: data.labelsSwarm ? JSON.stringify(data.labelsSwarm) : null,
}) })
.then(async () => { .then(async () => {
toast.success("Swarm settings updated"); toast.success("Swarm settings updated");
@@ -242,8 +248,8 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
Swarm Settings Swarm Settings
</Button> </Button>
</DialogTrigger> </DialogTrigger>
<DialogContent className="max-h-[85vh] overflow-y-auto sm:max-w-4xl"> <DialogContent className="max-h-[85vh] overflow-y-auto sm:max-w-5xl p-0">
<DialogHeader> <DialogHeader className="p-6">
<DialogTitle>Swarm Settings</DialogTitle> <DialogTitle>Swarm Settings</DialogTitle>
<DialogDescription> <DialogDescription>
Update certain settings using a json object. Update certain settings using a json object.
@@ -255,22 +261,27 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
<form <form
id="hook-form-add-permissions" id="hook-form-add-permissions"
onSubmit={form.handleSubmit(onSubmit)} onSubmit={form.handleSubmit(onSubmit)}
className="grid grid-cols-1 md:grid-cols-2 w-full gap-4" className="grid grid-cols-1 md:grid-cols-2 w-full gap-4 relative"
> >
<FormField <FormField
control={form.control} control={form.control}
name="healthCheckSwarm" name="healthCheckSwarm"
render={({ field }) => ( render={({ field }) => (
<FormItem className="relative"> <FormItem className="relative max-lg:px-4 lg:pl-6 ">
<FormLabel>Health Check</FormLabel> <FormLabel>Health Check</FormLabel>
<FormDescription className="break-all"> <FormDescription className="break-all">
Check the interface Check the interface
</FormDescription> </FormDescription>
<FormControl> <FormControl>
<Textarea <Textarea
className="font-mono [field-sizing:content;]" className="font-mono [field-sizing:content;] min-h-[11.2rem]"
placeholder={` placeholder={`{
`} "Test" : ["CMD-SHELL", "curl -f http://localhost:3000/health"],
"Interval" : 10000,
"Timeout" : 10000,
"StartPeriod" : 10000,
"Retries" : 10
}`}
{...field} {...field}
/> />
</FormControl> </FormControl>
@@ -285,7 +296,7 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
control={form.control} control={form.control}
name="restartPolicySwarm" name="restartPolicySwarm"
render={({ field }) => ( render={({ field }) => (
<FormItem className="relative"> <FormItem className="relative max-lg:px-4 lg:pr-6 ">
<FormLabel>Restart Policy</FormLabel> <FormLabel>Restart Policy</FormLabel>
<FormDescription className="break-all"> <FormDescription className="break-all">
{/* {path} */} {/* {path} */}
@@ -293,9 +304,13 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
</FormDescription> </FormDescription>
<FormControl> <FormControl>
<Textarea <Textarea
className="font-mono [field-sizing:content;]" className="font-mono [field-sizing:content;] min-h-[11.2rem]"
placeholder={` placeholder={`{
`} "Condition" : "on-failure",
"Delay" : 10000,
"MaxAttempts" : 10,
"Window" : 10000
} `}
{...field} {...field}
/> />
</FormControl> </FormControl>
@@ -310,16 +325,27 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
control={form.control} control={form.control}
name="placementSwarm" name="placementSwarm"
render={({ field }) => ( render={({ field }) => (
<FormItem className="relative"> <FormItem className="relative max-lg:px-4 lg:pl-6 ">
<FormLabel>Placement</FormLabel> <FormLabel>Placement</FormLabel>
<FormDescription className="break-all"> <FormDescription className="break-all">
Check the interface Check the interface
</FormDescription> </FormDescription>
<FormControl> <FormControl>
<Textarea <Textarea
className="font-mono [field-sizing:content;]" className="font-mono [field-sizing:content;] min-h-[18.7rem]"
placeholder={` placeholder={`{
`} "Constraints" : ["node.role==manager"],
"Preferences" : [{
"Spread" : {
"SpreadDescriptor" : "node.labels.region"
}
}],
"MaxReplicas" : 10,
"Platforms" : [{
"Architecture" : "amd64",
"OS" : "linux"
}]
} `}
{...field} {...field}
/> />
</FormControl> </FormControl>
@@ -334,16 +360,22 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
control={form.control} control={form.control}
name="updateConfigSwarm" name="updateConfigSwarm"
render={({ field }) => ( render={({ field }) => (
<FormItem className="relative"> <FormItem className="relative max-lg:px-4 lg:pr-6 ">
<FormLabel>Update Config</FormLabel> <FormLabel>Update Config</FormLabel>
<FormDescription className="break-all"> <FormDescription className="break-all">
Check the interface Check the interface
</FormDescription> </FormDescription>
<FormControl> <FormControl>
<Textarea <Textarea
className="font-mono [field-sizing:content;]" className="font-mono [field-sizing:content;] min-h-[18.7rem]"
placeholder={` placeholder={`{
`} "Parallelism" : 1,
"Delay" : 10000,
"FailureAction" : "continue",
"Monitor" : 10000,
"MaxFailureRatio" : 10,
"Order" : "start-first"
}`}
{...field} {...field}
/> />
</FormControl> </FormControl>
@@ -358,16 +390,22 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
control={form.control} control={form.control}
name="rollbackConfigSwarm" name="rollbackConfigSwarm"
render={({ field }) => ( render={({ field }) => (
<FormItem className="relative"> <FormItem className="relative max-lg:px-4 lg:pl-6 ">
<FormLabel>Rollback Config</FormLabel> <FormLabel>Rollback Config</FormLabel>
<FormDescription className="break-all"> <FormDescription className="break-all">
Check the interface Check the interface
</FormDescription> </FormDescription>
<FormControl> <FormControl>
<Textarea <Textarea
className="font-mono [field-sizing:content;]" className="font-mono [field-sizing:content;] min-h-[14.8rem]"
placeholder={` placeholder={`{
`} "Parallelism" : 1,
"Delay" : 10000,
"FailureAction" : "continue",
"Monitor" : 10000,
"MaxFailureRatio" : 10,
"Order" : "start-first"
}`}
{...field} {...field}
/> />
</FormControl> </FormControl>
@@ -382,16 +420,25 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
control={form.control} control={form.control}
name="modeSwarm" name="modeSwarm"
render={({ field }) => ( render={({ field }) => (
<FormItem className="relative"> <FormItem className="relative max-lg:px-4 lg:pr-6 ">
<FormLabel>Mode</FormLabel> <FormLabel>Mode</FormLabel>
<FormDescription className="break-all"> <FormDescription className="break-all">
Check the interface Check the interface
</FormDescription> </FormDescription>
<FormControl> <FormControl>
<Textarea <Textarea
className="font-mono [field-sizing:content;]" className="font-mono [field-sizing:content;] min-h-[14.8rem]"
placeholder={` placeholder={`{
`} "Replicated" : {
"Replicas" : 1
},
"Global" : {},
"ReplicatedJob" : {
"MaxConcurrent" : 1,
"TotalCompletions" : 1
},
"GlobalJob" : {}
}`}
{...field} {...field}
/> />
</FormControl> </FormControl>
@@ -406,7 +453,7 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
control={form.control} control={form.control}
name="labelsSwarm" name="labelsSwarm"
render={({ field }) => ( render={({ field }) => (
<FormItem className="relative"> <FormItem className="relative max-lg:px-4 lg:pl-6 ">
<FormLabel>Labels</FormLabel> <FormLabel>Labels</FormLabel>
<FormDescription className="break-all"> <FormDescription className="break-all">
Check the interface Check the interface
@@ -414,8 +461,10 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
<FormControl> <FormControl>
<Textarea <Textarea
className="font-mono [field-sizing:content;]" className="font-mono [field-sizing:content;]"
placeholder={` placeholder={`{
`} "com.example.app.name" : "my-app",
"com.example.app.version" : "1.0.0"
}`}
{...field} {...field}
/> />
</FormControl> </FormControl>
@@ -426,7 +475,7 @@ export const AddSwarmSettings = ({ applicationId }: Props) => {
)} )}
/> />
<DialogFooter className="flex w-full flex-row justify-end md:col-span-2"> <DialogFooter className="flex w-full flex-row justify-end md:col-span-2 m-0 sticky bottom-0 right-0 bg-muted border p-2 ">
<Button <Button
isLoading={isLoading} isLoading={isLoading}
form="hook-form-add-permissions" form="hook-form-add-permissions"

View File

@@ -166,6 +166,84 @@ export const applicationsRelations = relations(
}), }),
); );
const HealthCheckSwarmSchema = z
.object({
Test: z.array(z.string()).optional(),
Interval: z.number().optional(),
Timeout: z.number().optional(),
StartPeriod: z.number().optional(),
Retries: z.number().optional(),
})
.strict();
const RestartPolicySwarmSchema = z
.object({
Condition: z.string().optional(),
Delay: z.number().optional(),
MaxAttempts: z.number().optional(),
Window: z.number().optional(),
})
.strict();
const PreferenceSchema = z
.object({
Spread: z.object({
SpreadDescriptor: z.string(),
}),
})
.strict();
const PlatformSchema = z
.object({
Architecture: z.string(),
OS: z.string(),
})
.strict();
const PlacementSwarmSchema = z
.object({
Constraints: z.array(z.string()).optional(),
Preferences: z.array(PreferenceSchema).optional(),
MaxReplicas: z.number().optional(),
Platforms: z.array(PlatformSchema).optional(),
})
.strict();
const UpdateConfigSwarmSchema = z
.object({
Parallelism: z.number(),
Delay: z.number().optional(),
FailureAction: z.string().optional(),
Monitor: z.number().optional(),
MaxFailureRatio: z.number().optional(),
Order: z.string(),
})
.strict();
const ReplicatedSchema = z
.object({
Replicas: z.number().optional(),
})
.strict();
const ReplicatedJobSchema = z
.object({
MaxConcurrent: z.number().optional(),
TotalCompletions: z.number().optional(),
})
.strict();
const ServiceModeSwarmSchema = z
.object({
Replicated: ReplicatedSchema.optional(),
Global: z.object({}).optional(),
ReplicatedJob: ReplicatedJobSchema.optional(),
GlobalJob: z.object({}).optional(),
})
.strict();
const LabelsSwarmSchema = z.record(z.string());
const createSchema = createInsertSchema(applications, { const createSchema = createInsertSchema(applications, {
appName: z.string(), appName: z.string(),
createdAt: z.string(), createdAt: z.string(),
@@ -202,6 +280,68 @@ const createSchema = createInsertSchema(applications, {
"nixpacks", "nixpacks",
]), ]),
owner: z.string(), owner: z.string(),
healthCheckSwarm: HealthCheckSwarmSchema.nullable(),
restartPolicySwarm: RestartPolicySwarmSchema.nullable(),
placementSwarm: PlacementSwarmSchema.nullable(),
updateConfigSwarm: UpdateConfigSwarmSchema.nullable(),
rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable(),
modeSwarm: ServiceModeSwarmSchema.nullable(),
labelsSwarm: LabelsSwarmSchema.nullable(),
// restartPolicySwarm: z
// .object({
// Condition: z.string().optional(),
// Delay: z.number().optional(),
// MaxAttempts: z.number().optional(),
// Window: z.number().optional(),
// })
// .strict()
// .nullable(),
// placementSwarm: z
// .object({
// Constraints: z.array(z.string()).optional(),
// Preferences: z.array(PreferenceSchema).optional(),
// MaxReplicas: z.number().optional(),
// Platforms: z.array(PlatformSchema).optional(),
// })
// .strict()
// .nullable(),
// updateConfigSwarm: z
// .object({
// Parallelism: z.number(),
// Delay: z.number().optional(),
// FailureAction: z.string().optional(),
// Monitor: z.number().optional(),
// MaxFailureRatio: z.number().optional(),
// Order: z.string(),
// })
// .strict()
// .nullable(),
// rollbackConfigSwarm: z
// .object({
// Parallelism: z.number(),
// Delay: z.number().optional(),
// FailureAction: z.string().optional(),
// Monitor: z.number().optional(),
// MaxFailureRatio: z.number().optional(),
// Order: z.string(),
// })
// .strict()
// .nullable(),
// modeSwarm: z
// .object({
// Replicated: ReplicatedSchema.optional(),
// Global: z.object({}).optional(),
// ReplicatedJob: ReplicatedJobSchema.optional(),
// GlobalJob: z.object({}).optional(),
// })
// .strict()
// .nullable(),
// labelsSwarm: z
// .object({
// })
// .strict()
// .nullable(),
}); });
export const apiCreateApplication = createSchema.pick({ export const apiCreateApplication = createSchema.pick({

View File

@@ -100,8 +100,6 @@ export const mechanizeDockerContainer = async (
const registry = application.registry; const registry = application.registry;
console.log(Labels);
let image = let image =
sourceType === "docker" sourceType === "docker"
? dockerImage || "ERROR-NO-IMAGE-PROVIDED" ? dockerImage || "ERROR-NO-IMAGE-PROVIDED"
@@ -139,7 +137,6 @@ export const mechanizeDockerContainer = async (
Networks: [{ Target: "dokploy-network" }], Networks: [{ Target: "dokploy-network" }],
RestartPolicy, RestartPolicy,
Placement, Placement,
Resources: { Resources: {
...resources, ...resources,
}, },

View File

@@ -200,30 +200,17 @@ export const calculateResources = ({
}; };
export const generateConfigContainer = (application: ApplicationNested) => { export const generateConfigContainer = (application: ApplicationNested) => {
const { replicas, mounts } = application; const {
healthCheckSwarm,
const healthCheckSwarm = JSON.parse( restartPolicySwarm,
(application.healthCheckSwarm as string) || "{}", placementSwarm,
); updateConfigSwarm,
const restartPolicySwarm = JSON.parse( rollbackConfigSwarm,
(application.restartPolicySwarm as string) || "{}", modeSwarm,
); labelsSwarm,
const placementSwarm = JSON.parse( replicas,
(application.placementSwarm as string) || "{}", mounts,
); } = application;
const updateConfigSwarm = JSON.parse(
(application.updateConfigSwarm as unknown as string) || "{}",
);
const rollbackConfigSwarm = JSON.parse(
(application.rollbackConfigSwarm as unknown as string) || "{}",
);
const modeSwarm = JSON.parse((application.modeSwarm as string) || "{}");
const labelsSwarm = JSON.parse(
(application.labelsSwarm as unknown as string) || "{}",
);
const haveMounts = mounts.length > 0; const haveMounts = mounts.length > 0;