From 44e85647e423ea87a7f5b4d851e334cd5df565dd Mon Sep 17 00:00:00 2001 From: Sourabh Jain Date: Mon, 17 Mar 2025 06:35:19 +0530 Subject: [PATCH] add other db support --- .../CloudShellTab/CloudShellTabComponent.tsx | 5 +- src/Explorer/Tabs/CloudShellTab/Commands.tsx | 132 ++++++++++++------ src/Explorer/Tabs/CloudShellTab/Data.tsx | 11 +- .../Tabs/CloudShellTab/UseTerminal.tsx | 12 +- 4 files changed, 106 insertions(+), 54 deletions(-) diff --git a/src/Explorer/Tabs/CloudShellTab/CloudShellTabComponent.tsx b/src/Explorer/Tabs/CloudShellTab/CloudShellTabComponent.tsx index 720a77f50..4059d9102 100644 --- a/src/Explorer/Tabs/CloudShellTab/CloudShellTabComponent.tsx +++ b/src/Explorer/Tabs/CloudShellTab/CloudShellTabComponent.tsx @@ -3,8 +3,6 @@ import { Terminal } from "xterm"; import { FitAddon } from 'xterm-addon-fit'; import "xterm/css/xterm.css"; import { TerminalKind } from "../../../Contracts/ViewModels"; -import { getAuthorizationHeader } from "../../../Utils/AuthorizationUtils"; -import { getCommands } from "./Commands"; import { startCloudShellterminal } from "./UseTerminal"; export interface CloudShellTerminalProps { @@ -39,8 +37,7 @@ export const CloudShellTerminalComponent: React.FC = ({ const handleResize = () => fitAddon.fit(); window.addEventListener('resize', handleResize); - const authorizationHeader = getAuthorizationHeader() - socketRef.current = startCloudShellterminal(term, getCommands(shellType), authorizationHeader.token); + socketRef.current = startCloudShellterminal(term, shellType); term.onData((data) => { if (socketRef.current && socketRef.current.readyState === WebSocket.OPEN) { diff --git a/src/Explorer/Tabs/CloudShellTab/Commands.tsx b/src/Explorer/Tabs/CloudShellTab/Commands.tsx index 0aaf94469..4ac42eeb6 100644 --- a/src/Explorer/Tabs/CloudShellTab/Commands.tsx +++ b/src/Explorer/Tabs/CloudShellTab/Commands.tsx @@ -3,54 +3,94 @@ */ import { TerminalKind } from "../../../Contracts/ViewModels"; +import { userContext } from "../../../UserContext"; -export const getCommands = (terminalKind: TerminalKind): string => { - if (!Commands[terminalKind]) { - throw new Error(`Unsupported terminal kind: ${terminalKind}`); +export const getCommands = (terminalKind: TerminalKind, key: string) => { + let databaseacc = userContext.databaseAccount; + let endpoint; + switch (terminalKind) { + case TerminalKind.Postgres: + endpoint = databaseacc.properties.postgresqlEndpoint; + break; + case TerminalKind.Mongo: + endpoint = databaseacc.properties.mongoEndpoint; + break; + case TerminalKind.VCoreMongo: + endpoint = databaseacc.properties.vcoreMongoEndpoint; + break; + case TerminalKind.Cassandra: + endpoint = databaseacc.properties.cassandraEndpoint; + break; + default: + throw new Error("Unknown Terminal Kind"); } - return Commands[terminalKind].join("\n").concat("\n"); + + let config = { + host: getHostFromUrl(endpoint), + name: databaseacc.name, + password: key, + endpoint: endpoint + }; + + return commands(terminalKind, config).join("\n").concat("\n"); }; -export const Commands: Record = { - [TerminalKind.Postgres]: [ - "curl -s https://ipinfo.io", - "curl -LO https://ftp.postgresql.org/pub/source/v15.2/postgresql-15.2.tar.bz2", - "tar -xvjf postgresql-15.2.tar.bz2", - "cd postgresql-15.2", - "mkdir ~/pgsql", - "curl -LO https://ftp.gnu.org/gnu/readline/readline-8.1.tar.gz", - "tar -xvzf readline-8.1.tar.gz", - "cd readline-8.1", - "./configure --prefix=$HOME/pgsql" - ], - [TerminalKind.Mongo]: [ - "curl -s https://ipinfo.io", - "curl -LO https://downloads.mongodb.com/compass/mongosh-2.3.8-linux-x64.tgz", - "tar -xvzf mongosh-2.3.8-linux-x64.tgz", - "mkdir -p ~/mongosh && mv mongosh-2.3.8-linux-x64/* ~/mongosh/", - "echo 'export PATH=$PATH:$HOME/mongosh/bin' >> ~/.bashrc", - "source ~/.bashrc", - "mongosh --version" - ], - [TerminalKind.VCoreMongo]: [ - "curl -s https://ipinfo.io", - "curl -LO https://downloads.mongodb.com/compass/mongosh-2.3.8-linux-x64.tgz", - "tar -xvzf mongosh-2.3.8-linux-x64.tgz", - "mkdir -p ~/mongosh && mv mongosh-2.3.8-linux-x64/* ~/mongosh/", - "echo 'export PATH=$PATH:$HOME/mongosh/bin' >> ~/.bashrc", - "source ~/.bashrc", - "mongosh --version" - ], - [TerminalKind.Cassandra]: [ - "curl -s https://ipinfo.io", - "curl -LO https://downloads.apache.org/cassandra/4.1.2/apache-cassandra-4.1.2-bin.tar.gz", - "tar -xvzf apache-cassandra-4.1.2-bin.tar.gz", - "cd apache-cassandra-4.1.2", - "mkdir ~/cassandra", - "echo 'export CASSANDRA_HOME=$HOME/cassandra' >> ~/.bashrc", - "source ~/.bashrc" - ], - [TerminalKind.Default]: [ - "echo Unknown Shell" - ], +export interface CommandConfig { + host: string, + name: string, + password: string, + endpoint: string +} + +export const commands = (terminalKind: TerminalKind, config?: CommandConfig): string[] => { + switch (terminalKind) { + case TerminalKind.Postgres: + return [ + "curl -s https://ipinfo.io", + "curl -LO https://ftp.postgresql.org/pub/source/v15.2/postgresql-15.2.tar.bz2", + "tar -xvjf postgresql-15.2.tar.bz2", + "cd postgresql-15.2", + "mkdir ~/pgsql", + "curl -LO https://ftp.gnu.org/gnu/readline/readline-8.1.tar.gz", + "tar -xvzf readline-8.1.tar.gz", + "cd readline-8.1", + "./configure --prefix=$HOME/pgsql" + ]; + case TerminalKind.Mongo || TerminalKind.VCoreMongo: + return [ + "curl -s https://ipinfo.io", + "curl -LO https://downloads.mongodb.com/compass/mongosh-2.3.8-linux-x64.tgz", + "tar -xvzf mongosh-2.3.8-linux-x64.tgz", + "mkdir -p ~/mongosh && mv mongosh-2.3.8-linux-x64/* ~/mongosh/", + "echo 'export PATH=$PATH:$HOME/mongosh/bin' >> ~/.bashrc", + "source ~/.bashrc", + "mongosh --version", + `mongosh --host ${config.host} --port 10255 --username ${config.name} --password ${config.password} --ssl --sslAllowInvalidCertificates` + ]; + case TerminalKind.Cassandra: + return [ + "curl -s https://ipinfo.io", + "curl -LO https://archive.apache.org/dist/cassandra/5.0.3/apache-cassandra-5.0.3-bin.tar.gz", + "tar -xvzf apache-cassandra-5.0.3-bin.tar.gz", + "mkdir -p ~/cassandra && mv apache-cassandra-5.0.3/* ~/cassandra/", + "echo 'export PATH=$PATH:$HOME/cassandra/bin' >> ~/.bashrc", + "echo 'export SSL_VERSION=TLSv1_2' >> ~/.bashrc", + "echo 'export SSL_VALIDATE=false' >> ~/.bashrc", + "source ~/.bashrc", + + `cqlsh ${config.host} 10350 -u ${config.name} -p ${config.password} --ssl --protocol-version=4` + ]; + default: + return ["echo Unknown Shell"]; + } +} + +const getHostFromUrl = (mongoEndpoint: string): string => { + try { + const url = new URL(mongoEndpoint); + return url.hostname; + } catch (error) { + console.error("Invalid Mongo Endpoint URL:", error); + return ""; + } }; \ No newline at end of file diff --git a/src/Explorer/Tabs/CloudShellTab/Data.tsx b/src/Explorer/Tabs/CloudShellTab/Data.tsx index a31c9d8d5..b09a882db 100644 --- a/src/Explorer/Tabs/CloudShellTab/Data.tsx +++ b/src/Explorer/Tabs/CloudShellTab/Data.tsx @@ -51,7 +51,16 @@ export const putEphemeralUserSettings = async (userSubscriptionId: string, userR preferredOsType: OsType.Linux, preferredShellType: ShellType.Bash, preferredLocation: userRegion, - networkType: NetworkType.Default, + terminalSettings: { + fontSize: "Medium", + fontStyle: "monospace" + }, + vnetSettings: { + networkProfileResourceId: "/subscriptions/80be3961-0521-4a0a-8570-5cd5a4e2f98c/resourceGroups/neesharma-stage/providers/Microsoft.Network/networkProfiles/aci-networkProfile-eastus2", + relayNamespaceResourceId: "/subscriptions/80be3961-0521-4a0a-8570-5cd5a4e2f98c/resourceGroups/neesharma-stage/providers/Microsoft.Relay/namespaces/neesharma-stage-relay-namespace", + location: "eastus2" + }, + networkType: NetworkType.Isolated, sessionType: SessionType.Ephemeral, userSubscription: userSubscriptionId, } diff --git a/src/Explorer/Tabs/CloudShellTab/UseTerminal.tsx b/src/Explorer/Tabs/CloudShellTab/UseTerminal.tsx index 34755cf12..f6756f132 100644 --- a/src/Explorer/Tabs/CloudShellTab/UseTerminal.tsx +++ b/src/Explorer/Tabs/CloudShellTab/UseTerminal.tsx @@ -3,12 +3,15 @@ */ import { Terminal } from "xterm"; +import { TerminalKind } from "../../../Contracts/ViewModels"; import { userContext } from "../../../UserContext"; import { AttachAddon } from "./AttachAddOn"; +import { getCommands } from "./Commands"; import { authorizeSession, connectTerminal, getNormalizedRegion, getUserSettings, provisionConsole, putEphemeralUserSettings, registerCloudShellProvider, validateUserSettings, verifyCloudshellProviderRegistration } from "./Data"; import { LogError, LogInfo } from "./LogFormatter"; +import { listKeys } from "Utils/arm/generatedClients/cosmos/databaseAccounts"; -export const startCloudShellterminal = async (xterminal: Terminal, initCommands: string, authorizationToken: any) => { +export const startCloudShellterminal = async (xterminal: Terminal, shellType: TerminalKind) => { // validate that the subscription id is registered in the Cloudshell namespace try { @@ -43,9 +46,12 @@ export const startCloudShellterminal = async (xterminal: Terminal, initCommands: return{}; } - const socket = new WebSocket(socketUri); + let socket = new WebSocket(socketUri); - configureSocket(socket, socketUri, xterminal, initCommands, 0); + let keys = await listKeys(userContext.subscriptionId, userContext.resourceGroup, userContext.databaseAccount.name); + + const initCommands = getCommands(shellType, keys.primaryMasterKey); + socket = configureSocket(socket, socketUri, xterminal, initCommands, 0); const attachAddon = new AttachAddon(socket); xterminal.loadAddon(attachAddon);