Disabling telemetry for mongo shell (#2195)

* Disabling telemetry for mongo shell

* fix formatting issues

* removed empty spaces from terminal and segregated disableTelemetry command
This commit is contained in:
BChoudhury-ms 2025-07-31 10:03:09 +05:30 committed by GitHub
parent e3815734db
commit 870863a723
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 59 additions and 28 deletions

View File

@ -1,4 +1,4 @@
import { AbstractShellHandler, DISABLE_HISTORY, START_MARKER, EXIT_COMMAND } from "./AbstractShellHandler"; import { AbstractShellHandler, DISABLE_HISTORY, EXIT_COMMAND, START_MARKER } from "./AbstractShellHandler";
// Mock implementation for testing // Mock implementation for testing
class MockShellHandler extends AbstractShellHandler { class MockShellHandler extends AbstractShellHandler {
@ -18,8 +18,8 @@ class MockShellHandler extends AbstractShellHandler {
return "mock-endpoint"; return "mock-endpoint";
} }
getTerminalSuppressedData(): string { getTerminalSuppressedData(): string[] {
return "suppressed-data"; return ["suppressed-data"];
} }
} }
@ -90,7 +90,7 @@ describe("AbstractShellHandler", () => {
}); });
it("should return the terminal suppressed data", () => { it("should return the terminal suppressed data", () => {
expect(shellHandler.getTerminalSuppressedData()).toBe("suppressed-data"); expect(shellHandler.getTerminalSuppressedData()).toEqual(["suppressed-data"]);
}); });
}); });
}); });

View File

@ -15,6 +15,12 @@ export const DISABLE_HISTORY = `set +o history`;
*/ */
export const EXIT_COMMAND = ` printf "\\033[1;31mSession ended. Please close this tab and initiate a new shell session if needed.\\033[0m\\n" && disown -a && exit`; export const EXIT_COMMAND = ` printf "\\033[1;31mSession ended. Please close this tab and initiate a new shell session if needed.\\033[0m\\n" && disown -a && exit`;
/**
* This command runs mongosh in no-database and quiet mode,
* and evaluates the `disableTelemetry()` function to turn off telemetry collection.
*/
export const DISABLE_TELEMETRY_COMMAND = `mongosh --nodb --quiet --eval "disableTelemetry()"`;
/** /**
* Abstract class that defines the interface for shell-specific handlers * Abstract class that defines the interface for shell-specific handlers
* in the CloudShell terminal implementation. Each supported shell type * in the CloudShell terminal implementation. Each supported shell type
@ -31,7 +37,8 @@ export abstract class AbstractShellHandler {
abstract getShellName(): string; abstract getShellName(): string;
abstract getSetUpCommands(): string[]; abstract getSetUpCommands(): string[];
abstract getConnectionCommand(): string; abstract getConnectionCommand(): string;
abstract getTerminalSuppressedData(): string; abstract getTerminalSuppressedData(): string[];
updateTerminalData?(data: string): string;
/** /**
* Constructs the complete initialization command sequence for the shell. * Constructs the complete initialization command sequence for the shell.
@ -77,7 +84,7 @@ export abstract class AbstractShellHandler {
* is not already present in the environment. * is not already present in the environment.
*/ */
protected mongoShellSetupCommands(): string[] { protected mongoShellSetupCommands(): string[] {
const PACKAGE_VERSION: string = "2.5.0"; const PACKAGE_VERSION: string = "2.5.5";
return [ return [
"if ! command -v mongosh &> /dev/null; then echo '⚠️ mongosh not found. Installing...'; fi", "if ! command -v mongosh &> /dev/null; then echo '⚠️ mongosh not found. Installing...'; fi",
`if ! command -v mongosh &> /dev/null; then curl -LO https://downloads.mongodb.com/compass/mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`, `if ! command -v mongosh &> /dev/null; then curl -LO https://downloads.mongodb.com/compass/mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`,
@ -85,7 +92,7 @@ export abstract class AbstractShellHandler {
`if ! command -v mongosh &> /dev/null; then mkdir -p ~/mongosh/bin && mv mongosh-${PACKAGE_VERSION}-linux-x64/bin/mongosh ~/mongosh/bin/ && chmod +x ~/mongosh/bin/mongosh; fi`, `if ! command -v mongosh &> /dev/null; then mkdir -p ~/mongosh/bin && mv mongosh-${PACKAGE_VERSION}-linux-x64/bin/mongosh ~/mongosh/bin/ && chmod +x ~/mongosh/bin/mongosh; fi`,
`if ! command -v mongosh &> /dev/null; then rm -rf mongosh-${PACKAGE_VERSION}-linux-x64 mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`, `if ! command -v mongosh &> /dev/null; then rm -rf mongosh-${PACKAGE_VERSION}-linux-x64 mongosh-${PACKAGE_VERSION}-linux-x64.tgz; fi`,
"if ! command -v mongosh &> /dev/null; then echo 'export PATH=$HOME/mongosh/bin:$PATH' >> ~/.bashrc; fi", "if ! command -v mongosh &> /dev/null; then echo 'export PATH=$HOME/mongosh/bin:$PATH' >> ~/.bashrc; fi",
"source ~/.bashrc", "if ! command -v mongosh &> /dev/null; then source ~/.bashrc; fi",
]; ];
} }
} }

