feat: Implement load balancing and health check features for service groups, including DNS-based load balancing modes and health check configurations, enhancing service reliability and performance monitoring
Build, Test, and Push CFDM Docker Image / test (push) Successful in 4m0s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Successful in 2m13s
Build, Test, and Push CFDM Docker Image / update-wiki (push) Failing after 6s
Build, Test, and Push CFDM Docker Image / create-release (push) Has been skipped
Build, Test, and Push CFDM Docker Image / test (push) Successful in 4m0s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Successful in 2m13s
Build, Test, and Push CFDM Docker Image / update-wiki (push) Failing after 6s
Build, Test, and Push CFDM Docker Image / create-release (push) Has been skipped
This commit is contained in:
Vendored
+91
-3
@@ -160,6 +160,20 @@ function bindingToFqdn(binding) {
|
||||
// src/schemas.ts
|
||||
import { z } from "zod";
|
||||
var certMonitoringSchema = z.enum(["auto", "required", "skipped"]);
|
||||
var lbModeSchema = z.enum(["round_robin", "failover", "weighted"]);
|
||||
var healthCheckTypeSchema = z.enum(["tcp", "http"]);
|
||||
var ipHealthStateSchema = z.enum(["up", "down", "degraded", "unknown"]);
|
||||
var healthCheckScopeSchema = z.enum(["binding", "group"]);
|
||||
var ipHealthStatusSchema = z.object({
|
||||
scope: healthCheckScopeSchema,
|
||||
ref_id: z.number(),
|
||||
ip: z.string(),
|
||||
status: ipHealthStateSchema,
|
||||
latency_ms: z.number().nullable(),
|
||||
consecutive_failures: z.number(),
|
||||
last_checked_at: z.string().nullable(),
|
||||
last_error: z.string().nullable()
|
||||
});
|
||||
var groupSchema = z.object({
|
||||
id: z.number(),
|
||||
name: z.string(),
|
||||
@@ -184,6 +198,14 @@ var serviceGroupSchema = z.object({
|
||||
icon: z.string().nullable(),
|
||||
domain: z.string().nullable(),
|
||||
enabled: z.boolean(),
|
||||
lb_mode: lbModeSchema.catch("round_robin"),
|
||||
health_check_enabled: z.boolean().default(false),
|
||||
health_check_type: healthCheckTypeSchema.catch("tcp"),
|
||||
health_check_port: z.number().nullable(),
|
||||
health_check_path: z.string().nullable(),
|
||||
health_check_expected_status: z.number().nullable(),
|
||||
health_check_interval_sec: z.number().default(30),
|
||||
health_check_timeout_ms: z.number().default(3e3),
|
||||
created_at: z.string(),
|
||||
updated_at: z.string()
|
||||
});
|
||||
@@ -195,6 +217,8 @@ var serviceSchema = z.object({
|
||||
subdomain: z.string().optional(),
|
||||
enabled: z.boolean().optional(),
|
||||
computed_fqdn: z.string().nullable().optional(),
|
||||
lb_weight: z.number().default(1),
|
||||
lb_priority: z.number().default(1),
|
||||
created_at: z.string(),
|
||||
updated_at: z.string()
|
||||
});
|
||||
@@ -207,11 +231,23 @@ var serviceDomainBindingSchema = z.object({
|
||||
record_type: z.enum(["A", "CNAME"]).default("A"),
|
||||
target_ips: z.array(z.string()).optional(),
|
||||
target_ip: z.string().nullable().optional(),
|
||||
target_ip_weights: z.record(z.string(), z.number()).optional(),
|
||||
target_ip_priorities: z.record(z.string(), z.number()).optional(),
|
||||
target_cname: z.string().nullable().optional(),
|
||||
lb_mode: lbModeSchema.catch("round_robin"),
|
||||
health_check_enabled: z.boolean().default(false),
|
||||
health_check_type: healthCheckTypeSchema.catch("tcp"),
|
||||
health_check_port: z.number().nullable(),
|
||||
health_check_path: z.string().nullable(),
|
||||
health_check_expected_status: z.number().nullable(),
|
||||
health_check_interval_sec: z.number().default(30),
|
||||
health_check_timeout_ms: z.number().default(3e3),
|
||||
sync_status: z.string().nullable()
|
||||
}).transform((binding) => ({
|
||||
...binding,
|
||||
target_ips: binding.target_ips && binding.target_ips.length > 0 ? binding.target_ips : binding.target_ip ? [binding.target_ip] : [],
|
||||
target_ip_weights: binding.target_ip_weights ?? {},
|
||||
target_ip_priorities: binding.target_ip_priorities ?? {},
|
||||
target_cname: binding.target_cname?.trim() || null,
|
||||
record_type: binding.target_cname?.trim() ? "CNAME" : binding.record_type ?? "A"
|
||||
}));
|
||||
@@ -256,12 +292,24 @@ var serviceBindingSchema = z.object({
|
||||
service_slug: z.string(),
|
||||
target_ip: z.string().nullable(),
|
||||
target_ips: z.array(z.string()).optional(),
|
||||
target_ip_weights: z.record(z.string(), z.number()).optional(),
|
||||
target_ip_priorities: z.record(z.string(), z.number()).optional(),
|
||||
lb_mode: lbModeSchema.catch("round_robin"),
|
||||
health_check_enabled: z.boolean().default(false),
|
||||
health_check_type: healthCheckTypeSchema.catch("tcp"),
|
||||
health_check_port: z.number().nullable(),
|
||||
health_check_path: z.string().nullable(),
|
||||
health_check_expected_status: z.number().nullable(),
|
||||
health_check_interval_sec: z.number().default(30),
|
||||
health_check_timeout_ms: z.number().default(3e3),
|
||||
sync_status: z.string().nullable(),
|
||||
created_at: z.string(),
|
||||
updated_at: z.string()
|
||||
}).transform((binding) => ({
|
||||
...binding,
|
||||
target_ips: binding.target_ips && binding.target_ips.length > 0 ? binding.target_ips : binding.target_ip ? [binding.target_ip] : []
|
||||
target_ips: binding.target_ips && binding.target_ips.length > 0 ? binding.target_ips : binding.target_ip ? [binding.target_ip] : [],
|
||||
target_ip_weights: binding.target_ip_weights ?? {},
|
||||
target_ip_priorities: binding.target_ip_priorities ?? {}
|
||||
}));
|
||||
var dnsRecordSchema = z.object({
|
||||
id: z.number(),
|
||||
@@ -299,10 +347,24 @@ var ipv4Schema = z.string().regex(
|
||||
/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,
|
||||
"\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 IPv4"
|
||||
);
|
||||
var healthCheckConfigFields = {
|
||||
health_check_enabled: z.boolean().optional(),
|
||||
health_check_type: healthCheckTypeSchema.optional(),
|
||||
health_check_port: z.number().int().min(1).max(65535).nullable().optional(),
|
||||
health_check_path: z.string().nullable().optional(),
|
||||
health_check_expected_status: z.number().int().min(100).max(599).nullable().optional(),
|
||||
health_check_interval_sec: z.number().int().min(5).max(3600).optional(),
|
||||
health_check_timeout_ms: z.number().int().min(100).max(3e4).optional()
|
||||
};
|
||||
var healthCheckConfigSchema = z.object(healthCheckConfigFields);
|
||||
var serviceDomainInputSchema = z.object({
|
||||
fqdn: z.string().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 FQDN"),
|
||||
target_ips: z.array(ipv4Schema).optional(),
|
||||
target_cname: z.string().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 CNAME-\u0446\u0435\u043B\u044C").optional()
|
||||
target_cname: z.string().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 CNAME-\u0446\u0435\u043B\u044C").optional(),
|
||||
target_ip_weights: z.record(ipv4Schema, z.number().int().min(1).max(100)).optional(),
|
||||
target_ip_priorities: z.record(ipv4Schema, z.number().int().min(1).max(100)).optional(),
|
||||
lb_mode: lbModeSchema.optional(),
|
||||
...healthCheckConfigFields
|
||||
}).superRefine((data, ctx) => {
|
||||
const hasIps = (data.target_ips?.length ?? 0) > 0;
|
||||
const hasCname = Boolean(data.target_cname?.trim());
|
||||
@@ -328,6 +390,8 @@ var createServiceSchema = z.object({
|
||||
var createServiceWithConfigSchema = createServiceSchema.extend({
|
||||
service_group_id: z.number().nullable().optional(),
|
||||
ips: z.array(ipv4Schema).default([]),
|
||||
lb_weight: z.number().int().min(1).max(100).optional(),
|
||||
lb_priority: z.number().int().min(1).max(100).optional(),
|
||||
domains: z.array(serviceDomainInputSchema).default([])
|
||||
});
|
||||
var createServiceBindingSchema = z.object({
|
||||
@@ -383,13 +447,25 @@ var updateServiceConfigSchema = z.object({
|
||||
slug: z.string().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 slug").optional(),
|
||||
service_group_id: z.number().nullable().optional(),
|
||||
ips: z.array(ipv4Schema).optional(),
|
||||
lb_weight: z.number().int().min(1).max(100).optional(),
|
||||
lb_priority: z.number().int().min(1).max(100).optional(),
|
||||
domains: z.array(serviceDomainInputSchema).optional()
|
||||
});
|
||||
var createServiceGroupSchema = z.object({
|
||||
name: z.string().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435"),
|
||||
type: serviceGroupTypeSchema.default("custom"),
|
||||
icon: z.string().nullable().optional(),
|
||||
domain: z.string().nullable().optional()
|
||||
domain: z.string().nullable().optional(),
|
||||
lb_mode: lbModeSchema.optional(),
|
||||
...healthCheckConfigFields
|
||||
});
|
||||
var updateServiceGroupSchema = z.object({
|
||||
name: z.string().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435").optional(),
|
||||
type: serviceGroupTypeSchema.optional(),
|
||||
icon: z.string().nullable().optional(),
|
||||
domain: z.string().nullable().optional(),
|
||||
lb_mode: lbModeSchema.optional(),
|
||||
...healthCheckConfigFields
|
||||
});
|
||||
var toggleEnabledSchema = z.object({
|
||||
enabled: z.boolean()
|
||||
@@ -398,6 +474,10 @@ var reorderServicesSchema = z.object({
|
||||
group_id: z.union([z.number(), z.null()]).optional().default(null),
|
||||
service_ids: z.array(z.number().int().positive()).min(1)
|
||||
});
|
||||
var healthStatusQuerySchema = z.object({
|
||||
scope: healthCheckScopeSchema,
|
||||
ref_id: z.coerce.number().int().positive()
|
||||
});
|
||||
export {
|
||||
CERT_ERROR,
|
||||
CERT_EXPIRED,
|
||||
@@ -434,7 +514,14 @@ export {
|
||||
fqdnToDisplay,
|
||||
groupSchema,
|
||||
groupWithStatsSchema,
|
||||
healthCheckConfigSchema,
|
||||
healthCheckScopeSchema,
|
||||
healthCheckTypeSchema,
|
||||
healthStatusQuerySchema,
|
||||
ipHealthStateSchema,
|
||||
ipHealthStatusSchema,
|
||||
isValidIpv4,
|
||||
lbModeSchema,
|
||||
loginSchema,
|
||||
normalizeDnsRecordName,
|
||||
parseFqdn,
|
||||
@@ -454,6 +541,7 @@ export {
|
||||
updateDomainGroupSchema,
|
||||
updateDomainSchema,
|
||||
updateServiceConfigSchema,
|
||||
updateServiceGroupSchema,
|
||||
updateSubdomainSchema,
|
||||
validateDnsRecord
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user