Skip to content

Commit c54f829

Browse files
authored
fix: resolve SRV hostname before passing it to mongodb-cloud-info VSCODE-442 (#594)
Right now, we are passing the first hostname from the connection string to mongodb-cloud-info, regardless of whether the connection string is a `mongodb://` connection string or a `mongodb+srv://` one. In the latter case, telemetry gathering fails, because mongodb-cloud-info expects the name of an actual host with associated A or AAAA records (so that it can look up the host’s IP address), not a SRV one. Using resolve-mongodb-srv first matches what Compass does and solves this issue.
1 parent 7cb1ea2 commit c54f829

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,7 @@
10051005
"react-dom": "^17.0.2",
10061006
"react-redux": "^8.1.1",
10071007
"redux": "^4.2.1",
1008+
"resolve-mongodb-srv": "^1.1.2",
10081009
"ts-log": "^2.2.5",
10091010
"uuid": "^8.3.2",
10101011
"vscode-languageclient": "^8.1.0",

src/telemetry/connectionTelemetry.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type { DataService } from 'mongodb-data-service';
22
import { getCloudInfo } from 'mongodb-cloud-info';
33
import mongoDBBuildInfo from 'mongodb-build-info';
4+
import resolveMongodbSrv from 'resolve-mongodb-srv';
45

56
import { ConnectionTypes } from '../connectionController';
67
import { createLogger } from '../logging';
8+
import ConnectionString from 'mongodb-connection-string-url';
79

810
const log = createLogger('connection telemetry helper');
911
// eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -34,14 +36,36 @@ type CloudInfo = {
3436
publicCloudName?: string | null;
3537
};
3638

39+
async function getHostnameForConnection(
40+
connectionStringData: ConnectionString
41+
): Promise<string | null> {
42+
if (connectionStringData.isSRV) {
43+
const uri = await resolveMongodbSrv(connectionStringData.toString()).catch(
44+
() => null
45+
);
46+
if (!uri) {
47+
return null;
48+
}
49+
connectionStringData = new ConnectionString(uri, {
50+
looseValidation: true,
51+
});
52+
}
53+
54+
const [hostname] = (connectionStringData.hosts[0] ?? '').split(':');
55+
return hostname;
56+
}
57+
3758
async function getCloudInfoFromDataService(
38-
firstServerHostname: string
59+
dataService: DataService
3960
): Promise<CloudInfo> {
61+
const hostname = await getHostnameForConnection(
62+
dataService.getConnectionString()
63+
);
4064
const cloudInfo: {
4165
isAws?: boolean;
4266
isAzure?: boolean;
4367
isGcp?: boolean;
44-
} = await getCloudInfo(firstServerHostname);
68+
} = await getCloudInfo(hostname);
4569

4670
if (cloudInfo.isAws) {
4771
return {
@@ -82,15 +106,13 @@ export async function getConnectionTelemetryProperties(
82106

83107
try {
84108
const connectionString = dataService.getConnectionString();
85-
const firstHost = connectionString.hosts[0] || '';
86-
const [hostname] = firstHost.split(':');
87109
const authMechanism = connectionString.searchParams.get('authMechanism');
88110
const username = connectionString.username ? 'DEFAULT' : 'NONE';
89111
const authStrategy = authMechanism ?? username;
90112

91113
const [instance, cloudInfo] = await Promise.all([
92114
dataService.instance(),
93-
getCloudInfoFromDataService(hostname),
115+
getCloudInfoFromDataService(dataService),
94116
]);
95117

96118
preparedProperties = {

0 commit comments

Comments
 (0)