small frontend fix

This commit is contained in:
d34dscene
2024-10-03 21:55:47 +02:00
parent 0c0347c41f
commit 7bed0552b0
7 changed files with 78 additions and 26 deletions

View File

@@ -25,10 +25,10 @@ var backupCron *cron.Cron
// BackupData is the structure for the full manual backup // BackupData is the structure for the full manual backup
type BackupData struct { type BackupData struct {
Profiles []db.Profile `json:"profiles"` Profiles []db.Profile `json:"profiles"`
Configs []*traefik.Dynamic `json:"configs"`
Providers []db.Provider `json:"providers"` Providers []db.Provider `json:"providers"`
Settings []db.Setting `json:"settings"` Settings []db.Setting `json:"settings"`
Users []db.User `json:"users"` Users []db.User `json:"users"`
Configs []*traefik.Dynamic `json:"configs"`
} }
func DumpBackup(ctx context.Context) (*BackupData, error) { func DumpBackup(ctx context.Context) (*BackupData, error) {
@@ -44,12 +44,37 @@ func DumpBackup(ctx context.Context) (*BackupData, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get configs: %w", err) return nil, fmt.Errorf("failed to get configs: %w", err)
} }
// We're only interested in the our local provider
for _, config := range configs { for _, config := range configs {
dynamic, err := traefik.DecodeConfig(config) dynamic, err := traefik.DecodeConfig(config)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to decode config: %w", err) return nil, fmt.Errorf("failed to decode config: %w", err)
} }
data.Configs = append(data.Configs, dynamic)
newDynamic := &traefik.Dynamic{
ProfileID: config.ProfileID,
Routers: make(map[string]traefik.Router),
Services: make(map[string]traefik.Service),
Middlewares: make(map[string]traefik.Middleware),
}
for i, router := range dynamic.Routers {
if router.Provider == "http" {
newDynamic.Routers[i] = router
}
}
for i, service := range dynamic.Services {
if service.Provider == "http" {
newDynamic.Services[i] = service
}
}
for i, middleware := range dynamic.Middlewares {
if middleware.Provider == "http" {
newDynamic.Middlewares[i] = middleware
}
}
data.Configs = append(data.Configs, newDynamic)
} }
data.Providers, err = db.Query.ListProviders(ctx) data.Providers, err = db.Query.ListProviders(ctx)

View File

