fix(services): вернуть вес и приоритет в режиме балансировки
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / changes (push) Successful in 8s
quality / api (push) Skipped
quality / docker-check (push) Skipped
quality / web (push) Successful in 54s
CD / quality (push) Successful in 1m5s
CD / publish (push) Successful in 1m43s
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / changes (push) Successful in 8s
quality / api (push) Skipped
quality / docker-check (push) Skipped
quality / web (push) Successful in 54s
CD / quality (push) Successful in 1m5s
CD / publish (push) Successful in 1m43s
После объединения адресов в форме пропали per-IP поля. Weighted снова задаёт вес, failover — основной и запасной. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
emptyAddressBlock,
|
||||
emptyBindingDraft,
|
||||
hydrateAddressBlock,
|
||||
patchAddressIpMeta,
|
||||
removeAddressNode,
|
||||
toAddressBindings,
|
||||
toDomainsPayload,
|
||||
@@ -82,6 +83,26 @@ describe('hydrateAddressBlock', () => {
|
||||
expect(state.preservedBindings).toHaveLength(1)
|
||||
expect(state.preservedBindings[0]?.fqdn).toBe('edge.example.com')
|
||||
})
|
||||
|
||||
it('поднимает веса и приоритеты с общего FQDN', () => {
|
||||
const drafts = [
|
||||
aRecord('gt.rkns.top', ['130.49.213.153', '93.115.203.183'], {
|
||||
target_ip_weights: { '130.49.213.153': 3, '93.115.203.183': 1 },
|
||||
target_ip_priorities: { '130.49.213.153': 2, '93.115.203.183': 1 },
|
||||
}),
|
||||
aRecord('nsgt.rkns.top', ['130.49.213.153']),
|
||||
]
|
||||
const state = hydrateAddressBlock(drafts, ['130.49.213.153', '93.115.203.183'])
|
||||
expect(state.target_ip_weights).toEqual({
|
||||
'130.49.213.153': 3,
|
||||
'93.115.203.183': 1,
|
||||
})
|
||||
expect(state.target_ip_priorities).toEqual({
|
||||
'130.49.213.153': 2,
|
||||
'93.115.203.183': 1,
|
||||
})
|
||||
expect(state.nodes[0]?.extraFqdn).toBe('nsgt.rkns.top')
|
||||
})
|
||||
})
|
||||
|
||||
describe('toDomainsPayload', () => {
|
||||
@@ -161,6 +182,35 @@ describe('addAddressNode / addCommonFqdn', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('patchAddressIpMeta', () => {
|
||||
it('меняет вес одного IP и не трогает extraFqdn', () => {
|
||||
const state = {
|
||||
...addAddressNode(addAddressNode(emptyAddressBlock(), '1.1.1.1'), '2.2.2.2'),
|
||||
nodes: [
|
||||
{ ip: '1.1.1.1', extraFqdn: 'msk.example.com' },
|
||||
{ ip: '2.2.2.2', extraFqdn: '' },
|
||||
],
|
||||
}
|
||||
const next = patchAddressIpMeta(state, '1.1.1.1', { weight: 7 })
|
||||
expect(next.target_ip_weights).toEqual({ '1.1.1.1': 7, '2.2.2.2': 1 })
|
||||
expect(next.target_ip_priorities).toEqual(state.target_ip_priorities)
|
||||
expect(next.nodes).toEqual(state.nodes)
|
||||
})
|
||||
|
||||
it('clamp веса и приоритета в 1–100', () => {
|
||||
const state = addAddressNode(emptyAddressBlock(), '10.0.0.1')
|
||||
expect(patchAddressIpMeta(state, '10.0.0.1', { weight: 0 }).target_ip_weights['10.0.0.1']).toBe(1)
|
||||
expect(
|
||||
patchAddressIpMeta(state, '10.0.0.1', { priority: 999 }).target_ip_priorities['10.0.0.1'],
|
||||
).toBe(100)
|
||||
})
|
||||
|
||||
it('игнорирует IP вне пула', () => {
|
||||
const state = addAddressNode(emptyAddressBlock(), '10.0.0.1')
|
||||
expect(patchAddressIpMeta(state, '8.8.8.8', { weight: 5 })).toBe(state)
|
||||
})
|
||||
})
|
||||
|
||||
describe('CNAME / preservedBindings', () => {
|
||||
it('сохраняет CNAME в preserved при круге hydrate → payload', () => {
|
||||
const cname: ServiceBindingDraft = {
|
||||
|
||||
@@ -243,6 +243,33 @@ export function addAddressNode(state: AddressBlockState, ip: string): AddressBlo
|
||||
}
|
||||
}
|
||||
|
||||
const LB_META_MIN = 1
|
||||
const LB_META_MAX = 100
|
||||
|
||||
function clampLbMeta(value: number): number {
|
||||
if (!Number.isFinite(value)) return LB_META_MIN
|
||||
return Math.min(LB_META_MAX, Math.max(LB_META_MIN, Math.round(value)))
|
||||
}
|
||||
|
||||
export function patchAddressIpMeta(
|
||||
state: AddressBlockState,
|
||||
ip: string,
|
||||
meta: { weight?: number; priority?: number },
|
||||
): AddressBlockState {
|
||||
if (!state.nodes.some((node) => node.ip === ip)) return state
|
||||
return {
|
||||
...state,
|
||||
target_ip_weights:
|
||||
meta.weight === undefined
|
||||
? state.target_ip_weights
|
||||
: { ...state.target_ip_weights, [ip]: clampLbMeta(meta.weight) },
|
||||
target_ip_priorities:
|
||||
meta.priority === undefined
|
||||
? state.target_ip_priorities
|
||||
: { ...state.target_ip_priorities, [ip]: clampLbMeta(meta.priority) },
|
||||
}
|
||||
}
|
||||
|
||||
function fqdnKey(value: string): string {
|
||||
return value.trim().toLowerCase()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user