mirror of
https://github.com/MizuchiLabs/mantrae.git
synced 2025-12-16 20:05:17 -06:00
small frontend fix
This commit is contained in:
2
.github/workflows/cleanup.yml
vendored
2
.github/workflows/cleanup.yml
vendored
@@ -4,7 +4,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -25,10 +25,10 @@ var backupCron *cron.Cron
|
||||
// BackupData is the structure for the full manual backup
|
||||
type BackupData struct {
|
||||
Profiles []db.Profile `json:"profiles"`
|
||||
Configs []*traefik.Dynamic `json:"configs"`
|
||||
Providers []db.Provider `json:"providers"`
|
||||
Settings []db.Setting `json:"settings"`
|
||||
Users []db.User `json:"users"`
|
||||
Configs []*traefik.Dynamic `json:"configs"`
|
||||
}
|
||||
|
||||
func DumpBackup(ctx context.Context) (*BackupData, error) {
|
||||
@@ -44,12 +44,37 @@ func DumpBackup(ctx context.Context) (*BackupData, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get configs: %w", err)
|
||||
}
|
||||
|
||||
// We're only interested in the our local provider
|
||||
for _, config := range configs {
|
||||
dynamic, err := traefik.DecodeConfig(config)
|
||||
if err != nil {
|
||||
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)
|
||||
|
||||
@@ -450,7 +450,7 @@ func GetTraefikConfig() {
|
||||
|
||||
// Sync periodically syncs the Traefik configuration
|
||||
func Sync(ctx context.Context) {
|
||||
ticker := time.NewTicker(time.Second * 60)
|
||||
ticker := time.NewTicker(time.Second * 10)
|
||||
defer ticker.Stop()
|
||||
|
||||
GetTraefikConfig()
|
||||
|
||||
@@ -127,7 +127,6 @@
|
||||
const validate = () => {
|
||||
try {
|
||||
middleware.headers = headersSchema.parse(middleware.headers);
|
||||
console.log(middleware.headers.stsSeconds);
|
||||
errors = {};
|
||||
} catch (err) {
|
||||
if (err instanceof z.ZodError) {
|
||||
|
||||
@@ -83,7 +83,6 @@
|
||||
$: isNameTaken = $middlewares.some((m) => m.name === middleware.name + '@' + middleware.provider);
|
||||
|
||||
onMount(async () => {
|
||||
console.log(middleware);
|
||||
checkType();
|
||||
form = await LoadMiddlewareForm(middleware);
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
toggleMiddleware,
|
||||
toggleDNSProvider
|
||||
} 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 ArrayInput from '../ui/array-input/array-input.svelte';
|
||||
import logo from '$lib/images/logo.svg';
|
||||
@@ -25,23 +25,39 @@
|
||||
export let router: Router;
|
||||
export let disabled = false;
|
||||
|
||||
const formSchema = z.object({
|
||||
name: z.string({ required_error: 'Name is required' }).min(1).max(255),
|
||||
provider: z.string().optional(),
|
||||
status: z.string().optional(),
|
||||
routerType: z
|
||||
.string()
|
||||
.toLowerCase()
|
||||
.regex(/^(http|tcp|udp)$/),
|
||||
dnsProvider: z.coerce.number().int().nonnegative().optional(),
|
||||
entrypoints: 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' }),
|
||||
priority: z.coerce.number().int().nonnegative().optional(),
|
||||
tls: z.object({
|
||||
certResolver: z.string().trim().optional()
|
||||
const formSchema = z
|
||||
.object({
|
||||
name: z.string().trim().min(1, 'Name is required').max(255),
|
||||
provider: z.string().trim().optional(),
|
||||
status: z.string().trim().optional(),
|
||||
routerType: z
|
||||
.string()
|
||||
.toLowerCase()
|
||||
.regex(/^(http|tcp|udp)$/),
|
||||
dnsProvider: z.coerce.number().int().nonnegative().optional(),
|
||||
entrypoints: z.array(z.string()).optional(),
|
||||
middlewares: z.array(z.string()).optional(),
|
||||
rule: z.string().trim().optional(),
|
||||
priority: z.coerce.number().int().nonnegative().optional(),
|
||||
tls: z
|
||||
.object({
|
||||
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> = {};
|
||||
export const validate = () => {
|
||||
@@ -298,6 +314,9 @@
|
||||
|
||||
<!-- Rule -->
|
||||
{#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} />
|
||||
{/if}
|
||||
</Card.Content>
|
||||
|
||||
@@ -24,7 +24,19 @@
|
||||
.regex(/^(http|tcp|udp)$/),
|
||||
serverStatus: z.record(z.string()).optional(),
|
||||
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()
|
||||
})
|
||||
});
|
||||
@@ -33,7 +45,6 @@
|
||||
export const validate = () => {
|
||||
try {
|
||||
serviceSchema.parse({ ...service });
|
||||
|
||||
errors = {};
|
||||
return true;
|
||||
} catch (err) {
|
||||
@@ -45,7 +56,6 @@
|
||||
};
|
||||
|
||||
const update = () => {
|
||||
validate();
|
||||
if (service.loadBalancer === undefined) service.loadBalancer = { servers: [] };
|
||||
|
||||
service.loadBalancer.passHostHeader = passHostHeader;
|
||||
|
||||
Reference in New Issue
Block a user