fix(integrations): разворачивать CNAME до IP при sync в VPS Tracker
CNAME-bindings отдавали пустой ips[]; теперь IP берутся из локальной цепочки bindings, DNS resolve4 или IP сервиса — чтобы vps-tracker мог матчить домен к VPS. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Vendored
+40
-26
@@ -10,7 +10,8 @@ import {
|
||||
integer,
|
||||
primaryKey,
|
||||
sqliteTable,
|
||||
text
|
||||
text,
|
||||
unique
|
||||
} from "drizzle-orm/sqlite-core";
|
||||
var groups = sqliteTable("groups", {
|
||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
||||
@@ -94,27 +95,39 @@ var dnsRecords = sqliteTable("dns_records", {
|
||||
created_at: text("created_at").notNull().default(sql`datetime('now')`),
|
||||
updated_at: text("updated_at").notNull().default(sql`datetime('now')`)
|
||||
});
|
||||
var serviceBindings = sqliteTable("service_bindings", {
|
||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
||||
domain_id: integer("domain_id").notNull().references(() => domains.id, { onDelete: "cascade" }),
|
||||
service_id: integer("service_id").notNull().references(() => services.id, { onDelete: "cascade" }),
|
||||
hostname: text("hostname").notNull().default("@"),
|
||||
cname_target: text("cname_target"),
|
||||
dns_record_id: integer("dns_record_id").references(() => dnsRecords.id, {
|
||||
onDelete: "set null"
|
||||
}),
|
||||
lb_mode: text("lb_mode").notNull().default("round_robin"),
|
||||
health_check_enabled: integer("health_check_enabled", { mode: "boolean" }).notNull().default(false),
|
||||
health_check_type: text("health_check_type").notNull().default("tcp"),
|
||||
health_check_port: integer("health_check_port"),
|
||||
health_check_path: text("health_check_path"),
|
||||
health_check_expected_status: integer("health_check_expected_status"),
|
||||
health_check_interval_sec: integer("health_check_interval_sec").notNull().default(30),
|
||||
health_check_timeout_ms: integer("health_check_timeout_ms").notNull().default(3e3),
|
||||
health_check_verify_tls: integer("health_check_verify_tls", { mode: "boolean" }).notNull().default(false),
|
||||
created_at: text("created_at").notNull().default(sql`datetime('now')`),
|
||||
updated_at: text("updated_at").notNull().default(sql`datetime('now')`)
|
||||
});
|
||||
var serviceBindings = sqliteTable(
|
||||
"service_bindings",
|
||||
{
|
||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
||||
domain_id: integer("domain_id").notNull().references(() => domains.id, { onDelete: "cascade" }),
|
||||
service_id: integer("service_id").notNull().references(() => services.id, { onDelete: "cascade" }),
|
||||
hostname: text("hostname").notNull().default("@"),
|
||||
cname_target: text("cname_target"),
|
||||
dns_record_id: integer("dns_record_id").references(() => dnsRecords.id, {
|
||||
onDelete: "set null"
|
||||
}),
|
||||
lb_mode: text("lb_mode").notNull().default("round_robin"),
|
||||
health_check_enabled: integer("health_check_enabled", { mode: "boolean" }).notNull().default(false),
|
||||
health_check_type: text("health_check_type").notNull().default("tcp"),
|
||||
health_check_port: integer("health_check_port"),
|
||||
health_check_path: text("health_check_path"),
|
||||
health_check_expected_status: integer("health_check_expected_status"),
|
||||
health_check_interval_sec: integer("health_check_interval_sec").notNull().default(30),
|
||||
health_check_timeout_ms: integer("health_check_timeout_ms").notNull().default(3e3),
|
||||
health_check_verify_tls: integer("health_check_verify_tls", {
|
||||
mode: "boolean"
|
||||
}).notNull().default(false),
|
||||
created_at: text("created_at").notNull().default(sql`datetime('now')`),
|
||||
updated_at: text("updated_at").notNull().default(sql`datetime('now')`)
|
||||
},
|
||||
(table) => [
|
||||
unique("service_bindings_domain_service_hostname").on(
|
||||
table.domain_id,
|
||||
table.service_id,
|
||||
table.hostname
|
||||
)
|
||||
]
|
||||
);
|
||||
var serviceIps = sqliteTable("service_ips", {
|
||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
||||
service_id: integer("service_id").notNull().references(() => services.id, { onDelete: "cascade" }),
|
||||
@@ -1189,6 +1202,7 @@ function enrichServiceBindingView(db, row) {
|
||||
const sync_status = row.sync_status ?? linkedRecords.find((record) => record.sync_status)?.sync_status ?? null;
|
||||
return {
|
||||
...row,
|
||||
cname_target: row.cname_target ?? null,
|
||||
target_ips,
|
||||
target_ip: target_ips[0] ?? null,
|
||||
target_ip_weights,
|
||||
@@ -1646,14 +1660,14 @@ function listDomainTags(db, domainId) {
|
||||
}
|
||||
function setDomainTags(db, domainId, tags) {
|
||||
db.delete(domainTags).where(eq3(domainTags.domain_id, domainId)).run();
|
||||
const unique = [...new Set(tags.map((t) => t.trim()).filter(Boolean))];
|
||||
for (const tag of unique) {
|
||||
const unique2 = [...new Set(tags.map((t) => t.trim()).filter(Boolean))];
|
||||
for (const tag of unique2) {
|
||||
db.insert(domainTags).values({ domain_id: domainId, tag }).run();
|
||||
}
|
||||
}
|
||||
function addDomainTags(db, domainId, tags) {
|
||||
const unique = [...new Set(tags.map((t) => t.trim()).filter(Boolean))];
|
||||
for (const tag of unique) {
|
||||
const unique2 = [...new Set(tags.map((t) => t.trim()).filter(Boolean))];
|
||||
for (const tag of unique2) {
|
||||
db.run(sql2`
|
||||
INSERT INTO domain_tags (domain_id, tag)
|
||||
VALUES (${domainId}, ${tag})
|
||||
|
||||
@@ -1154,6 +1154,7 @@ function enrichServiceBindingView(
|
||||
|
||||
return {
|
||||
...row,
|
||||
cname_target: row.cname_target ?? null,
|
||||
target_ips,
|
||||
target_ip: target_ips[0] ?? null,
|
||||
target_ip_weights,
|
||||
|
||||
Vendored
+1
@@ -78,6 +78,7 @@ interface ServiceBindingView {
|
||||
target_ips: string[];
|
||||
target_ip_weights: Record<string, number>;
|
||||
target_ip_priorities: Record<string, number>;
|
||||
cname_target: string | null;
|
||||
lb_mode: LbMode;
|
||||
health_check_enabled: boolean;
|
||||
health_check_type: HealthCheckType;
|
||||
|
||||
@@ -140,6 +140,7 @@ export interface ServiceBindingView {
|
||||
target_ips: string[];
|
||||
target_ip_weights: Record<string, number>;
|
||||
target_ip_priorities: Record<string, number>;
|
||||
cname_target: string | null;
|
||||
lb_mode: LbMode;
|
||||
health_check_enabled: boolean;
|
||||
health_check_type: HealthCheckType;
|
||||
|
||||
Reference in New Issue
Block a user