fix(services): сохранить доп. FQDN у IP при пуле из одного адреса
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / changes (push) Successful in 9s
quality / api (push) Skipped
quality / docker-check (push) Skipped
quality / web (push) Successful in 1m10s
CD / quality (push) Successful in 1m23s
CD / publish (push) Successful in 1m41s
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / changes (push) Successful in 9s
quality / api (push) Skipped
quality / docker-check (push) Skipped
quality / web (push) Successful in 1m10s
CD / quality (push) Successful in 1m23s
CD / publish (push) Successful in 1m41s
При одном IP общий и доп. FQDN неотличимы по target_ips; после сохранения гидратация относила оба к общим доменам. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -84,6 +84,21 @@ describe('hydrateAddressBlock', () => {
|
||||
expect(state.preservedBindings[0]?.fqdn).toBe('edge.example.com')
|
||||
})
|
||||
|
||||
it('при одном IP пула отделяет второй A в extraFqdn узла', () => {
|
||||
const drafts = [
|
||||
aRecord('dns.shnt.top', ['130.49.213.176']),
|
||||
aRecord('ndns.shnt.top', ['130.49.213.176']),
|
||||
]
|
||||
|
||||
const state = hydrateAddressBlock(drafts, ['130.49.213.176'])
|
||||
|
||||
expect(state.commonFqdns).toEqual(['dns.shnt.top'])
|
||||
expect(state.nodes).toEqual([
|
||||
{ ip: '130.49.213.176', extraFqdn: 'ndns.shnt.top' },
|
||||
])
|
||||
expect(state.preservedBindings).toEqual([])
|
||||
})
|
||||
|
||||
it('поднимает веса и приоритеты с общего FQDN', () => {
|
||||
const drafts = [
|
||||
aRecord('gt.rkns.top', ['130.49.213.153', '93.115.203.183'], {
|
||||
@@ -143,6 +158,24 @@ describe('toDomainsPayload', () => {
|
||||
expect(second.nodes).toEqual(first.nodes)
|
||||
expect(second.preservedBindings).toEqual([])
|
||||
})
|
||||
|
||||
it('круг hydrate → payload → hydrate сохраняет extra FQDN при одном IP', () => {
|
||||
const drafts = [
|
||||
aRecord('dns.shnt.top', ['130.49.213.176']),
|
||||
aRecord('ndns.shnt.top', ['130.49.213.176']),
|
||||
]
|
||||
const first = hydrateAddressBlock(drafts, ['130.49.213.176'])
|
||||
expect(first.commonFqdns).toEqual(['dns.shnt.top'])
|
||||
expect(first.nodes).toEqual([
|
||||
{ ip: '130.49.213.176', extraFqdn: 'ndns.shnt.top' },
|
||||
])
|
||||
const rebound = toAddressBindings(first, primaryMeta)
|
||||
const second = hydrateAddressBlock(rebound, ['130.49.213.176'])
|
||||
|
||||
expect(second.commonFqdns).toEqual(first.commonFqdns)
|
||||
expect(second.nodes).toEqual(first.nodes)
|
||||
expect(second.preservedBindings).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('removeAddressNode', () => {
|
||||
|
||||
@@ -145,6 +145,23 @@ function isFullPoolA(draft: ServiceBindingDraft, pool: string[]): boolean {
|
||||
return draft.record_type === 'A' && sameIpSet(draft.target_ips, pool)
|
||||
}
|
||||
|
||||
function takeAsCommon(
|
||||
draft: ServiceBindingDraft,
|
||||
fqdn: string,
|
||||
commonFqdns: string[],
|
||||
weights: Record<string, number>,
|
||||
priorities: Record<string, number>,
|
||||
): { weights: Record<string, number>; priorities: Record<string, number> } {
|
||||
if (fqdn) commonFqdns.push(draft.fqdn)
|
||||
if (Object.keys(weights).length === 0) {
|
||||
return {
|
||||
weights: { ...draft.target_ip_weights },
|
||||
priorities: { ...draft.target_ip_priorities },
|
||||
}
|
||||
}
|
||||
return { weights, priorities }
|
||||
}
|
||||
|
||||
export function hydrateAddressBlock(
|
||||
drafts: ServiceBindingDraft[],
|
||||
pool: string[] = [],
|
||||
@@ -166,15 +183,36 @@ export function hydrateAddressBlock(
|
||||
const preservedBindings: ServiceBindingDraft[] = []
|
||||
let weights: Record<string, number> = {}
|
||||
let priorities: Record<string, number> = {}
|
||||
const splitSinglePool =
|
||||
ips.length === 1 &&
|
||||
drafts.filter((draft) => isFullPoolA(draft, ips)).length > 1
|
||||
let assignedFirstSinglePoolCommon = false
|
||||
|
||||
for (const draft of drafts) {
|
||||
const fqdn = draft.fqdn.trim()
|
||||
if (isFullPoolA(draft, ips)) {
|
||||
if (fqdn) commonFqdns.push(draft.fqdn)
|
||||
if (Object.keys(weights).length === 0) {
|
||||
weights = { ...draft.target_ip_weights }
|
||||
priorities = { ...draft.target_ip_priorities }
|
||||
if (splitSinglePool && isFullPoolA(draft, ips)) {
|
||||
if (!assignedFirstSinglePoolCommon) {
|
||||
assignedFirstSinglePoolCommon = true
|
||||
const next = takeAsCommon(draft, fqdn, commonFqdns, weights, priorities)
|
||||
weights = next.weights
|
||||
priorities = next.priorities
|
||||
continue
|
||||
}
|
||||
const ip = draft.target_ips[0]?.trim() ?? ''
|
||||
if (ip && poolSet.has(ip) && fqdn && !claimed.has(ip)) {
|
||||
claimed.add(ip)
|
||||
extraByIp.set(ip, draft.fqdn)
|
||||
continue
|
||||
}
|
||||
const overflow = takeAsCommon(draft, fqdn, commonFqdns, weights, priorities)
|
||||
weights = overflow.weights
|
||||
priorities = overflow.priorities
|
||||
continue
|
||||
}
|
||||
if (isFullPoolA(draft, ips)) {
|
||||
const next = takeAsCommon(draft, fqdn, commonFqdns, weights, priorities)
|
||||
weights = next.weights
|
||||
priorities = next.priorities
|
||||
continue
|
||||
}
|
||||
if (draft.record_type === 'A' && draft.target_ips.length === 1) {
|
||||
|
||||
Reference in New Issue
Block a user