const assert = require('node:assert/strict'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const { test } = require('node:test'); const { loadPostgresCertificateAuthorityFile, } = require('@qinglong/cluster-postgres/runtime'); const { ClusterControlConfigError, createClusterControlDatabaseBinding, loadClusterControlConfig, } = require('@qinglong/cluster-control/config'); const CA_FILE = path.join(__dirname, 'fixtures', 'mtls', 'ca-cert.pem'); const CA_BUNDLE = loadPostgresCertificateAuthorityFile(CA_FILE); const BASE_ENV = Object.freeze({ QL3_CLUSTER_CONTROL_ENABLED: 'true', QL_DEPLOYMENT_PROFILE: 'cluster-control', QL3_POSTGRES_RUNTIME_URL: 'postgresql://ql3_runtime:secret@database.internal:5432/qinglong', QL3_POSTGRES_TLS_SERVERNAME: 'database.internal', QL3_API_CREDENTIAL_PEPPER: 'A'.repeat(43), }); test('disabled configuration does not read PostgreSQL credentials', () => { const reads = []; const environment = new Proxy( { QL3_CLUSTER_CONTROL_ENABLED: 'false', QL_DEPLOYMENT_PROFILE: 'standalone', }, { get(target, property, receiver) { reads.push(property); if ( property === 'QL3_POSTGRES_RUNTIME_URL' || property === 'QL3_API_CREDENTIAL_PEPPER' ) { throw new Error('credential must not be read'); } return Reflect.get(target, property, receiver); }, }, ); assert.deepEqual(loadClusterControlConfig(environment), { enabled: false, profile: 'standalone', }); assert.equal(reads.includes('QL3_POSTGRES_RUNTIME_URL'), false); assert.equal(reads.includes('QL3_API_CREDENTIAL_PEPPER'), false); }); test('enabled configuration requires the exact cluster-control profile', () => { assert.throws( () => loadClusterControlConfig({ ...BASE_ENV, QL_DEPLOYMENT_PROFILE: 'standalone', }), ClusterControlConfigError, ); assert.throws( () => loadClusterControlConfig({ ...BASE_ENV, QL3_CLUSTER_CONTROL_ENABLED: 'yes', }), ClusterControlConfigError, ); }); test('builds an exact runtime-only TLS-verified Pool configuration', async () => { const config = loadClusterControlConfig({ ...BASE_ENV, QL3_CLUSTER_HTTP_HOST: '127.0.0.1', QL3_CLUSTER_HTTP_PORT: '5900', QL3_CLUSTER_HTTP_MAX_IN_FLIGHT: '32', QL3_CLUSTER_AUTH_RATE_WINDOW_MS: '30000', QL3_CLUSTER_AUTH_RATE_PER_PEER: '20', QL3_CLUSTER_AUTH_RATE_GLOBAL: '200', QL3_CLUSTER_AUTH_RATE_MAX_PEERS: '512', QL3_POSTGRES_MAX_CONNECTIONS: '12', QL3_POSTGRES_TLS_SERVERNAME: 'database.internal', QL3_POSTGRES_TLS_CA_FILE: CA_FILE, }); assert.equal(config.enabled, true); assert.deepEqual(config.http, { host: '127.0.0.1', port: 5900, maxBodyBytes: 1024 * 1024, maxInFlightRequests: 32, authenticationRateWindowMs: 30_000, authenticationRatePerPeer: 20, authenticationRateGlobal: 200, authenticationRateMaxPeers: 512, requestTimeoutMs: 15_000, drainTimeoutMs: 10_000, }); assert.deepEqual(config.database, { connection: { connectionString: BASE_ENV.QL3_POSTGRES_RUNTIME_URL, tls: { mode: 'verify-full', ca: CA_BUNDLE, servername: 'database.internal', }, }, pool: { applicationName: 'qinglong-cluster-runtime', maxConnections: 12, connectionTimeoutMs: 5_000, }, }); assert.deepEqual(config.security, { apiCredentialPepperKeyring: { schemaVersion: 1, activePepperKeyId: 'legacy-v1', keys: [ { pepperKeyId: 'legacy-v1', pepper: BASE_ENV.QL3_API_CREDENTIAL_PEPPER, }, ], }, }); assert.deepEqual(config.logRetention, { enabled: true, retentionMs: 30 * 24 * 60 * 60_000, claimLimit: 4, leaseMs: 30_000, maximumCycleMs: 10_000, retryBaseMs: 5_000, retryMaximumMs: 60 * 60_000, maximumFailures: 8, intervalMs: 60_000, stopTimeoutMs: 10_000, }); const binding = createClusterControlDatabaseBinding(config); assert.equal(binding.availability.status, 'available'); const database = await binding.openDatabase(); await database.close(); }); test('loads an exact private dual-generation pepper keyring file', (context) => { const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-keyring-')); context.after(() => fs.rmSync(directory, { recursive: true, force: true })); fs.chmodSync(directory, 0o700); const keyringFile = path.join(directory, 'api-credential-keyring.json'); const nextPepper = Buffer.alloc(32, 2).toString('base64url'); fs.writeFileSync( keyringFile, JSON.stringify({ schemaVersion: 1, activePepperKeyId: 'rotation-2026-08', keys: [ { pepperKeyId: 'legacy-v1', pepper: 'A'.repeat(43) }, { pepperKeyId: 'rotation-2026-08', pepper: nextPepper }, ], }), { mode: 0o600 }, ); const environment = { ...BASE_ENV, QL3_API_CREDENTIAL_PEPPER: undefined, QL3_API_CREDENTIAL_PEPPER_KEYRING_FILE: keyringFile, }; assert.equal( loadClusterControlConfig(environment).security.apiCredentialPepperKeyring .activePepperKeyId, 'rotation-2026-08', ); assert.throws( () => loadClusterControlConfig({ ...environment, QL3_API_CREDENTIAL_PEPPER: 'A'.repeat(43), }), /exactly one API credential pepper source/, ); fs.chmodSync(keyringFile, 0o622); assert.throws( () => loadClusterControlConfig(environment), /file authority is invalid/, ); }); test('loads discrete operator-managed runtime credentials without a DSN copy', () => { const { QL3_POSTGRES_RUNTIME_URL: _connectionString, ...withoutConnectionString } = BASE_ENV; const config = loadClusterControlConfig({ ...withoutConnectionString, QL3_POSTGRES_RUNTIME_HOST: 'ql3-postgres-rw.qinglong3-system.svc', QL3_POSTGRES_RUNTIME_PORT: '5432', QL3_POSTGRES_RUNTIME_DATABASE: 'qinglong', QL3_POSTGRES_RUNTIME_USER: 'ql3_runtime', QL3_POSTGRES_RUNTIME_PASSWORD: 'operator-secret', }); assert.deepEqual(config.database.connection, { host: 'ql3-postgres-rw.qinglong3-system.svc', port: 5432, database: 'qinglong', user: 'ql3_runtime', password: 'operator-secret', tls: { mode: 'verify-full', servername: 'database.internal', }, }); }); test('requires a second explicit gate before disabling PostgreSQL TLS', () => { assert.throws( () => loadClusterControlConfig({ ...BASE_ENV, QL3_POSTGRES_TLS_MODE: 'disable', }), /requires QL3_POSTGRES_ALLOW_INSECURE=true/, ); const config = loadClusterControlConfig({ ...BASE_ENV, QL3_POSTGRES_TLS_MODE: 'disable', QL3_POSTGRES_ALLOW_INSECURE: 'true', }); assert.deepEqual(config.database.connection.tls, { mode: 'disable' }); }); test('rejects TLS query overrides, missing credentials and unbounded values', () => { for (const environment of [ { ...BASE_ENV, QL3_POSTGRES_RUNTIME_URL: 'postgresql://database.internal/qinglong?sslmode=disable', }, { ...BASE_ENV, QL3_POSTGRES_TLS_SERVERNAME: undefined }, { ...BASE_ENV, QL3_POSTGRES_TLS_SERVERNAME: '127.0.0.1' }, { ...BASE_ENV, QL3_POSTGRES_TLS_CA_FILE: 'relative-ca.pem' }, { ...BASE_ENV, QL3_POSTGRES_TLS_MODE: 'disable', QL3_POSTGRES_ALLOW_INSECURE: 'true', QL3_POSTGRES_TLS_CA_FILE: CA_FILE, }, { ...BASE_ENV, QL3_POSTGRES_RUNTIME_URL: '' }, { ...BASE_ENV, QL3_POSTGRES_RUNTIME_HOST: 'database.internal', }, { ...BASE_ENV, QL3_POSTGRES_MAX_CONNECTIONS: '65' }, { ...BASE_ENV, QL3_CLUSTER_HTTP_MAX_BODY_BYTES: '99999999' }, { ...BASE_ENV, QL3_CLUSTER_AUTH_RATE_WINDOW_MS: '99999999' }, { ...BASE_ENV, QL3_CLUSTER_AUTH_RATE_PER_PEER: '0' }, { ...BASE_ENV, QL3_CLUSTER_AUTH_RATE_GLOBAL: '1000001' }, { ...BASE_ENV, QL3_CLUSTER_AUTH_RATE_MAX_PEERS: '65537' }, { ...BASE_ENV, QL3_API_CREDENTIAL_PEPPER: 'weak' }, { ...BASE_ENV, QL3_CLUSTER_LOG_RETENTION_CLAIM_LIMIT: '17' }, { ...BASE_ENV, QL3_CLUSTER_LOG_RETENTION_LEASE_MS: '5000', QL3_CLUSTER_LOG_RETENTION_CYCLE_BUDGET_MS: '4501', }, { ...BASE_ENV, QL3_CLUSTER_LOG_RETENTION_RETRY_BASE_MS: '5000', QL3_CLUSTER_LOG_RETENTION_RETRY_MAX_MS: '4999', }, ]) { assert.throws( () => loadClusterControlConfig(environment), ClusterControlConfigError, ); } }); test('loads bounded Cluster log retention policy and permits explicit disable', () => { const disabled = loadClusterControlConfig({ ...BASE_ENV, QL3_CLUSTER_LOG_RETENTION_ENABLED: 'false', QL3_CLUSTER_LOG_RETENTION_CLAIM_LIMIT: '999', }); assert.deepEqual(disabled.logRetention, { enabled: false }); const configured = loadClusterControlConfig({ ...BASE_ENV, QL3_CLUSTER_LOG_RETENTION_MS: '60000', QL3_CLUSTER_LOG_RETENTION_CLAIM_LIMIT: '2', QL3_CLUSTER_LOG_RETENTION_LEASE_MS: '5000', QL3_CLUSTER_LOG_RETENTION_CYCLE_BUDGET_MS: '4000', QL3_CLUSTER_LOG_RETENTION_RETRY_BASE_MS: '250', QL3_CLUSTER_LOG_RETENTION_RETRY_MAX_MS: '1000', QL3_CLUSTER_LOG_RETENTION_MAX_FAILURES: '3', QL3_CLUSTER_LOG_RETENTION_INTERVAL_MS: '2000', QL3_CLUSTER_LOG_RETENTION_STOP_TIMEOUT_MS: '500', }); assert.deepEqual(configured.logRetention, { enabled: true, retentionMs: 60_000, claimLimit: 2, leaseMs: 5_000, maximumCycleMs: 4_000, retryBaseMs: 250, retryMaximumMs: 1_000, maximumFailures: 3, intervalMs: 2_000, stopTimeoutMs: 500, }); });