Compare commits

..

2 Commits

Author SHA1 Message Date
Sindhu Balasubramanian
a6dbfc70aa Add console log 2025-09-16 09:15:23 -07:00
Sindhu Balasubramanian
9cf3c7902e Add flags for PPAF 2025-09-15 11:33:41 -07:00
9 changed files with 52 additions and 98 deletions

View File

@@ -124,10 +124,13 @@ export const endpoint = () => {
const location = _global.parent ? _global.parent.location : _global.location; const location = _global.parent ? _global.parent.location : _global.location;
return configContext.EMULATOR_ENDPOINT || location.origin; return configContext.EMULATOR_ENDPOINT || location.origin;
} }
return ( const endpoint: string = userContext.selectedRegionalEndpoint ||
userContext.selectedRegionalEndpoint ||
userContext.endpoint || userContext.endpoint ||
userContext?.databaseAccount?.properties?.documentEndpoint userContext?.databaseAccount?.properties?.documentEndpoint;
console.log("endpoint value", endpoint);
return (
endpoint
); );
}; };
@@ -207,6 +210,8 @@ export function client(): Cosmos.CosmosClient {
defaultHeaders: _defaultHeaders, defaultHeaders: _defaultHeaders,
connectionPolicy: { connectionPolicy: {
enableEndpointDiscovery: !userContext.selectedRegionalEndpoint, enableEndpointDiscovery: !userContext.selectedRegionalEndpoint,
enablePartitionLevelFailover: true,
enablePartitionLevelCircuitBreaker: true,
retryOptions: { retryOptions: {
maxRetryAttemptCount: LocalStorageUtility.getEntryNumber(StorageKey.RetryAttempts), maxRetryAttemptCount: LocalStorageUtility.getEntryNumber(StorageKey.RetryAttempts),
fixedRetryIntervalInMilliseconds: LocalStorageUtility.getEntryNumber(StorageKey.RetryInterval), fixedRetryIntervalInMilliseconds: LocalStorageUtility.getEntryNumber(StorageKey.RetryInterval),

View File

@@ -44,12 +44,6 @@ export interface DatabaseAccountExtendedProperties {
publicNetworkAccess?: string; publicNetworkAccess?: string;
enablePriorityBasedExecution?: boolean; enablePriorityBasedExecution?: boolean;
vcoreMongoEndpoint?: string; vcoreMongoEndpoint?: string;
apiProperties?: ApiProperties;
}
export interface ApiProperties {
/* Describes the version of the MongoDB account. */
serverVersion?: "3.2" | "3.6" | "4.0" | "4.2" | "5.0" | "6.0" | "7.0";
} }
export interface DatabaseAccountResponseLocation { export interface DatabaseAccountResponseLocation {

View File

@@ -18,7 +18,6 @@ import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
import { acquireMsalTokenForAccount } from "Utils/AuthorizationUtils"; import { acquireMsalTokenForAccount } from "Utils/AuthorizationUtils";
import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointUtils"; import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointUtils";
import { featureRegistered } from "Utils/FeatureRegistrationUtils"; import { featureRegistered } from "Utils/FeatureRegistrationUtils";
import { getVSCodeUrl } from "Utils/VSCodeExtensionUtils";
import { update } from "Utils/arm/generatedClients/cosmos/databaseAccounts"; import { update } from "Utils/arm/generatedClients/cosmos/databaseAccounts";
import { useQueryCopilot } from "hooks/useQueryCopilot"; import { useQueryCopilot } from "hooks/useQueryCopilot";
import * as ko from "knockout"; import * as ko from "knockout";
@@ -290,8 +289,40 @@ export default class Explorer {
} }
} }
/**
* Generates a VS Code DocumentDB connection URL using the current user's MongoDB connection parameters.
* Double-encodes the updated connection string for safe usage in VS Code URLs.
*
* The DocumentDB VS Code extension requires double encoding for connection strings.
* See: https://microsoft.github.io/vscode-documentdb/manual/how-to-construct-url.html#double-encoding
*
* @returns {string} The encoded VS Code DocumentDB connection URL.
*/
private getDocumentDbUrl() {
const { adminLogin: adminLoginuserName = "", connectionString = "" } = userContext.vcoreMongoConnectionParams;
const updatedConnectionString = connectionString.replace(/<(user|username)>:<password>/i, adminLoginuserName);
const encodedUpdatedConnectionString = encodeURIComponent(encodeURIComponent(updatedConnectionString));
const documentDbUrl = `vscode://ms-azuretools.vscode-documentdb?connectionString=${encodedUpdatedConnectionString}`;
return documentDbUrl;
}
private getCosmosDbUrl() {
const activeTab = useTabs.getState().activeTab;
const resourceId = encodeURIComponent(userContext.databaseAccount.id);
const database = encodeURIComponent(activeTab?.collection?.databaseId);
const container = encodeURIComponent(activeTab?.collection?.id());
const baseUrl = `vscode://ms-azuretools.vscode-cosmosdb?resourceId=${resourceId}`;
const vscodeUrl = activeTab ? `${baseUrl}&database=${database}&container=${container}` : baseUrl;
return vscodeUrl;
}
private getVSCodeUrl(): string {
const isvCore = (userContext.apiType || userContext.databaseAccount.kind) === "VCoreMongo";
return isvCore ? this.getDocumentDbUrl() : this.getCosmosDbUrl();
}
public openInVsCode(): void { public openInVsCode(): void {
const vscodeUrl = getVSCodeUrl(); const vscodeUrl = this.getVSCodeUrl();
const openVSCodeDialogProps: DialogProps = { const openVSCodeDialogProps: DialogProps = {
linkProps: { linkProps: {
linkText: "Download Visual Studio Code", linkText: "Download Visual Studio Code",

View File

@@ -14,11 +14,6 @@ export const DISABLE_HISTORY = `set +o history`;
* Used when shell initialization or connection fails. * Used when shell initialization or connection fails.
*/ */
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`;
/**
* Command that displays error message with MongoDB networking guidance and exits the shell session.
* Used when MongoDB shell connection fails due to networking issues.
*/
export const EXIT_COMMAND_MONGO = ` printf "\\033[1;31mSession ended. Please close this tab and initiate a new shell session if needed.\\033[0m\\n" && printf "\\033[1;36mPlease use the 'Add Azure Cloud Shell IPs' button in the Networking blade to allow Cloud Shell access, if not already configured.\\033[0m\\n" && disown -a && exit`;
/** /**
* This command runs mongosh in no-database and quiet mode, * This command runs mongosh in no-database and quiet mode,
@@ -45,14 +40,6 @@ export abstract class AbstractShellHandler {
abstract getTerminalSuppressedData(): string[]; abstract getTerminalSuppressedData(): string[];
updateTerminalData?(data: string): string; updateTerminalData?(data: string): string;
/**
* Gets the exit command to use when connection fails.
* Can be overridden by subclasses to provide custom exit commands.
*/
protected getExitCommand(): string {
return EXIT_COMMAND;
}
/** /**
* Constructs the complete initialization command sequence for the shell. * Constructs the complete initialization command sequence for the shell.
* *
@@ -77,7 +64,7 @@ export abstract class AbstractShellHandler {
START_MARKER, START_MARKER,
DISABLE_HISTORY, DISABLE_HISTORY,
...setupCommands, ...setupCommands,
`{ ${connectionCommand}; } || true;${this.getExitCommand()}`, `{ ${connectionCommand}; } || true;${EXIT_COMMAND}`,
]; ];
return allCommands.join("\n").concat("\n"); return allCommands.join("\n").concat("\n");

View File

@@ -1,6 +1,6 @@
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
import { filterAndCleanTerminalOutput, getHostFromUrl, getMongoShellRemoveInfoText } from "../Utils/CommonUtils"; import { filterAndCleanTerminalOutput, getHostFromUrl, getMongoShellRemoveInfoText } from "../Utils/CommonUtils";
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND, EXIT_COMMAND_MONGO } 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;
@@ -48,10 +48,6 @@ export class MongoShellHandler extends AbstractShellHandler {
return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."]; return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
} }
protected getExitCommand(): string {
return EXIT_COMMAND_MONGO;
}
updateTerminalData(data: string): string { updateTerminalData(data: string): string {
return filterAndCleanTerminalOutput(data, this._removeInfoText); return filterAndCleanTerminalOutput(data, this._removeInfoText);
} }

View File

@@ -1,6 +1,6 @@
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
import { filterAndCleanTerminalOutput, getMongoShellRemoveInfoText } from "../Utils/CommonUtils"; import { filterAndCleanTerminalOutput, getMongoShellRemoveInfoText } from "../Utils/CommonUtils";
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND, EXIT_COMMAND_MONGO } 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;
@@ -35,13 +35,6 @@ export class VCoreMongoShellHandler extends AbstractShellHandler {
return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."]; return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
} }
/**
* Override getExitCommand to include MongoDB networking guidance
*/
protected getExitCommand(): string {
return EXIT_COMMAND_MONGO;
}
updateTerminalData(data: string): string { updateTerminalData(data: string): string {
return filterAndCleanTerminalOutput(data, this._removeInfoText); return filterAndCleanTerminalOutput(data, this._removeInfoText);
} }

View File

@@ -7,6 +7,7 @@ const validCloudShellRegions = new Set([
"westeurope", "westeurope",
"centralindia", "centralindia",
"southeastasia", "southeastasia",
"westcentralus",
"usgovvirginia", "usgovvirginia",
"usgovarizona", "usgovarizona",
]); ]);
@@ -40,6 +41,7 @@ export const getNormalizedRegion = (region: string, defaultCloudshellRegion: str
} }
const regionMap: Record<string, string> = { const regionMap: Record<string, string> = {
centralus: "westcentralus",
eastus2: "eastus", eastus2: "eastus",
}; };

View File

@@ -4,6 +4,7 @@ import { QuickstartFirewallNotification } from "Explorer/Quickstart/QuickstartFi
import { getShellNameForDisplay } from "Explorer/Tabs/CloudShellTab/Utils/CommonUtils"; import { getShellNameForDisplay } from "Explorer/Tabs/CloudShellTab/Utils/CommonUtils";
import * as React from "react"; import * as React from "react";
import FirewallRuleScreenshot from "../../../../images/firewallRule.png"; import FirewallRuleScreenshot from "../../../../images/firewallRule.png";
import VcoreFirewallRuleScreenshot from "../../../../images/vcoreMongoFirewallRule.png";
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler"; import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
import * as DataModels from "../../../Contracts/DataModels"; import * as DataModels from "../../../Contracts/DataModels";
import * as ViewModels from "../../../Contracts/ViewModels"; import * as ViewModels from "../../../Contracts/ViewModels";
@@ -24,15 +25,15 @@ export abstract class BaseTerminalComponentAdapter implements ReactAdapter {
) {} ) {}
public renderComponent(): JSX.Element { public renderComponent(): JSX.Element {
if (this.kind === ViewModels.TerminalKind.Mongo || this.kind === ViewModels.TerminalKind.VCoreMongo) {
return this.renderTerminalComponent();
}
if (!this.isAllPublicIPAddressesEnabled()) { if (!this.isAllPublicIPAddressesEnabled()) {
return ( return (
<QuickstartFirewallNotification <QuickstartFirewallNotification
messageType={this.getMessageType()} messageType={this.getMessageType()}
screenshot={FirewallRuleScreenshot} screenshot={
this.kind === ViewModels.TerminalKind.Mongo || this.kind === ViewModels.TerminalKind.VCoreMongo
? VcoreFirewallRuleScreenshot
: FirewallRuleScreenshot
}
shellName={getShellNameForDisplay(this.kind)} shellName={getShellNameForDisplay(this.kind)}
/> />
); );

View File

@@ -1,55 +0,0 @@
import { useTabs } from "hooks/useTabs";
import { userContext } from "UserContext";
import { getHostFromUrl } from "./../Explorer/Tabs/CloudShellTab/Utils/CommonUtils";
export const DOCUMENTDB_VSCODE_EXTENSION_BASEURL = "vscode://ms-azuretools.vscode-documentdb";
export const COSMOSDB_VSCODE_EXTENSION_BASEURL = "vscode://ms-azuretools.vscode-cosmosdb";
/**
* Generates a VS Code DocumentDB connection URL using the current user's MongoDB connection parameters.
* Double-encodes the updated connection string for safe usage in VS Code URLs.
*
* The DocumentDB VS Code extension requires double encoding for connection strings.
* See: https://microsoft.github.io/vscode-documentdb/manual/how-to-construct-url.html#double-encoding
*
* @returns {string} The encoded VS Code DocumentDB connection URL.
*/
export const getVSCodeUrl = (): string => {
const isvCore = (userContext.apiType || userContext.databaseAccount.kind) === "VCoreMongo";
const isMongo =
userContext.apiType === "Mongo" && userContext.databaseAccount?.properties?.apiProperties?.serverVersion !== "3.2";
return isvCore ? getDocumentDbUrl() : isMongo ? getMongoRUUrl() : getCosmosDbUrl();
};
export const getCosmosDbUrl = () => {
const activeTab = useTabs.getState().activeTab;
const resourceId = encodeURIComponent(userContext.databaseAccount.id);
const database = encodeURIComponent(activeTab?.collection?.databaseId);
const container = encodeURIComponent(activeTab?.collection?.id());
const baseUrl = `${COSMOSDB_VSCODE_EXTENSION_BASEURL}?resourceId=${resourceId}`;
const vscodeUrl = activeTab ? `${baseUrl}&database=${database}&container=${container}` : baseUrl;
return vscodeUrl;
};
export const getMongoRUUrl = () => {
const activeTab = useTabs.getState().activeTab;
const databaseAccount = userContext.databaseAccount;
const host = getHostFromUrl(databaseAccount.properties?.mongoEndpoint);
const port = 10255;
const database = activeTab?.collection?.databaseId;
const container = activeTab?.collection?.id();
const encodedUpdatedConnectionString = encodeURIComponent(`mongodb://${databaseAccount?.name}@${host}:${port}`);
const documentDbUrl = `${DOCUMENTDB_VSCODE_EXTENSION_BASEURL}?connectionString=${encodedUpdatedConnectionString}${
database ? `&database=${database}` : ""
}${container ? `&collection=${container}` : ""}`;
return documentDbUrl;
};
export const getDocumentDbUrl = () => {
const { adminLogin: adminLoginuserName = "", connectionString = "" } = userContext.vcoreMongoConnectionParams;
const updatedConnectionString = connectionString.replace(/<(user|username)>:<password>/i, adminLoginuserName);
const encodedUpdatedConnectionString = encodeURIComponent(encodeURIComponent(updatedConnectionString));
const documentDbUrl = `${DOCUMENTDB_VSCODE_EXTENSION_BASEURL}?connectionString=${encodedUpdatedConnectionString}`;
return documentDbUrl;
};