Skip to content

Commit f35fd91

Browse files
EOD commit
1 parent 233a2e0 commit f35fd91

File tree

7 files changed

+74
-11
lines changed

7 files changed

+74
-11
lines changed

src/cmap/connect.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
type ConnectionOptions,
2626
CryptoConnection
2727
} from './connection';
28-
import type { ClientMetadata } from './handshake/client_metadata';
28+
import { type ClientMetadata, addAllEnvClientMetadata } from './handshake/client_metadata';
2929
import {
3030
MAX_SUPPORTED_SERVER_VERSION,
3131
MAX_SUPPORTED_WIRE_VERSION,
@@ -200,11 +200,11 @@ export async function prepareHandshakeDocument(
200200
const options = authContext.options;
201201
const compressors = options.compressors ? options.compressors : [];
202202
const { serverApi } = authContext.connection;
203-
203+
const clientMetadata = await addAllEnvClientMetadata(options.internalMetadata);
204204
const handshakeDoc: HandshakeDocument = {
205205
[serverApi?.version || options.loadBalanced === true ? 'hello' : LEGACY_HELLO_COMMAND]: 1,
206206
helloOk: true,
207-
client: options.metadata,
207+
client: clientMetadata.toObject(),
208208
compression: compressors
209209
};
210210

src/cmap/connection.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import {
5757
type WriteProtocolMessageType
5858
} from './commands';
5959
import type { Stream } from './connect';
60-
import type { ClientMetadata } from './handshake/client_metadata';
60+
import type { ClientMetadata, LimitedSizeDocument } from './handshake/client_metadata';
6161
import { StreamDescription, type StreamDescriptionOptions } from './stream_description';
6262
import { type CompressorName, decompressResponse } from './wire_protocol/compression';
6363
import { onData } from './wire_protocol/on_data';
@@ -118,6 +118,8 @@ export interface ConnectionOptions
118118
socketTimeoutMS?: number;
119119
cancellationToken?: CancellationToken;
120120
metadata: ClientMetadata;
121+
/** @internal */
122+
internalMetadata: LimitedSizeDocument;
121123
/** @internal */
122124
mongoLogger?: MongoLogger | undefined;
123125
}

src/cmap/connection_pool.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
234234
waitQueueTimeoutMS: options.waitQueueTimeoutMS ?? 0,
235235
minPoolSizeCheckFrequencyMS: options.minPoolSizeCheckFrequencyMS ?? 100,
236236
autoEncrypter: options.autoEncrypter,
237-
metadata: options.metadata
237+
metadata: options.metadata,
238238
});
239239

240240
if (this.options.minPoolSize > this.options.maxPoolSize) {
@@ -634,7 +634,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
634634
generation: this[kGeneration],
635635
cancellationToken: this[kCancellationToken],
636636
mongoLogger: this.mongoLogger,
637-
authProviders: this[kServer].topology.client.s.authProviders
637+
authProviders: this[kServer].topology.client.s.authProviders,
638638
};
639639

640640
this[kPending]++;

src/cmap/handshake/client_metadata.ts

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { promises as fs } from 'fs';
12
import * as os from 'os';
23
import * as process from 'process';
34

@@ -91,8 +92,14 @@ type MakeClientMetadataOptions = Pick<MongoOptions, 'appName' | 'driverInfo'>;
9192
* 4. Truncate `platform`. -- special we do not truncate this field
9293
*/
9394
export function makeClientMetadata(options: MakeClientMetadataOptions): ClientMetadata {
94-
const metadataDocument = new LimitedSizeDocument(512);
95+
let metadataDocument = new LimitedSizeDocument(512);
96+
metadataDocument = addNonEnvClientMetadata(options, metadataDocument);
97+
metadataDocument = addFAASOnlyEnvClientMetadata(metadataDocument);
98+
return metadataDocument.toObject();
99+
}
100+
95101

102+
export function addNonEnvClientMetadata(options: MakeClientMetadataOptions, metadataDocument: LimitedSizeDocument): LimitedSizeDocument {
96103
const { appName = '' } = options;
97104
// Add app name first, it must be sent
98105
if (appName.length > 0) {
@@ -142,6 +149,10 @@ export function makeClientMetadata(options: MakeClientMetadataOptions): ClientMe
142149
}
143150
}
144151

152+
return metadataDocument;
153+
}
154+
155+
function addFAASOnlyEnvClientMetadata(metadataDocument: LimitedSizeDocument): LimitedSizeDocument {
145156
const faasEnv = getFAASEnv();
146157
if (faasEnv != null) {
147158
if (!metadataDocument.ifItFitsItSits('env', faasEnv)) {
@@ -152,8 +163,50 @@ export function makeClientMetadata(options: MakeClientMetadataOptions): ClientMe
152163
}
153164
}
154165
}
166+
return metadataDocument;
167+
}
155168

