feat(vpn,target-profiles,migrations): add startup data migrations, support scoped VPN route allow entries, and rename target profile hosts to ips
This commit is contained in:
@@ -15,6 +15,9 @@ import { StorageBackedCertManager } from './classes.storage-cert-manager.js';
|
||||
import { CertProvisionScheduler } from './classes.cert-provision-scheduler.js';
|
||||
// Import unified database
|
||||
import { DcRouterDb, type IDcRouterDbConfig, CacheCleaner, ProxyCertDoc, AcmeCertDoc } from './db/index.js';
|
||||
// Import migration runner and app version
|
||||
import { createMigrationRunner } from '../ts_migrations/index.js';
|
||||
import { commitinfo } from './00_commitinfo_data.js';
|
||||
|
||||
import { OpsServer } from './opsserver/index.js';
|
||||
import { MetricsManager } from './monitoring/index.js';
|
||||
@@ -775,6 +778,19 @@ export class DcRouter {
|
||||
|
||||
await this.dcRouterDb.start();
|
||||
|
||||
// Run any pending data migrations before anything else reads from the DB.
|
||||
// This must complete before ConfigManagers loads profiles.
|
||||
const migration = await createMigrationRunner(this.dcRouterDb.getDb(), commitinfo.version);
|
||||
const migrationResult = await migration.run();
|
||||
if (migrationResult.stepsApplied.length > 0) {
|
||||
logger.log('info',
|
||||
`smartmigration: ${migrationResult.currentVersionBefore ?? 'fresh'} → ${migrationResult.currentVersionAfter} ` +
|
||||
`(${migrationResult.stepsApplied.length} step(s) applied in ${migrationResult.totalDurationMs}ms)`,
|
||||
);
|
||||
} else if (migrationResult.wasFreshInstall) {
|
||||
logger.log('info', `smartmigration: fresh install stamped to ${migrationResult.currentVersionAfter}`);
|
||||
}
|
||||
|
||||
// Start the cache cleaner for TTL-based document cleanup
|
||||
const cleanupIntervalMs = (dbConfig.cleanupIntervalHours || 1) * 60 * 60 * 1000;
|
||||
this.cacheCleaner = new CacheCleaner(this.dcRouterDb, {
|
||||
@@ -1042,15 +1058,9 @@ export class DcRouter {
|
||||
});
|
||||
});
|
||||
|
||||
this.smartProxy.on('certificate-renewed', (event: plugins.smartproxy.ICertificateIssuedEvent) => {
|
||||
logger.log('info', `Certificate renewed for ${event.domain} via ${event.source}, expires ${event.expiryDate}`);
|
||||
const routeNames = this.findRouteNamesForDomain(event.domain);
|
||||
this.certificateStatusMap.set(event.domain, {
|
||||
status: 'valid', routeNames,
|
||||
expiryDate: event.expiryDate, issuedAt: new Date().toISOString(),
|
||||
source: event.source,
|
||||
});
|
||||
});
|
||||
// Note: smartproxy v27.5.0 emits only 'certificate-issued' and 'certificate-failed'.
|
||||
// Renewals come through 'certificate-issued' (with optional isRenewal? in the payload).
|
||||
// The vestigial 'certificate-renewed' event from common-types.ts is never emitted.
|
||||
|
||||
this.smartProxy.on('certificate-failed', (event: plugins.smartproxy.ICertificateFailedEvent) => {
|
||||
logger.log('error', `Certificate failed for ${event.domain} (${event.source}): ${event.error}`);
|
||||
|
||||
Reference in New Issue
Block a user