View File

@ -94,7 +94,7 @@ describe("CassandraShellHandler", () => {
}); });
test("should return the correct terminal suppressed data", () => { test("should return the correct terminal suppressed data", () => {
expect(handler.getTerminalSuppressedData()).toBe(""); expect(handler.getTerminalSuppressedData()).toEqual([""]);
}); });
test("should include the correct package version in setup commands", () => { test("should include the correct package version in setup commands", () => {

View File

@ -41,7 +41,7 @@ export class CassandraShellHandler extends AbstractShellHandler {
return `cqlsh ${getHostFromUrl(this._endpoint)} 10350 -u ${dbName} -p ${this._key} --ssl`; return `cqlsh ${getHostFromUrl(this._endpoint)} 10350 -u ${dbName} -p ${this._key} --ssl`;
} }
public getTerminalSuppressedData(): string { public getTerminalSuppressedData(): string[] {
return ""; return [""];
} }
} }

View File

@ -69,7 +69,7 @@ describe("MongoShellHandler", () => {
expect(Array.isArray(commands)).toBe(true); expect(Array.isArray(commands)).toBe(true);
expect(commands.length).toBe(7); expect(commands.length).toBe(7);
expect(commands[1]).toContain("mongosh-2.5.0-linux-x64.tgz"); expect(commands[1]).toContain("mongosh-2.5.5-linux-x64.tgz");
}); });
}); });
@ -91,7 +91,7 @@ describe("MongoShellHandler", () => {
const command = mongoShellHandler.getConnectionCommand(); const command = mongoShellHandler.getConnectionCommand();
expect(command).toBe( expect(command).toBe(
"mongosh mongodb://test-mongo.documents.azure.com:10255?appName=CosmosExplorerTerminal --username test-account --password test-key --tls --tlsAllowInvalidCertificates", 'mongosh --nodb --quiet --eval "disableTelemetry()" && mongosh mongodb://test-mongo.documents.azure.com:10255?appName=CosmosExplorerTerminal --username test-account --password test-key --tls --tlsAllowInvalidCertificates',
); );
expect(CommonUtils.getHostFromUrl).toHaveBeenCalledWith("https://test-mongo.documents.azure.com:443/"); expect(CommonUtils.getHostFromUrl).toHaveBeenCalledWith("https://test-mongo.documents.azure.com:443/");
@ -124,7 +124,7 @@ describe("MongoShellHandler", () => {
describe("getTerminalSuppressedData", () => { describe("getTerminalSuppressedData", () => {
it("should return the correct warning message", () => { it("should return the correct warning message", () => {
expect(mongoShellHandler.getTerminalSuppressedData()).toBe("Warning: Non-Genuine MongoDB Detected"); expect(mongoShellHandler.getTerminalSuppressedData()).toEqual(["Warning: Non-Genuine MongoDB Detected"]);
}); });
}); });
}); });

View File

@ -1,6 +1,6 @@
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
import { getHostFromUrl } from "../Utils/CommonUtils"; import { getHostFromUrl } from "../Utils/CommonUtils";
import { AbstractShellHandler } from "./AbstractShellHandler"; import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
export class MongoShellHandler extends AbstractShellHandler { export class MongoShellHandler extends AbstractShellHandler {
private _key: string; private _key: string;
@ -29,6 +29,8 @@ export class MongoShellHandler extends AbstractShellHandler {
return "echo 'Database name not found.'"; return "echo 'Database name not found.'";
} }
return ( return (
DISABLE_TELEMETRY_COMMAND +
" && " +
"mongosh mongodb://" + "mongosh mongodb://" +
getHostFromUrl(this._endpoint) + getHostFromUrl(this._endpoint) +
":10255?appName=" + ":10255?appName=" +
@ -41,7 +43,7 @@ export class MongoShellHandler extends AbstractShellHandler {
); );
} }
public getTerminalSuppressedData(): string { public getTerminalSuppressedData(): string[] {
return "Warning: Non-Genuine MongoDB Detected"; return ["Warning: Non-Genuine MongoDB Detected"];
} }
} }

View File