156-
return metadataDocument.toObject();
169+
170+
let isDocker: boolean;
171+
export async function addAllEnvClientMetadata(metadataDocument: LimitedSizeDocument) {
172+
const faasEnv = getFAASEnv();
173+
174+
async function getContainerMetadata() {
175+
const containerMetadata: Record<string, any> = {};
176+
if (isDocker !== false && isDocker !== true) {
177+
try {
178+
await fs.access('/.dockerenv');
179+
isDocker = true;
180+
} catch {
181+
isDocker = false;
182+
}
183+
}
184+
const isKubernetes = process.env.KUBERNETES_SERVICE_HOST ? true : false;
185+
186+
if (isDocker || isKubernetes) {
187+
if (isDocker) {
188+
containerMetadata['runtime'] = 'docker';
189+
}
190+
if (isKubernetes) {
191+
containerMetadata['orchestrator'] = 'kubernetes';
192+
}
193+
}
194+
return containerMetadata;
195+
}
196+
197+
const containerMetadata = await getContainerMetadata();
198+
const envMetadata = faasEnv ? faasEnv.set('container', containerMetadata) : containerMetadata;
199+
200+
if (envMetadata != null) {
201+
if (!metadataDocument.ifItFitsItSits('env', envMetadata)) {
202+
for (const key of envMetadata.keys()) {
203+
envMetadata.delete(key);
204+
if (envMetadata.size === 0) break;
205+
if (metadataDocument.ifItFitsItSits('env', envMetadata)) break;
206+
}
207+
}
208+
}
209+
return metadataDocument;
157210
}
158211

159212
/**

src/connection_string.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { URLSearchParams } from 'url';
55
import type { Document } from './bson';
66
import { MongoCredentials } from './cmap/auth/mongo_credentials';
77
import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './cmap/auth/providers';
8-
import { makeClientMetadata } from './cmap/handshake/client_metadata';
8+
import { type ClientMetadata, makeClientMetadata } from './cmap/handshake/client_metadata';
99
import { Compressor, type CompressorName } from './cmap/wire_protocol/compression';
1010
import { Encrypter } from './encrypter';
1111
import {

src/mongo_client.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
import { AuthMechanism } from './cmap/auth/providers';
1515
import type { LEGAL_TCP_SOCKET_OPTIONS, LEGAL_TLS_SOCKET_OPTIONS } from './cmap/connect';
1616
import type { Connection } from './cmap/connection';
17-
import type { ClientMetadata } from './cmap/handshake/client_metadata';
17+
import type { ClientMetadata, LimitedSizeDocument } from './cmap/handshake/client_metadata';
1818
import type { CompressorName } from './cmap/wire_protocol/compression';
1919
import { parseOptions, resolveSRVRecord } from './connection_string';
2020
import { MONGO_CLIENT_EVENTS } from './constants';
@@ -897,4 +897,11 @@ export interface MongoOptions
897897
* TODO: NODE-5671 - remove internal flag
898898
*/
899899
mongodbLogPath?: 'stderr' | 'stdout' | MongoDBLogWritable;
900+
901+
/**
902+
* @internal
903+
* Metadata as BSON bytes.
904+
* Does not contain any environment information.
905+
*/
906+
internalMetadata: LimitedSizeDocument;
900907
}

src/sdam/topology.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { BSONSerializeOptions, Document } from '../bson';
44
import type { MongoCredentials } from '../cmap/auth/mongo_credentials';
55
import type { ConnectionEvents, DestroyOptions } from '../cmap/connection';
66
import type { CloseOptions, ConnectionPoolEvents } from '../cmap/connection_pool';
7-
import type { ClientMetadata } from '../cmap/handshake/client_metadata';
7+
import type { ClientMetadata, LimitedSizeDocument } from '../cmap/handshake/client_metadata';
88
import { DEFAULT_OPTIONS, FEATURE_FLAGS } from '../connection_string';
99
import {
1010
CLOSE,
@@ -158,6 +158,7 @@ export interface TopologyOptions extends BSONSerializeOptions, ServerOptions {
158158
directConnection: boolean;
159159
loadBalanced: boolean;
160160
metadata: ClientMetadata;
161+
internalMetadata: LimitedSizeDocument;
161162
serverMonitoringMode: ServerMonitoringMode;
162163
/** MongoDB server API version */
163164
serverApi?: ServerApi;

0 commit comments

Comments
 (0)