feat(health-check): add TLS verification option to health check configuration
Introduced a new `verify_tls` boolean option in health check configurations across various services, allowing users to specify whether to validate TLS certificates during health checks. Updated related components and services to accommodate this new option, ensuring proper handling in both the backend and frontend. Enhanced tests to validate the new functionality and ensure correct behavior with different configurations.
This commit is contained in:
1 parent
9783974949
commit
1d497d01c2
123 files changed
+351
-15912
No files matched your search
@@ -736,6 +736,7 @@ function mapServiceGroup(row: typeof serviceGroups.$inferSelect): ServiceGroup {
|
||||
health_check_expected_status: row.health_check_expected_status,
|
||||
health_check_interval_sec: row.health_check_interval_sec,
|
||||
health_check_timeout_ms: row.health_check_timeout_ms,
|
||||
health_check_verify_tls: row.health_check_verify_tls,
|
||||
created_at: row.created_at,
|
||||
updated_at: row.updated_at,
|
||||
};
|
||||
@@ -769,6 +770,7 @@ export interface ServiceGroupLbPatch {
|
||||
health_check_expected_status?: number | null;
|
||||
health_check_interval_sec?: number;
|
||||
health_check_timeout_ms?: number;
|
||||
health_check_verify_tls?: boolean;
|
||||
}
|
||||
|
||||
export function createServiceGroup(
|
||||
@@ -794,6 +796,7 @@ export function createServiceGroup(
|
||||
health_check_expected_status: lbPatch?.health_check_expected_status ?? null,
|
||||
health_check_interval_sec: lbPatch?.health_check_interval_sec ?? 30,
|
||||
health_check_timeout_ms: lbPatch?.health_check_timeout_ms ?? 3000,
|
||||
health_check_verify_tls: lbPatch?.health_check_verify_tls ?? false,
|
||||
})
|
||||
.returning({ id: serviceGroups.id })
|
||||
.get()!.id;
|
||||
@@ -832,6 +835,8 @@ export function updateServiceGroup(
|
||||
update.health_check_interval_sec = lbPatch.health_check_interval_sec;
|
||||
if (lbPatch.health_check_timeout_ms !== undefined)
|
||||
update.health_check_timeout_ms = lbPatch.health_check_timeout_ms;
|
||||
if (lbPatch.health_check_verify_tls !== undefined)
|
||||
update.health_check_verify_tls = lbPatch.health_check_verify_tls;
|
||||
}
|
||||
const result = db
|
||||
.update(serviceGroups)
|
||||
@@ -956,6 +961,7 @@ export interface BindingLbPatch {
|
||||
health_check_expected_status?: number | null;
|
||||
health_check_interval_sec?: number;
|
||||
health_check_timeout_ms?: number;
|
||||
health_check_verify_tls?: boolean;
|
||||
}
|
||||
|
||||
export function updateBindingLbConfig(
|
||||
@@ -981,6 +987,8 @@ export function updateBindingLbConfig(
|
||||
update.health_check_interval_sec = patch.health_check_interval_sec;
|
||||
if (patch.health_check_timeout_ms !== undefined)
|
||||
update.health_check_timeout_ms = patch.health_check_timeout_ms;
|
||||
if (patch.health_check_verify_tls !== undefined)
|
||||
update.health_check_verify_tls = patch.health_check_verify_tls;
|
||||
db.update(serviceBindings)
|
||||
.set(update)
|
||||
.where(eq(serviceBindings.id, bindingId))
|
||||
@@ -1088,7 +1096,7 @@ function dnsRecordMatchesHostname(
|
||||
const SERVICE_BINDING_SELECT_COLUMNS = `sb.id, sb.domain_id, sb.service_id, sb.hostname, sb.dns_record_id,
|
||||
sb.lb_mode, sb.health_check_enabled, sb.health_check_type, sb.health_check_port,
|
||||
sb.health_check_path, sb.health_check_expected_status, sb.health_check_interval_sec,
|
||||
sb.health_check_timeout_ms, sb.cname_target,
|
||||
sb.health_check_timeout_ms, sb.health_check_verify_tls, sb.cname_target,
|
||||
d.zone_name, d.group_id, g.name AS group_name,
|
||||
s.name AS service_name, s.slug AS service_slug,
|
||||
dr.content AS target_ip, dr.sync_status,
|
||||
@@ -1734,7 +1742,8 @@ export function listHealthCheckTargets(db: Db): HealthCheckTarget[] {
|
||||
sb.health_check_port AS port,
|
||||
sb.health_check_path AS path,
|
||||
sb.health_check_expected_status AS expected_status,
|
||||
sb.health_check_timeout_ms AS timeout_ms
|
||||
sb.health_check_timeout_ms AS timeout_ms,
|
||||
sb.health_check_verify_tls AS verify_tls
|
||||
FROM service_binding_ips sbi
|
||||
JOIN service_bindings sb ON sb.id = sbi.binding_id
|
||||
JOIN domains d ON d.id = sb.domain_id
|
||||
@@ -1748,7 +1757,8 @@ export function listHealthCheckTargets(db: Db): HealthCheckTarget[] {
|
||||
sg.health_check_port AS port,
|
||||
sg.health_check_path AS path,
|
||||
sg.health_check_expected_status AS expected_status,
|
||||
sg.health_check_timeout_ms AS timeout_ms
|
||||
sg.health_check_timeout_ms AS timeout_ms,
|
||||
sg.health_check_verify_tls AS verify_tls
|
||||
FROM services s
|
||||
JOIN service_ips sip ON sip.service_id = s.id
|
||||
JOIN service_groups sg ON sg.id = s.service_group_id
|
||||
@@ -1769,7 +1779,8 @@ export function listHealthCheckTargets(db: Db): HealthCheckTarget[] {
|
||||
sg.health_check_port AS port,
|
||||
sg.health_check_path AS path,
|
||||
sg.health_check_expected_status AS expected_status,
|
||||
sg.health_check_timeout_ms AS timeout_ms
|
||||
sg.health_check_timeout_ms AS timeout_ms,
|
||||
sg.health_check_verify_tls AS verify_tls
|
||||
FROM service_binding_ips sbi
|
||||
JOIN service_bindings sb ON sb.id = sbi.binding_id
|
||||
JOIN domains d ON d.id = sb.domain_id
|
||||
@@ -1790,7 +1801,8 @@ export function listHealthCheckTargets(db: Db): HealthCheckTarget[] {
|
||||
sb.health_check_port AS port,
|
||||
sb.health_check_path AS path,
|
||||
sb.health_check_expected_status AS expected_status,
|
||||
sb.health_check_timeout_ms AS timeout_ms
|
||||
sb.health_check_timeout_ms AS timeout_ms,
|
||||
sb.health_check_verify_tls AS verify_tls
|
||||
FROM service_bindings sb
|
||||
JOIN domains d ON d.id = sb.domain_id
|
||||
JOIN services s ON s.id = sb.service_id
|
||||
@@ -1809,7 +1821,8 @@ export function listHealthCheckTargets(db: Db): HealthCheckTarget[] {
|
||||
sg.health_check_port AS port,
|
||||
sg.health_check_path AS path,
|
||||
sg.health_check_expected_status AS expected_status,
|
||||
sg.health_check_timeout_ms AS timeout_ms
|
||||
sg.health_check_timeout_ms AS timeout_ms,
|
||||
sg.health_check_verify_tls AS verify_tls
|
||||
FROM service_bindings sb
|
||||
JOIN domains d ON d.id = sb.domain_id
|
||||
JOIN services s ON s.id = sb.service_id
|
||||
@@ -1829,7 +1842,10 @@ export function listHealthCheckTargets(db: Db): HealthCheckTarget[] {
|
||||
...groupInheritedBindingTargets,
|
||||
...cnameBindingTargets,
|
||||
...groupInheritedCnameBindingTargets,
|
||||
];
|
||||
].map((t) => ({
|
||||
...t,
|
||||
verify_tls: Boolean(t.verify_tls),
|
||||
}));
|
||||
}
|
||||
|
||||
// --- Domain tags ---
|
||||
|
||||
@@ -60,6 +60,9 @@ export const serviceGroups = sqliteTable("service_groups", {
|
||||
health_check_timeout_ms: integer("health_check_timeout_ms")
|
||||
.notNull()
|
||||
.default(3000),
|
||||
health_check_verify_tls: integer("health_check_verify_tls", { mode: "boolean" })
|
||||
.notNull()
|
||||
.default(false),
|
||||
created_at: text("created_at")
|
||||
.notNull()
|
||||
.default(sql`datetime('now')`),
|
||||
@@ -154,6 +157,9 @@ export const serviceBindings = sqliteTable("service_bindings", {
|
||||
health_check_timeout_ms: integer("health_check_timeout_ms")
|
||||
.notNull()
|
||||
.default(3000),
|
||||
health_check_verify_tls: integer("health_check_verify_tls", { mode: "boolean" })
|
||||
.notNull()
|
||||
.default(false),
|
||||
created_at: text("created_at")
|
||||
.notNull()
|
||||
.default(sql`datetime('now')`),
|
||||
@@ -271,7 +277,7 @@ export const ipHealthStatus = sqliteTable(
|
||||
|
||||
export const appSettings = sqliteTable("app_settings", {
|
||||
id: text("id").primaryKey(),
|
||||
app_switcher_json: text("app_switcher_json"),
|
||||
app_switcher_json: text("app_switcher_json"), // deprecated: portal is SoT; column kept for migrate compat
|
||||
vps_tracker_url: text("vps_tracker_url"),
|
||||
vps_tracker_integration_token: text("vps_tracker_integration_token"),
|
||||
vps_tracker_sync_enabled: integer("vps_tracker_sync_enabled", {
|
||||
|
||||
@@ -1,43 +1,11 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { appSwitcherConfigSchema, type AppSwitcherConfig } from "@cfdm/shared";
|
||||
import type { Db } from "./client.js";
|
||||
import { appSettings } from "./schema.js";
|
||||
|
||||
const SETTINGS_ID = "settings-main";
|
||||
|
||||
const DEFAULT_APP_SWITCHER: AppSwitcherConfig = {
|
||||
menuLabel: "Приложения",
|
||||
apps: [
|
||||
{
|
||||
id: "vps-tracker",
|
||||
name: "VPS Tracker",
|
||||
subtitle: "Учёт виртуальных серверов",
|
||||
url: "http://192.168.100.67:3001",
|
||||
icon: "server",
|
||||
shortcut: "⌘1",
|
||||
},
|
||||
{
|
||||
id: "cfdm",
|
||||
name: "CF Domain Manager",
|
||||
subtitle: "Управление доменами",
|
||||
url: "http://192.168.100.67:6363",
|
||||
icon: "cloud",
|
||||
shortcut: "⌘2",
|
||||
},
|
||||
{
|
||||
id: "evobgp",
|
||||
name: "EvoBGP",
|
||||
subtitle: "BGP маршрутизация",
|
||||
url: "http://192.168.100.67:3000",
|
||||
icon: "globe",
|
||||
shortcut: "⌘3",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export type AppSettingsDto = {
|
||||
id: string;
|
||||
appSwitcher: AppSwitcherConfig;
|
||||
vpsTrackerUrl: string;
|
||||
vpsTrackerIntegrationTokenSet: boolean;
|
||||
vpsTrackerSyncEnabled: boolean;
|
||||
@@ -46,26 +14,15 @@ export type AppSettingsDto = {
|
||||
};
|
||||
|
||||
export type AppSettingsPatch = {
|
||||
appSwitcher?: AppSwitcherConfig;
|
||||
vpsTrackerUrl?: string;
|
||||
vpsTrackerIntegrationToken?: string;
|
||||
vpsTrackerSyncEnabled?: boolean;
|
||||
showQuickActions?: boolean;
|
||||
};
|
||||
|
||||
function parseAppSwitcher(raw: string | null | undefined): AppSwitcherConfig {
|
||||
if (!raw?.trim()) return DEFAULT_APP_SWITCHER;
|
||||
try {
|
||||
return appSwitcherConfigSchema.parse(JSON.parse(raw));
|
||||
} catch {
|
||||
return DEFAULT_APP_SWITCHER;
|
||||
}
|
||||
}
|
||||
|
||||
function toDto(row: typeof appSettings.$inferSelect): AppSettingsDto {
|
||||
return {
|
||||
id: row.id,
|
||||
appSwitcher: parseAppSwitcher(row.app_switcher_json),
|
||||
vpsTrackerUrl: row.vps_tracker_url?.trim() ?? "",
|
||||
vpsTrackerIntegrationTokenSet: Boolean(
|
||||
row.vps_tracker_integration_token?.trim(),
|
||||
@@ -127,10 +84,7 @@ export function updateAppSettings(db: Db, patch: AppSettingsPatch): AppSettingsD
|
||||
|
||||
db.update(appSettings)
|
||||
.set({
|
||||
app_switcher_json:
|
||||
patch.appSwitcher !== undefined
|
||||
? JSON.stringify(patch.appSwitcher)
|
||||
: current.app_switcher_json,
|
||||
// app_switcher_json: deprecated — source of truth is auth-portal
|
||||
vps_tracker_url:
|
||||
patch.vpsTrackerUrl !== undefined
|
||||
? patch.vpsTrackerUrl
|
||||
@@ -165,7 +119,3 @@ export function touchVpsTrackerSync(db: Db): void {
|
||||
.where(eq(appSettings.id, SETTINGS_ID))
|
||||
.run();
|
||||
}
|
||||
|
||||
export function getAppSwitcher(db: Db): AppSwitcherConfig {
|
||||
return getAppSettings(db).appSwitcher;
|
||||
}
|
||||
Reference in new issue
Block a user