fix(integrations): отдавать origin IP и cnameTarget для CNAME sync
Публичный DNS даёт CF anycast; для матча в VPS Tracker нужны origin из dns_records и цель CNAME. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -533,6 +533,49 @@ export function listDnsByDomain(db: Db, domainId: number): DnsRecord[] {
|
||||
.map(mapDnsRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Origin A/AAAA из локальной таблицы dns_records для FQDN.
|
||||
* content в CFDM — origin IP даже при proxied=true (в отличие от публичного DNS).
|
||||
* Следует по CNAME-записям в той же БД.
|
||||
*/
|
||||
export function listOriginIpsForFqdn(
|
||||
db: Db,
|
||||
fqdn: string,
|
||||
depth = 0,
|
||||
): string[] {
|
||||
if (depth > 8) return [];
|
||||
const normalized = fqdn.trim().toLowerCase().replace(/\.+$/, "");
|
||||
if (!normalized) return [];
|
||||
|
||||
const aIps: string[] = [];
|
||||
let cnameNext: string | null = null;
|
||||
|
||||
for (const domain of listAllDomains(db)) {
|
||||
const zone = domain.zone_name.trim().toLowerCase().replace(/\.+$/, "");
|
||||
if (!zone) continue;
|
||||
if (normalized !== zone && !normalized.endsWith(`.${zone}`)) continue;
|
||||
|
||||
const hostLabel =
|
||||
normalized === zone ? "@" : normalized.slice(0, -(zone.length + 1));
|
||||
|
||||
for (const record of listDnsByDomain(db, domain.id)) {
|
||||
const type = record.record_type.toUpperCase();
|
||||
if (!dnsRecordNamesMatch(record.name, hostLabel, zone)) continue;
|
||||
if (type === "A" || type === "AAAA") {
|
||||
const ip = record.content.trim();
|
||||
if (ip) aIps.push(ip);
|
||||
} else if (type === "CNAME" && !cnameNext) {
|
||||
const target = record.content.trim().replace(/\.+$/, "");
|
||||
if (target) cnameNext = target.includes(".") ? target : `${target}.${zone}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aIps.length > 0) return [...new Set(aIps)];
|
||||
if (cnameNext) return listOriginIpsForFqdn(db, cnameNext, depth + 1);
|
||||
return [];
|
||||
}
|
||||
|
||||
export function findDnsByCfId(
|
||||
db: Db,
|
||||
domainId: number,
|
||||
|
||||
Vendored
+2
@@ -1467,6 +1467,7 @@ declare const cfdmBindingSyncItemSchema: z.ZodObject<{
|
||||
zoneName: z.ZodString;
|
||||
hostname: z.ZodString;
|
||||
ips: z.ZodArray<z.ZodString>;
|
||||
cnameTarget: z.ZodOptional<z.ZodString>;
|
||||
deleted: z.ZodOptional<z.ZodBoolean>;
|
||||
}, z.core.$strip>;
|
||||
declare const cfdmSyncBindingsBodySchema: z.ZodObject<{
|
||||
@@ -1479,6 +1480,7 @@ declare const cfdmSyncBindingsBodySchema: z.ZodObject<{
|
||||
zoneName: z.ZodString;
|
||||
hostname: z.ZodString;
|
||||
ips: z.ZodArray<z.ZodString>;
|
||||
cnameTarget: z.ZodOptional<z.ZodString>;
|
||||
deleted: z.ZodOptional<z.ZodBoolean>;
|
||||
}, z.core.$strip>>;
|
||||
fullSync: z.ZodOptional<z.ZodBoolean>;
|
||||
|
||||
Vendored
+2
@@ -579,6 +579,8 @@ var cfdmBindingSyncItemSchema = z3.object({
|
||||
zoneName: z3.string().min(1),
|
||||
hostname: z3.string(),
|
||||
ips: z3.array(z3.string()),
|
||||
/** CNAME-цель (FQDN), если binding — CNAME; для матчинга в VPS Tracker. */
|
||||
cnameTarget: z3.string().optional(),
|
||||
deleted: z3.boolean().optional()
|
||||
});
|
||||
var cfdmSyncBindingsBodySchema = z3.object({
|
||||
|
||||
@@ -9,6 +9,8 @@ export const cfdmBindingSyncItemSchema = z.object({
|
||||
zoneName: z.string().min(1),
|
||||
hostname: z.string(),
|
||||
ips: z.array(z.string()),
|
||||
/** CNAME-цель (FQDN), если binding — CNAME; для матчинга в VPS Tracker. */
|
||||
cnameTarget: z.string().optional(),
|
||||
deleted: z.boolean().optional(),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user