Improve VPN client connection management
Build and Deploy Gateway / build-and-push (push) Successful in 20s
Build and Deploy Gateway / deploy (push) Successful in 13s

This commit is contained in:
2026-08-12 21:48:37 +03:00
parent 068a7f9890
commit 9e52ccc24d
22 changed files with 962 additions and 76 deletions
+76
View File
@@ -1018,11 +1018,87 @@ test('an old dataplane without domain traffic keeps inventory refresh and existi
const service = createDeviceInventoryService({
store,
observe: () => ({ observedAt: '2026-08-08T10:00:00.000Z', observations: [], error: null }),
observeTraffic: () => ({
epoch: 'epoch-a',
generation: 'rules-a',
observedAt: '2026-08-08T10:00:00.000Z',
source: { error: null },
direct: { uploadBytes: '0', downloadBytes: '0' },
devices: [],
}),
observeDomainTraffic: () => { throw new Error('Dataplane HTTP 404'); },
});
const snapshot = await service.refresh();
assert.equal(snapshot.devices.length, 0);
assert.equal(service.metricsSnapshot().domainTraffic.source.error, 'Dataplane HTTP 404');
assert.deepEqual(service.metricsSnapshot().directTraffic, {
epoch: 'epoch-a',
observedAt: '2026-08-08T10:00:00.000Z',
source: { error: null },
uploadBytes: '0',
downloadBytes: '0',
series: [],
});
assert.equal(service.metricsSnapshot().traffic.totalBytes, '0');
});
test('direct IPv4 counters stay metrics-only and keep the last good transport snapshot', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'harbor-direct-metrics-'));
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));
const store = createJsonStore({ filePath: path.join(directory, 'devices.json'), defaultValue: {} });
const observedAt = '2026-08-12T10:00:00.000Z';
const mac = '00:11:22:33:44:55';
let fail = false;
let includeDirect = true;
const service = createDeviceInventoryService({
store,
observe: () => ({
observedAt,
error: null,
observations: [{ ip: '192.168.50.7', mac, interface: 'eth0', observedAt, active: true }],
}),
observeTraffic: () => {
if (fail) throw new Error('Dataplane direct counters unavailable');
return {
epoch: 'epoch-a',
generation: 'rules-a',
observedAt,
source: { error: null },
direct: includeDirect ? { uploadBytes: '56', downloadBytes: '78' } : undefined,
devices: [{
mac,
uploadBytes: '100',
downloadBytes: '200',
...(includeDirect ? { directUploadBytes: '12', directDownloadBytes: '34' } : {}),
}],
};
},
});
await service.refresh();
assert.deepEqual(service.metricsSnapshot().directTraffic.series, [{
deviceId: deviceId(mac),
uploadBytes: '12',
downloadBytes: '34',
}]);
assert.equal(service.metricsSnapshot().directTraffic.uploadBytes, '56');
assert.equal(service.metricsSnapshot().directTraffic.downloadBytes, '78');
assert.equal(Object.hasOwn(service.snapshot().devices[0], 'directUploadBytes'), false);
assert.doesNotMatch(JSON.stringify(store.read()), /directUploadBytes|directDownloadBytes/);
fail = true;
await service.refresh();
assert.deepEqual(service.metricsSnapshot().directTraffic.series, [{
deviceId: deviceId(mac),
uploadBytes: '12',
downloadBytes: '34',
}]);
assert.equal(service.metricsSnapshot().directTraffic.source.error, 'Dataplane direct counters unavailable');
fail = false;
includeDirect = false;
await service.refresh();
assert.deepEqual(service.metricsSnapshot().directTraffic.series, []);
assert.equal(service.metricsSnapshot().directTraffic.source.error, null);
});