fix(integrations): не считать CNAME hostname за IP при sync
Build and Push CFDM Docker Image / build-and-push (push) Successful in 1m49s
Build and Push CFDM Docker Image / create-release (push) Skipped
Build and Push CFDM Docker Image / update-wiki (push) Successful in 6s

JOIN dns_record клал content CNAME в target_ips и блокировал разворот до origin IP / service IPs.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-08-01 01:30:25 +07:00
co-authored by Cursor
parent ec70104085
commit 721332e767
6 changed files with 86 additions and 19 deletions
+20 -13
View File
@@ -1,5 +1,6 @@
import { resolve4 } from "node:dns/promises";
import type { CfdmBindingSyncItem, ServiceBindingView } from "@cfdm/shared";
import { isIpLiteral } from "@cfdm/shared";
import type { Db } from "@cfdm/db";
import { repos, getAppSettingsSecrets, touchVpsTrackerSync } from "@cfdm/db";
@@ -42,8 +43,8 @@ function resolveIpsLocally(
const binding = index.byFqdn.get(key);
if (!binding) return [];
if (binding.target_ips.length > 0) {
return [...binding.target_ips];
if (binding.target_ips.some(isIpLiteral)) {
return binding.target_ips.filter(isIpLiteral);
}
const cname = binding.cname_target?.trim();
@@ -66,11 +67,11 @@ async function resolveIpsViaDns(hostname: string): Promise<string[]> {
/**
* IP для матчинга в VPS Tracker:
* 1) A-записи binding
* 2) разворот локальной CNAME-цепочки по другим bindings
* 3) origin A/AAAA из dns_records CFDM (даже proxied — content = origin)
* 4) публичный DNS (resolve4) — часто CF anycast, слабый сигнал
* 5) IP сервиса
* 1) A/AAAA binding (только литералы IP — не CNAME hostname из dns_record.content)
* 2) локальная CNAME-цепочка по другим bindings
* 3) origin A/AAAA из dns_records CFDM
* 4) IP сервиса
* 5) публичный DNS — последний и обычно вреден (CF anycast при proxied)
*/
export async function resolveBindingIpsForSync(
binding: ServiceBindingView,
@@ -78,26 +79,32 @@ export async function resolveBindingIpsForSync(
index: BindingIpIndex,
db?: Db,
): Promise<string[]> {
if (binding.target_ips.length > 0) {
return [...binding.target_ips];
const directIps = binding.target_ips.filter(isIpLiteral);
if (directIps.length > 0) {
return [...directIps];
}
const cname = binding.cname_target?.trim();
if (cname) {
const targetFqdn = normalizeCnameHost(cname, binding.zone_name);
const local = resolveIpsLocally(index, targetFqdn);
const local = resolveIpsLocally(index, targetFqdn).filter(isIpLiteral);
if (local.length > 0) return local;
if (db) {
const fromTable = repos.listOriginIpsForFqdn(db, targetFqdn);
const fromTable = repos.listOriginIpsForFqdn(db, targetFqdn).filter(isIpLiteral);
if (fromTable.length > 0) return fromTable;
}
}
const viaDns = await resolveIpsViaDns(targetFqdn);
const fromService = serviceIps.filter(isIpLiteral);
if (fromService.length > 0) return [...fromService];
if (cname) {
const targetFqdn = normalizeCnameHost(cname, binding.zone_name);
const viaDns = (await resolveIpsViaDns(targetFqdn)).filter(isIpLiteral);
if (viaDns.length > 0) return viaDns;
}
if (serviceIps.length > 0) return [...serviceIps];
return [];
}