From 4f696bc159ae728dd83fddecc84694b764909b8d Mon Sep 17 00:00:00 2001 From: Jonathan Hess Date: Tue, 11 Aug 2026 23:26:37 +0000 Subject: [PATCH 1/2] fix: Update instance DNS regex to correct format --- src/parse-instance-connection-name.ts | 89 +++++--------------------- test/parse-instance-connection-name.ts | 44 ++++++++++++- 2 files changed, 58 insertions(+), 75 deletions(-) diff --git a/src/parse-instance-connection-name.ts b/src/parse-instance-connection-name.ts index dc7407af..4b6bd535 100644 --- a/src/parse-instance-connection-name.ts +++ b/src/parse-instance-connection-name.ts @@ -16,6 +16,9 @@ import {InstanceConnectionInfo} from './instance-connection-info'; import {CloudSQLConnectorError} from './errors'; import {resolveTxtRecord, resolveCnameRecord} from './dns-lookup'; +export const INSTANCE_DNS_NAME_PATTERN = + /^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\.(sql|sql-psa|sql-psc)\.goog\.?$/; + export interface DNSFetcher { resolveConnectSettings(region: string, dnsName: string): Promise; } @@ -27,13 +30,9 @@ export function parseInstanceDNSName(dnsName: string): { suffix: string; ok: boolean; } { - let name = dnsName.toLowerCase(); - if (name.endsWith('.')) { - name = name.slice(0, -1); - } - - const parts = name.split('.'); - if (parts.length !== 5) { + const name = dnsName.toLowerCase(); + const match = name.match(INSTANCE_DNS_NAME_PATTERN); + if (!match) { return { instanceLabel: '', projectLabel: '', @@ -43,35 +42,10 @@ export function parseInstanceDNSName(dnsName: string): { }; } - if (parts[4] !== 'goog') { - return { - instanceLabel: '', - projectLabel: '', - region: '', - suffix: '', - ok: false, - }; - } - - const suffixType = parts[3]; - if ( - suffixType !== 'sql' && - suffixType !== 'sql-psa' && - suffixType !== 'sql-psc' - ) { - return { - instanceLabel: '', - projectLabel: '', - region: '', - suffix: '', - ok: false, - }; - } - - const instanceLabel = parts[0]; - const projectLabel = parts[1]; - const region = parts[2]; - const suffix = suffixType + '.goog'; + const instanceLabel = match[1]; + const projectLabel = match[2]; + const region = match[3]; + const suffix = match[4] + '.goog'; if (region === 'global') { return { @@ -83,37 +57,6 @@ export function parseInstanceDNSName(dnsName: string): { }; } - if (instanceLabel.length !== 12) { - return { - instanceLabel: '', - projectLabel: '', - region: '', - suffix: '', - ok: false, - }; - } - - // Validate instanceLabel is hex - if (!/^[0-9a-f]{12}$/.test(instanceLabel)) { - return { - instanceLabel: '', - projectLabel: '', - region: '', - suffix: '', - ok: false, - }; - } - - if (!region.includes('-')) { - return { - instanceLabel: '', - projectLabel: '', - region: '', - suffix: '', - ok: false, - }; - } - return {instanceLabel, projectLabel, region, suffix, ok: true}; } @@ -178,14 +121,14 @@ export function isValidDomainName(name: string): boolean { return Boolean(matches); } -const instanceDNSSuffixRegex = /\.sql(-\w+)?\.goog\.?$/; -const globalInstanceDNSRegex = /\.global\.sql(-\w+)?\.goog\.?$/; - export function isInstanceDNSName(name: string): boolean { const lower = name.toLowerCase(); - return ( - instanceDNSSuffixRegex.test(lower) && !globalInstanceDNSRegex.test(lower) - ); + const match = lower.match(INSTANCE_DNS_NAME_PATTERN); + if (!match) { + return false; + } + const region = match[3]; + return region !== 'global'; } export function isInstanceConnectionName(name: string): boolean { diff --git a/test/parse-instance-connection-name.ts b/test/parse-instance-connection-name.ts index 4e9db60e..5b9c5882 100644 --- a/test/parse-instance-connection-name.ts +++ b/test/parse-instance-connection-name.ts @@ -406,6 +406,26 @@ t.test('parseInstanceDNSName', async t => { ok: true, }, }, + { + dns: 'not-hex-label.fedcba9876543.us-central1.sql-psc.goog', + want: { + instanceLabel: 'not-hex-label', + projectLabel: 'fedcba9876543', + region: 'us-central1', + suffix: 'sql-psc.goog', + ok: true, + }, + }, + { + dns: 'abc.def.uscentral.sql-psc.goog', + want: { + instanceLabel: 'abc', + projectLabel: 'def', + region: 'uscentral', + suffix: 'sql-psc.goog', + ok: true, + }, + }, { dns: '0123456789ab.fedcba9876543.global.sql-psc.goog', want: { @@ -417,7 +437,7 @@ t.test('parseInstanceDNSName', async t => { }, }, { - dns: 'not-hex-label.fedcba9876543.us-central1.sql-psc.goog', + dns: '0123456789ab.fedcba9876543.us-central1.invalid-suffix.goog', want: { instanceLabel: '', projectLabel: '', @@ -427,7 +447,27 @@ t.test('parseInstanceDNSName', async t => { }, }, { - dns: '0123456789ab.fedcba9876543.us-central1.invalid-suffix.goog', + dns: '-starts-with-hyphen.proj.region.sql.goog', + want: { + instanceLabel: '', + projectLabel: '', + region: '', + suffix: '', + ok: false, + }, + }, + { + dns: 'ends-with-hyphen-.proj.region.sql.goog', + want: { + instanceLabel: '', + projectLabel: '', + region: '', + suffix: '', + ok: false, + }, + }, + { + dns: 'empty..region.sql.goog', want: { instanceLabel: '', projectLabel: '', From 7703618b1b4a9cc0dc34a1081d1c463b0dfe93bb Mon Sep 17 00:00:00 2001 From: Jonathan Hess Date: Wed, 12 Aug 2026 00:07:34 +0000 Subject: [PATCH 2/2] test: Add unit tests for periodic resolution optimization for immutable DNS names --- test/cloud-sql-instance-dns.ts | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/test/cloud-sql-instance-dns.ts b/test/cloud-sql-instance-dns.ts index bca9016c..b1afb5ea 100644 --- a/test/cloud-sql-instance-dns.ts +++ b/test/cloud-sql-instance-dns.ts @@ -39,6 +39,9 @@ t.test('CloudSQLInstance DNS Lookup', async t => { expirationTime: '2033-01-06T10:00:00.232Z', }; }, + async resolveConnectSettings() { + return 'my-project:us-east1:my-instance'; + }, }; let resolveARecordMock = async (): Promise => { @@ -161,4 +164,65 @@ t.test('CloudSQLInstance DNS Lookup', async t => { t.equal(instance.host, '127.0.0.1', 'Host should use metadata IP'); }); + + t.test('optimization for immutable names - custom DNS', async t => { + resolveARecordMock = async () => ['10.0.0.1']; + resolveTXTRecordMock = async () => ['my-project:us-east1:my-instance']; + + const instance = await CloudSQLInstance.getCloudSQLInstance({ + ipType: IpAddressTypes.PUBLIC, + authType: AuthTypes.PASSWORD, + domainName: 'example.com', + sqlAdminFetcher: fetcher, + }); + t.after(() => instance.close()); + + t.ok( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (instance as any).checkDomainID, + 'should enable checkDomain interval for custom DNS' + ); + }); + + t.test( + 'optimization for immutable names - immutable instance DNS', + async t => { + resolveARecordMock = async () => ['10.0.0.1']; + + const instance = await CloudSQLInstance.getCloudSQLInstance({ + ipType: IpAddressTypes.PUBLIC, + authType: AuthTypes.PASSWORD, + domainName: '0123456789ab.fedcba9876543.us-central1.sql-psc.goog', + sqlAdminFetcher: fetcher, + }); + t.after(() => instance.close()); + + t.notOk( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (instance as any).checkDomainID, + 'should NOT enable checkDomain interval for immutable instance DNS' + ); + } + ); + + t.test( + 'optimization for immutable names - mutable global instance DNS', + async t => { + resolveARecordMock = async () => ['10.0.0.1']; + + const instance = await CloudSQLInstance.getCloudSQLInstance({ + ipType: IpAddressTypes.PUBLIC, + authType: AuthTypes.PASSWORD, + domainName: '0123456789ab.fedcba9876543.global.sql-psc.goog', + sqlAdminFetcher: fetcher, + }); + t.after(() => instance.close()); + + t.ok( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (instance as any).checkDomainID, + 'should enable checkDomain interval for mutable global instance DNS' + ); + } + ); });