@@ -450,7 +450,7 @@ func GetTraefikConfig() {
// Sync periodically syncs the Traefik configuration // Sync periodically syncs the Traefik configuration
func Sync(ctx context.Context) { func Sync(ctx context.Context) {
ticker := time.NewTicker(time.Second * 60) ticker := time.NewTicker(time.Second * 10)
defer ticker.Stop() defer ticker.Stop()
GetTraefikConfig() GetTraefikConfig()

View File

@@ -127,7 +127,6 @@
const validate = () => { const validate = () => {
try { try {
middleware.headers = headersSchema.parse(middleware.headers); middleware.headers = headersSchema.parse(middleware.headers);
console.log(middleware.headers.stsSeconds);
errors = {}; errors = {};
} catch (err) { } catch (err) {
if (err instanceof z.ZodError) { if (err instanceof z.ZodError) {

View File

@@ -83,7 +83,6 @@
$: isNameTaken = $middlewares.some((m) => m.name === middleware.name + '@' + middleware.provider); $: isNameTaken = $middlewares.some((m) => m.name === middleware.name + '@' + middleware.provider);
onMount(async () => { onMount(async () => {
console.log(middleware);
checkType(); checkType();
form = await LoadMiddlewareForm(middleware); form = await LoadMiddlewareForm(middleware);
}); });

View File

@@ -14,7 +14,7 @@
toggleMiddleware, toggleMiddleware,
toggleDNSProvider toggleDNSProvider
} from '$lib/api'; } from '$lib/api';
import { newRouter, type Router } from '$lib/types/config'; import { type Router } from '$lib/types/config';
import RuleEditor from '../utils/ruleEditor.svelte'; import RuleEditor from '../utils/ruleEditor.svelte';
import ArrayInput from '../ui/array-input/array-input.svelte'; import ArrayInput from '../ui/array-input/array-input.svelte';
import logo from '$lib/images/logo.svg'; import logo from '$lib/images/logo.svg';
@@ -25,10 +25,11 @@
export let router: Router; export let router: Router;
export let disabled = false; export let disabled = false;
const formSchema = z.object({ const formSchema = z
name: z.string({ required_error: 'Name is required' }).min(1).max(255), .object({
provider: z.string().optional(), name: z.string().trim().min(1, 'Name is required').max(255),
status: z.string().optional(), provider: z.string().trim().optional(),
status: z.string().trim().optional(),
routerType: z routerType: z
.string() .string()
.toLowerCase() .toLowerCase()
@@ -36,12 +37,27 @@
dnsProvider: z.coerce.number().int().nonnegative().optional(), dnsProvider: z.coerce.number().int().nonnegative().optional(),
entrypoints: z.array(z.string()).optional(), entrypoints: z.array(z.string()).optional(),
middlewares: z.array(z.string()).optional(), middlewares: z.array(z.string()).optional(),
rule: z.string({ required_error: 'Rule is required' }).min(1, { message: 'Rule is required' }), rule: z.string().trim().optional(),
priority: z.coerce.number().int().nonnegative().optional(), priority: z.coerce.number().int().nonnegative().optional(),
tls: z.object({ tls: z
.object({
certResolver: z.string().trim().optional() certResolver: z.string().trim().optional()
}) })
}); .optional()
})
.refine(
(data) => {
// Conditionally check if `rule` is required for `http` or `tcp`
if (['http', 'tcp'].includes(data.routerType) && !data.rule) {
return false;
}
return true;
},
{
message: 'Rule is required for HTTP and TCP routers',
path: ['rule'] // This points to the 'rule' field
}
);
let errors: Record<any, string[] | undefined> = {}; let errors: Record<any, string[] | undefined> = {};
export const validate = () => { export const validate = () => {
@@ -298,6 +314,9 @@
<!-- Rule --> <!-- Rule -->
{#if router.routerType === 'http' || router.routerType === 'tcp'} {#if router.routerType === 'http' || router.routerType === 'tcp'}
{#if errors.rule}
<div class="col-span-4 text-right text-sm text-red-500">{errors.rule}</div>
{/if}
<RuleEditor bind:rule={router.rule} bind:type={router.routerType} {disabled} /> <RuleEditor bind:rule={router.rule} bind:type={router.routerType} {disabled} />
{/if} {/if}
</Card.Content> </Card.Content>

View File

@@ -24,7 +24,19 @@
.regex(/^(http|tcp|udp)$/), .regex(/^(http|tcp|udp)$/),
serverStatus: z.record(z.string()).optional(), serverStatus: z.record(z.string()).optional(),
loadBalancer: z.object({ loadBalancer: z.object({
servers: z.array(z.object({ url: z.string() }).or(z.object({ address: z.string() }))), servers: z
.array(
z
.object({
url: z.string().trim().optional(),
address: z.string().trim().optional()
})
.refine((data) => data.url || data.address, {
message: 'At least one server is required',
path: ['servers'] // Points to the 'servers' array in case of error
})
)
.nonempty('At least one server is required'),
passHostHeader: z.boolean().optional() passHostHeader: z.boolean().optional()
}) })
}); });
@@ -33,7 +45,6 @@
export const validate = () => { export const validate = () => {
try { try {
serviceSchema.parse({ ...service }); serviceSchema.parse({ ...service });
errors = {}; errors = {};
return true; return true;
} catch (err) { } catch (err) {
@@ -45,7 +56,6 @@
}; };
const update = () => { const update = () => {
validate();
if (service.loadBalancer === undefined) service.loadBalancer = { servers: [] }; if (service.loadBalancer === undefined) service.loadBalancer = { servers: [] };
service.loadBalancer.passHostHeader = passHostHeader; service.loadBalancer.passHostHeader = passHostHeader;