minor changes

This commit is contained in:
Sourabh Jain 2025-04-09 23:07:40 +05:30
parent b26420cd85
commit bfe778fa11
8 changed files with 65 additions and 64 deletions

View File

@ -14,7 +14,7 @@ import {
registerCloudShellProvider, registerCloudShellProvider,
verifyCloudShellProviderRegistration verifyCloudShellProviderRegistration
} from "./Data/CloudShellClient"; } from "./Data/CloudShellClient";
import { END_MARKER, START_MARKER } from "./ShellTypes/AbstractShellHandler"; import { START_MARKER, AbstractShellHandler } from "./ShellTypes/AbstractShellHandler";
import { ShellTypeHandlerFactory } from "./ShellTypes/ShellTypeFactory"; import { ShellTypeHandlerFactory } from "./ShellTypes/ShellTypeFactory";
import { AttachAddon } from "./Utils/AttachAddOn"; import { AttachAddon } from "./Utils/AttachAddOn";
import { askConfirmation, wait } from "./Utils/CommonUtils"; import { askConfirmation, wait } from "./Utils/CommonUtils";
@ -62,7 +62,7 @@ export const startCloudShellTerminal =
} }
// Get the shell handler for this type // Get the shell handler for this type
const shellHandler = ShellTypeHandlerFactory.getHandler(shellType); const shellHandler = await ShellTypeHandlerFactory.getHandler(shellType);
// Configure WebSocket connection with shell-specific commands // Configure WebSocket connection with shell-specific commands
const socket = await establishTerminalConnection( const socket = await establishTerminalConnection(
terminal, terminal,
@ -162,7 +162,7 @@ export const provisionCloudShellSession = async (
*/ */
export const establishTerminalConnection = async ( export const establishTerminalConnection = async (
terminal: Terminal, terminal: Terminal,
shellHandler: any, shellHandler: AbstractShellHandler,
socketUri: string, socketUri: string,
provisionConsoleResponse: any, provisionConsoleResponse: any,
targetUri: string targetUri: string
@ -171,15 +171,14 @@ export const establishTerminalConnection = async (
let socket = new WebSocket(socketUri); let socket = new WebSocket(socketUri);
// Get shell-specific initial commands // Get shell-specific initial commands
const initCommands = await shellHandler.getInitialCommands(); const initCommands = shellHandler.getInitialCommands();
// Configure the socket // Configure the socket
socket = await configureSocketConnection(socket, socketUri, terminal, initCommands, 0); socket = await configureSocketConnection(socket, socketUri, terminal, initCommands, 0);
const options = { const options = {
startMarker: START_MARKER, startMarker: START_MARKER,
endMarker: END_MARKER, shellHandler: shellHandler
terminalSuppressedData: shellHandler.getTerminalSuppressedData()
}; };
// Attach the terminal addon // Attach the terminal addon

View File

@ -1,43 +1,21 @@
import { userContext } from "../../../../UserContext";
import { listKeys } from "../../../../Utils/arm/generatedClients/cosmos/databaseAccounts";
import { getHostFromUrl } from "../Utils/CommonUtils";
export const START_MARKER = `echo "START INITIALIZATION" > /dev/null`; export const START_MARKER = `echo "START INITIALIZATION" > /dev/null`;
export const END_MARKER = `echo "END INITIALIZATION" > /dev/null`;
export abstract class AbstractShellHandler { export abstract class AbstractShellHandler {
abstract getShellName(): string; abstract getShellName(): string;
abstract getSetUpCommands(): string[]; abstract getSetUpCommands(): string[];
abstract getConnectionCommands(config: any): string[]; abstract getConnectionCommand(): string;
abstract getEndpoint(): string; abstract getEndpoint(): string;
abstract getTerminalSuppressedData(): string; abstract getTerminalSuppressedData(): string;
public async getInitialCommands(): Promise<string> { public getInitialCommands(): string {
const dbAccount = userContext.databaseAccount;
const dbName = dbAccount.name;
let key = "";
if (dbName) {
const keys = await listKeys(userContext.subscriptionId, userContext.resourceGroup, dbName);
key = keys?.primaryMasterKey || "";
}
const setupCommands = this.getSetUpCommands(); const setupCommands = this.getSetUpCommands();
const connectionCommand = this.getConnectionCommand();
const config = {
host: getHostFromUrl(this.getEndpoint()),
name: dbName,
password: key,
endpoint: this.getEndpoint(),
};
const connectionCommands = this.getConnectionCommands(config);
const allCommands = [ const allCommands = [
START_MARKER, START_MARKER,
...setupCommands, ...setupCommands,
END_MARKER, ...connectionCommand
...connectionCommands
]; ];
return allCommands.join("\n").concat("\n"); return allCommands.join("\n").concat("\n");

View File

@ -4,11 +4,18 @@
*/ */
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
import { getHostFromUrl } from "../Utils/CommonUtils";
import { AbstractShellHandler } from "./AbstractShellHandler"; import { AbstractShellHandler } from "./AbstractShellHandler";
const PACKAGE_VERSION: string = "5.0.3"; const PACKAGE_VERSION: string = "5.0.3";
export class CassandraShellHandler extends AbstractShellHandler { export class CassandraShellHandler extends AbstractShellHandler {
private _key: string;
constructor(private key: string) {
super();
this.key = key;
}
public getShellName(): string { public getShellName(): string {
return "Cassandra"; return "Cassandra";
@ -31,10 +38,8 @@ export class CassandraShellHandler extends AbstractShellHandler {
]; ];
} }
public getConnectionCommands(config: any): string[] { public getConnectionCommand(): string {
return [ return `cqlsh ${getHostFromUrl(this.getEndpoint())} 10350 -u ${userContext.databaseAccount?.name} -p ${this._key} --ssl --protocol-version=4`;
`cqlsh ${config.host} 10350 -u ${config.name} -p ${config.password} --ssl --protocol-version=4`
];
} }
public getTerminalSuppressedData(): string { public getTerminalSuppressedData(): string {

View File

@ -5,11 +5,18 @@
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
import { AbstractShellHandler } from "./AbstractShellHandler"; import { AbstractShellHandler } from "./AbstractShellHandler";
import { getHostFromUrl } from "../Utils/CommonUtils";
const PACKAGE_VERSION: string = "2.3.8"; const PACKAGE_VERSION: string = "2.3.8";
export class MongoShellHandler extends AbstractShellHandler { export class MongoShellHandler extends AbstractShellHandler {
private _key: string;
constructor(private key: string) {
super();
this.key = key;
}
public getShellName(): string { public getShellName(): string {
return "MongoDB"; return "MongoDB";
} }
@ -29,10 +36,8 @@ export class MongoShellHandler extends AbstractShellHandler {
]; ];
} }
public getConnectionCommands(config: any): string[] { public getConnectionCommand(): string {
return [ return `mongosh --host ${getHostFromUrl(this.getEndpoint())} --port 10255 --username ${userContext.databaseAccount?.name} --password ${this._key} --tls --tlsAllowInvalidCertificates`;
`mongosh --host ${config.host} --port 10255 --username ${config.name} --password ${config.password} --tls --tlsAllowInvalidCertificates`
];
} }
public getTerminalSuppressedData(): string { public getTerminalSuppressedData(): string {

View File

@ -32,10 +32,8 @@ export class PostgresShellHandler extends AbstractShellHandler {
]; ];
} }
public getConnectionCommands(config: any): string[] { public getConnectionCommand(): string {
return [ return `psql 'read -p "Enter Database Name: " dbname && read -p "Enter Username: " username && host=${this.getEndpoint()} port=5432 dbname=$dbname user=$username sslmode=require'`;
`psql 'read -p "Enter Database Name: " dbname && read -p "Enter Username: " username && host=${config.endpoint} port=5432 dbname=$dbname user=$username sslmode=require'`
];
} }
public getTerminalSuppressedData(): string { public getTerminalSuppressedData(): string {

View File

@ -9,23 +9,37 @@ import { MongoShellHandler } from "./MongoShellHandler";
import { PostgresShellHandler } from "./PostgresShellHandler"; import { PostgresShellHandler } from "./PostgresShellHandler";
import { VCoreMongoShellHandler } from "./VCoreMongoShellHandler"; import { VCoreMongoShellHandler } from "./VCoreMongoShellHandler";
import { AbstractShellHandler } from "./AbstractShellHandler"; import { AbstractShellHandler } from "./AbstractShellHandler";
import { userContext } from "../../../../UserContext";
import { listKeys } from "../../../../Utils/arm/generatedClients/cosmos/databaseAccounts";
export class ShellTypeHandlerFactory { export class ShellTypeHandlerFactory {
/** /**
* Gets the appropriate handler for the given shell type * Gets the appropriate handler for the given shell type
*/ */
public static getHandler(shellType: TerminalKind): AbstractShellHandler { public static async getHandler(shellType: TerminalKind): Promise<AbstractShellHandler> {
switch (shellType) { switch (shellType) {
case TerminalKind.Postgres: case TerminalKind.Postgres:
return new PostgresShellHandler(); return new PostgresShellHandler();
case TerminalKind.Mongo: case TerminalKind.Mongo:
return new MongoShellHandler(); return new MongoShellHandler(await ShellTypeHandlerFactory.getKey());
case TerminalKind.VCoreMongo: case TerminalKind.VCoreMongo:
return new VCoreMongoShellHandler(); return new VCoreMongoShellHandler();
case TerminalKind.Cassandra: case TerminalKind.Cassandra:
return new CassandraShellHandler(); return new CassandraShellHandler(await ShellTypeHandlerFactory.getKey());
default: default:
throw new Error(`Unsupported shell type: ${shellType}`); throw new Error(`Unsupported shell type: ${shellType}`);
} }
} }
public static async getKey(): Promise<string> {
const dbName = userContext.databaseAccount.name;
let key = "";
if (dbName) {
const keys = await listKeys(userContext.subscriptionId, userContext.resourceGroup, dbName);
key = keys?.primaryMasterKey || "";
}
return key;
}
} }

View File

@ -29,10 +29,8 @@ export class VCoreMongoShellHandler extends AbstractShellHandler {
]; ];
} }
public getConnectionCommands(config: any): string[] { public getConnectionCommand(): string {
return [ return `read -p "Enter username: " username && mongosh "mongodb+srv://$username:@${this.getEndpoint()}/?authMechanism=SCRAM-SHA-256&retrywrites=false&maxIdleTimeMS=120000" --tls --tlsAllowInvalidCertificates`;
`read -p "Enter username: " username && mongosh "mongodb+srv://$username:@${config.endpoint}/?authMechanism=SCRAM-SHA-256&retrywrites=false&maxIdleTimeMS=120000" --tls --tlsAllowInvalidCertificates`
];
} }
public getTerminalSuppressedData(): string { public getTerminalSuppressedData(): string {

View File

@ -1,11 +1,11 @@
import { AbstractShellHandler } from 'Explorer/Tabs/CloudShellTab/ShellTypes/AbstractShellHandler';
import { IDisposable, ITerminalAddon, Terminal } from 'xterm'; import { IDisposable, ITerminalAddon, Terminal } from 'xterm';
interface IAttachOptions { interface IAttachOptions {
bidirectional?: boolean; bidirectional?: boolean;
startMarker?: string; startMarker?: string;
endMarker?: string; shellHandler?: AbstractShellHandler;
terminalSuppressedData?: string;
} }
export class AttachAddon implements ITerminalAddon { export class AttachAddon implements ITerminalAddon {
@ -14,11 +14,10 @@ export class AttachAddon implements ITerminalAddon {
private _disposables: IDisposable[] = []; private _disposables: IDisposable[] = [];
private _socketData: string; private _socketData: string;
private _flag: boolean = true; private _allowTerminalWrite: boolean = true;
private _startMarker: string; private _startMarker: string;
private _endMarker: string; private _shellHandler: AbstractShellHandler;
private _terminalSuppressedData: string;
constructor(socket: WebSocket, options?: IAttachOptions) { constructor(socket: WebSocket, options?: IAttachOptions) {
this._socket = socket; this._socket = socket;
@ -26,10 +25,9 @@ export class AttachAddon implements ITerminalAddon {
this._socket.binaryType = 'arraybuffer'; this._socket.binaryType = 'arraybuffer';
this._bidirectional = !(options && options.bidirectional === false); this._bidirectional = !(options && options.bidirectional === false);
this._startMarker = options?.startMarker; this._startMarker = options?.startMarker;
this._endMarker = options?.endMarker; this._shellHandler = options?.shellHandler;
this._terminalSuppressedData = options?.terminalSuppressedData;
this._socketData = ''; this._socketData = '';
this._flag = true; this._allowTerminalWrite = true;
} }
public activate(terminal: Terminal): void { public activate(terminal: Terminal): void {
@ -82,15 +80,21 @@ export class AttachAddon implements ITerminalAddon {
} }
if (data.includes(this._startMarker)) { if (data.includes(this._startMarker)) {
this._flag = false; this._allowTerminalWrite = false;
terminal.write("Preparing environment...\r\n"); terminal.write(`Preparing ${this._shellHandler.getShellName()} environment...\r\n`);
} }
if (this._flag && this._terminalSuppressedData && this._terminalSuppressedData.length > 0 && !data.includes(this._terminalSuppressedData)) { if (this._allowTerminalWrite &&
this._shellHandler?.getTerminalSuppressedData() &&
this._shellHandler?.getTerminalSuppressedData().length > 0 &&
!data.includes(this._shellHandler?.getTerminalSuppressedData())) {
terminal.write(data); terminal.write(data);
} }
if (data.includes(this._endMarker)) { console.log('data', data);
this._flag = true; console.log("connection command", this._shellHandler.getConnectionCommand());
console.log("----")
if (data.includes(this._shellHandler.getConnectionCommand())) {
this._allowTerminalWrite = true;
} }
}) })
); );