@ -58,7 +58,7 @@ describe("PostgresShellHandler", () => {
}); });
it("should return empty string for terminal suppressed data", () => { it("should return empty string for terminal suppressed data", () => {
expect(postgresShellHandler.getTerminalSuppressedData()).toBe(""); expect(postgresShellHandler.getTerminalSuppressedData()).toEqual([""]);
}); });
}); });
}); });

View File

@ -57,7 +57,7 @@ export class PostgresShellHandler extends AbstractShellHandler {
return `psql -h "${this._endpoint}" -p 5432 -d "citus" -U "${loginName}" --set=sslmode=require --set=application_name=${this.APP_NAME}`; return `psql -h "${this._endpoint}" -p 5432 -d "citus" -U "${loginName}" --set=sslmode=require --set=application_name=${this.APP_NAME}`;
} }
public getTerminalSuppressedData(): string { public getTerminalSuppressedData(): string[] {
return ""; return [""];
} }
} }

View File

@ -45,7 +45,7 @@ describe("VCoreMongoShellHandler", () => {
expect(Array.isArray(commands)).toBe(true); expect(Array.isArray(commands)).toBe(true);
expect(commands.length).toBe(7); expect(commands.length).toBe(7);
expect(commands[1]).toContain("mongosh-2.5.0-linux-x64.tgz"); expect(commands[1]).toContain("mongosh-2.5.5-linux-x64.tgz");
expect(commands[0]).toContain("mongosh not found"); expect(commands[0]).toContain("mongosh not found");
}); });
@ -57,7 +57,10 @@ describe("VCoreMongoShellHandler", () => {
}); });
it("should return the correct terminal suppressed data", () => { it("should return the correct terminal suppressed data", () => {
expect(vcoreMongoShellHandler.getTerminalSuppressedData()).toBe("Warning: Non-Genuine MongoDB Detected"); expect(vcoreMongoShellHandler.getTerminalSuppressedData()).toEqual([
"Warning: Non-Genuine MongoDB Detected",
"Telemetry is now disabled.",
]);
}); });
}); });
}); });

View File

@ -1,8 +1,13 @@
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
import { AbstractShellHandler } from "./AbstractShellHandler"; import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
export class VCoreMongoShellHandler extends AbstractShellHandler { export class VCoreMongoShellHandler extends AbstractShellHandler {
private _endpoint: string | undefined; private _endpoint: string | undefined;
private _textFilterRules: string[] = [
"For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/",
"disableTelemetry() command",
"https://www.mongodb.com/legal/privacy-policy",
];
constructor() { constructor() {
super(); super();
@ -23,10 +28,22 @@ export class VCoreMongoShellHandler extends AbstractShellHandler {
} }
const userName = userContext.vcoreMongoConnectionParams.adminLogin; const userName = userContext.vcoreMongoConnectionParams.adminLogin;
return `mongosh "mongodb+srv://${userName}:@${this._endpoint}/?authMechanism=SCRAM-SHA-256&retrywrites=false&maxIdleTimeMS=120000&appName=${this.APP_NAME}"`;
const connectionUri = `mongodb+srv://${userName}:@${this._endpoint}/?authMechanism=SCRAM-SHA-256&retrywrites=false&maxIdleTimeMS=120000&appName=${this.APP_NAME}`;
return `${DISABLE_TELEMETRY_COMMAND} && mongosh "${connectionUri}"`;
} }
public getTerminalSuppressedData(): string { public getTerminalSuppressedData(): string[] {
return "Warning: Non-Genuine MongoDB Detected"; return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
}
updateTerminalData(content: string): string {
const updatedContent = content
.split("\n")
.filter((line) => !this._textFilterRules.some((part) => line.includes(part)))
.filter((line, idx, arr) => (arr.length > 3 && idx <= arr.length - 3 ? !["", "\r"].includes(line) : true)) // Filter out empty lines and carriage returns, but keep the last 3 lines if they exist
.join("\n");
return updatedContent;
} }
} }

View File

@ -135,11 +135,13 @@ export class AttachAddon implements ITerminalAddon {
} }
if (this._allowTerminalWrite) { if (this._allowTerminalWrite) {
const updatedData = this._shellHandler?.updateTerminalData(data) ?? data;
const suppressedData = this._shellHandler?.getTerminalSuppressedData(); const suppressedData = this._shellHandler?.getTerminalSuppressedData();
const hasSuppressedData = suppressedData && suppressedData.length > 0;
if (!hasSuppressedData || !data.includes(suppressedData)) { const shouldNotWrite = suppressedData.filter(Boolean).some((item) => updatedData.includes(item));
terminal.write(data);
if (!shouldNotWrite) {
terminal.write(updatedData);
} }
} }